JSON for Modern C++ 3.9.1

json.hpp
1 /*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.9.1
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-2019 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 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
31 #define INCLUDE_NLOHMANN_JSON_HPP_
32
33 #define NLOHMANN_JSON_VERSION_MAJOR 3
34 #define NLOHMANN_JSON_VERSION_MINOR 9
35 #define NLOHMANN_JSON_VERSION_PATCH 1
36
37 #include <algorithm> // all_of, find, for_each
38 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
39 #include <functional> // hash, less
40 #include <initializer_list> // initializer_list
41 #include <iosfwd> // istream, ostream
42 #include <iterator> // random_access_iterator_tag
43 #include <memory> // unique_ptr
44 #include <numeric> // accumulate
45 #include <string> // string, stoi, to_string
46 #include <utility> // declval, forward, move, pair, swap
47 #include <vector> // vector
48
49 // #include <nlohmann/adl_serializer.hpp>
50
51
52 #include <type_traits>
53 #include <utility>
54
55 // #include <nlohmann/detail/conversions/from_json.hpp>
56
57
58 #include <algorithm> // transform
59 #include <array> // array
60 #include <forward_list> // forward_list
61 #include <iterator> // inserter, front_inserter, end
62 #include <map> // map
63 #include <string> // string
64 #include <tuple> // tuple, make_tuple
65 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
66 #include <unordered_map> // unordered_map
67 #include <utility> // pair, declval
68 #include <valarray> // valarray
69
70 // #include <nlohmann/detail/exceptions.hpp>
71
72
73 #include <exception> // exception
74 #include <stdexcept> // runtime_error
75 #include <string> // to_string
76 #include <vector> // vector
77
78 // #include <nlohmann/detail/value_t.hpp>
79
80
81 #include <array> // array
82 #include <cstddef> // size_t
83 #include <cstdint> // uint8_t
84 #include <string> // string
85
86 namespace nlohmann
87 {
88 namespace detail
89 {
91 // JSON type enumeration //
93
118 enum class value_t : std::uint8_t
119 {
120 null,
121 object,
122 array,
123 string,
124 boolean,
125 number_integer,
126 number_unsigned,
127 number_float,
128 binary,
129 discarded
130 };
131
145 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
146 {
147 static constexpr std::array<std::uint8_t, 9> order = {{
148 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
149 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
150 6 /* binary */
151 }
152 };
153
154 const auto l_index = static_cast<std::size_t>(lhs);
155 const auto r_index = static_cast<std::size_t>(rhs);
156 return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
157 }
158 } // namespace detail
159 } // namespace nlohmann
160
161 // #include <nlohmann/detail/string_escape.hpp>
162
163
164 #include <string>
165 // #include <nlohmann/detail/macro_scope.hpp>
166
167
168 #include <utility> // pair
169 // #include <nlohmann/thirdparty/hedley/hedley.hpp>
170
171
172 /* Hedley - https://nemequ.github.io/hedley
173 * Created by Evan Nemerson <evan@nemerson.com>
174 *
175 * To the extent possible under law, the author(s) have dedicated all
176 * copyright and related and neighboring rights to this software to
177 * the public domain worldwide. This software is distributed without
178 * any warranty.
179 *
180 * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
181 * SPDX-License-Identifier: CC0-1.0
182 */
183
184 #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
185 #if defined(JSON_HEDLEY_VERSION)
186 #undef JSON_HEDLEY_VERSION
187 #endif
188 #define JSON_HEDLEY_VERSION 15
189
190 #if defined(JSON_HEDLEY_STRINGIFY_EX)
191 #undef JSON_HEDLEY_STRINGIFY_EX
192 #endif
193 #define JSON_HEDLEY_STRINGIFY_EX(x) #x
194
195 #if defined(JSON_HEDLEY_STRINGIFY)
196 #undef JSON_HEDLEY_STRINGIFY
197 #endif
198 #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
199
200 #if defined(JSON_HEDLEY_CONCAT_EX)
201 #undef JSON_HEDLEY_CONCAT_EX
202 #endif
203 #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
204
205 #if defined(JSON_HEDLEY_CONCAT)
206 #undef JSON_HEDLEY_CONCAT
207 #endif
208 #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
209
210 #if defined(JSON_HEDLEY_CONCAT3_EX)
211 #undef JSON_HEDLEY_CONCAT3_EX
212 #endif
213 #define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
214
215 #if defined(JSON_HEDLEY_CONCAT3)
216 #undef JSON_HEDLEY_CONCAT3
217 #endif
218 #define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
219
220 #if defined(JSON_HEDLEY_VERSION_ENCODE)
221 #undef JSON_HEDLEY_VERSION_ENCODE
222 #endif
223 #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
224
225 #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
226 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
227 #endif
228 #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
229
230 #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
231 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
232 #endif
233 #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
234
235 #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
236 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
237 #endif
238 #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
239
240 #if defined(JSON_HEDLEY_GNUC_VERSION)
241 #undef JSON_HEDLEY_GNUC_VERSION
242 #endif
243 #if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
244 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
245 #elif defined(__GNUC__)
246 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
247 #endif
248
249 #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
250 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
251 #endif
252 #if defined(JSON_HEDLEY_GNUC_VERSION)
253 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
254 #else
255 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
256 #endif
257
258 #if defined(JSON_HEDLEY_MSVC_VERSION)
259 #undef JSON_HEDLEY_MSVC_VERSION
260 #endif
261 #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
262 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
263 #elif defined(_MSC_FULL_VER) && !defined(__ICL)
264 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
265 #elif defined(_MSC_VER) && !defined(__ICL)
266 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
267 #endif
268
269 #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
270 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
271 #endif
272 #if !defined(JSON_HEDLEY_MSVC_VERSION)
273 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
274 #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
275 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
276 #elif defined(_MSC_VER) && (_MSC_VER >= 1200)
277 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
278 #else
279 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
280 #endif
281
282 #if defined(JSON_HEDLEY_INTEL_VERSION)
283 #undef JSON_HEDLEY_INTEL_VERSION
284 #endif
285 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
286 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
287 #elif defined(__INTEL_COMPILER) && !defined(__ICL)
288 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
289 #endif
290
291 #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
292 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
293 #endif
294 #if defined(JSON_HEDLEY_INTEL_VERSION)
295 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
296 #else
297 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
298 #endif
299
300 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
301 #undef JSON_HEDLEY_INTEL_CL_VERSION
302 #endif
303 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
304 #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
305 #endif
306
307 #if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
308 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
309 #endif
310 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
311 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
312 #else
313 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
314 #endif
315
316 #if defined(JSON_HEDLEY_PGI_VERSION)
317 #undef JSON_HEDLEY_PGI_VERSION
318 #endif
319 #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
320 #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
321 #endif
322
323 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
324 #undef JSON_HEDLEY_PGI_VERSION_CHECK
325 #endif
326 #if defined(JSON_HEDLEY_PGI_VERSION)
327 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
328 #else
329 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
330 #endif
331
332 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
333 #undef JSON_HEDLEY_SUNPRO_VERSION
334 #endif
335 #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
336 #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)
337 #elif defined(__SUNPRO_C)
338 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
339 #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
340 #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)
341 #elif defined(__SUNPRO_CC)
342 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
343 #endif
344
345 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
346 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
347 #endif
348 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
349 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
350 #else
351 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
352 #endif
353
354 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
355 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
356 #endif
357 #if defined(__EMSCRIPTEN__)
358 #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
359 #endif
360
361 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
362 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
363 #endif
364 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
365 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
366 #else
367 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
368 #endif
369
370 #if defined(JSON_HEDLEY_ARM_VERSION)
371 #undef JSON_HEDLEY_ARM_VERSION
372 #endif
373 #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
374 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
375 #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
376 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
377 #endif
378
379 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
380 #undef JSON_HEDLEY_ARM_VERSION_CHECK
381 #endif
382 #if defined(JSON_HEDLEY_ARM_VERSION)
383 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
384 #else
385 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
386 #endif
387
388 #if defined(JSON_HEDLEY_IBM_VERSION)
389 #undef JSON_HEDLEY_IBM_VERSION
390 #endif
391 #if defined(__ibmxl__)
392 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
393 #elif defined(__xlC__) && defined(__xlC_ver__)
394 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
395 #elif defined(__xlC__)
396 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
397 #endif
398
399 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
400 #undef JSON_HEDLEY_IBM_VERSION_CHECK
401 #endif
402 #if defined(JSON_HEDLEY_IBM_VERSION)
403 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
404 #else
405 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
406 #endif
407
408 #if defined(JSON_HEDLEY_TI_VERSION)
409 #undef JSON_HEDLEY_TI_VERSION
410 #endif
411 #if \
412 defined(__TI_COMPILER_VERSION__) && \
413 ( \
414 defined(__TMS470__) || defined(__TI_ARM__) || \
415 defined(__MSP430__) || \
416 defined(__TMS320C2000__) \
417 )
418 #if (__TI_COMPILER_VERSION__ >= 16000000)
419 #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
420 #endif
421 #endif
422
423 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
424 #undef JSON_HEDLEY_TI_VERSION_CHECK
425 #endif
426 #if defined(JSON_HEDLEY_TI_VERSION)
427 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
428 #else
429 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
430 #endif
431
432 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
433 #undef JSON_HEDLEY_TI_CL2000_VERSION
434 #endif
435 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
436 #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
437 #endif
438
439 #if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
440 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
441 #endif
442 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
443 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
444 #else
445 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
446 #endif
447
448 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
449 #undef JSON_HEDLEY_TI_CL430_VERSION
450 #endif
451 #if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
452 #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
453 #endif
454
455 #if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
456 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
457 #endif
458 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
459 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
460 #else
461 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
462 #endif
463
464 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
465 #undef JSON_HEDLEY_TI_ARMCL_VERSION
466 #endif
467 #if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
468 #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
469 #endif
470
471 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
472 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
473 #endif
474 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
475 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
476 #else
477 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
478 #endif
479
480 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
481 #undef JSON_HEDLEY_TI_CL6X_VERSION
482 #endif
483 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
484 #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
485 #endif
486
487 #if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
488 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
489 #endif
490 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
491 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
492 #else
493 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
494 #endif
495
496 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
497 #undef JSON_HEDLEY_TI_CL7X_VERSION
498 #endif
499 #if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
500 #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
501 #endif
502
503 #if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
504 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
505 #endif
506 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
507 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
508 #else
509 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
510 #endif
511
512 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
513 #undef JSON_HEDLEY_TI_CLPRU_VERSION
514 #endif
515 #if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
516 #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
517 #endif
518
519 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
520 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
521 #endif
522 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
523 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
524 #else
525 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
526 #endif
527
528 #if defined(JSON_HEDLEY_CRAY_VERSION)
529 #undef JSON_HEDLEY_CRAY_VERSION
530 #endif
531 #if defined(_CRAYC)
532 #if defined(_RELEASE_PATCHLEVEL)
533 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
534 #else
535 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
536 #endif
537 #endif
538
539 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
540 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
541 #endif
542 #if defined(JSON_HEDLEY_CRAY_VERSION)
543 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
544 #else
545 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
546 #endif
547
548 #if defined(JSON_HEDLEY_IAR_VERSION)
549 #undef JSON_HEDLEY_IAR_VERSION
550 #endif
551 #if defined(__IAR_SYSTEMS_ICC__)
552 #if __VER__ > 1000
553 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
554 #else
555 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
556 #endif
557 #endif
558
559 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
560 #undef JSON_HEDLEY_IAR_VERSION_CHECK
561 #endif
562 #if defined(JSON_HEDLEY_IAR_VERSION)
563 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
564 #else
565 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
566 #endif
567
568 #if defined(JSON_HEDLEY_TINYC_VERSION)
569 #undef JSON_HEDLEY_TINYC_VERSION
570 #endif
571 #if defined(__TINYC__)
572 #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
573 #endif
574
575 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
576 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
577 #endif
578 #if defined(JSON_HEDLEY_TINYC_VERSION)
579 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
580 #else
581 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
582 #endif
583
584 #if defined(JSON_HEDLEY_DMC_VERSION)
585 #undef JSON_HEDLEY_DMC_VERSION
586 #endif
587 #if defined(__DMC__)
588 #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
589 #endif
590
591 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
592 #undef JSON_HEDLEY_DMC_VERSION_CHECK
593 #endif
594 #if defined(JSON_HEDLEY_DMC_VERSION)
595 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
596 #else
597 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
598 #endif
599
600 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
601 #undef JSON_HEDLEY_COMPCERT_VERSION
602 #endif
603 #if defined(__COMPCERT_VERSION__)
604 #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
605 #endif
606
607 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
608 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
609 #endif
610 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
611 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
612 #else
613 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
614 #endif
615
616 #if defined(JSON_HEDLEY_PELLES_VERSION)
617 #undef JSON_HEDLEY_PELLES_VERSION
618 #endif
619 #if defined(__POCC__)
620 #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
621 #endif
622
623 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
624 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
625 #endif
626 #if defined(JSON_HEDLEY_PELLES_VERSION)
627 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
628 #else
629 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
630 #endif
631
632 #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
633 #undef JSON_HEDLEY_MCST_LCC_VERSION
634 #endif
635 #if defined(__LCC__) && defined(__LCC_MINOR__)
636 #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
637 #endif
638
639 #if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
640 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
641 #endif
642 #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
643 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
644 #else
645 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
646 #endif
647
648 #if defined(JSON_HEDLEY_GCC_VERSION)
649 #undef JSON_HEDLEY_GCC_VERSION
650 #endif
651 #if \
652 defined(JSON_HEDLEY_GNUC_VERSION) && \
653 !defined(__clang__) && \
654 !defined(JSON_HEDLEY_INTEL_VERSION) && \
655 !defined(JSON_HEDLEY_PGI_VERSION) && \
656 !defined(JSON_HEDLEY_ARM_VERSION) && \
657 !defined(JSON_HEDLEY_CRAY_VERSION) && \
658 !defined(JSON_HEDLEY_TI_VERSION) && \
659 !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
660 !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
661 !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
662 !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
663 !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
664 !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
665 !defined(__COMPCERT__) && \
666 !defined(JSON_HEDLEY_MCST_LCC_VERSION)
667 #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
668 #endif
669
670 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
671 #undef JSON_HEDLEY_GCC_VERSION_CHECK
672 #endif
673 #if defined(JSON_HEDLEY_GCC_VERSION)
674 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
675 #else
676 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
677 #endif
678
679 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
680 #undef JSON_HEDLEY_HAS_ATTRIBUTE
681 #endif
682 #if \
683 defined(__has_attribute) && \
684 ( \
685 (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
686 )
687 # define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
688 #else
689 # define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
690 #endif
691
692 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
693 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
694 #endif
695 #if defined(__has_attribute)
696 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
697 #else
698 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
699 #endif
700
701 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
702 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
703 #endif
704 #if defined(__has_attribute)
705 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
706 #else
707 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
708 #endif
709
710 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
711 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
712 #endif
713 #if \
714 defined(__has_cpp_attribute) && \
715 defined(__cplusplus) && \
716 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
717 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
718 #else
719 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
720 #endif
721
722 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
723 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
724 #endif
725 #if !defined(__cplusplus) || !defined(__has_cpp_attribute)
726 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
727 #elif \
728 !defined(JSON_HEDLEY_PGI_VERSION) && \
729 !defined(JSON_HEDLEY_IAR_VERSION) && \
730 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
731 (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
732 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
733 #else
734 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
735 #endif
736
737 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
738 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
739 #endif
740 #if defined(__has_cpp_attribute) && defined(__cplusplus)
741 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
742 #else
743 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
744 #endif
745
746 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
747 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
748 #endif
749 #if defined(__has_cpp_attribute) && defined(__cplusplus)
750 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
751 #else
752 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
753 #endif
754
755 #if defined(JSON_HEDLEY_HAS_BUILTIN)
756 #undef JSON_HEDLEY_HAS_BUILTIN
757 #endif
758 #if defined(__has_builtin)
759 #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
760 #else
761 #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
762 #endif
763
764 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
765 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
766 #endif
767 #if defined(__has_builtin)
768 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
769 #else
770 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
771 #endif
772
773 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
774 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
775 #endif
776 #if defined(__has_builtin)
777 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
778 #else
779 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
780 #endif
781
782 #if defined(JSON_HEDLEY_HAS_FEATURE)
783 #undef JSON_HEDLEY_HAS_FEATURE
784 #endif
785 #if defined(__has_feature)
786 #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
787 #else
788 #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
789 #endif
790
791 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
792 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
793 #endif
794 #if defined(__has_feature)
795 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
796 #else
797 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
798 #endif
799
800 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
801 #undef JSON_HEDLEY_GCC_HAS_FEATURE
802 #endif
803 #if defined(__has_feature)
804 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
805 #else
806 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
807 #endif
808
809 #if defined(JSON_HEDLEY_HAS_EXTENSION)
810 #undef JSON_HEDLEY_HAS_EXTENSION
811 #endif
812 #if defined(__has_extension)
813 #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
814 #else
815 #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
816 #endif
817
818 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
819 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
820 #endif
821 #if defined(__has_extension)
822 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
823 #else
824 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
825 #endif
826
827 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
828 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
829 #endif
830 #if defined(__has_extension)
831 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
832 #else
833 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
834 #endif
835
836 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
837 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
838 #endif
839 #if defined(__has_declspec_attribute)
840 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
841 #else
842 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
843 #endif
844
845 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
846 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
847 #endif
848 #if defined(__has_declspec_attribute)
849 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
850 #else
851 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
852 #endif
853
854 #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
855 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
856 #endif
857 #if defined(__has_declspec_attribute)
858 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
859 #else
860 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
861 #endif
862
863 #if defined(JSON_HEDLEY_HAS_WARNING)
864 #undef JSON_HEDLEY_HAS_WARNING
865 #endif
866 #if defined(__has_warning)
867 #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
868 #else
869 #define JSON_HEDLEY_HAS_WARNING(warning) (0)
870 #endif
871
872 #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
873 #undef JSON_HEDLEY_GNUC_HAS_WARNING
874 #endif
875 #if defined(__has_warning)
876 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
877 #else
878 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
879 #endif
880
881 #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
882 #undef JSON_HEDLEY_GCC_HAS_WARNING
883 #endif
884 #if defined(__has_warning)
885 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
886 #else
887 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
888 #endif
889
890 #if \
891 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
892 defined(__clang__) || \
893 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
894 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
895 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
896 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
897 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
898 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
899 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
900 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
901 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
902 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
903 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
904 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
905 JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
906 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
907 JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
908 (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
909 #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
910 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
911 #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
912 #else
913 #define JSON_HEDLEY_PRAGMA(value)
914 #endif
915
916 #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
917 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
918 #endif
919 #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
920 #undef JSON_HEDLEY_DIAGNOSTIC_POP
921 #endif
922 #if defined(__clang__)
923 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
924 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
925 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
926 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
927 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
928 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
929 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
930 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
931 #elif \
932 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
933 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
934 #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
935 #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
936 #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
937 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
938 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
939 #elif \
940 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
941 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
942 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
943 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
944 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
945 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
946 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
947 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
948 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
949 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
950 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
951 #else
952 #define JSON_HEDLEY_DIAGNOSTIC_PUSH
953 #define JSON_HEDLEY_DIAGNOSTIC_POP
954 #endif
955
956 /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
957 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
958 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
959 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
960 #endif
961 #if defined(__cplusplus)
962 # if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
963 # if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
964 # if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
965 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
966 JSON_HEDLEY_DIAGNOSTIC_PUSH \
967 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
968 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
969 _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
970 xpr \
971 JSON_HEDLEY_DIAGNOSTIC_POP
972 # else
973 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
974 JSON_HEDLEY_DIAGNOSTIC_PUSH \
975 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
976 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
977 xpr \
978 JSON_HEDLEY_DIAGNOSTIC_POP
979 # endif
980 # else
981 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
982 JSON_HEDLEY_DIAGNOSTIC_PUSH \
983 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
984 xpr \
985 JSON_HEDLEY_DIAGNOSTIC_POP
986 # endif
987 # endif
988 #endif
989 #if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
990 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
991 #endif
992
993 #if defined(JSON_HEDLEY_CONST_CAST)
994 #undef JSON_HEDLEY_CONST_CAST
995 #endif
996 #if defined(__cplusplus)
997 # define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
998 #elif \
999 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1000 JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1001 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1002 # define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1003 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1004 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1005 ((T) (expr)); \
1006 JSON_HEDLEY_DIAGNOSTIC_POP \
1007 }))
1008 #else
1009 # define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1010 #endif
1011
1012 #if defined(JSON_HEDLEY_REINTERPRET_CAST)
1013 #undef JSON_HEDLEY_REINTERPRET_CAST
1014 #endif
1015 #if defined(__cplusplus)
1016 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1017 #else
1018 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1019 #endif
1020
1021 #if defined(JSON_HEDLEY_STATIC_CAST)
1022 #undef JSON_HEDLEY_STATIC_CAST
1023 #endif
1024 #if defined(__cplusplus)
1025 #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1026 #else
1027 #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1028 #endif
1029
1030 #if defined(JSON_HEDLEY_CPP_CAST)
1031 #undef JSON_HEDLEY_CPP_CAST
1032 #endif
1033 #if defined(__cplusplus)
1034 # if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
1035 # define JSON_HEDLEY_CPP_CAST(T, expr) \
1036 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1037 _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
1038 ((T) (expr)) \
1039 JSON_HEDLEY_DIAGNOSTIC_POP
1040 # elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
1041 # define JSON_HEDLEY_CPP_CAST(T, expr) \
1042 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1043 _Pragma("diag_suppress=Pe137") \
1044 JSON_HEDLEY_DIAGNOSTIC_POP
1045 # else
1046 # define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1047 # endif
1048 #else
1049 # define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1050 #endif
1051
1052 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1053 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1054 #endif
1055 #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
1056 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
1057 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1058 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1059 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1060 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1061 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1062 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1063 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1064 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1065 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1066 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1067 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1068 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1069 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1070 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1071 #elif \
1072 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1073 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1074 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1075 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1076 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1077 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1078 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1079 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1080 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1081 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1082 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1083 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1084 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1085 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1086 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1087 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1088 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1089 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1090 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1091 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1092 #else
1093 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1094 #endif
1095
1096 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1097 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1098 #endif
1099 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1100 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1101 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1102 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1103 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1104 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1105 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1106 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1107 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1108 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1109 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1110 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1111 #elif \
1112 JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1113 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1114 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1115 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1116 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1117 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1118 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1119 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1120 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1121 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1122 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1123 #else
1124 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1125 #endif
1126
1127 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1128 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1129 #endif
1130 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1131 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1132 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1133 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1134 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1135 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1136 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1137 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1138 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1139 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1140 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1141 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1142 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1143 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1144 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1145 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1146 #elif \
1147 JSON_HEDLEY_TI_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 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1151 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1152 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1153 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1154 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1155 #else
1156 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1157 #endif
1158
1159 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1160 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1161 #endif
1162 #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1163 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1164 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1165 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1166 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1167 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1168 #else
1169 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1170 #endif
1171
1172 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1173 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1174 #endif
1175 #if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1176 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1177 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1178 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1179 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1180 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1181 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1182 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1183 #else
1184 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1185 #endif
1186
1187 #if defined(JSON_HEDLEY_DEPRECATED)
1188 #undef JSON_HEDLEY_DEPRECATED
1189 #endif
1190 #if defined(JSON_HEDLEY_DEPRECATED_FOR)
1191 #undef JSON_HEDLEY_DEPRECATED_FOR
1192 #endif
1193 #if \
1194 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1195 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1196 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1197 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1198 #elif \
1199 (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1200 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1201 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1202 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1203 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1204 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1205 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1206 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1207 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1208 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1209 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1210 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1211 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1212 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1213 #elif defined(__cplusplus) && (__cplusplus >= 201402L)
1214 #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1215 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1216 #elif \
1217 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1218 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1219 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1220 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1221 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1222 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1223 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1224 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1225 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1226 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1227 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1228 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1229 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1230 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1231 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1232 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1233 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1234 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1235 #elif \
1236 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1237 JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1238 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1239 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1240 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1241 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1242 #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1243 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1244 #else
1245 #define JSON_HEDLEY_DEPRECATED(since)
1246 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1247 #endif
1248
1249 #if defined(JSON_HEDLEY_UNAVAILABLE)
1250 #undef JSON_HEDLEY_UNAVAILABLE
1251 #endif
1252 #if \
1253 JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1254 JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1255 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1256 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1257 #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1258 #else
1259 #define JSON_HEDLEY_UNAVAILABLE(available_since)
1260 #endif
1261
1262 #if defined()
1263 #undef
1264 #endif
1265 #if defined(_MSG)
1266 #undef _MSG
1267 #endif
1268 #if \
1269 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1270 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1271 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1272 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1273 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1274 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1275 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1276 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1277 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1278 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1279 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1280 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1281 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1282 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1283 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1284 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1285 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1286 #define __attribute__((__warn_unused_result__))
1287 #define _MSG(msg) __attribute__((__warn_unused_result__))
1288 #elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1289 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1290 #define _MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1291 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1292 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1293 #define _MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1294 #elif defined(_Check_return_) /* SAL */
1295 #define _Check_return_
1296 #define _MSG(msg) _Check_return_
1297 #else
1298 #define
1299 #define _MSG(msg)
1300 #endif
1301
1302 #if defined(JSON_HEDLEY_SENTINEL)
1303 #undef JSON_HEDLEY_SENTINEL
1304 #endif
1305 #if \
1306 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1307 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1308 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1309 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1310 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1311 #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1312 #else
1313 #define JSON_HEDLEY_SENTINEL(position)
1314 #endif
1315
1316 #if defined(JSON_HEDLEY_NO_RETURN)
1317 #undef JSON_HEDLEY_NO_RETURN
1318 #endif
1319 #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1320 #define JSON_HEDLEY_NO_RETURN __noreturn
1321 #elif \
1322 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1323 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1324 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1325 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1326 #define JSON_HEDLEY_NO_RETURN _Noreturn
1327 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
1328 #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1329 #elif \
1330 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1331 JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1332 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1333 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1334 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1335 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1336 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1337 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1338 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1339 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1340 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1341 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1342 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1343 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1344 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1345 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1346 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1347 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1348 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1349 #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1350 #elif \
1351 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1352 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1353 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1354 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1355 #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1356 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1357 #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1358 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1359 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1360 #else
1361 #define JSON_HEDLEY_NO_RETURN
1362 #endif
1363
1364 #if defined(JSON_HEDLEY_NO_ESCAPE)
1365 #undef JSON_HEDLEY_NO_ESCAPE
1366 #endif
1367 #if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1368 #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1369 #else
1370 #define JSON_HEDLEY_NO_ESCAPE
1371 #endif
1372
1373 #if defined(JSON_HEDLEY_UNREACHABLE)
1374 #undef JSON_HEDLEY_UNREACHABLE
1375 #endif
1376 #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1377 #undef JSON_HEDLEY_UNREACHABLE_RETURN
1378 #endif
1379 #if defined(JSON_HEDLEY_ASSUME)
1380 #undef JSON_HEDLEY_ASSUME
1381 #endif
1382 #if \
1383 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1384 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1385 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1386 #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1387 #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1388 #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1389 #elif \
1390 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1391 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1392 #if defined(__cplusplus)
1393 #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1394 #else
1395 #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1396 #endif
1397 #endif
1398 #if \
1399 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1400 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1401 JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1402 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1403 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1404 JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1405 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1406 #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1407 #elif defined(JSON_HEDLEY_ASSUME)
1408 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1409 #endif
1410 #if !defined(JSON_HEDLEY_ASSUME)
1411 #if defined(JSON_HEDLEY_UNREACHABLE)
1412 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1413 #else
1414 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1415 #endif
1416 #endif
1417 #if defined(JSON_HEDLEY_UNREACHABLE)
1418 #if \
1419 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1420 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1421 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1422 #else
1423 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1424 #endif
1425 #else
1426 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1427 #endif
1428 #if !defined(JSON_HEDLEY_UNREACHABLE)
1429 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1430 #endif
1431
1432 JSON_HEDLEY_DIAGNOSTIC_PUSH
1433 #if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1434 #pragma clang diagnostic ignored "-Wpedantic"
1435 #endif
1436 #if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1437 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1438 #endif
1439 #if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1440 #if defined(__clang__)
1441 #pragma clang diagnostic ignored "-Wvariadic-macros"
1442 #elif defined(JSON_HEDLEY_GCC_VERSION)
1443 #pragma GCC diagnostic ignored "-Wvariadic-macros"
1444 #endif
1445 #endif
1446 #if defined(JSON_HEDLEY_NON_NULL)
1447 #undef JSON_HEDLEY_NON_NULL
1448 #endif
1449 #if \
1450 JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1451 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1452 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1453 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1454 #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1455 #else
1456 #define JSON_HEDLEY_NON_NULL(...)
1457 #endif
1458 JSON_HEDLEY_DIAGNOSTIC_POP
1459
1460 #if defined(JSON_HEDLEY_PRINTF_FORMAT)
1461 #undef JSON_HEDLEY_PRINTF_FORMAT
1462 #endif
1463 #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1464 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1465 #elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1466 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1467 #elif \
1468 JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1469 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1470 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1471 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1472 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1473 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1474 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1475 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1476 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1477 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1478 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1479 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1480 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1481 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1482 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1483 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1484 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1485 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1486 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1487 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1488 #else
1489 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1490 #endif
1491
1492 #if defined(JSON_HEDLEY_CONSTEXPR)
1493 #undef JSON_HEDLEY_CONSTEXPR
1494 #endif
1495 #if defined(__cplusplus)
1496 #if __cplusplus >= 201103L
1497 #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1498 #endif
1499 #endif
1500 #if !defined(JSON_HEDLEY_CONSTEXPR)
1501 #define JSON_HEDLEY_CONSTEXPR
1502 #endif
1503
1504 #if defined(JSON_HEDLEY_PREDICT)
1505 #undef JSON_HEDLEY_PREDICT
1506 #endif
1507 #if defined(JSON_HEDLEY_LIKELY)
1508 #undef JSON_HEDLEY_LIKELY
1509 #endif
1510 #if defined(JSON_HEDLEY_UNLIKELY)
1511 #undef JSON_HEDLEY_UNLIKELY
1512 #endif
1513 #if defined(JSON_HEDLEY_UNPREDICTABLE)
1514 #undef JSON_HEDLEY_UNPREDICTABLE
1515 #endif
1516 #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1517 #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1518 #endif
1519 #if \
1520 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1521 JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1522 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1523 # define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1524 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1525 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1526 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1527 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1528 #elif \
1529 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1530 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1531 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1532 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1533 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1534 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1535 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1536 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1537 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1538 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1539 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1540 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1541 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1542 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1543 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1544 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1545 # define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1546 (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1547 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1548 (__extension__ ({ \
1549 double hedley_probability_ = (probability); \
1550 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1551 }))
1552 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1553 (__extension__ ({ \
1554 double hedley_probability_ = (probability); \
1555 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1556 }))
1557 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1558 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1559 #else
1560 # define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1561 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1562 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1563 # define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1564 # define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1565 #endif
1566 #if !defined(JSON_HEDLEY_UNPREDICTABLE)
1567 #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1568 #endif
1569
1570 #if defined(JSON_HEDLEY_MALLOC)
1571 #undef JSON_HEDLEY_MALLOC
1572 #endif
1573 #if \
1574 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1575 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1576 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1577 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1578 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1579 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1580 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1581 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1582 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1583 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1584 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1585 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1586 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1587 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1588 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1589 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1590 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1591 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1592 #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1593 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1594 #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1595 #elif \
1596 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1597 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1598 #define JSON_HEDLEY_MALLOC __declspec(restrict)
1599 #else
1600 #define JSON_HEDLEY_MALLOC
1601 #endif
1602
1603 #if defined(JSON_HEDLEY_PURE)
1604 #undef JSON_HEDLEY_PURE
1605 #endif
1606 #if \
1607 JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1608 JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1609 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1610 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1611 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1612 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1613 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1614 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1615 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1616 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1617 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1618 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1619 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1620 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1621 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1622 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1623 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1624 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1625 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1626 # define JSON_HEDLEY_PURE __attribute__((__pure__))
1627 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1628 # define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1629 #elif defined(__cplusplus) && \
1630 ( \
1631 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1632 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1633 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1634 )
1635 # define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1636 #else
1637 # define JSON_HEDLEY_PURE
1638 #endif
1639
1640 #if defined(JSON_HEDLEY_CONST)
1641 #undef JSON_HEDLEY_CONST
1642 #endif
1643 #if \
1644 JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1645 JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1646 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1647 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1648 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1649 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1650 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1651 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1652 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1653 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1654 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1655 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1656 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1657 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1658 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1659 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1660 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1661 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1662 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1663 #define JSON_HEDLEY_CONST __attribute__((__const__))
1664 #elif \
1665 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1666 #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1667 #else
1668 #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1669 #endif
1670
1671 #if defined(JSON_HEDLEY_RESTRICT)
1672 #undef JSON_HEDLEY_RESTRICT
1673 #endif
1674 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1675 #define JSON_HEDLEY_RESTRICT restrict
1676 #elif \
1677 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1678 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1679 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1680 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1681 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1682 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1683 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1684 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1685 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1686 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1687 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1688 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1689 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1690 defined(__clang__) || \
1691 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1692 #define JSON_HEDLEY_RESTRICT __restrict
1693 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1694 #define JSON_HEDLEY_RESTRICT _Restrict
1695 #else
1696 #define JSON_HEDLEY_RESTRICT
1697 #endif
1698
1699 #if defined(JSON_HEDLEY_INLINE)
1700 #undef JSON_HEDLEY_INLINE
1701 #endif
1702 #if \
1703 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1704 (defined(__cplusplus) && (__cplusplus >= 199711L))
1705 #define JSON_HEDLEY_INLINE inline
1706 #elif \
1707 defined(JSON_HEDLEY_GCC_VERSION) || \
1708 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1709 #define JSON_HEDLEY_INLINE __inline__
1710 #elif \
1711 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1712 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1713 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1714 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1715 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1716 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1717 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1718 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1719 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1720 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1721 #define JSON_HEDLEY_INLINE __inline
1722 #else
1723 #define JSON_HEDLEY_INLINE
1724 #endif
1725
1726 #if defined(JSON_HEDLEY_ALWAYS_INLINE)
1727 #undef JSON_HEDLEY_ALWAYS_INLINE
1728 #endif
1729 #if \
1730 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1731 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1732 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1733 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1734 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1735 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1736 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1737 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1738 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1739 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1740 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1741 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1742 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1743 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1744 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1745 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1746 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1747 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1748 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1749 # define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1750 #elif \
1751 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1752 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1753 # define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1754 #elif defined(__cplusplus) && \
1755 ( \
1756 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1757 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1758 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1759 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1760 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1761 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1762 )
1763 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1764 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1765 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1766 #else
1767 # define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1768 #endif
1769
1770 #if defined(JSON_HEDLEY_NEVER_INLINE)
1771 #undef JSON_HEDLEY_NEVER_INLINE
1772 #endif
1773 #if \
1774 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1775 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1776 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1777 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1778 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1779 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1780 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1781 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1782 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1783 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1784 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1785 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1786 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1787 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1788 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1789 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1790 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1791 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1792 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1793 #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1794 #elif \
1795 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1796 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1797 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1798 #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1799 #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1800 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1801 #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1802 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1803 #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1804 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1805 #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1806 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1807 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1808 #else
1809 #define JSON_HEDLEY_NEVER_INLINE
1810 #endif
1811
1812 #if defined(JSON_HEDLEY_PRIVATE)
1813 #undef JSON_HEDLEY_PRIVATE
1814 #endif
1815 #if defined(JSON_HEDLEY_PUBLIC)
1816 #undef JSON_HEDLEY_PUBLIC
1817 #endif
1818 #if defined(JSON_HEDLEY_IMPORT)
1819 #undef JSON_HEDLEY_IMPORT
1820 #endif
1821 #if defined(_WIN32) || defined(__CYGWIN__)
1822 # define JSON_HEDLEY_PRIVATE
1823 # define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1824 # define JSON_HEDLEY_IMPORT __declspec(dllimport)
1825 #else
1826 # if \
1827 JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1828 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1829 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1830 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1831 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1832 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1833 ( \
1834 defined(__TI_EABI__) && \
1835 ( \
1836 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1837 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1838 ) \
1839 ) || \
1840 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1841 # define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1842 # define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1843 # else
1844 # define JSON_HEDLEY_PRIVATE
1845 # define JSON_HEDLEY_PUBLIC
1846 # endif
1847 # define JSON_HEDLEY_IMPORT extern
1848 #endif
1849
1850 #if defined(JSON_HEDLEY_NO_THROW)
1851 #undef JSON_HEDLEY_NO_THROW
1852 #endif
1853 #if \
1854 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1855 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1856 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1857 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1858 #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1859 #elif \
1860 JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1861 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1862 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1863 #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1864 #else
1865 #define JSON_HEDLEY_NO_THROW
1866 #endif
1867
1868 #if defined(JSON_HEDLEY_FALL_THROUGH)
1869 #undef JSON_HEDLEY_FALL_THROUGH
1870 #endif
1871 #if \
1872 JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1873 JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
1874 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1875 #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1876 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1877 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1878 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1879 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1880 #elif defined(__fallthrough) /* SAL */
1881 #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1882 #else
1883 #define JSON_HEDLEY_FALL_THROUGH
1884 #endif
1885
1886 #if defined()
1887 #undef
1888 #endif
1889 #if \
1890 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1891 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1892 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1893 #define __attribute__((__returns_nonnull__))
1894 #elif defined(_Ret_notnull_) /* SAL */
1895 #define _Ret_notnull_
1896 #else
1897 #define
1898 #endif
1899
1900 #if defined(JSON_HEDLEY_ARRAY_PARAM)
1901 #undef JSON_HEDLEY_ARRAY_PARAM
1902 #endif
1903 #if \
1904 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1905 !defined(__STDC_NO_VLA__) && \
1906 !defined(__cplusplus) && \
1907 !defined(JSON_HEDLEY_PGI_VERSION) && \
1908 !defined(JSON_HEDLEY_TINYC_VERSION)
1909 #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1910 #else
1911 #define JSON_HEDLEY_ARRAY_PARAM(name)
1912 #endif
1913
1914 #if defined(JSON_HEDLEY_IS_CONSTANT)
1915 #undef JSON_HEDLEY_IS_CONSTANT
1916 #endif
1917 #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1918 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1919 #endif
1920 /* JSON_HEDLEY_IS_CONSTEXPR_ is for
1921 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1922 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1923 #undef JSON_HEDLEY_IS_CONSTEXPR_
1924 #endif
1925 #if \
1926 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1927 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1928 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1929 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1930 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1931 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1932 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1933 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1934 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1935 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1936 #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1937 #endif
1938 #if !defined(__cplusplus)
1939 # if \
1940 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1941 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1942 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1943 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1944 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1945 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1946 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1947 #if defined(__INTPTR_TYPE__)
1948 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1949 #else
1950 #include <stdint.h>
1951 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1952 #endif
1953 # elif \
1954 ( \
1955 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1956 !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1957 !defined(JSON_HEDLEY_PGI_VERSION) && \
1958 !defined(JSON_HEDLEY_IAR_VERSION)) || \
1959 (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1960 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1961 JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1962 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1963 JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1964 #if defined(__INTPTR_TYPE__)
1965 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1966 #else
1967 #include <stdint.h>
1968 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1969 #endif
1970 # elif \
1971 defined(JSON_HEDLEY_GCC_VERSION) || \
1972 defined(JSON_HEDLEY_INTEL_VERSION) || \
1973 defined(JSON_HEDLEY_TINYC_VERSION) || \
1974 defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1975 JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1976 defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1977 defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1978 defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1979 defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1980 defined(__clang__)
1981 # define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1982 sizeof(void) != \
1983 sizeof(*( \
1984 1 ? \
1985 ((void*) ((expr) * 0L) ) : \
1986 ((struct { char v[sizeof(void) * 2]; } *) 1) \
1987 ) \
1988 ) \
1989 )
1990 # endif
1991 #endif
1992 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1993 #if !defined(JSON_HEDLEY_IS_CONSTANT)
1994 #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1995 #endif
1996 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
1997 #else
1998 #if !defined(JSON_HEDLEY_IS_CONSTANT)
1999 #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2000 #endif
2001 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2002 #endif
2003
2004 #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2005 #undef JSON_HEDLEY_BEGIN_C_DECLS
2006 #endif
2007 #if defined(JSON_HEDLEY_END_C_DECLS)
2008 #undef JSON_HEDLEY_END_C_DECLS
2009 #endif
2010 #if defined(JSON_HEDLEY_C_DECL)
2011 #undef JSON_HEDLEY_C_DECL
2012 #endif
2013 #if defined(__cplusplus)
2014 #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2015 #define JSON_HEDLEY_END_C_DECLS }
2016 #define JSON_HEDLEY_C_DECL extern "C"
2017 #else
2018 #define JSON_HEDLEY_BEGIN_C_DECLS
2019 #define JSON_HEDLEY_END_C_DECLS
2020 #define JSON_HEDLEY_C_DECL
2021 #endif
2022
2023 #if defined(JSON_HEDLEY_STATIC_ASSERT)
2024 #undef JSON_HEDLEY_STATIC_ASSERT
2025 #endif
2026 #if \
2027 !defined(__cplusplus) && ( \
2028 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2029 (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
2030 JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2031 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2032 defined(_Static_assert) \
2033 )
2034 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2035 #elif \
2036 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2037 JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2038 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2039 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2040 #else
2041 # define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2042 #endif
2043
2044 #if defined(JSON_HEDLEY_NULL)
2045 #undef JSON_HEDLEY_NULL
2046 #endif
2047 #if defined(__cplusplus)
2048 #if __cplusplus >= 201103L
2049 #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2050 #elif defined(NULL)
2051 #define JSON_HEDLEY_NULL NULL
2052 #else
2053 #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2054 #endif
2055 #elif defined(NULL)
2056 #define JSON_HEDLEY_NULL NULL
2057 #else
2058 #define JSON_HEDLEY_NULL ((void*) 0)
2059 #endif
2060
2061 #if defined(JSON_HEDLEY_MESSAGE)
2062 #undef JSON_HEDLEY_MESSAGE
2063 #endif
2064 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2065 # define JSON_HEDLEY_MESSAGE(msg) \
2066 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2067 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2068 JSON_HEDLEY_PRAGMA(message msg) \
2069 JSON_HEDLEY_DIAGNOSTIC_POP
2070 #elif \
2071 JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2072 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2073 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2074 #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2075 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2076 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2077 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2078 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2079 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2080 #else
2081 # define JSON_HEDLEY_MESSAGE(msg)
2082 #endif
2083
2084 #if defined(JSON_HEDLEY_WARNING)
2085 #undef JSON_HEDLEY_WARNING
2086 #endif
2087 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2088 # define JSON_HEDLEY_WARNING(msg) \
2089 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2090 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2091 JSON_HEDLEY_PRAGMA(clang warning msg) \
2092 JSON_HEDLEY_DIAGNOSTIC_POP
2093 #elif \
2094 JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2095 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2096 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2097 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2098 #elif \
2099 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2100 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2101 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2102 #else
2103 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2104 #endif
2105
2106 #if defined(JSON_HEDLEY_REQUIRE)
2107 #undef JSON_HEDLEY_REQUIRE
2108 #endif
2109 #if defined(JSON_HEDLEY_REQUIRE_MSG)
2110 #undef JSON_HEDLEY_REQUIRE_MSG
2111 #endif
2112 #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2113 # if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2114 # define JSON_HEDLEY_REQUIRE(expr) \
2115 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2116 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2117 __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2118 JSON_HEDLEY_DIAGNOSTIC_POP
2119 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2120 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2121 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2122 __attribute__((diagnose_if(!(expr), msg, "error"))) \
2123 JSON_HEDLEY_DIAGNOSTIC_POP
2124 # else
2125 # define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2126 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2127 # endif
2128 #else
2129 # define JSON_HEDLEY_REQUIRE(expr)
2130 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2131 #endif
2132
2133 #if defined(JSON_HEDLEY_FLAGS)
2134 #undef JSON_HEDLEY_FLAGS
2135 #endif
2136 #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2137 #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2138 #else
2139 #define JSON_HEDLEY_FLAGS
2140 #endif
2141
2142 #if defined(JSON_HEDLEY_FLAGS_CAST)
2143 #undef JSON_HEDLEY_FLAGS_CAST
2144 #endif
2145 #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2146 # define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2147 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2148 _Pragma("warning(disable:188)") \
2149 ((T) (expr)); \
2150 JSON_HEDLEY_DIAGNOSTIC_POP \
2151 }))
2152 #else
2153 # define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2154 #endif
2155
2156 #if defined(JSON_HEDLEY_EMPTY_BASES)
2157 #undef JSON_HEDLEY_EMPTY_BASES
2158 #endif
2159 #if \
2160 (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2161 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2162 #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2163 #else
2164 #define JSON_HEDLEY_EMPTY_BASES
2165 #endif
2166
2167 /* Remaining macros are deprecated. */
2168
2169 #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2170 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2171 #endif
2172 #if defined(__clang__)
2173 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2174 #else
2175 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2176 #endif
2177
2178 #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2179 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2180 #endif
2181 #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2182
2183 #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2184 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2185 #endif
2186 #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2187
2188 #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2189 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2190 #endif
2191 #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2192
2193 #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2194 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2195 #endif
2196 #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2197
2198 #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2199 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2200 #endif
2201 #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2202
2203 #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2204 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2205 #endif
2206 #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2207
2208 #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2209 #undef JSON_HEDLEY_CLANG_HAS_WARNING
2210 #endif
2211 #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2212
2213 #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2214
2215
2216 // This file contains all internal macro definitions
2217 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2218
2219 // exclude unsupported compilers
2220 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2221 #if defined(__clang__)
2222 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2223 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2224 #endif
2225 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2226 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2227 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2228 #endif
2229 #endif
2230 #endif
2231
2232 // C++ language standard detection
2233 #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2234 #define JSON_HAS_CPP_20
2235 #define JSON_HAS_CPP_17
2236 #define JSON_HAS_CPP_14
2237 #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2238 #define JSON_HAS_CPP_17
2239 #define JSON_HAS_CPP_14
2240 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2241 #define JSON_HAS_CPP_14
2242 #endif
2243
2244 // disable documentation warnings on clang
2245 #if defined(__clang__)
2246 #pragma GCC diagnostic push
2247 #pragma GCC diagnostic ignored "-Wdocumentation"
2248 #endif
2249
2250 // allow to disable exceptions
2251 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2252 #define JSON_THROW(exception) throw exception
2253 #define JSON_TRY try
2254 #define JSON_CATCH(exception) catch(exception)
2255 #define JSON_INTERNAL_CATCH(exception) catch(exception)
2256 #else
2257 #include <cstdlib>
2258 #define JSON_THROW(exception) std::abort()
2259 #define JSON_TRY if(true)
2260 #define JSON_CATCH(exception) if(false)
2261 #define JSON_INTERNAL_CATCH(exception) if(false)
2262 #endif
2263
2264 // override exception macros
2265 #if defined(JSON_THROW_USER)
2266 #undef JSON_THROW
2267 #define JSON_THROW JSON_THROW_USER
2268 #endif
2269 #if defined(JSON_TRY_USER)
2270 #undef JSON_TRY
2271 #define JSON_TRY JSON_TRY_USER
2272 #endif
2273 #if defined(JSON_CATCH_USER)
2274 #undef JSON_CATCH
2275 #define JSON_CATCH JSON_CATCH_USER
2276 #undef JSON_INTERNAL_CATCH
2277 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2278 #endif
2279 #if defined(JSON_INTERNAL_CATCH_USER)
2280 #undef JSON_INTERNAL_CATCH
2281 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2282 #endif
2283
2284 // allow to override assert
2285 #if !defined(JSON_ASSERT)
2286 #include <cassert> // assert
2287 #define JSON_ASSERT(x) assert(x)
2288 #endif
2289
2290 // allow to access some private functions (needed by the test suite)
2291 #if defined(JSON_TESTS_PRIVATE)
2292 #define JSON_PRIVATE_UNLESS_TESTED public
2293 #else
2294 #define JSON_PRIVATE_UNLESS_TESTED private
2295 #endif
2296
2302 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2303 template<typename BasicJsonType> \
2304 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2305 { \
2306 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2307 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2308 auto it = std::find_if(std::begin(m), std::end(m), \
2309 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2310 { \
2311 return ej_pair.first == e; \
2312 }); \
2313 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2314 } \
2315 template<typename BasicJsonType> \
2316 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2317 { \
2318 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2319 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2320 auto it = std::find_if(std::begin(m), std::end(m), \
2321 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2322 { \
2323 return ej_pair.second == j; \
2324 }); \
2325 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2326 }
2327
2328 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2329 // may be removed in the future once the class is split.
2330
2331 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2332 template<template<typename, typename, typename...> class ObjectType, \
2333 template<typename, typename...> class ArrayType, \
2334 class StringType, class BooleanType, class NumberIntegerType, \
2335 class NumberUnsignedType, class NumberFloatType, \
2336 template<typename> class AllocatorType, \
2337 template<typename, typename = void> class JSONSerializer, \
2338 class BinaryType>
2339
2340 #define NLOHMANN_BASIC_JSON_TPL \
2341 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2342 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2343 AllocatorType, JSONSerializer, BinaryType>
2344
2345 // Macros to simplify conversion from/to types
2346
2347 #define NLOHMANN_JSON_EXPAND( x ) x
2348 #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
2349 #define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2350 NLOHMANN_JSON_PASTE64, \
2351 NLOHMANN_JSON_PASTE63, \
2352 NLOHMANN_JSON_PASTE62, \
2353 NLOHMANN_JSON_PASTE61, \
2354 NLOHMANN_JSON_PASTE60, \
2355 NLOHMANN_JSON_PASTE59, \
2356 NLOHMANN_JSON_PASTE58, \
2357 NLOHMANN_JSON_PASTE57, \
2358 NLOHMANN_JSON_PASTE56, \
2359 NLOHMANN_JSON_PASTE55, \
2360 NLOHMANN_JSON_PASTE54, \
2361 NLOHMANN_JSON_PASTE53, \
2362 NLOHMANN_JSON_PASTE52, \
2363 NLOHMANN_JSON_PASTE51, \
2364 NLOHMANN_JSON_PASTE50, \
2365 NLOHMANN_JSON_PASTE49, \
2366 NLOHMANN_JSON_PASTE48, \
2367 NLOHMANN_JSON_PASTE47, \
2368 NLOHMANN_JSON_PASTE46, \
2369 NLOHMANN_JSON_PASTE45, \
2370 NLOHMANN_JSON_PASTE44, \
2371 NLOHMANN_JSON_PASTE43, \
2372 NLOHMANN_JSON_PASTE42, \
2373 NLOHMANN_JSON_PASTE41, \
2374 NLOHMANN_JSON_PASTE40, \
2375 NLOHMANN_JSON_PASTE39, \
2376 NLOHMANN_JSON_PASTE38, \
2377 NLOHMANN_JSON_PASTE37, \
2378 NLOHMANN_JSON_PASTE36, \
2379 NLOHMANN_JSON_PASTE35, \
2380 NLOHMANN_JSON_PASTE34, \
2381 NLOHMANN_JSON_PASTE33, \
2382 NLOHMANN_JSON_PASTE32, \
2383 NLOHMANN_JSON_PASTE31, \
2384 NLOHMANN_JSON_PASTE30, \
2385 NLOHMANN_JSON_PASTE29, \
2386 NLOHMANN_JSON_PASTE28, \
2387 NLOHMANN_JSON_PASTE27, \
2388 NLOHMANN_JSON_PASTE26, \
2389 NLOHMANN_JSON_PASTE25, \
2390 NLOHMANN_JSON_PASTE24, \
2391 NLOHMANN_JSON_PASTE23, \
2392 NLOHMANN_JSON_PASTE22, \
2393 NLOHMANN_JSON_PASTE21, \
2394 NLOHMANN_JSON_PASTE20, \
2395 NLOHMANN_JSON_PASTE19, \
2396 NLOHMANN_JSON_PASTE18, \
2397 NLOHMANN_JSON_PASTE17, \
2398 NLOHMANN_JSON_PASTE16, \
2399 NLOHMANN_JSON_PASTE15, \
2400 NLOHMANN_JSON_PASTE14, \
2401 NLOHMANN_JSON_PASTE13, \
2402 NLOHMANN_JSON_PASTE12, \
2403 NLOHMANN_JSON_PASTE11, \
2404 NLOHMANN_JSON_PASTE10, \
2405 NLOHMANN_JSON_PASTE9, \
2406 NLOHMANN_JSON_PASTE8, \
2407 NLOHMANN_JSON_PASTE7, \
2408 NLOHMANN_JSON_PASTE6, \
2409 NLOHMANN_JSON_PASTE5, \
2410 NLOHMANN_JSON_PASTE4, \
2411 NLOHMANN_JSON_PASTE3, \
2412 NLOHMANN_JSON_PASTE2, \
2413 NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2414 #define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2415 #define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2416 #define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2417 #define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2418 #define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2419 #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)
2420 #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)
2421 #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)
2422 #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)
2423 #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)
2424 #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)
2425 #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)
2426 #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)
2427 #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)
2428 #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)
2429 #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)
2430 #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)
2431 #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)
2432 #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)
2433 #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)
2434 #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)
2435 #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)
2436 #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)
2437 #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)
2438 #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)
2439 #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)
2440 #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)
2441 #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)
2442 #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)
2443 #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)
2444 #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)
2445 #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)
2446 #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)
2447 #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)
2448 #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)
2449 #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)
2450 #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)
2451 #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)
2452 #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)
2453 #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)
2454 #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)
2455 #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)
2456 #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)
2457 #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)
2458 #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)
2459 #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)
2460 #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)
2461 #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)
2462 #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)
2463 #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)
2464 #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)
2465 #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)
2466 #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)
2467 #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)
2468 #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)
2469 #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)
2470 #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)
2471 #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)
2472 #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)
2473 #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)
2474 #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)
2475 #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)
2476 #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)
2477
2478 #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2479 #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2480
2486 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2487 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__)) } \
2488 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__)) }
2489
2495 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2496 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__)) } \
2497 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__)) }
2498
2499 #ifndef JSON_USE_IMPLICIT_CONVERSIONS
2500 #define JSON_USE_IMPLICIT_CONVERSIONS 1
2501 #endif
2502
2503 #if JSON_USE_IMPLICIT_CONVERSIONS
2504 #define JSON_EXPLICIT
2505 #else
2506 #define JSON_EXPLICIT explicit
2507 #endif
2508
2509
2510 namespace nlohmann
2511 {
2512 namespace detail
2513 {
2514
2528 inline void replace_substring(std::string& s, const std::string& f,
2529 const std::string& t)
2530 {
2531 JSON_ASSERT(!f.empty());
2532 for (auto pos = s.find(f); // find first occurrence of f
2533 pos != std::string::npos; // make sure f was found
2534 s.replace(pos, f.size(), t), // replace with t, and
2535 pos = s.find(f, pos + t.size())) // find next occurrence of f
2536 {}
2537 }
2538
2546 inline std::string escape(std::string s)
2547 {
2548 replace_substring(s, "~", "~0");
2549 replace_substring(s, "/", "~1");
2550 return s;
2551 }
2552
2560 static void unescape(std::string& s)
2561 {
2562 replace_substring(s, "~1", "/");
2563 replace_substring(s, "~0", "~");
2564 }
2565
2566 } // namespace detail
2567 } // namespace nlohmann
2568
2569 // #include <nlohmann/detail/input/position_t.hpp>
2570
2571
2572 #include <cstddef> // size_t
2573
2574 namespace nlohmann
2575 {
2576 namespace detail
2577 {
2579 struct position_t
2580 {
2582 std::size_t chars_read_total = 0;
2584 std::size_t chars_read_current_line = 0;
2586 std::size_t lines_read = 0;
2587
2589 constexpr operator size_t() const
2590 {
2591 return chars_read_total;
2592 }
2593 };
2594
2595 } // namespace detail
2596 } // namespace nlohmann
2597
2598 // #include <nlohmann/detail/macro_scope.hpp>
2599
2600
2601 namespace nlohmann
2602 {
2603 namespace detail
2604 {
2606 // exceptions //
2608
2637 class exception : public std::exception
2638 {
2639 public:
2641 const char* what() const noexcept override
2642 {
2643 return m.what();
2644 }
2645
2647 const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
2648
2649 protected:
2650 JSON_HEDLEY_NON_NULL(3)
2651 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
2652
2653 static std::string name(const std::string& ename, int id_)
2654 {
2655 return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2656 }
2657
2658 template<typename BasicJsonType>
2659 static std::string diagnostics(const BasicJsonType& leaf_element)
2660 {
2661 #if JSON_DIAGNOSTICS
2662 std::vector<std::string> tokens;
2663 for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent)
2664 {
2665 switch (current->m_parent->type())
2666 {
2667 case value_t::array:
2668 {
2669 for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
2670 {
2671 if (&current->m_parent->m_value.array->operator[](i) == current)
2672 {
2673 tokens.emplace_back(std::to_string(i));
2674 break;
2675 }
2676 }
2677 break;
2678 }
2679
2680 case value_t::object:
2681 {
2682 for (const auto& element : *current->m_parent->m_value.object)
2683 {
2684 if (&element.second == current)
2685 {
2686 tokens.emplace_back(element.first.c_str());
2687 break;
2688 }
2689 }
2690 break;
2691 }
2692
2693 default: // LCOV_EXCL_LINE
2694 break; // LCOV_EXCL_LINE
2695 }
2696 }
2697
2698 if (tokens.empty())
2699 {
2700 return "";
2701 }
2702
2703 return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
2704 [](const std::string & a, const std::string & b)
2705 {
2706 return a + "/" + detail::escape(b);
2707 }) + ") ";
2708 #else
2709 static_cast<void>(leaf_element);
2710 return "";
2711 #endif
2712 }
2713
2714 private:
2716 std::runtime_error m;
2717 };
2718
2764 class parse_error : public exception
2765 {
2766 public:
2776 template<typename BasicJsonType>
2777 static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context)
2778 {
2779 std::string w = exception::name("parse_error", id_) + "parse error" +
2780 position_string(pos) + ": " + exception::diagnostics(context) + what_arg;
2781 return parse_error(id_, pos.chars_read_total, w.c_str());
2782 }
2783
2784 template<typename BasicJsonType>
2785 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context)
2786 {
2787 std::string w = exception::name("parse_error", id_) + "parse error" +
2788 (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2789 ": " + exception::diagnostics(context) + what_arg;
2790 return parse_error(id_, byte_, w.c_str());
2791 }
2792
2802 const std::size_t byte;
2803
2804 private:
2805 parse_error(int id_, std::size_t byte_, const char* what_arg)
2806 : exception(id_, what_arg), byte(byte_) {}
2807
2808 static std::string position_string(const position_t& pos)
2809 {
2810 return " at line " + std::to_string(pos.lines_read + 1) +
2811 ", column " + std::to_string(pos.chars_read_current_line);
2812 }
2813 };
2814
2852 class invalid_iterator : public exception
2853 {
2854 public:
2855 template<typename BasicJsonType>
2856 static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context)
2857 {
2858 std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg;
2859 return invalid_iterator(id_, w.c_str());
2860 }
2861
2862 private:
2863 JSON_HEDLEY_NON_NULL(3)
2864 invalid_iterator(int id_, const char* what_arg)
2865 : exception(id_, what_arg) {}
2866 };
2867
2907 class type_error : public exception
2908 {
2909 public:
2910 template<typename BasicJsonType>
2911 static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
2912 {
2913 std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg;
2914 return type_error(id_, w.c_str());
2915 }
2916
2917 private:
2918 JSON_HEDLEY_NON_NULL(3)
2919 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2920 };
2921
2955 class out_of_range : public exception
2956 {
2957 public:
2958 template<typename BasicJsonType>
2959 static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context)
2960 {
2961 std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg;
2962 return out_of_range(id_, w.c_str());
2963 }
2964
2965 private:
2966 JSON_HEDLEY_NON_NULL(3)
2967 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
2968 };
2969
2994 class other_error : public exception
2995 {
2996 public:
2997 template<typename BasicJsonType>
2998 static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
2999 {
3000 std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg;
3001 return other_error(id_, w.c_str());
3002 }
3003
3004 private:
3005 JSON_HEDLEY_NON_NULL(3)
3006 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
3007 };
3008 } // namespace detail
3009 } // namespace nlohmann
3010
3011 // #include <nlohmann/detail/macro_scope.hpp>
3012
3013 // #include <nlohmann/detail/meta/cpp_future.hpp>
3014
3015
3016 #include <cstddef> // size_t
3017 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3018 #include <utility> // index_sequence, make_index_sequence, index_sequence_for
3019
3020 // #include <nlohmann/detail/macro_scope.hpp>
3021
3022
3023 namespace nlohmann
3024 {
3025 namespace detail
3026 {
3027
3028 template<typename T>
3029 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3030
3031 #ifdef JSON_HAS_CPP_14
3032
3033 // the following utilities are natively available in C++14
3034 using std::enable_if_t;
3035 using std::index_sequence;
3036 using std::make_index_sequence;
3037 using std::index_sequence_for;
3038
3039 #else
3040
3041 // alias templates to reduce boilerplate
3042 template<bool B, typename T = void>
3043 using enable_if_t = typename std::enable_if<B, T>::type;
3044
3045 // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3046 // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3047
3049
3050 // integer_sequence
3051 //
3052 // Class template representing a compile-time integer sequence. An instantiation
3053 // of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3054 // type through its template arguments (which is a common need when
3055 // working with C++11 variadic templates). `absl::integer_sequence` is designed
3056 // to be a drop-in replacement for C++14's `std::integer_sequence`.
3057 //
3058 // Example:
3059 //
3060 // template< class T, T... Ints >
3061 // void user_function(integer_sequence<T, Ints...>);
3062 //
3063 // int main()
3064 // {
3065 // // user_function's `T` will be deduced to `int` and `Ints...`
3066 // // will be deduced to `0, 1, 2, 3, 4`.
3067 // user_function(make_integer_sequence<int, 5>());
3068 // }
3069 template <typename T, T... Ints>
3070 struct integer_sequence
3071 {
3072 using value_type = T;
3073 static constexpr std::size_t size() noexcept
3074 {
3075 return sizeof...(Ints);
3076 }
3077 };
3078
3079 // index_sequence
3080 //
3081 // A helper template for an `integer_sequence` of `size_t`,
3082 // `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3083 // `std::index_sequence`.
3084 template <size_t... Ints>
3085 using index_sequence = integer_sequence<size_t, Ints...>;
3086
3087 namespace utility_internal
3088 {
3089
3090 template <typename Seq, size_t SeqSize, size_t Rem>
3091 struct Extend;
3092
3093 // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3094 template <typename T, T... Ints, size_t SeqSize>
3095 struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3096 {
3097 using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3098 };
3099
3100 template <typename T, T... Ints, size_t SeqSize>
3101 struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3102 {
3103 using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3104 };
3105
3106 // Recursion helper for 'make_integer_sequence<T, N>'.
3107 // 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3108 template <typename T, size_t N>
3109 struct Gen
3110 {
3111 using type =
3112 typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3113 };
3114
3115 template <typename T>
3116 struct Gen<T, 0>
3117 {
3118 using type = integer_sequence<T>;
3119 };
3120
3121 } // namespace utility_internal
3122
3123 // Compile-time sequences of integers
3124
3125 // make_integer_sequence
3126 //
3127 // This template alias is equivalent to
3128 // `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3129 // replacement for C++14's `std::make_integer_sequence`.
3130 template <typename T, T N>
3131 using make_integer_sequence = typename utility_internal::Gen<T, N>::type;
3132
3133 // make_index_sequence
3134 //
3135 // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3136 // and is designed to be a drop-in replacement for C++14's
3137 // `std::make_index_sequence`.
3138 template <size_t N>
3139 using make_index_sequence = make_integer_sequence<size_t, N>;
3140
3141 // index_sequence_for
3142 //
3143 // Converts a typename pack into an index sequence of the same length, and
3144 // is designed to be a drop-in replacement for C++14's
3145 // `std::index_sequence_for()`
3146 template <typename... Ts>
3147 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
3148
3150
3151 #endif
3152
3153 // dispatch utility (taken from ranges-v3)
3154 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3155 template<> struct priority_tag<0> {};
3156
3157 // taken from ranges-v3
3158 template<typename T>
3159 struct static_const
3160 {
3161 static constexpr T value{};
3162 };
3163
3164 template<typename T>
3165 constexpr T static_const<T>::value;
3166
3167 } // namespace detail
3168 } // namespace nlohmann
3169
3170 // #include <nlohmann/detail/meta/identity_tag.hpp>
3171
3172
3173 namespace nlohmann
3174 {
3175 namespace detail
3176 {
3177 // dispatching helper struct
3178 template <class T> struct identity_tag {};
3179 } // namespace detail
3180 } // namespace nlohmann
3181
3182 // #include <nlohmann/detail/meta/type_traits.hpp>
3183
3184
3185 #include <limits> // numeric_limits
3186 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3187 #include <utility> // declval
3188 #include <tuple> // tuple
3189
3190 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
3191
3192
3193 #include <iterator> // random_access_iterator_tag
3194
3195 // #include <nlohmann/detail/meta/void_t.hpp>
3196
3197
3198 namespace nlohmann
3199 {
3200 namespace detail
3201 {
3202 template<typename ...Ts> struct make_void
3203 {
3204 using type = void;
3205 };
3206 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
3207 } // namespace detail
3208 } // namespace nlohmann
3209
3210 // #include <nlohmann/detail/meta/cpp_future.hpp>
3211
3212
3213 namespace nlohmann
3214 {
3215 namespace detail
3216 {
3217 template<typename It, typename = void>
3218 struct iterator_types {};
3219
3220 template<typename It>
3221 struct iterator_types <
3222 It,
3223 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3224 typename It::reference, typename It::iterator_category >>
3225 {
3226 using difference_type = typename It::difference_type;
3227 using value_type = typename It::value_type;
3228 using pointer = typename It::pointer;
3229 using reference = typename It::reference;
3230 using iterator_category = typename It::iterator_category;
3231 };
3232
3233 // This is required as some compilers implement std::iterator_traits in a way that
3234 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3235 template<typename T, typename = void>
3236 struct iterator_traits
3237 {
3238 };
3239
3240 template<typename T>
3241 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3242 : iterator_types<T>
3243 {
3244 };
3245
3246 template<typename T>
3247 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
3248 {
3249 using iterator_category = std::random_access_iterator_tag;
3250 using value_type = T;
3251 using difference_type = ptrdiff_t;
3252 using pointer = T*;
3253 using reference = T&;
3254 };
3255 } // namespace detail
3256 } // namespace nlohmann
3257
3258 // #include <nlohmann/detail/macro_scope.hpp>
3259
3260 // #include <nlohmann/detail/meta/cpp_future.hpp>
3261
3262 // #include <nlohmann/detail/meta/detected.hpp>
3263
3264
3265 #include <type_traits>
3266
3267 // #include <nlohmann/detail/meta/void_t.hpp>
3268
3269
3270 // https://en.cppreference.com/w/cpp/experimental/is_detected
3271 namespace nlohmann
3272 {
3273 namespace detail
3274 {
3275 struct nonesuch
3276 {
3277 nonesuch() = delete;
3278 ~nonesuch() = delete;
3279 nonesuch(nonesuch const&) = delete;
3280 nonesuch(nonesuch const&&) = delete;
3281 void operator=(nonesuch const&) = delete;
3282 void operator=(nonesuch&&) = delete;
3283 };
3284
3285 template<class Default,
3286 class AlwaysVoid,
3287 template<class...> class Op,
3288 class... Args>
3289 struct detector
3290 {
3291 using value_t = std::false_type;
3292 using type = Default;
3293 };
3294
3295 template<class Default, template<class...> class Op, class... Args>
3296 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
3297 {
3298 using value_t = std::true_type;
3299 using type = Op<Args...>;
3300 };
3301
3302 template<template<class...> class Op, class... Args>
3303 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
3304
3305 template<template<class...> class Op, class... Args>
3306 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
3307
3308 template<class Default, template<class...> class Op, class... Args>
3309 using detected_or = detector<Default, void, Op, Args...>;
3310
3311 template<class Default, template<class...> class Op, class... Args>
3312 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
3313
3314 template<class Expected, template<class...> class Op, class... Args>
3315 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
3316
3317 template<class To, template<class...> class Op, class... Args>
3318 using is_detected_convertible =
3319 std::is_convertible<detected_t<Op, Args...>, To>;
3320 } // namespace detail
3321 } // namespace nlohmann
3322
3323 // #include <nlohmann/json_fwd.hpp>
3324 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3325 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3326
3327 #include <cstdint> // int64_t, uint64_t
3328 #include <map> // map
3329 #include <memory> // allocator
3330 #include <string> // string
3331 #include <vector> // vector
3332
3338 namespace nlohmann
3339 {
3347 template<typename T = void, typename SFINAE = void>
3348 struct adl_serializer;
3349
3350 template<template<typename U, typename V, typename... Args> class ObjectType =
3351 std::map,
3352 template<typename U, typename... Args> class ArrayType = std::vector,
3353 class StringType = std::string, class BooleanType = bool,
3354 class NumberIntegerType = std::int64_t,
3355 class NumberUnsignedType = std::uint64_t,
3356 class NumberFloatType = double,
3357 template<typename U> class AllocatorType = std::allocator,
3358 template<typename T, typename SFINAE = void> class JSONSerializer =
3359 adl_serializer,
3360 class BinaryType = std::vector<std::uint8_t>>
3361 class basic_json;
3362
3374 template<typename BasicJsonType>
3375 class json_pointer;
3376
3385 using json = basic_json<>;
3386
3387 template<class Key, class T, class IgnoredLess, class Allocator>
3388 struct ordered_map;
3389
3397 using ordered_json = basic_json<nlohmann::ordered_map>;
3398
3399 } // namespace nlohmann
3400
3401 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3402
3403
3404 namespace nlohmann
3405 {
3414 namespace detail
3415 {
3417 // helpers //
3419
3420 // Note to maintainers:
3421 //
3422 // Every trait in this file expects a non CV-qualified type.
3423 // The only exceptions are in the 'aliases for detected' section
3424 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3425 //
3426 // In this case, T has to be properly CV-qualified to constraint the function arguments
3427 // (e.g. to_json(BasicJsonType&, const T&))
3428
3429 template<typename> struct is_basic_json : std::false_type {};
3430
3431 NLOHMANN_BASIC_JSON_TPL_DECLARATION
3432 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3433
3435 // json_ref helpers //
3437
3438 template<typename>
3439 class json_ref;
3440
3441 template<typename>
3442 struct is_json_ref : std::false_type {};
3443
3444 template<typename T>
3445 struct is_json_ref<json_ref<T>> : std::true_type {};
3446
3448 // aliases for detected //
3450
3451 template<typename T>
3452 using mapped_type_t = typename T::mapped_type;
3453
3454 template<typename T>
3455 using key_type_t = typename T::key_type;
3456
3457 template<typename T>
3458 using value_type_t = typename T::value_type;
3459
3460 template<typename T>
3461 using difference_type_t = typename T::difference_type;
3462
3463 template<typename T>
3464 using pointer_t = typename T::pointer;
3465
3466 template<typename T>
3467 using reference_t = typename T::reference;
3468
3469 template<typename T>
3470 using iterator_category_t = typename T::iterator_category;
3471
3472 template<typename T>
3473 using iterator_t = typename T::iterator;
3474
3475 template<typename T, typename... Args>
3476 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3477
3478 template<typename T, typename... Args>
3479 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3480
3481 template<typename T, typename U>
3482 using get_template_function = decltype(std::declval<T>().template get<U>());
3483
3484 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3485 template<typename BasicJsonType, typename T, typename = void>
3486 struct has_from_json : std::false_type {};
3487
3488 // trait checking if j.get<T> is valid
3489 // use this trait instead of std::is_constructible or std::is_convertible,
3490 // both rely on, or make use of implicit conversions, and thus fail when T
3491 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3492 template <typename BasicJsonType, typename T>
3493 struct is_getable
3494 {
3495 static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
3496 };
3497
3498 template<typename BasicJsonType, typename T>
3499 struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3500 {
3501 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3502
3503 static constexpr bool value =
3504 is_detected_exact<void, from_json_function, serializer,
3505 const BasicJsonType&, T&>::value;
3506 };
3507
3508 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3509 // this overload is used for non-default-constructible user-defined-types
3510 template<typename BasicJsonType, typename T, typename = void>
3511 struct has_non_default_from_json : std::false_type {};
3512
3513 template<typename BasicJsonType, typename T>
3514 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3515 {
3516 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3517
3518 static constexpr bool value =
3519 is_detected_exact<T, from_json_function, serializer,
3520 const BasicJsonType&>::value;
3521 };
3522
3523 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3524 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3525 template<typename BasicJsonType, typename T, typename = void>
3526 struct has_to_json : std::false_type {};
3527
3528 template<typename BasicJsonType, typename T>
3529 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3530 {
3531 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3532
3533 static constexpr bool value =
3534 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3535 T>::value;
3536 };
3537
3538
3540 // is_ functions //
3542
3543 // https://en.cppreference.com/w/cpp/types/conjunction
3544 template<class...> struct conjunction : std::true_type { };
3545 template<class B1> struct conjunction<B1> : B1 { };
3546 template<class B1, class... Bn>
3547 struct conjunction<B1, Bn...>
3548 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3549
3550 // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3551 // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3552 // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3553 template <typename T>
3554 struct is_default_constructible : std::is_default_constructible<T> {};
3555
3556 template <typename T1, typename T2>
3557 struct is_default_constructible<std::pair<T1, T2>>
3558 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3559
3560 template <typename T1, typename T2>
3561 struct is_default_constructible<const std::pair<T1, T2>>
3562 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3563
3564 template <typename... Ts>
3565 struct is_default_constructible<std::tuple<Ts...>>
3566 : conjunction<is_default_constructible<Ts>...> {};
3567
3568 template <typename... Ts>
3569 struct is_default_constructible<const std::tuple<Ts...>>
3570 : conjunction<is_default_constructible<Ts>...> {};
3571
3572
3573 template <typename T, typename... Args>
3574 struct is_constructible : std::is_constructible<T, Args...> {};
3575
3576 template <typename T1, typename T2>
3577 struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3578
3579 template <typename T1, typename T2>
3580 struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3581
3582 template <typename... Ts>
3583 struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3584
3585 template <typename... Ts>
3586 struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3587
3588
3589 template<typename T, typename = void>
3590 struct is_iterator_traits : std::false_type {};
3591
3592 template<typename T>
3593 struct is_iterator_traits<iterator_traits<T>>
3594 {
3595 private:
3596 using traits = iterator_traits<T>;
3597
3598 public:
3599 static constexpr auto value =
3600 is_detected<value_type_t, traits>::value &&
3601 is_detected<difference_type_t, traits>::value &&
3602 is_detected<pointer_t, traits>::value &&
3603 is_detected<iterator_category_t, traits>::value &&
3604 is_detected<reference_t, traits>::value;
3605 };
3606
3607 // The following implementation of is_complete_type is taken from
3608 // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3609 // and is written by Xiang Fan who agreed to using it in this library.
3610
3611 template<typename T, typename = void>
3612 struct is_complete_type : std::false_type {};
3613
3614 template<typename T>
3615 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3616
3617 template<typename BasicJsonType, typename CompatibleObjectType,
3618 typename = void>
3619 struct is_compatible_object_type_impl : std::false_type {};
3620
3621 template<typename BasicJsonType, typename CompatibleObjectType>
3622 struct is_compatible_object_type_impl <
3623 BasicJsonType, CompatibleObjectType,
3624 enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3625 is_detected<key_type_t, CompatibleObjectType>::value >>
3626 {
3627 using object_t = typename BasicJsonType::object_t;
3628
3629 // macOS's is_constructible does not play well with nonesuch...
3630 static constexpr bool value =
3631 is_constructible<typename object_t::key_type,
3632 typename CompatibleObjectType::key_type>::value &&
3633 is_constructible<typename object_t::mapped_type,
3634 typename CompatibleObjectType::mapped_type>::value;
3635 };
3636
3637 template<typename BasicJsonType, typename CompatibleObjectType>
3638 struct is_compatible_object_type
3639 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3640
3641 template<typename BasicJsonType, typename ConstructibleObjectType,
3642 typename = void>
3643 struct is_constructible_object_type_impl : std::false_type {};
3644
3645 template<typename BasicJsonType, typename ConstructibleObjectType>
3646 struct is_constructible_object_type_impl <
3647 BasicJsonType, ConstructibleObjectType,
3648 enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3649 is_detected<key_type_t, ConstructibleObjectType>::value >>
3650 {
3651 using object_t = typename BasicJsonType::object_t;
3652
3653 static constexpr bool value =
3654 (is_default_constructible<ConstructibleObjectType>::value &&
3655 (std::is_move_assignable<ConstructibleObjectType>::value ||
3656 std::is_copy_assignable<ConstructibleObjectType>::value) &&
3657 (is_constructible<typename ConstructibleObjectType::key_type,
3658 typename object_t::key_type>::value &&
3659 std::is_same <
3660 typename object_t::mapped_type,
3661 typename ConstructibleObjectType::mapped_type >::value)) ||
3662 (has_from_json<BasicJsonType,
3663 typename ConstructibleObjectType::mapped_type>::value ||
3664 has_non_default_from_json <
3665 BasicJsonType,
3666 typename ConstructibleObjectType::mapped_type >::value);
3667 };
3668
3669 template<typename BasicJsonType, typename ConstructibleObjectType>
3670 struct is_constructible_object_type
3671 : is_constructible_object_type_impl<BasicJsonType,
3672 ConstructibleObjectType> {};
3673
3674 template<typename BasicJsonType, typename CompatibleStringType,
3675 typename = void>
3676 struct is_compatible_string_type_impl : std::false_type {};
3677
3678 template<typename BasicJsonType, typename CompatibleStringType>
3679 struct is_compatible_string_type_impl <
3680 BasicJsonType, CompatibleStringType,
3681 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3682 value_type_t, CompatibleStringType>::value >>
3683 {
3684 static constexpr auto value =
3685 is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
3686 };
3687
3688 template<typename BasicJsonType, typename ConstructibleStringType>
3689 struct is_compatible_string_type
3690 : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3691
3692 template<typename BasicJsonType, typename ConstructibleStringType,
3693 typename = void>
3694 struct is_constructible_string_type_impl : std::false_type {};
3695
3696 template<typename BasicJsonType, typename ConstructibleStringType>
3697 struct is_constructible_string_type_impl <
3698 BasicJsonType, ConstructibleStringType,
3699 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3700 value_type_t, ConstructibleStringType>::value >>
3701 {
3702 static constexpr auto value =
3703 is_constructible<ConstructibleStringType,
3704 typename BasicJsonType::string_t>::value;
3705 };
3706
3707 template<typename BasicJsonType, typename ConstructibleStringType>
3708 struct is_constructible_string_type
3709 : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3710
3711 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3712 struct is_compatible_array_type_impl : std::false_type {};
3713
3714 template<typename BasicJsonType, typename CompatibleArrayType>
3715 struct is_compatible_array_type_impl <
3716 BasicJsonType, CompatibleArrayType,
3717 enable_if_t < is_detected<value_type_t, CompatibleArrayType>::value&&
3718 is_detected<iterator_t, CompatibleArrayType>::value&&
3719 // This is needed because json_reverse_iterator has a ::iterator type...
3720 // Therefore it is detected as a CompatibleArrayType.
3721 // The real fix would be to have an Iterable concept.
3722 !is_iterator_traits <
3723 iterator_traits<CompatibleArrayType >>::value >>
3724 {
3725 static constexpr bool value =
3726 is_constructible<BasicJsonType,
3727 typename CompatibleArrayType::value_type>::value;
3728 };
3729
3730 template<typename BasicJsonType, typename CompatibleArrayType>
3731 struct is_compatible_array_type
3732 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3733
3734 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3735 struct is_constructible_array_type_impl : std::false_type {};
3736
3737 template<typename BasicJsonType, typename ConstructibleArrayType>
3738 struct is_constructible_array_type_impl <
3739 BasicJsonType, ConstructibleArrayType,
3740 enable_if_t<std::is_same<ConstructibleArrayType,
3741 typename BasicJsonType::value_type>::value >>
3742 : std::true_type {};
3743
3744 template<typename BasicJsonType, typename ConstructibleArrayType>
3745 struct is_constructible_array_type_impl <
3746 BasicJsonType, ConstructibleArrayType,
3747 enable_if_t < !std::is_same<ConstructibleArrayType,
3748 typename BasicJsonType::value_type>::value&&
3749 is_default_constructible<ConstructibleArrayType>::value&&
3750 (std::is_move_assignable<ConstructibleArrayType>::value ||
3751 std::is_copy_assignable<ConstructibleArrayType>::value)&&
3752 is_detected<value_type_t, ConstructibleArrayType>::value&&
3753 is_detected<iterator_t, ConstructibleArrayType>::value&&
3754 is_complete_type <
3755 detected_t<value_type_t, ConstructibleArrayType >>::value >>
3756 {
3757 static constexpr bool value =
3758 // This is needed because json_reverse_iterator has a ::iterator type,
3759 // furthermore, std::back_insert_iterator (and other iterators) have a
3760 // base class `iterator`... Therefore it is detected as a
3761 // ConstructibleArrayType. The real fix would be to have an Iterable
3762 // concept.
3763 !is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value &&
3764
3765 (std::is_same<typename ConstructibleArrayType::value_type,
3766 typename BasicJsonType::array_t::value_type>::value ||
3767 has_from_json<BasicJsonType,
3768 typename ConstructibleArrayType::value_type>::value ||
3769 has_non_default_from_json <
3770 BasicJsonType, typename ConstructibleArrayType::value_type >::value);
3771 };
3772
3773 template<typename BasicJsonType, typename ConstructibleArrayType>
3774 struct is_constructible_array_type
3775 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3776
3777 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3778 typename = void>
3779 struct is_compatible_integer_type_impl : std::false_type {};
3780
3781 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3782 struct is_compatible_integer_type_impl <
3783 RealIntegerType, CompatibleNumberIntegerType,
3784 enable_if_t < std::is_integral<RealIntegerType>::value&&
3785 std::is_integral<CompatibleNumberIntegerType>::value&&
3786 !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3787 {
3788 // is there an assert somewhere on overflows?
3789 using RealLimits = std::numeric_limits<RealIntegerType>;
3790 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3791
3792 static constexpr auto value =
3793 is_constructible<RealIntegerType,
3794 CompatibleNumberIntegerType>::value &&
3795 CompatibleLimits::is_integer &&
3796 RealLimits::is_signed == CompatibleLimits::is_signed;
3797 };
3798
3799 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3800 struct is_compatible_integer_type
3801 : is_compatible_integer_type_impl<RealIntegerType,
3802 CompatibleNumberIntegerType> {};
3803
3804 template<typename BasicJsonType, typename CompatibleType, typename = void>
3805 struct is_compatible_type_impl: std::false_type {};
3806
3807 template<typename BasicJsonType, typename CompatibleType>
3808 struct is_compatible_type_impl <
3809 BasicJsonType, CompatibleType,
3810 enable_if_t<is_complete_type<CompatibleType>::value >>
3811 {
3812 static constexpr bool value =
3813 has_to_json<BasicJsonType, CompatibleType>::value;
3814 };
3815
3816 template<typename BasicJsonType, typename CompatibleType>
3817 struct is_compatible_type
3818 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3819
3820 template<typename T1, typename T2>
3821 struct is_constructible_tuple : std::false_type {};
3822
3823 template<typename T1, typename... Args>
3824 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3825 } // namespace detail
3826 } // namespace nlohmann
3827
3828 // #include <nlohmann/detail/value_t.hpp>
3829
3830
3831 namespace nlohmann
3832 {
3833 namespace detail
3834 {
3835 template<typename BasicJsonType>
3836 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3837 {
3838 if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
3839 {
3840 JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()), j));
3841 }
3842 n = nullptr;
3843 }
3844
3845 // overloads for basic_json template parameters
3846 template < typename BasicJsonType, typename ArithmeticType,
3847 enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
3848 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3849 int > = 0 >
3850 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3851 {
3852 switch (static_cast<value_t>(j))
3853 {
3854 case value_t::number_unsigned:
3855 {
3856 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3857 break;
3858 }
3859 case value_t::number_integer:
3860 {
3861 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3862 break;
3863 }
3864 case value_t::number_float:
3865 {
3866 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3867 break;
3868 }
3869
3870 default:
3871 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
3872 }
3873 }
3874
3875 template<typename BasicJsonType>
3876 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
3877 {
3878 if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
3879 {
3880 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()), j));
3881 }
3882 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
3883 }
3884
3885 template<typename BasicJsonType>
3886 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
3887 {
3888 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3889 {
3890 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
3891 }
3892 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3893 }
3894
3895 template <
3896 typename BasicJsonType, typename ConstructibleStringType,
3897 enable_if_t <
3898 is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&
3899 !std::is_same<typename BasicJsonType::string_t,
3900 ConstructibleStringType>::value,
3901 int > = 0 >
3902 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
3903 {
3904 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3905 {
3906 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
3907 }
3908
3909 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3910 }
3911
3912 template<typename BasicJsonType>
3913 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
3914 {
3915 get_arithmetic_value(j, val);
3916 }
3917
3918 template<typename BasicJsonType>
3919 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
3920 {
3921 get_arithmetic_value(j, val);
3922 }
3923
3924 template<typename BasicJsonType>
3925 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
3926 {
3927 get_arithmetic_value(j, val);
3928 }
3929
3930 template<typename BasicJsonType, typename EnumType,
3931 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
3932 void from_json(const BasicJsonType& j, EnumType& e)
3933 {
3934 typename std::underlying_type<EnumType>::type val;
3935 get_arithmetic_value(j, val);
3936 e = static_cast<EnumType>(val);
3937 }
3938
3939 // forward_list doesn't have an insert method
3940 template<typename BasicJsonType, typename T, typename Allocator,
3941 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
3942 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
3943 {
3944 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3945 {
3946 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
3947 }
3948 l.clear();
3949 std::transform(j.rbegin(), j.rend(),
3950 std::front_inserter(l), [](const BasicJsonType & i)
3951 {
3952 return i.template get<T>();
3953 });
3954 }
3955
3956 // valarray doesn't have an insert method
3957 template<typename BasicJsonType, typename T,
3958 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
3959 void from_json(const BasicJsonType& j, std::valarray<T>& l)
3960 {
3961 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3962 {
3963 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
3964 }
3965 l.resize(j.size());
3966 std::transform(j.begin(), j.end(), std::begin(l),
3967 [](const BasicJsonType & elem)
3968 {
3969 return elem.template get<T>();
3970 });
3971 }
3972
3973 template<typename BasicJsonType, typename T, std::size_t N>
3974 auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3975 -> decltype(j.template get<T>(), void())
3976 {
3977 for (std::size_t i = 0; i < N; ++i)
3978 {
3979 arr[i] = j.at(i).template get<T>();
3980 }
3981 }
3982
3983 template<typename BasicJsonType>
3984 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
3985 {
3986 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
3987 }
3988
3989 template<typename BasicJsonType, typename T, std::size_t N>
3990 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
3991 priority_tag<2> /*unused*/)
3992 -> decltype(j.template get<T>(), void())
3993 {
3994 for (std::size_t i = 0; i < N; ++i)
3995 {
3996 arr[i] = j.at(i).template get<T>();
3997 }
3998 }
3999
4000 template<typename BasicJsonType, typename ConstructibleArrayType,
4001 enable_if_t<
4002 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4003 int> = 0>
4004 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4005 -> decltype(
4006 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4007 j.template get<typename ConstructibleArrayType::value_type>(),
4008 void())
4009 {
4010 using std::end;
4011
4012 ConstructibleArrayType ret;
4013 ret.reserve(j.size());
4014 std::transform(j.begin(), j.end(),
4015 std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4016 {
4017 // get<BasicJsonType>() returns *this, this won't call a from_json
4018 // method when value_type is BasicJsonType
4019 return i.template get<typename ConstructibleArrayType::value_type>();
4020 });
4021 arr = std::move(ret);
4022 }
4023
4024 template<typename BasicJsonType, typename ConstructibleArrayType,
4025 enable_if_t<
4026 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4027 int> = 0>
4028 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4029 priority_tag<0> /*unused*/)
4030 {
4031 using std::end;
4032
4033 ConstructibleArrayType ret;
4034 std::transform(
4035 j.begin(), j.end(), std::inserter(ret, end(ret)),
4036 [](const BasicJsonType & i)
4037 {
4038 // get<BasicJsonType>() returns *this, this won't call a from_json
4039 // method when value_type is BasicJsonType
4040 return i.template get<typename ConstructibleArrayType::value_type>();
4041 });
4042 arr = std::move(ret);
4043 }
4044
4045 template < typename BasicJsonType, typename ConstructibleArrayType,
4046 enable_if_t <
4047 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
4048 !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
4049 !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
4050 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
4051 !is_basic_json<ConstructibleArrayType>::value,
4052 int > = 0 >
4053 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4054 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4055 j.template get<typename ConstructibleArrayType::value_type>(),
4056 void())
4057 {
4058 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4059 {
4060 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4061 }
4062
4063 from_json_array_impl(j, arr, priority_tag<3> {});
4064 }
4065
4066 template < typename BasicJsonType, typename T, std::size_t... Idx >
4067 std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4068 identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4069 {
4070 return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4071 }
4072
4073 template < typename BasicJsonType, typename T, std::size_t N >
4074 auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4075 -> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4076 {
4077 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4078 {
4079 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4080 }
4081
4082 return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4083 }
4084
4085 template<typename BasicJsonType>
4086 void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4087 {
4088 if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4089 {
4090 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()), j));
4091 }
4092
4093 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4094 }
4095
4096 template<typename BasicJsonType, typename ConstructibleObjectType,
4097 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4098 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4099 {
4100 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4101 {
4102 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()), j));
4103 }
4104
4105 ConstructibleObjectType ret;
4106 const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4107 using value_type = typename ConstructibleObjectType::value_type;
4108 std::transform(
4109 inner_object->begin(), inner_object->end(),
4110 std::inserter(ret, ret.begin()),
4111 [](typename BasicJsonType::object_t::value_type const & p)
4112 {
4113 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4114 });
4115 obj = std::move(ret);
4116 }
4117
4118 // overload for arithmetic types, not chosen for basic_json template arguments
4119 // (BooleanType, etc..); note: Is it really necessary to provide explicit
4120 // overloads for boolean_t etc. in case of a custom BooleanType which is not
4121 // an arithmetic type?
4122 template < typename BasicJsonType, typename ArithmeticType,
4123 enable_if_t <
4124 std::is_arithmetic<ArithmeticType>::value&&
4125 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
4126 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
4127 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
4128 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4129 int > = 0 >
4130 void from_json(const BasicJsonType& j, ArithmeticType& val)
4131 {
4132 switch (static_cast<value_t>(j))
4133 {
4134 case value_t::number_unsigned:
4135 {
4136 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4137 break;
4138 }
4139 case value_t::number_integer:
4140 {
4141 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4142 break;
4143 }
4144 case value_t::number_float:
4145 {
4146 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4147 break;
4148 }
4149 case value_t::boolean:
4150 {
4151 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4152 break;
4153 }
4154
4155 default:
4156 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4157 }
4158 }
4159
4160 template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4161 std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4162 {
4163 return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4164 }
4165
4166 template < typename BasicJsonType, class A1, class A2 >
4167 std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4168 {
4169 return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4170 std::forward<BasicJsonType>(j).at(1).template get<A2>()};
4171 }
4172
4173 template<typename BasicJsonType, typename A1, typename A2>
4174 void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4175 {
4176 p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4177 }
4178
4179 template<typename BasicJsonType, typename... Args>
4180 std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4181 {
4182 return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4183 }
4184
4185 template<typename BasicJsonType, typename... Args>
4186 void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4187 {
4188 t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4189 }
4190
4191 template<typename BasicJsonType, typename TupleRelated>
4192 auto from_json(BasicJsonType&& j, TupleRelated&& t)
4193 -> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4194 {
4195 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4196 {
4197 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4198 }
4199
4200 return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4201 }
4202
4203 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4204 typename = enable_if_t < !std::is_constructible <
4205 typename BasicJsonType::string_t, Key >::value >>
4206 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4207 {
4208 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4209 {
4210 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4211 }
4212 m.clear();
4213 for (const auto& p : j)
4214 {
4215 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4216 {
4217 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4218 }
4219 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4220 }
4221 }
4222
4223 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4224 typename = enable_if_t < !std::is_constructible <
4225 typename BasicJsonType::string_t, Key >::value >>
4226 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
4227 {
4228 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4229 {
4230 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4231 }
4232 m.clear();
4233 for (const auto& p : j)
4234 {
4235 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4236 {
4237 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4238 }
4239 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4240 }
4241 }
4242
4243 struct from_json_fn
4244 {
4245 template<typename BasicJsonType, typename T>
4246 auto operator()(const BasicJsonType& j, T&& val) const
4247 noexcept(noexcept(from_json(j, std::forward<T>(val))))
4248 -> decltype(from_json(j, std::forward<T>(val)))
4249 {
4250 return from_json(j, std::forward<T>(val));
4251 }
4252 };
4253 } // namespace detail
4254
4258 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4259 {
4260 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4261 } // namespace
4262 } // namespace nlohmann
4263
4264 // #include <nlohmann/detail/conversions/to_json.hpp>
4265
4266
4267 #include <algorithm> // copy
4268 #include <iterator> // begin, end
4269 #include <string> // string
4270 #include <tuple> // tuple, get
4271 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
4272 #include <utility> // move, forward, declval, pair
4273 #include <valarray> // valarray
4274 #include <vector> // vector
4275
4276 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4277
4278
4279 #include <cstddef> // size_t
4280 #include <iterator> // input_iterator_tag
4281 #include <string> // string, to_string
4282 #include <tuple> // tuple_size, get, tuple_element
4283 #include <utility> // move
4284
4285 // #include <nlohmann/detail/meta/type_traits.hpp>
4286
4287 // #include <nlohmann/detail/value_t.hpp>
4288
4289
4290 namespace nlohmann
4291 {
4292 namespace detail
4293 {
4294 template<typename string_type>
4295 void int_to_string( string_type& target, std::size_t value )
4296 {
4297 // For ADL
4298 using std::to_string;
4299 target = to_string(value);
4300 }
4301 template<typename IteratorType> class iteration_proxy_value
4302 {
4303 public:
4304 using difference_type = std::ptrdiff_t;
4305 using value_type = iteration_proxy_value;
4306 using pointer = value_type * ;
4307 using reference = value_type & ;
4308 using iterator_category = std::input_iterator_tag;
4309 using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
4310
4311 private:
4313 IteratorType anchor;
4315 std::size_t array_index = 0;
4317 mutable std::size_t array_index_last = 0;
4319 mutable string_type array_index_str = "0";
4321 const string_type empty_str{};
4322
4323 public:
4324 explicit iteration_proxy_value(IteratorType it) noexcept
4325 : anchor(std::move(it))
4326 {}
4327
4329 iteration_proxy_value& operator*()
4330 {
4331 return *this;
4332 }
4333
4335 iteration_proxy_value& operator++()
4336 {
4337 ++anchor;
4338 ++array_index;
4339
4340 return *this;
4341 }
4342
4344 bool operator==(const iteration_proxy_value& o) const
4345 {
4346 return anchor == o.anchor;
4347 }
4348
4350 bool operator!=(const iteration_proxy_value& o) const
4351 {
4352 return anchor != o.anchor;
4353 }
4354
4356 const string_type& key() const
4357 {
4358 JSON_ASSERT(anchor.m_object != nullptr);
4359
4360 switch (anchor.m_object->type())
4361 {
4362 // use integer array index as key
4363 case value_t::array:
4364 {
4365 if (array_index != array_index_last)
4366 {
4367 int_to_string( array_index_str, array_index );
4368 array_index_last = array_index;
4369 }
4370 return array_index_str;
4371 }
4372
4373 // use key from the object
4374 case value_t::object:
4375 return anchor.key();
4376
4377 // use an empty key for all primitive types
4378 default:
4379 return empty_str;
4380 }
4381 }
4382
4384 typename IteratorType::reference value() const
4385 {
4386 return anchor.value();
4387 }
4388 };
4389
4391 template<typename IteratorType> class iteration_proxy
4392 {
4393 private:
4395 typename IteratorType::reference container;
4396
4397 public:
4399 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4400 : container(cont) {}
4401
4403 iteration_proxy_value<IteratorType> begin() noexcept
4404 {
4405 return iteration_proxy_value<IteratorType>(container.begin());
4406 }
4407
4409 iteration_proxy_value<IteratorType> end() noexcept
4410 {
4411 return iteration_proxy_value<IteratorType>(container.end());
4412 }
4413 };
4414 // Structured Bindings Support
4415 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4416 // And see https://github.com/nlohmann/json/pull/1391
4417 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
4418 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
4419 {
4420 return i.key();
4421 }
4422 // Structured Bindings Support
4423 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4424 // And see https://github.com/nlohmann/json/pull/1391
4425 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
4426 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
4427 {
4428 return i.value();
4429 }
4430 } // namespace detail
4431 } // namespace nlohmann
4432
4433 // The Addition to the STD Namespace is required to add
4434 // Structured Bindings Support to the iteration_proxy_value class
4435 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4436 // And see https://github.com/nlohmann/json/pull/1391
4437 namespace std
4438 {
4439 #if defined(__clang__)
4440 // Fix: https://github.com/nlohmann/json/issues/1401
4441 #pragma clang diagnostic push
4442 #pragma clang diagnostic ignored "-Wmismatched-tags"
4443 #endif
4444 template<typename IteratorType>
4445 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4446 : public std::integral_constant<std::size_t, 2> {};
4447
4448 template<std::size_t N, typename IteratorType>
4449 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4450 {
4451 public:
4452 using type = decltype(
4453 get<N>(std::declval <
4454 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
4455 };
4456 #if defined(__clang__)
4457 #pragma clang diagnostic pop
4458 #endif
4459 } // namespace std
4460
4461 // #include <nlohmann/detail/meta/cpp_future.hpp>
4462
4463 // #include <nlohmann/detail/meta/type_traits.hpp>
4464
4465 // #include <nlohmann/detail/value_t.hpp>
4466
4467
4468 namespace nlohmann
4469 {
4470 namespace detail
4471 {
4473 // constructors //
4475
4476 template<value_t> struct external_constructor;
4477
4478 template<>
4479 struct external_constructor<value_t::boolean>
4480 {
4481 template<typename BasicJsonType>
4482 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4483 {
4484 j.m_type = value_t::boolean;
4485 j.m_value = b;
4486 j.assert_invariant();
4487 }
4488 };
4489
4490 template<>
4491 struct external_constructor<value_t::string>
4492 {
4493 template<typename BasicJsonType>
4494 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4495 {
4496 j.m_type = value_t::string;
4497 j.m_value = s;
4498 j.assert_invariant();
4499 }
4500
4501 template<typename BasicJsonType>
4502 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4503 {
4504 j.m_type = value_t::string;
4505 j.m_value = std::move(s);
4506 j.assert_invariant();
4507 }
4508
4509 template < typename BasicJsonType, typename CompatibleStringType,
4510 enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
4511 int > = 0 >
4512 static void construct(BasicJsonType& j, const CompatibleStringType& str)
4513 {
4514 j.m_type = value_t::string;
4515 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4516 j.assert_invariant();
4517 }
4518 };
4519
4520 template<>
4521 struct external_constructor<value_t::binary>
4522 {
4523 template<typename BasicJsonType>
4524 static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4525 {
4526 j.m_type = value_t::binary;
4527 j.m_value = typename BasicJsonType::binary_t(b);
4528 j.assert_invariant();
4529 }
4530
4531 template<typename BasicJsonType>
4532 static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4533 {
4534 j.m_type = value_t::binary;
4535 j.m_value = typename BasicJsonType::binary_t(std::move(b));;
4536 j.assert_invariant();
4537 }
4538 };
4539
4540 template<>
4541 struct external_constructor<value_t::number_float>
4542 {
4543 template<typename BasicJsonType>
4544 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4545 {
4546 j.m_type = value_t::number_float;
4547 j.m_value = val;
4548 j.assert_invariant();
4549 }
4550 };
4551
4552 template<>
4553 struct external_constructor<value_t::number_unsigned>
4554 {
4555 template<typename BasicJsonType>
4556 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4557 {
4558 j.m_type = value_t::number_unsigned;
4559 j.m_value = val;
4560 j.assert_invariant();
4561 }
4562 };
4563
4564 template<>
4565 struct external_constructor<value_t::number_integer>
4566 {
4567 template<typename BasicJsonType>
4568 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4569 {
4570 j.m_type = value_t::number_integer;
4571 j.m_value = val;
4572 j.assert_invariant();
4573 }
4574 };
4575
4576 template<>
4577 struct external_constructor<value_t::array>
4578 {
4579 template<typename BasicJsonType>
4580 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4581 {
4582 j.m_type = value_t::array;
4583 j.m_value = arr;
4584 j.set_parents();
4585 j.assert_invariant();
4586 }
4587
4588 template<typename BasicJsonType>
4589 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4590 {
4591 j.m_type = value_t::array;
4592 j.m_value = std::move(arr);
4593 j.set_parents();
4594 j.assert_invariant();
4595 }
4596
4597 template < typename BasicJsonType, typename CompatibleArrayType,
4598 enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
4599 int > = 0 >
4600 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4601 {
4602 using std::begin;
4603 using std::end;
4604 j.m_type = value_t::array;
4605 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4606 j.set_parents();
4607 j.assert_invariant();
4608 }
4609
4610 template<typename BasicJsonType>
4611 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4612 {
4613 j.m_type = value_t::array;
4614 j.m_value = value_t::array;
4615 j.m_value.array->reserve(arr.size());
4616 for (const bool x : arr)
4617 {
4618 j.m_value.array->push_back(x);
4619 j.set_parent(j.m_value.array->back());
4620 }
4621 j.assert_invariant();
4622 }
4623
4624 template<typename BasicJsonType, typename T,
4625 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4626 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4627 {
4628 j.m_type = value_t::array;
4629 j.m_value = value_t::array;
4630 j.m_value.array->resize(arr.size());
4631 if (arr.size() > 0)
4632 {
4633 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4634 }
4635 j.set_parents();
4636 j.assert_invariant();
4637 }
4638 };
4639
4640 template<>
4641 struct external_constructor<value_t::object>
4642 {
4643 template<typename BasicJsonType>
4644 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
4645 {
4646 j.m_type = value_t::object;
4647 j.m_value = obj;
4648 j.set_parents();
4649 j.assert_invariant();
4650 }
4651
4652 template<typename BasicJsonType>
4653 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4654 {
4655 j.m_type = value_t::object;
4656 j.m_value = std::move(obj);
4657 j.set_parents();
4658 j.assert_invariant();
4659 }
4660
4661 template < typename BasicJsonType, typename CompatibleObjectType,
4662 enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
4663 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4664 {
4665 using std::begin;
4666 using std::end;
4667
4668 j.m_type = value_t::object;
4669 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4670 j.set_parents();
4671 j.assert_invariant();
4672 }
4673 };
4674
4676 // to_json //
4678
4679 template<typename BasicJsonType, typename T,
4680 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
4681 void to_json(BasicJsonType& j, T b) noexcept
4682 {
4683 external_constructor<value_t::boolean>::construct(j, b);
4684 }
4685
4686 template<typename BasicJsonType, typename CompatibleString,
4687 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
4688 void to_json(BasicJsonType& j, const CompatibleString& s)
4689 {
4690 external_constructor<value_t::string>::construct(j, s);
4691 }
4692
4693 template<typename BasicJsonType>
4694 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4695 {
4696 external_constructor<value_t::string>::construct(j, std::move(s));
4697 }
4698
4699 template<typename BasicJsonType, typename FloatType,
4700 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
4701 void to_json(BasicJsonType& j, FloatType val) noexcept
4702 {
4703 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4704 }
4705
4706 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4707 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
4708 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4709 {
4710 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4711 }
4712
4713 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4714 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
4715 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4716 {
4717 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4718 }
4719
4720 template<typename BasicJsonType, typename EnumType,
4721 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4722 void to_json(BasicJsonType& j, EnumType e) noexcept
4723 {
4724 using underlying_type = typename std::underlying_type<EnumType>::type;
4725 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4726 }
4727
4728 template<typename BasicJsonType>
4729 void to_json(BasicJsonType& j, const std::vector<bool>& e)
4730 {
4731 external_constructor<value_t::array>::construct(j, e);
4732 }
4733
4734 template < typename BasicJsonType, typename CompatibleArrayType,
4735 enable_if_t < is_compatible_array_type<BasicJsonType,
4736 CompatibleArrayType>::value&&
4737 !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
4738 !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
4739 !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
4740 !is_basic_json<CompatibleArrayType>::value,
4741 int > = 0 >
4742 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4743 {
4744 external_constructor<value_t::array>::construct(j, arr);
4745 }
4746
4747 template<typename BasicJsonType>
4748 void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4749 {
4750 external_constructor<value_t::binary>::construct(j, bin);
4751 }
4752
4753 template<typename BasicJsonType, typename T,
4754 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4755 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4756 {
4757 external_constructor<value_t::array>::construct(j, std::move(arr));
4758 }
4759
4760 template<typename BasicJsonType>
4761 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4762 {
4763 external_constructor<value_t::array>::construct(j, std::move(arr));
4764 }
4765
4766 template < typename BasicJsonType, typename CompatibleObjectType,
4767 enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
4768 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4769 {
4770 external_constructor<value_t::object>::construct(j, obj);
4771 }
4772
4773 template<typename BasicJsonType>
4774 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4775 {
4776 external_constructor<value_t::object>::construct(j, std::move(obj));
4777 }
4778
4779 template <
4780 typename BasicJsonType, typename T, std::size_t N,
4781 enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4782 const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4783 int > = 0 >
4784 void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4785 {
4786 external_constructor<value_t::array>::construct(j, arr);
4787 }
4788
4789 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
4790 void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4791 {
4792 j = { p.first, p.second };
4793 }
4794
4795 // for https://github.com/nlohmann/json/pull/1134
4796 template<typename BasicJsonType, typename T,
4797 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
4798 void to_json(BasicJsonType& j, const T& b)
4799 {
4800 j = { {b.key(), b.value()} };
4801 }
4802
4803 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
4804 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4805 {
4806 j = { std::get<Idx>(t)... };
4807 }
4808
4809 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
4810 void to_json(BasicJsonType& j, const T& t)
4811 {
4812 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
4813 }
4814
4815 struct to_json_fn
4816 {
4817 template<typename BasicJsonType, typename T>
4818 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
4819 -> decltype(to_json(j, std::forward<T>(val)), void())
4820 {
4821 return to_json(j, std::forward<T>(val));
4822 }
4823 };
4824 } // namespace detail
4825
4829 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4830 {
4831 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4832 } // namespace
4833 } // namespace nlohmann
4834
4835 // #include <nlohmann/detail/meta/identity_tag.hpp>
4836
4837 // #include <nlohmann/detail/meta/type_traits.hpp>
4838
4839
4840 namespace nlohmann
4841 {
4842
4843 template<typename ValueType, typename>
4844 struct adl_serializer
4845 {
4857 template<typename BasicJsonType, typename TargetType = ValueType>
4858 static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
4859 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
4860 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
4861 {
4862 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
4863 }
4864
4877 template<typename BasicJsonType, typename TargetType = ValueType>
4878 static auto from_json(BasicJsonType && j) noexcept(
4879 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
4880 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
4881 {
4882 return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
4883 }
4884
4894 template<typename BasicJsonType, typename TargetType = ValueType>
4895 static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
4896 noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
4897 -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
4898 {
4899 ::nlohmann::to_json(j, std::forward<TargetType>(val));
4900 }
4901 };
4902 } // namespace nlohmann
4903
4904 // #include <nlohmann/byte_container_with_subtype.hpp>
4905
4906
4907 #include <cstdint> // uint8_t
4908 #include <tuple> // tie
4909 #include <utility> // move
4910
4911 namespace nlohmann
4912 {
4913
4927 template<typename BinaryType>
4928 class byte_container_with_subtype : public BinaryType
4929 {
4930 public:
4932 using container_type = BinaryType;
4933
4934 byte_container_with_subtype() noexcept(noexcept(container_type()))
4935 : container_type()
4936 {}
4937
4938 byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))
4939 : container_type(b)
4940 {}
4941
4942 byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
4943 : container_type(std::move(b))
4944 {}
4945
4946 byte_container_with_subtype(const container_type& b, std::uint8_t subtype_) noexcept(noexcept(container_type(b)))
4947 : container_type(b)
4948 , m_subtype(subtype_)
4949 , m_has_subtype(true)
4950 {}
4951
4952 byte_container_with_subtype(container_type&& b, std::uint8_t subtype_) noexcept(noexcept(container_type(std::move(b))))
4953 : container_type(std::move(b))
4954 , m_subtype(subtype_)
4955 , m_has_subtype(true)
4956 {}
4957
4958 bool operator==(const byte_container_with_subtype& rhs) const
4959 {
4960 return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
4961 std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
4962 }
4963
4964 bool operator!=(const byte_container_with_subtype& rhs) const
4965 {
4966 return !(rhs == *this);
4967 }
4968
4987 void set_subtype(std::uint8_t subtype_) noexcept
4988 {
4989 m_subtype = subtype_;
4990 m_has_subtype = true;
4991 }
4992
5014 constexpr std::uint8_t subtype() const noexcept
5015 {
5016 return m_subtype;
5017 }
5018
5035 constexpr bool has_subtype() const noexcept
5036 {
5037 return m_has_subtype;
5038 }
5039
5059 void clear_subtype() noexcept
5060 {
5061 m_subtype = 0;
5062 m_has_subtype = false;
5063 }
5064
5065 private:
5066 std::uint8_t m_subtype = 0;
5067 bool m_has_subtype = false;
5068 };
5069
5070 } // namespace nlohmann
5071
5072 // #include <nlohmann/detail/conversions/from_json.hpp>
5073
5074 // #include <nlohmann/detail/conversions/to_json.hpp>
5075
5076 // #include <nlohmann/detail/exceptions.hpp>
5077
5078 // #include <nlohmann/detail/hash.hpp>
5079
5080
5081 #include <cstdint> // uint8_t
5082 #include <cstddef> // size_t
5083 #include <functional> // hash
5084
5085 // #include <nlohmann/detail/macro_scope.hpp>
5086
5087
5088 namespace nlohmann
5089 {
5090 namespace detail
5091 {
5092
5093 // boost::hash_combine
5094 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5095 {
5096 seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5097 return seed;
5098 }
5099
5111 template<typename BasicJsonType>
5112 std::size_t hash(const BasicJsonType& j)
5113 {
5114 using string_t = typename BasicJsonType::string_t;
5115 using number_integer_t = typename BasicJsonType::number_integer_t;
5116 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5117 using number_float_t = typename BasicJsonType::number_float_t;
5118
5119 const auto type = static_cast<std::size_t>(j.type());
5120 switch (j.type())
5121 {
5122 case BasicJsonType::value_t::null:
5123 case BasicJsonType::value_t::discarded:
5124 {
5125 return combine(type, 0);
5126 }
5127
5128 case BasicJsonType::value_t::object:
5129 {
5130 auto seed = combine(type, j.size());
5131 for (const auto& element : j.items())
5132 {
5133 const auto h = std::hash<string_t> {}(element.key());
5134 seed = combine(seed, h);
5135 seed = combine(seed, hash(element.value()));
5136 }
5137 return seed;
5138 }
5139
5140 case BasicJsonType::value_t::array:
5141 {
5142 auto seed = combine(type, j.size());
5143 for (const auto& element : j)
5144 {
5145 seed = combine(seed, hash(element));
5146 }
5147 return seed;
5148 }
5149
5150 case BasicJsonType::value_t::string:
5151 {
5152 const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
5153 return combine(type, h);
5154 }
5155
5156 case BasicJsonType::value_t::boolean:
5157 {
5158 const auto h = std::hash<bool> {}(j.template get<bool>());
5159 return combine(type, h);
5160 }
5161
5162 case BasicJsonType::value_t::number_integer:
5163 {
5164 const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
5165 return combine(type, h);
5166 }
5167
5168 case BasicJsonType::value_t::number_unsigned:
5169 {
5170 const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
5171 return combine(type, h);
5172 }
5173
5174 case BasicJsonType::value_t::number_float:
5175 {
5176 const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
5177 return combine(type, h);
5178 }
5179
5180 case BasicJsonType::value_t::binary:
5181 {
5182 auto seed = combine(type, j.get_binary().size());
5183 const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
5184 seed = combine(seed, h);
5185 seed = combine(seed, j.get_binary().subtype());
5186 for (const auto byte : j.get_binary())
5187 {
5188 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
5189 }
5190 return seed;
5191 }
5192
5193 default: // LCOV_EXCL_LINE
5194 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
5195 return 0; // LCOV_EXCL_LINE
5196 }
5197 }
5198
5199 } // namespace detail
5200 } // namespace nlohmann
5201
5202 // #include <nlohmann/detail/input/binary_reader.hpp>
5203
5204
5205 #include <algorithm> // generate_n
5206 #include <array> // array
5207 #include <cmath> // ldexp
5208 #include <cstddef> // size_t
5209 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5210 #include <cstdio> // snprintf
5211 #include <cstring> // memcpy
5212 #include <iterator> // back_inserter
5213 #include <limits> // numeric_limits
5214 #include <string> // char_traits, string
5215 #include <utility> // make_pair, move
5216 #include <vector> // vector
5217
5218 // #include <nlohmann/detail/exceptions.hpp>
5219
5220 // #include <nlohmann/detail/input/input_adapters.hpp>
5221
5222
5223 #include <array> // array
5224 #include <cstddef> // size_t
5225 #include <cstdio> //FILE *
5226 #include <cstring> // strlen
5227 #include <istream> // istream
5228 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
5229 #include <memory> // shared_ptr, make_shared, addressof
5230 #include <numeric> // accumulate
5231 #include <string> // string, char_traits
5232 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
5233 #include <utility> // pair, declval
5234
5235 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
5236
5237 // #include <nlohmann/detail/macro_scope.hpp>
5238
5239
5240 namespace nlohmann
5241 {
5242 namespace detail
5243 {
5245 enum class input_format_t { json, cbor, msgpack, ubjson, bson };
5246
5248 // input adapters //
5250
5255 class file_input_adapter
5256 {
5257 public:
5258 using char_type = char;
5259
5260 JSON_HEDLEY_NON_NULL(2)
5261 explicit file_input_adapter(std::FILE* f) noexcept
5262 : m_file(f)
5263 {}
5264
5265 // make class move-only
5266 file_input_adapter(const file_input_adapter&) = delete;
5267 file_input_adapter(file_input_adapter&&) noexcept = default;
5268 file_input_adapter& operator=(const file_input_adapter&) = delete;
5269 file_input_adapter& operator=(file_input_adapter&&) = delete;
5270 ~file_input_adapter() = default;
5271
5272 std::char_traits<char>::int_type get_character() noexcept
5273 {
5274 return std::fgetc(m_file);
5275 }
5276
5277 private:
5279 std::FILE* m_file;
5280 };
5281
5282
5292 class input_stream_adapter
5293 {
5294 public:
5295 using char_type = char;
5296
5297 ~input_stream_adapter()
5298 {
5299 // clear stream flags; we use underlying streambuf I/O, do not
5300 // maintain ifstream flags, except eof
5301 if (is != nullptr)
5302 {
5303 is->clear(is->rdstate() & std::ios::eofbit);
5304 }
5305 }
5306
5307 explicit input_stream_adapter(std::istream& i)
5308 : is(&i), sb(i.rdbuf())
5309 {}
5310
5311 // delete because of pointer members
5312 input_stream_adapter(const input_stream_adapter&) = delete;
5313 input_stream_adapter& operator=(input_stream_adapter&) = delete;
5314 input_stream_adapter& operator=(input_stream_adapter&&) = delete;
5315
5316 input_stream_adapter(input_stream_adapter&& rhs) noexcept
5317 : is(rhs.is), sb(rhs.sb)
5318 {
5319 rhs.is = nullptr;
5320 rhs.sb = nullptr;
5321 }
5322
5323 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
5324 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
5325 // end up as the same value, eg. 0xFFFFFFFF.
5326 std::char_traits<char>::int_type get_character()
5327 {
5328 auto res = sb->sbumpc();
5329 // set eof manually, as we don't use the istream interface.
5330 if (JSON_HEDLEY_UNLIKELY(res == EOF))
5331 {
5332 is->clear(is->rdstate() | std::ios::eofbit);
5333 }
5334 return res;
5335 }
5336
5337 private:
5339 std::istream* is = nullptr;
5340 std::streambuf* sb = nullptr;
5341 };
5342
5343 // General-purpose iterator-based adapter. It might not be as fast as
5344 // theoretically possible for some containers, but it is extremely versatile.
5345 template<typename IteratorType>
5346 class iterator_input_adapter
5347 {
5348 public:
5349 using char_type = typename std::iterator_traits<IteratorType>::value_type;
5350
5351 iterator_input_adapter(IteratorType first, IteratorType last)
5352 : current(std::move(first)), end(std::move(last))
5353 {}
5354
5355 typename std::char_traits<char_type>::int_type get_character()
5356 {
5357 if (JSON_HEDLEY_LIKELY(current != end))
5358 {
5359 auto result = std::char_traits<char_type>::to_int_type(*current);
5360 std::advance(current, 1);
5361 return result;
5362 }
5363
5364 return std::char_traits<char_type>::eof();
5365 }
5366
5367 private:
5368 IteratorType current;
5369 IteratorType end;
5370
5371 template<typename BaseInputAdapter, size_t T>
5372 friend struct wide_string_input_helper;
5373
5374 bool empty() const
5375 {
5376 return current == end;
5377 }
5378 };
5379
5380
5381 template<typename BaseInputAdapter, size_t T>
5382 struct wide_string_input_helper;
5383
5384 template<typename BaseInputAdapter>
5385 struct wide_string_input_helper<BaseInputAdapter, 4>
5386 {
5387 // UTF-32
5388 static void fill_buffer(BaseInputAdapter& input,
5389 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5390 size_t& utf8_bytes_index,
5391 size_t& utf8_bytes_filled)
5392 {
5393 utf8_bytes_index = 0;
5394
5395 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5396 {
5397 utf8_bytes[0] = std::char_traits<char>::eof();
5398 utf8_bytes_filled = 1;
5399 }
5400 else
5401 {
5402 // get the current character
5403 const auto wc = input.get_character();
5404
5405 // UTF-32 to UTF-8 encoding
5406 if (wc < 0x80)
5407 {
5408 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5409 utf8_bytes_filled = 1;
5410 }
5411 else if (wc <= 0x7FF)
5412 {
5413 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
5414 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5415 utf8_bytes_filled = 2;
5416 }
5417 else if (wc <= 0xFFFF)
5418 {
5419 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
5420 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5421 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5422 utf8_bytes_filled = 3;
5423 }
5424 else if (wc <= 0x10FFFF)
5425 {
5426 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
5427 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
5428 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5429 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5430 utf8_bytes_filled = 4;
5431 }
5432 else
5433 {
5434 // unknown character
5435 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5436 utf8_bytes_filled = 1;
5437 }
5438 }
5439 }
5440 };
5441
5442 template<typename BaseInputAdapter>
5443 struct wide_string_input_helper<BaseInputAdapter, 2>
5444 {
5445 // UTF-16
5446 static void fill_buffer(BaseInputAdapter& input,
5447 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5448 size_t& utf8_bytes_index,
5449 size_t& utf8_bytes_filled)
5450 {
5451 utf8_bytes_index = 0;
5452
5453 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5454 {
5455 utf8_bytes[0] = std::char_traits<char>::eof();
5456 utf8_bytes_filled = 1;
5457 }
5458 else
5459 {
5460 // get the current character
5461 const auto wc = input.get_character();
5462
5463 // UTF-16 to UTF-8 encoding
5464 if (wc < 0x80)
5465 {
5466 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5467 utf8_bytes_filled = 1;
5468 }
5469 else if (wc <= 0x7FF)
5470 {
5471 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5472 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5473 utf8_bytes_filled = 2;
5474 }
5475 else if (0xD800 > wc || wc >= 0xE000)
5476 {
5477 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5478 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5479 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5480 utf8_bytes_filled = 3;
5481 }
5482 else
5483 {
5484 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
5485 {
5486 const auto wc2 = static_cast<unsigned int>(input.get_character());
5487 const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
5488 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
5489 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
5490 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
5491 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
5492 utf8_bytes_filled = 4;
5493 }
5494 else
5495 {
5496 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5497 utf8_bytes_filled = 1;
5498 }
5499 }
5500 }
5501 }
5502 };
5503
5504 // Wraps another input apdater to convert wide character types into individual bytes.
5505 template<typename BaseInputAdapter, typename WideCharType>
5506 class wide_string_input_adapter
5507 {
5508 public:
5509 using char_type = char;
5510
5511 wide_string_input_adapter(BaseInputAdapter base)
5512 : base_adapter(base) {}
5513
5514 typename std::char_traits<char>::int_type get_character() noexcept
5515 {
5516 // check if buffer needs to be filled
5517 if (utf8_bytes_index == utf8_bytes_filled)
5518 {
5519 fill_buffer<sizeof(WideCharType)>();
5520
5521 JSON_ASSERT(utf8_bytes_filled > 0);
5522 JSON_ASSERT(utf8_bytes_index == 0);
5523 }
5524
5525 // use buffer
5526 JSON_ASSERT(utf8_bytes_filled > 0);
5527 JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
5528 return utf8_bytes[utf8_bytes_index++];
5529 }
5530
5531 private:
5532 BaseInputAdapter base_adapter;
5533
5534 template<size_t T>
5535 void fill_buffer()
5536 {
5537 wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
5538 }
5539
5541 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5542
5544 std::size_t utf8_bytes_index = 0;
5546 std::size_t utf8_bytes_filled = 0;
5547 };
5548
5549
5550 template<typename IteratorType, typename Enable = void>
5551 struct iterator_input_adapter_factory
5552 {
5553 using iterator_type = IteratorType;
5554 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5555 using adapter_type = iterator_input_adapter<iterator_type>;
5556
5557 static adapter_type create(IteratorType first, IteratorType last)
5558 {
5559 return adapter_type(std::move(first), std::move(last));
5560 }
5561 };
5562
5563 template<typename T>
5564 struct is_iterator_of_multibyte
5565 {
5566 using value_type = typename std::iterator_traits<T>::value_type;
5567 enum
5568 {
5569 value = sizeof(value_type) > 1
5570 };
5571 };
5572
5573 template<typename IteratorType>
5574 struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
5575 {
5576 using iterator_type = IteratorType;
5577 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5578 using base_adapter_type = iterator_input_adapter<iterator_type>;
5579 using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
5580
5581 static adapter_type create(IteratorType first, IteratorType last)
5582 {
5583 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5584 }
5585 };
5586
5587 // General purpose iterator-based input
5588 template<typename IteratorType>
5589 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
5590 {
5591 using factory_type = iterator_input_adapter_factory<IteratorType>;
5592 return factory_type::create(first, last);
5593 }
5594
5595 // Convenience shorthand from container to iterator
5596 // Enables ADL on begin(container) and end(container)
5597 // Encloses the using declarations in namespace for not to leak them to outside scope
5598
5599 namespace container_input_adapter_factory_impl
5600 {
5601
5602 using std::begin;
5603 using std::end;
5604
5605 template<typename ContainerType, typename Enable = void>
5606 struct container_input_adapter_factory {};
5607
5608 template<typename ContainerType>
5609 struct container_input_adapter_factory< ContainerType,
5610 void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
5611 {
5612 using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
5613
5614 static adapter_type create(const ContainerType& container)
5615 {
5616 return input_adapter(begin(container), end(container));
5617 }
5618 };
5619
5620 } // namespace container_input_adapter_factory_impl
5621
5622 template<typename ContainerType>
5623 typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)
5624 {
5625 return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);
5626 }
5627
5628 // Special cases with fast paths
5629 inline file_input_adapter input_adapter(std::FILE* file)
5630 {
5631 return file_input_adapter(file);
5632 }
5633
5634 inline input_stream_adapter input_adapter(std::istream& stream)
5635 {
5636 return input_stream_adapter(stream);
5637 }
5638
5639 inline input_stream_adapter input_adapter(std::istream&& stream)
5640 {
5641 return input_stream_adapter(stream);
5642 }
5643
5644 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5645
5646 // Null-delimited strings, and the like.
5647 template < typename CharT,
5648 typename std::enable_if <
5649 std::is_pointer<CharT>::value&&
5650 !std::is_array<CharT>::value&&
5651 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5652 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5653 int >::type = 0 >
5654 contiguous_bytes_input_adapter input_adapter(CharT b)
5655 {
5656 auto length = std::strlen(reinterpret_cast<const char*>(b));
5657 const auto* ptr = reinterpret_cast<const char*>(b);
5658 return input_adapter(ptr, ptr + length);
5659 }
5660
5661 template<typename T, std::size_t N>
5662 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)
5663 {
5664 return input_adapter(array, array + N);
5665 }
5666
5667 // This class only handles inputs of input_buffer_adapter type.
5668 // It's required so that expressions like {ptr, len} can be implicitely casted
5669 // to the correct adapter.
5670 class span_input_adapter
5671 {
5672 public:
5673 template < typename CharT,
5674 typename std::enable_if <
5675 std::is_pointer<CharT>::value&&
5676 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5677 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5678 int >::type = 0 >
5679 span_input_adapter(CharT b, std::size_t l)
5680 : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5681
5682 template<class IteratorType,
5683 typename std::enable_if<
5684 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5685 int>::type = 0>
5686 span_input_adapter(IteratorType first, IteratorType last)
5687 : ia(input_adapter(first, last)) {}
5688
5689 contiguous_bytes_input_adapter&& get()
5690 {
5691 return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
5692 }
5693
5694 private:
5695 contiguous_bytes_input_adapter ia;
5696 };
5697 } // namespace detail
5698 } // namespace nlohmann
5699
5700 // #include <nlohmann/detail/input/json_sax.hpp>
5701
5702
5703 #include <cstddef>
5704 #include <string> // string
5705 #include <utility> // move
5706 #include <vector> // vector
5707
5708 // #include <nlohmann/detail/exceptions.hpp>
5709
5710 // #include <nlohmann/detail/macro_scope.hpp>
5711
5712
5713 namespace nlohmann
5714 {
5715
5724 template<typename BasicJsonType>
5725 struct json_sax
5726 {
5727 using number_integer_t = typename BasicJsonType::number_integer_t;
5728 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5729 using number_float_t = typename BasicJsonType::number_float_t;
5730 using string_t = typename BasicJsonType::string_t;
5731 using binary_t = typename BasicJsonType::binary_t;
5732
5737 virtual bool null() = 0;
5738
5744 virtual bool boolean(bool val) = 0;
5745
5751 virtual bool number_integer(number_integer_t val) = 0;
5752
5758 virtual bool number_unsigned(number_unsigned_t val) = 0;
5759
5766 virtual bool number_float(number_float_t val, const string_t& s) = 0;
5767
5774 virtual bool string(string_t& val) = 0;
5775
5782 virtual bool binary(binary_t& val) = 0;
5783
5790 virtual bool start_object(std::size_t elements) = 0;
5791
5798 virtual bool key(string_t& val) = 0;
5799
5804 virtual bool end_object() = 0;
5805
5812 virtual bool start_array(std::size_t elements) = 0;
5813
5818 virtual bool end_array() = 0;
5819
5827 virtual bool parse_error(std::size_t position,
5828 const std::string& last_token,
5829 const detail::exception& ex) = 0;
5830
5831 json_sax() = default;
5832 json_sax(const json_sax&) = default;
5833 json_sax(json_sax&&) noexcept = default;
5834 json_sax& operator=(const json_sax&) = default;
5835 json_sax& operator=(json_sax&&) noexcept = default;
5836 virtual ~json_sax() = default;
5837 };
5838
5839
5840 namespace detail
5841 {
5855 template<typename BasicJsonType>
5856 class json_sax_dom_parser
5857 {
5858 public:
5859 using number_integer_t = typename BasicJsonType::number_integer_t;
5860 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5861 using number_float_t = typename BasicJsonType::number_float_t;
5862 using string_t = typename BasicJsonType::string_t;
5863 using binary_t = typename BasicJsonType::binary_t;
5864
5870 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
5871 : root(r), allow_exceptions(allow_exceptions_)
5872 {}
5873
5874 // make class move-only
5875 json_sax_dom_parser(const json_sax_dom_parser&) = delete;
5876 json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
5877 json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
5878 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
5879 ~json_sax_dom_parser() = default;
5880
5881 bool null()
5882 {
5883 handle_value(nullptr);
5884 return true;
5885 }
5886
5887 bool boolean(bool val)
5888 {
5889 handle_value(val);
5890 return true;
5891 }
5892
5893 bool number_integer(number_integer_t val)
5894 {
5895 handle_value(val);
5896 return true;
5897 }
5898
5899 bool number_unsigned(number_unsigned_t val)
5900 {
5901 handle_value(val);
5902 return true;
5903 }
5904
5905 bool number_float(number_float_t val, const string_t& /*unused*/)
5906 {
5907 handle_value(val);
5908 return true;
5909 }
5910
5911 bool string(string_t& val)
5912 {
5913 handle_value(val);
5914 return true;
5915 }
5916
5917 bool binary(binary_t& val)
5918 {
5919 handle_value(std::move(val));
5920 return true;
5921 }
5922
5923 bool start_object(std::size_t len)
5924 {
5925 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
5926
5927 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5928 {
5929 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
5930 }
5931
5932 return true;
5933 }
5934
5935 bool key(string_t& val)
5936 {
5937 // add null at given key and store the reference for later
5938 object_element = &(ref_stack.back()->m_value.object->operator[](val));
5939 return true;
5940 }
5941
5942 bool end_object()
5943 {
5944 ref_stack.back()->set_parents();
5945 ref_stack.pop_back();
5946 return true;
5947 }
5948
5949 bool start_array(std::size_t len)
5950 {
5951 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
5952
5953 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5954 {
5955 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
5956 }
5957
5958 return true;
5959 }
5960
5961 bool end_array()
5962 {
5963 ref_stack.back()->set_parents();
5964 ref_stack.pop_back();
5965 return true;
5966 }
5967
5968 template<class Exception>
5969 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5970 const Exception& ex)
5971 {
5972 errored = true;
5973 static_cast<void>(ex);
5974 if (allow_exceptions)
5975 {
5976 JSON_THROW(ex);
5977 }
5978 return false;
5979 }
5980
5981 constexpr bool is_errored() const
5982 {
5983 return errored;
5984 }
5985
5986 private:
5993 template<typename Value>
5994
5995 BasicJsonType* handle_value(Value&& v)
5996 {
5997 if (ref_stack.empty())
5998 {
5999 root = BasicJsonType(std::forward<Value>(v));
6000 return &root;
6001 }
6002
6003 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6004
6005 if (ref_stack.back()->is_array())
6006 {
6007 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6008 return &(ref_stack.back()->m_value.array->back());
6009 }
6010
6011 JSON_ASSERT(ref_stack.back()->is_object());
6012 JSON_ASSERT(object_element);
6013 *object_element = BasicJsonType(std::forward<Value>(v));
6014 return object_element;
6015 }
6016
6018 BasicJsonType& root;
6020 std::vector<BasicJsonType*> ref_stack {};
6022 BasicJsonType* object_element = nullptr;
6024 bool errored = false;
6026 const bool allow_exceptions = true;
6027 };
6028
6029 template<typename BasicJsonType>
6030 class json_sax_dom_callback_parser
6031 {
6032 public:
6033 using number_integer_t = typename BasicJsonType::number_integer_t;
6034 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6035 using number_float_t = typename BasicJsonType::number_float_t;
6036 using string_t = typename BasicJsonType::string_t;
6037 using binary_t = typename BasicJsonType::binary_t;
6038 using parser_callback_t = typename BasicJsonType::parser_callback_t;
6039 using parse_event_t = typename BasicJsonType::parse_event_t;
6040
6041 json_sax_dom_callback_parser(BasicJsonType& r,
6042 const parser_callback_t cb,
6043 const bool allow_exceptions_ = true)
6044 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6045 {
6046 keep_stack.push_back(true);
6047 }
6048
6049 // make class move-only
6050 json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
6051 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6052 json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
6053 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6054 ~json_sax_dom_callback_parser() = default;
6055
6056 bool null()
6057 {
6058 handle_value(nullptr);
6059 return true;
6060 }
6061
6062 bool boolean(bool val)
6063 {
6064 handle_value(val);
6065 return true;
6066 }
6067
6068 bool number_integer(number_integer_t val)
6069 {
6070 handle_value(val);
6071 return true;
6072 }
6073
6074 bool number_unsigned(number_unsigned_t val)
6075 {
6076 handle_value(val);
6077 return true;
6078 }
6079
6080 bool number_float(number_float_t val, const string_t& /*unused*/)
6081 {
6082 handle_value(val);
6083 return true;
6084 }
6085
6086 bool string(string_t& val)
6087 {
6088 handle_value(val);
6089 return true;
6090 }
6091
6092 bool binary(binary_t& val)
6093 {
6094 handle_value(std::move(val));
6095 return true;
6096 }
6097
6098 bool start_object(std::size_t len)
6099 {
6100 // check callback for object start
6101 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6102 keep_stack.push_back(keep);
6103
6104 auto val = handle_value(BasicJsonType::value_t::object, true);
6105 ref_stack.push_back(val.second);
6106
6107 // check object limit
6108 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6109 {
6110 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6111 }
6112
6113 return true;
6114 }
6115
6116 bool key(string_t& val)
6117 {
6118 BasicJsonType k = BasicJsonType(val);
6119
6120 // check callback for key
6121 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
6122 key_keep_stack.push_back(keep);
6123
6124 // add discarded value at given key and store the reference for later
6125 if (keep && ref_stack.back())
6126 {
6127 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
6128 }
6129
6130 return true;
6131 }
6132
6133 bool end_object()
6134 {
6135 if (ref_stack.back())
6136 {
6137 if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
6138 {
6139 // discard object
6140 *ref_stack.back() = discarded;
6141 }
6142 else
6143 {
6144 ref_stack.back()->set_parents();
6145 }
6146 }
6147
6148 JSON_ASSERT(!ref_stack.empty());
6149 JSON_ASSERT(!keep_stack.empty());
6150 ref_stack.pop_back();
6151 keep_stack.pop_back();
6152
6153 if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
6154 {
6155 // remove discarded value
6156 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
6157 {
6158 if (it->is_discarded())
6159 {
6160 ref_stack.back()->erase(it);
6161 break;
6162 }
6163 }
6164 }
6165
6166 return true;
6167 }
6168
6169 bool start_array(std::size_t len)
6170 {
6171 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
6172 keep_stack.push_back(keep);
6173
6174 auto val = handle_value(BasicJsonType::value_t::array, true);
6175 ref_stack.push_back(val.second);
6176
6177 // check array limit
6178 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6179 {
6180 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6181 }
6182
6183 return true;
6184 }
6185
6186 bool end_array()
6187 {
6188 bool keep = true;
6189
6190 if (ref_stack.back())
6191 {
6192 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
6193 if (keep)
6194 {
6195 ref_stack.back()->set_parents();
6196 }
6197 else
6198 {
6199 // discard array
6200 *ref_stack.back() = discarded;
6201 }
6202 }
6203
6204 JSON_ASSERT(!ref_stack.empty());
6205 JSON_ASSERT(!keep_stack.empty());
6206 ref_stack.pop_back();
6207 keep_stack.pop_back();
6208
6209 // remove discarded value
6210 if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
6211 {
6212 ref_stack.back()->m_value.array->pop_back();
6213 }
6214
6215 return true;
6216 }
6217
6218 template<class Exception>
6219 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6220 const Exception& ex)
6221 {
6222 errored = true;
6223 static_cast<void>(ex);
6224 if (allow_exceptions)
6225 {
6226 JSON_THROW(ex);
6227 }
6228 return false;
6229 }
6230
6231 constexpr bool is_errored() const
6232 {
6233 return errored;
6234 }
6235
6236 private:
6252 template<typename Value>
6253 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
6254 {
6255 JSON_ASSERT(!keep_stack.empty());
6256
6257 // do not handle this value if we know it would be added to a discarded
6258 // container
6259 if (!keep_stack.back())
6260 {
6261 return {false, nullptr};
6262 }
6263
6264 // create value
6265 auto value = BasicJsonType(std::forward<Value>(v));
6266
6267 // check callback
6268 const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
6269
6270 // do not handle this value if we just learnt it shall be discarded
6271 if (!keep)
6272 {
6273 return {false, nullptr};
6274 }
6275
6276 if (ref_stack.empty())
6277 {
6278 root = std::move(value);
6279 return {true, &root};
6280 }
6281
6282 // skip this value if we already decided to skip the parent
6283 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
6284 if (!ref_stack.back())
6285 {
6286 return {false, nullptr};
6287 }
6288
6289 // we now only expect arrays and objects
6290 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6291
6292 // array
6293 if (ref_stack.back()->is_array())
6294 {
6295 ref_stack.back()->m_value.array->emplace_back(std::move(value));
6296 return {true, &(ref_stack.back()->m_value.array->back())};
6297 }
6298
6299 // object
6300 JSON_ASSERT(ref_stack.back()->is_object());
6301 // check if we should store an element for the current key
6302 JSON_ASSERT(!key_keep_stack.empty());
6303 const bool store_element = key_keep_stack.back();
6304 key_keep_stack.pop_back();
6305
6306 if (!store_element)
6307 {
6308 return {false, nullptr};
6309 }
6310
6311 JSON_ASSERT(object_element);
6312 *object_element = std::move(value);
6313 return {true, object_element};
6314 }
6315
6317 BasicJsonType& root;
6319 std::vector<BasicJsonType*> ref_stack {};
6321 std::vector<bool> keep_stack {};
6323 std::vector<bool> key_keep_stack {};
6325 BasicJsonType* object_element = nullptr;
6327 bool errored = false;
6329 const parser_callback_t callback = nullptr;
6331 const bool allow_exceptions = true;
6333 BasicJsonType discarded = BasicJsonType::value_t::discarded;
6334 };
6335
6336 template<typename BasicJsonType>
6337 class json_sax_acceptor
6338 {
6339 public:
6340 using number_integer_t = typename BasicJsonType::number_integer_t;
6341 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6342 using number_float_t = typename BasicJsonType::number_float_t;
6343 using string_t = typename BasicJsonType::string_t;
6344 using binary_t = typename BasicJsonType::binary_t;
6345
6346 bool null()
6347 {
6348 return true;
6349 }
6350
6351 bool boolean(bool /*unused*/)
6352 {
6353 return true;
6354 }
6355
6356 bool number_integer(number_integer_t /*unused*/)
6357 {
6358 return true;
6359 }
6360
6361 bool number_unsigned(number_unsigned_t /*unused*/)
6362 {
6363 return true;
6364 }
6365
6366 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
6367 {
6368 return true;
6369 }
6370
6371 bool string(string_t& /*unused*/)
6372 {
6373 return true;
6374 }
6375
6376 bool binary(binary_t& /*unused*/)
6377 {
6378 return true;
6379 }
6380
6381 bool start_object(std::size_t /*unused*/ = std::size_t(-1))
6382 {
6383 return true;
6384 }
6385
6386 bool key(string_t& /*unused*/)
6387 {
6388 return true;
6389 }
6390
6391 bool end_object()
6392 {
6393 return true;
6394 }
6395
6396 bool start_array(std::size_t /*unused*/ = std::size_t(-1))
6397 {
6398 return true;
6399 }
6400
6401 bool end_array()
6402 {
6403 return true;
6404 }
6405
6406 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
6407 {
6408 return false;
6409 }
6410 };
6411 } // namespace detail
6412
6413 } // namespace nlohmann
6414
6415 // #include <nlohmann/detail/input/lexer.hpp>
6416
6417
6418 #include <array> // array
6419 #include <clocale> // localeconv
6420 #include <cstddef> // size_t
6421 #include <cstdio> // snprintf
6422 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
6423 #include <initializer_list> // initializer_list
6424 #include <string> // char_traits, string
6425 #include <utility> // move
6426 #include <vector> // vector
6427
6428 // #include <nlohmann/detail/input/input_adapters.hpp>
6429
6430 // #include <nlohmann/detail/input/position_t.hpp>
6431
6432 // #include <nlohmann/detail/macro_scope.hpp>
6433
6434
6435 namespace nlohmann
6436 {
6437 namespace detail
6438 {
6440 // lexer //
6442
6443 template<typename BasicJsonType>
6444 class lexer_base
6445 {
6446 public:
6448 enum class token_type
6449 {
6450 uninitialized,
6451 literal_true,
6452 literal_false,
6453 literal_null,
6454 value_string,
6455 value_unsigned,
6456 value_integer,
6457 value_float,
6458 begin_array,
6459 begin_object,
6460 end_array,
6461 end_object,
6462 name_separator,
6463 value_separator,
6464 parse_error,
6465 end_of_input,
6466 literal_or_value
6467 };
6468
6470
6471 JSON_HEDLEY_CONST
6472 static const char* token_type_name(const token_type t) noexcept
6473 {
6474 switch (t)
6475 {
6476 case token_type::uninitialized:
6477 return "<uninitialized>";
6478 case token_type::literal_true:
6479 return "true literal";
6480 case token_type::literal_false:
6481 return "false literal";
6482 case token_type::literal_null:
6483 return "null literal";
6484 case token_type::value_string:
6485 return "string literal";
6486 case token_type::value_unsigned:
6487 case token_type::value_integer:
6488 case token_type::value_float:
6489 return "number literal";
6490 case token_type::begin_array:
6491 return "'['";
6492 case token_type::begin_object:
6493 return "'{'";
6494 case token_type::end_array:
6495 return "']'";
6496 case token_type::end_object:
6497 return "'}'";
6498 case token_type::name_separator:
6499 return "':'";
6500 case token_type::value_separator:
6501 return "','";
6502 case token_type::parse_error:
6503 return "<parse error>";
6504 case token_type::end_of_input:
6505 return "end of input";
6506 case token_type::literal_or_value:
6507 return "'[', '{', or a literal";
6508 // LCOV_EXCL_START
6509 default: // catch non-enum values
6510 return "unknown token";
6511 // LCOV_EXCL_STOP
6512 }
6513 }
6514 };
6520 template<typename BasicJsonType, typename InputAdapterType>
6521 class lexer : public lexer_base<BasicJsonType>
6522 {
6523 using number_integer_t = typename BasicJsonType::number_integer_t;
6524 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6525 using number_float_t = typename BasicJsonType::number_float_t;
6526 using string_t = typename BasicJsonType::string_t;
6527 using char_type = typename InputAdapterType::char_type;
6528 using char_int_type = typename std::char_traits<char_type>::int_type;
6529
6530 public:
6531 using token_type = typename lexer_base<BasicJsonType>::token_type;
6532
6533 explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
6534 : ia(std::move(adapter))
6535 , ignore_comments(ignore_comments_)
6536 , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
6537 {}
6538
6539 // delete because of pointer members
6540 lexer(const lexer&) = delete;
6541 lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6542 lexer& operator=(lexer&) = delete;
6543 lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6544 ~lexer() = default;
6545
6546 private:
6548 // locales
6550
6552 JSON_HEDLEY_PURE
6553 static char get_decimal_point() noexcept
6554 {
6555 const auto* loc = localeconv();
6556 JSON_ASSERT(loc != nullptr);
6557 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6558 }
6559
6561 // scan functions
6563
6579 int get_codepoint()
6580 {
6581 // this function only makes sense after reading `\u`
6582 JSON_ASSERT(current == 'u');
6583 int codepoint = 0;
6584
6585 const auto factors = { 12u, 8u, 4u, 0u };
6586 for (const auto factor : factors)
6587 {
6588 get();
6589
6590 if (current >= '0' && current <= '9')
6591 {
6592 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6593 }
6594 else if (current >= 'A' && current <= 'F')
6595 {
6596 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6597 }
6598 else if (current >= 'a' && current <= 'f')
6599 {
6600 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6601 }
6602 else
6603 {
6604 return -1;
6605 }
6606 }
6607
6608 JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6609 return codepoint;
6610 }
6611
6627 bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6628 {
6629 JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6630 add(current);
6631
6632 for (auto range = ranges.begin(); range != ranges.end(); ++range)
6633 {
6634 get();
6635 if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6636 {
6637 add(current);
6638 }
6639 else
6640 {
6641 error_message = "invalid string: ill-formed UTF-8 byte";
6642 return false;
6643 }
6644 }
6645
6646 return true;
6647 }
6648
6664 token_type scan_string()
6665 {
6666 // reset token_buffer (ignore opening quote)
6667 reset();
6668
6669 // we entered the function by reading an open quote
6670 JSON_ASSERT(current == '\"');
6671
6672 while (true)
6673 {
6674 // get next character
6675 switch (get())
6676 {
6677 // end of file while parsing string
6678 case std::char_traits<char_type>::eof():
6679 {
6680 error_message = "invalid string: missing closing quote";
6681 return token_type::parse_error;
6682 }
6683
6684 // closing quote
6685 case '\"':
6686 {
6687 return token_type::value_string;
6688 }
6689
6690 // escapes
6691 case '\\':
6692 {
6693 switch (get())
6694 {
6695 // quotation mark
6696 case '\"':
6697 add('\"');
6698 break;
6699 // reverse solidus
6700 case '\\':
6701 add('\\');
6702 break;
6703 // solidus
6704 case '/':
6705 add('/');
6706 break;
6707 // backspace
6708 case 'b':
6709 add('\b');
6710 break;
6711 // form feed
6712 case 'f':
6713 add('\f');
6714 break;
6715 // line feed
6716 case 'n':
6717 add('\n');
6718 break;
6719 // carriage return
6720 case 'r':
6721 add('\r');
6722 break;
6723 // tab
6724 case 't':
6725 add('\t');
6726 break;
6727
6728 // unicode escapes
6729 case 'u':
6730 {
6731 const int codepoint1 = get_codepoint();
6732 int codepoint = codepoint1; // start with codepoint1
6733
6734 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
6735 {
6736 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6737 return token_type::parse_error;
6738 }
6739
6740 // check if code point is a high surrogate
6741 if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6742 {
6743 // expect next \uxxxx entry
6744 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6745 {
6746 const int codepoint2 = get_codepoint();
6747
6748 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
6749 {
6750 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6751 return token_type::parse_error;
6752 }
6753
6754 // check if codepoint2 is a low surrogate
6755 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6756 {
6757 // overwrite codepoint
6758 codepoint = static_cast<int>(
6759 // high surrogate occupies the most significant 22 bits
6760 (static_cast<unsigned int>(codepoint1) << 10u)
6761 // low surrogate occupies the least significant 15 bits
6762 + static_cast<unsigned int>(codepoint2)
6763 // there is still the 0xD800, 0xDC00 and 0x10000 noise
6764 // in the result so we have to subtract with:
6765 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6766 - 0x35FDC00u);
6767 }
6768 else
6769 {
6770 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6771 return token_type::parse_error;
6772 }
6773 }
6774 else
6775 {
6776 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6777 return token_type::parse_error;
6778 }
6779 }
6780 else
6781 {
6782 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6783 {
6784 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6785 return token_type::parse_error;
6786 }
6787 }
6788
6789 // result of the above calculation yields a proper codepoint
6790 JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
6791
6792 // translate codepoint into bytes
6793 if (codepoint < 0x80)
6794 {
6795 // 1-byte characters: 0xxxxxxx (ASCII)
6796 add(static_cast<char_int_type>(codepoint));
6797 }
6798 else if (codepoint <= 0x7FF)
6799 {
6800 // 2-byte characters: 110xxxxx 10xxxxxx
6801 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
6802 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6803 }
6804 else if (codepoint <= 0xFFFF)
6805 {
6806 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
6807 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
6808 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6809 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6810 }
6811 else
6812 {
6813 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
6814 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
6815 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
6816 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6817 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6818 }
6819
6820 break;
6821 }
6822
6823 // other characters after escape
6824 default:
6825 error_message = "invalid string: forbidden character after backslash";
6826 return token_type::parse_error;
6827 }
6828
6829 break;
6830 }
6831
6832 // invalid control characters
6833 case 0x00:
6834 {
6835 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
6836 return token_type::parse_error;
6837 }
6838
6839 case 0x01:
6840 {
6841 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
6842 return token_type::parse_error;
6843 }
6844
6845 case 0x02:
6846 {
6847 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
6848 return token_type::parse_error;
6849 }
6850
6851 case 0x03:
6852 {
6853 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
6854 return token_type::parse_error;
6855 }
6856
6857 case 0x04:
6858 {
6859 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
6860 return token_type::parse_error;
6861 }
6862
6863 case 0x05:
6864 {
6865 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
6866 return token_type::parse_error;
6867 }
6868
6869 case 0x06:
6870 {
6871 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
6872 return token_type::parse_error;
6873 }
6874
6875 case 0x07:
6876 {
6877 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
6878 return token_type::parse_error;
6879 }
6880
6881 case 0x08:
6882 {
6883 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
6884 return token_type::parse_error;
6885 }
6886
6887 case 0x09:
6888 {
6889 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
6890 return token_type::parse_error;
6891 }
6892
6893 case 0x0A:
6894 {
6895 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
6896 return token_type::parse_error;
6897 }
6898
6899 case 0x0B:
6900 {
6901 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
6902 return token_type::parse_error;
6903 }
6904
6905 case 0x0C:
6906 {
6907 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
6908 return token_type::parse_error;
6909 }
6910
6911 case 0x0D:
6912 {
6913 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
6914 return token_type::parse_error;
6915 }
6916
6917 case 0x0E:
6918 {
6919 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
6920 return token_type::parse_error;
6921 }
6922
6923 case 0x0F:
6924 {
6925 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
6926 return token_type::parse_error;
6927 }
6928
6929 case 0x10:
6930 {
6931 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
6932 return token_type::parse_error;
6933 }
6934
6935 case 0x11:
6936 {
6937 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
6938 return token_type::parse_error;
6939 }
6940
6941 case 0x12:
6942 {
6943 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
6944 return token_type::parse_error;
6945 }
6946
6947 case 0x13:
6948 {
6949 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
6950 return token_type::parse_error;
6951 }
6952
6953 case 0x14:
6954 {
6955 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
6956 return token_type::parse_error;
6957 }
6958
6959 case 0x15:
6960 {
6961 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
6962 return token_type::parse_error;
6963 }
6964
6965 case 0x16:
6966 {
6967 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
6968 return token_type::parse_error;
6969 }
6970
6971 case 0x17:
6972 {
6973 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
6974 return token_type::parse_error;
6975 }
6976
6977 case 0x18:
6978 {
6979 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
6980 return token_type::parse_error;
6981 }
6982
6983 case 0x19:
6984 {
6985 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
6986 return token_type::parse_error;
6987 }
6988
6989 case 0x1A:
6990 {
6991 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
6992 return token_type::parse_error;
6993 }
6994
6995 case 0x1B:
6996 {
6997 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
6998 return token_type::parse_error;
6999 }
7000
7001 case 0x1C:
7002 {
7003 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7004 return token_type::parse_error;
7005 }
7006
7007 case 0x1D:
7008 {
7009 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7010 return token_type::parse_error;
7011 }
7012
7013 case 0x1E:
7014 {
7015 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7016 return token_type::parse_error;
7017 }
7018
7019 case 0x1F:
7020 {
7021 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7022 return token_type::parse_error;
7023 }
7024
7025 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7026 case 0x20:
7027 case 0x21:
7028 case 0x23:
7029 case 0x24:
7030 case 0x25:
7031 case 0x26:
7032 case 0x27:
7033 case 0x28:
7034 case 0x29:
7035 case 0x2A:
7036 case 0x2B:
7037 case 0x2C:
7038 case 0x2D:
7039 case 0x2E:
7040 case 0x2F:
7041 case 0x30:
7042 case 0x31:
7043 case 0x32:
7044 case 0x33:
7045 case 0x34:
7046 case 0x35:
7047 case 0x36:
7048 case 0x37:
7049 case 0x38:
7050 case 0x39:
7051 case 0x3A:
7052 case 0x3B:
7053 case 0x3C:
7054 case 0x3D:
7055 case 0x3E:
7056 case 0x3F:
7057 case 0x40:
7058 case 0x41:
7059 case 0x42:
7060 case 0x43:
7061 case 0x44:
7062 case 0x45:
7063 case 0x46:
7064 case 0x47:
7065 case 0x48:
7066 case 0x49:
7067 case 0x4A:
7068 case 0x4B:
7069 case 0x4C:
7070 case 0x4D:
7071 case 0x4E:
7072 case 0x4F:
7073 case 0x50:
7074 case 0x51:
7075 case 0x52:
7076 case 0x53:
7077 case 0x54:
7078 case 0x55:
7079 case 0x56:
7080 case 0x57:
7081 case 0x58:
7082 case 0x59:
7083 case 0x5A:
7084 case 0x5B:
7085 case 0x5D:
7086 case 0x5E:
7087 case 0x5F:
7088 case 0x60:
7089 case 0x61:
7090 case 0x62:
7091 case 0x63:
7092 case 0x64:
7093 case 0x65:
7094 case 0x66:
7095 case 0x67:
7096 case 0x68:
7097 case 0x69:
7098 case 0x6A:
7099 case 0x6B:
7100 case 0x6C:
7101 case 0x6D:
7102 case 0x6E:
7103 case 0x6F:
7104 case 0x70:
7105 case 0x71:
7106 case 0x72:
7107 case 0x73:
7108 case 0x74:
7109 case 0x75:
7110 case 0x76:
7111 case 0x77:
7112 case 0x78:
7113 case 0x79:
7114 case 0x7A:
7115 case 0x7B:
7116 case 0x7C:
7117 case 0x7D:
7118 case 0x7E:
7119 case 0x7F:
7120 {
7121 add(current);
7122 break;
7123 }
7124
7125 // U+0080..U+07FF: bytes C2..DF 80..BF
7126 case 0xC2:
7127 case 0xC3:
7128 case 0xC4:
7129 case 0xC5:
7130 case 0xC6:
7131 case 0xC7:
7132 case 0xC8:
7133 case 0xC9:
7134 case 0xCA:
7135 case 0xCB:
7136 case 0xCC:
7137 case 0xCD:
7138 case 0xCE:
7139 case 0xCF:
7140 case 0xD0:
7141 case 0xD1:
7142 case 0xD2:
7143 case 0xD3:
7144 case 0xD4:
7145 case 0xD5:
7146 case 0xD6:
7147 case 0xD7:
7148 case 0xD8:
7149 case 0xD9:
7150 case 0xDA:
7151 case 0xDB:
7152 case 0xDC:
7153 case 0xDD:
7154 case 0xDE:
7155 case 0xDF:
7156 {
7157 if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
7158 {
7159 return token_type::parse_error;
7160 }
7161 break;
7162 }
7163
7164 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7165 case 0xE0:
7166 {
7167 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7168 {
7169 return token_type::parse_error;
7170 }
7171 break;
7172 }
7173
7174 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7175 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7176 case 0xE1:
7177 case 0xE2:
7178 case 0xE3:
7179 case 0xE4:
7180 case 0xE5:
7181 case 0xE6:
7182 case 0xE7:
7183 case 0xE8:
7184 case 0xE9:
7185 case 0xEA:
7186 case 0xEB:
7187 case 0xEC:
7188 case 0xEE:
7189 case 0xEF:
7190 {
7191 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
7192 {
7193 return token_type::parse_error;
7194 }
7195 break;
7196 }
7197
7198 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7199 case 0xED:
7200 {
7201 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
7202 {
7203 return token_type::parse_error;
7204 }
7205 break;
7206 }
7207
7208 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7209 case 0xF0:
7210 {
7211 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7212 {
7213 return token_type::parse_error;
7214 }
7215 break;
7216 }
7217
7218 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7219 case 0xF1:
7220 case 0xF2:
7221 case 0xF3:
7222 {
7223 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7224 {
7225 return token_type::parse_error;
7226 }
7227 break;
7228 }
7229
7230 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7231 case 0xF4:
7232 {
7233 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
7234 {
7235 return token_type::parse_error;
7236 }
7237 break;
7238 }
7239
7240 // remaining bytes (80..C1 and F5..FF) are ill-formed
7241 default:
7242 {
7243 error_message = "invalid string: ill-formed UTF-8 byte";
7244 return token_type::parse_error;
7245 }
7246 }
7247 }
7248 }
7249
7254 bool scan_comment()
7255 {
7256 switch (get())
7257 {
7258 // single-line comments skip input until a newline or EOF is read
7259 case '/':
7260 {
7261 while (true)
7262 {
7263 switch (get())
7264 {
7265 case '\n':
7266 case '\r':
7267 case std::char_traits<char_type>::eof():
7268 case '\0':
7269 return true;
7270
7271 default:
7272 break;
7273 }
7274 }
7275 }
7276
7277 // multi-line comments skip input until */ is read
7278 case '*':
7279 {
7280 while (true)
7281 {
7282 switch (get())
7283 {
7284 case std::char_traits<char_type>::eof():
7285 case '\0':
7286 {
7287 error_message = "invalid comment; missing closing '*/'";
7288 return false;
7289 }
7290
7291 case '*':
7292 {
7293 switch (get())
7294 {
7295 case '/':
7296 return true;
7297
7298 default:
7299 {
7300 unget();
7301 continue;
7302 }
7303 }
7304 }
7305
7306 default:
7307 continue;
7308 }
7309 }
7310 }
7311
7312 // unexpected character after reading '/'
7313 default:
7314 {
7315 error_message = "invalid comment; expecting '/' or '*' after '/'";
7316 return false;
7317 }
7318 }
7319 }
7320
7321 JSON_HEDLEY_NON_NULL(2)
7322 static void strtof(float& f, const char* str, char** endptr) noexcept
7323 {
7324 f = std::strtof(str, endptr);
7325 }
7326
7327 JSON_HEDLEY_NON_NULL(2)
7328 static void strtof(double& f, const char* str, char** endptr) noexcept
7329 {
7330 f = std::strtod(str, endptr);
7331 }
7332
7333 JSON_HEDLEY_NON_NULL(2)
7334 static void strtof(long double& f, const char* str, char** endptr) noexcept
7335 {
7336 f = std::strtold(str, endptr);
7337 }
7338
7379 token_type scan_number() // lgtm [cpp/use-of-goto]
7380 {
7381 // reset token_buffer to store the number's bytes
7382 reset();
7383
7384 // the type of the parsed number; initially set to unsigned; will be
7385 // changed if minus sign, decimal point or exponent is read
7386 token_type number_type = token_type::value_unsigned;
7387
7388 // state (init): we just found out we need to scan a number
7389 switch (current)
7390 {
7391 case '-':
7392 {
7393 add(current);
7394 goto scan_number_minus;
7395 }
7396
7397 case '0':
7398 {
7399 add(current);
7400 goto scan_number_zero;
7401 }
7402
7403 case '1':
7404 case '2':
7405 case '3':
7406 case '4':
7407 case '5':
7408 case '6':
7409 case '7':
7410 case '8':
7411 case '9':
7412 {
7413 add(current);
7414 goto scan_number_any1;
7415 }
7416
7417 // all other characters are rejected outside scan_number()
7418 default: // LCOV_EXCL_LINE
7419 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
7420 }
7421
7422 scan_number_minus:
7423 // state: we just parsed a leading minus sign
7424 number_type = token_type::value_integer;
7425 switch (get())
7426 {
7427 case '0':
7428 {
7429 add(current);
7430 goto scan_number_zero;
7431 }
7432
7433 case '1':
7434 case '2':
7435 case '3':
7436 case '4':
7437 case '5':
7438 case '6':
7439 case '7':
7440 case '8':
7441 case '9':
7442 {
7443 add(current);
7444 goto scan_number_any1;
7445 }
7446
7447 default:
7448 {
7449 error_message = "invalid number; expected digit after '-'";
7450 return token_type::parse_error;
7451 }
7452 }
7453
7454 scan_number_zero:
7455 // state: we just parse a zero (maybe with a leading minus sign)
7456 switch (get())
7457 {
7458 case '.':
7459 {
7460 add(decimal_point_char);
7461 goto scan_number_decimal1;
7462 }
7463
7464 case 'e':
7465 case 'E':
7466 {
7467 add(current);
7468 goto scan_number_exponent;
7469 }
7470
7471 default:
7472 goto scan_number_done;
7473 }
7474
7475 scan_number_any1:
7476 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7477 switch (get())
7478 {
7479 case '0':
7480 case '1':
7481 case '2':
7482 case '3':
7483 case '4':
7484 case '5':
7485 case '6':
7486 case '7':
7487 case '8':
7488 case '9':
7489 {
7490 add(current);
7491 goto scan_number_any1;
7492 }
7493
7494 case '.':
7495 {
7496 add(decimal_point_char);
7497 goto scan_number_decimal1;
7498 }
7499
7500 case 'e':
7501 case 'E':
7502 {
7503 add(current);
7504 goto scan_number_exponent;
7505 }
7506
7507 default:
7508 goto scan_number_done;
7509 }
7510
7511 scan_number_decimal1:
7512 // state: we just parsed a decimal point
7513 number_type = token_type::value_float;
7514 switch (get())
7515 {
7516 case '0':
7517 case '1':
7518 case '2':
7519 case '3':
7520 case '4':
7521 case '5':
7522 case '6':
7523 case '7':
7524 case '8':
7525 case '9':
7526 {
7527 add(current);
7528 goto scan_number_decimal2;
7529 }
7530
7531 default:
7532 {
7533 error_message = "invalid number; expected digit after '.'";
7534 return token_type::parse_error;
7535 }
7536 }
7537
7538 scan_number_decimal2:
7539 // we just parsed at least one number after a decimal point
7540 switch (get())
7541 {
7542 case '0':
7543 case '1':
7544 case '2':
7545 case '3':
7546 case '4':
7547 case '5':
7548 case '6':
7549 case '7':
7550 case '8':
7551 case '9':
7552 {
7553 add(current);
7554 goto scan_number_decimal2;
7555 }
7556
7557 case 'e':
7558 case 'E':
7559 {
7560 add(current);
7561 goto scan_number_exponent;
7562 }
7563
7564 default:
7565 goto scan_number_done;
7566 }
7567
7568 scan_number_exponent:
7569 // we just parsed an exponent
7570 number_type = token_type::value_float;
7571 switch (get())
7572 {
7573 case '+':
7574 case '-':
7575 {
7576 add(current);
7577 goto scan_number_sign;
7578 }
7579
7580 case '0':
7581 case '1':
7582 case '2':
7583 case '3':
7584 case '4':
7585 case '5':
7586 case '6':
7587 case '7':
7588 case '8':
7589 case '9':
7590 {
7591 add(current);
7592 goto scan_number_any2;
7593 }
7594
7595 default:
7596 {
7597 error_message =
7598 "invalid number; expected '+', '-', or digit after exponent";
7599 return token_type::parse_error;
7600 }
7601 }
7602
7603 scan_number_sign:
7604 // we just parsed an exponent sign
7605 switch (get())
7606 {
7607 case '0':
7608 case '1':
7609 case '2':
7610 case '3':
7611 case '4':
7612 case '5':
7613 case '6':
7614 case '7':
7615 case '8':
7616 case '9':
7617 {
7618 add(current);
7619 goto scan_number_any2;
7620 }
7621
7622 default:
7623 {
7624 error_message = "invalid number; expected digit after exponent sign";
7625 return token_type::parse_error;
7626 }
7627 }
7628
7629 scan_number_any2:
7630 // we just parsed a number after the exponent or exponent sign
7631 switch (get())
7632 {
7633 case '0':
7634 case '1':
7635 case '2':
7636 case '3':
7637 case '4':
7638 case '5':
7639 case '6':
7640 case '7':
7641 case '8':
7642 case '9':
7643 {
7644 add(current);
7645 goto scan_number_any2;
7646 }
7647
7648 default:
7649 goto scan_number_done;
7650 }
7651
7652 scan_number_done:
7653 // unget the character after the number (we only read it to know that
7654 // we are done scanning a number)
7655 unget();
7656
7657 char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7658 errno = 0;
7659
7660 // try to parse integers first and fall back to floats
7661 if (number_type == token_type::value_unsigned)
7662 {
7663 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7664
7665 // we checked the number format before
7666 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7667
7668 if (errno == 0)
7669 {
7670 value_unsigned = static_cast<number_unsigned_t>(x);
7671 if (value_unsigned == x)
7672 {
7673 return token_type::value_unsigned;
7674 }
7675 }
7676 }
7677 else if (number_type == token_type::value_integer)
7678 {
7679 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7680
7681 // we checked the number format before
7682 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7683
7684 if (errno == 0)
7685 {
7686 value_integer = static_cast<number_integer_t>(x);
7687 if (value_integer == x)
7688 {
7689 return token_type::value_integer;
7690 }
7691 }
7692 }
7693
7694 // this code is reached if we parse a floating-point number or if an
7695 // integer conversion above failed
7696 strtof(value_float, token_buffer.data(), &endptr);
7697
7698 // we checked the number format before
7699 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7700
7701 return token_type::value_float;
7702 }
7703
7709 JSON_HEDLEY_NON_NULL(2)
7710 token_type scan_literal(const char_type* literal_text, const std::size_t length,
7711 token_type return_type)
7712 {
7713 JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
7714 for (std::size_t i = 1; i < length; ++i)
7715 {
7716 if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
7717 {
7718 error_message = "invalid literal";
7719 return token_type::parse_error;
7720 }
7721 }
7722 return return_type;
7723 }
7724
7726 // input management
7728
7730 void reset() noexcept
7731 {
7732 token_buffer.clear();
7733 token_string.clear();
7734 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7735 }
7736
7737 /*
7738 @brief get next character from the input
7739
7740 This function provides the interface to the used input adapter. It does
7741 not throw in case the input reached EOF, but returns a
7742 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
7743 for use in error messages.
7744
7745 @return character read from the input
7746 */
7747 char_int_type get()
7748 {
7749 ++position.chars_read_total;
7750 ++position.chars_read_current_line;
7751
7752 if (next_unget)
7753 {
7754 // just reset the next_unget variable and work with current
7755 next_unget = false;
7756 }
7757 else
7758 {
7759 current = ia.get_character();
7760 }
7761
7762 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7763 {
7764 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7765 }
7766
7767 if (current == '\n')
7768 {
7769 ++position.lines_read;
7770 position.chars_read_current_line = 0;
7771 }
7772
7773 return current;
7774 }
7775
7784 void unget()
7785 {
7786 next_unget = true;
7787
7788 --position.chars_read_total;
7789
7790 // in case we "unget" a newline, we have to also decrement the lines_read
7791 if (position.chars_read_current_line == 0)
7792 {
7793 if (position.lines_read > 0)
7794 {
7795 --position.lines_read;
7796 }
7797 }
7798 else
7799 {
7800 --position.chars_read_current_line;
7801 }
7802
7803 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7804 {
7805 JSON_ASSERT(!token_string.empty());
7806 token_string.pop_back();
7807 }
7808 }
7809
7811 void add(char_int_type c)
7812 {
7813 token_buffer.push_back(static_cast<typename string_t::value_type>(c));
7814 }
7815
7816 public:
7818 // value getters
7820
7822 constexpr number_integer_t get_number_integer() const noexcept
7823 {
7824 return value_integer;
7825 }
7826
7828 constexpr number_unsigned_t get_number_unsigned() const noexcept
7829 {
7830 return value_unsigned;
7831 }
7832
7834 constexpr number_float_t get_number_float() const noexcept
7835 {
7836 return value_float;
7837 }
7838
7840 string_t& get_string()
7841 {
7842 return token_buffer;
7843 }
7844
7846 // diagnostics
7848
7850 constexpr position_t get_position() const noexcept
7851 {
7852 return position;
7853 }
7854
7858 std::string get_token_string() const
7859 {
7860 // escape control characters
7861 std::string result;
7862 for (const auto c : token_string)
7863 {
7864 if (static_cast<unsigned char>(c) <= '\x1F')
7865 {
7866 // escape control characters
7867 std::array<char, 9> cs{{}};
7868 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7869 result += cs.data();
7870 }
7871 else
7872 {
7873 // add character as is
7874 result.push_back(static_cast<std::string::value_type>(c));
7875 }
7876 }
7877
7878 return result;
7879 }
7880
7882
7883 constexpr const char* get_error_message() const noexcept
7884 {
7885 return error_message;
7886 }
7887
7889 // actual scanner
7891
7896 bool skip_bom()
7897 {
7898 if (get() == 0xEF)
7899 {
7900 // check if we completely parse the BOM
7901 return get() == 0xBB && get() == 0xBF;
7902 }
7903
7904 // the first character is not the beginning of the BOM; unget it to
7905 // process is later
7906 unget();
7907 return true;
7908 }
7909
7910 void skip_whitespace()
7911 {
7912 do
7913 {
7914 get();
7915 }
7916 while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
7917 }
7918
7919 token_type scan()
7920 {
7921 // initially, skip the BOM
7922 if (position.chars_read_total == 0 && !skip_bom())
7923 {
7924 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
7925 return token_type::parse_error;
7926 }
7927
7928 // read next character and ignore whitespace
7929 skip_whitespace();
7930
7931 // ignore comments
7932 while (ignore_comments && current == '/')
7933 {
7934 if (!scan_comment())
7935 {
7936 return token_type::parse_error;
7937 }
7938
7939 // skip following whitespace
7940 skip_whitespace();
7941 }
7942
7943 switch (current)
7944 {
7945 // structural characters
7946 case '[':
7947 return token_type::begin_array;
7948 case ']':
7949 return token_type::end_array;
7950 case '{':
7951 return token_type::begin_object;
7952 case '}':
7953 return token_type::end_object;
7954 case ':':
7955 return token_type::name_separator;
7956 case ',':
7957 return token_type::value_separator;
7958
7959 // literals
7960 case 't':
7961 {
7962 std::array<char_type, 4> true_literal = {{char_type('t'), char_type('r'), char_type('u'), char_type('e')}};
7963 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
7964 }
7965 case 'f':
7966 {
7967 std::array<char_type, 5> false_literal = {{char_type('f'), char_type('a'), char_type('l'), char_type('s'), char_type('e')}};
7968 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
7969 }
7970 case 'n':
7971 {
7972 std::array<char_type, 4> null_literal = {{char_type('n'), char_type('u'), char_type('l'), char_type('l')}};
7973 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
7974 }
7975
7976 // string
7977 case '\"':
7978 return scan_string();
7979
7980 // number
7981 case '-':
7982 case '0':
7983 case '1':
7984 case '2':
7985 case '3':
7986 case '4':
7987 case '5':
7988 case '6':
7989 case '7':
7990 case '8':
7991 case '9':
7992 return scan_number();
7993
7994 // end of input (the null byte is needed when parsing from
7995 // string literals)
7996 case '\0':
7997 case std::char_traits<char_type>::eof():
7998 return token_type::end_of_input;
7999
8000 // error
8001 default:
8002 error_message = "invalid literal";
8003 return token_type::parse_error;
8004 }
8005 }
8006
8007 private:
8009 InputAdapterType ia;
8010
8012 const bool ignore_comments = false;
8013
8015 char_int_type current = std::char_traits<char_type>::eof();
8016
8018 bool next_unget = false;
8019
8021 position_t position {};
8022
8024 std::vector<char_type> token_string {};
8025
8027 string_t token_buffer {};
8028
8030 const char* error_message = "";
8031
8032 // number values
8033 number_integer_t value_integer = 0;
8034 number_unsigned_t value_unsigned = 0;
8035 number_float_t value_float = 0;
8036
8038 const char_int_type decimal_point_char = '.';
8039 };
8040 } // namespace detail
8041 } // namespace nlohmann
8042
8043 // #include <nlohmann/detail/macro_scope.hpp>
8044
8045 // #include <nlohmann/detail/meta/is_sax.hpp>
8046
8047
8048 #include <cstdint> // size_t
8049 #include <utility> // declval
8050 #include <string> // string
8051
8052 // #include <nlohmann/detail/meta/detected.hpp>
8053
8054 // #include <nlohmann/detail/meta/type_traits.hpp>
8055
8056
8057 namespace nlohmann
8058 {
8059 namespace detail
8060 {
8061 template<typename T>
8062 using null_function_t = decltype(std::declval<T&>().null());
8063
8064 template<typename T>
8065 using boolean_function_t =
8066 decltype(std::declval<T&>().boolean(std::declval<bool>()));
8067
8068 template<typename T, typename Integer>
8069 using number_integer_function_t =
8070 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8071
8072 template<typename T, typename Unsigned>
8073 using number_unsigned_function_t =
8074 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8075
8076 template<typename T, typename Float, typename String>
8077 using number_float_function_t = decltype(std::declval<T&>().number_float(
8078 std::declval<Float>(), std::declval<const String&>()));
8079
8080 template<typename T, typename String>
8081 using string_function_t =
8082 decltype(std::declval<T&>().string(std::declval<String&>()));
8083
8084 template<typename T, typename Binary>
8085 using binary_function_t =
8086 decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8087
8088 template<typename T>
8089 using start_object_function_t =
8090 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8091
8092 template<typename T, typename String>
8093 using key_function_t =
8094 decltype(std::declval<T&>().key(std::declval<String&>()));
8095
8096 template<typename T>
8097 using end_object_function_t = decltype(std::declval<T&>().end_object());
8098
8099 template<typename T>
8100 using start_array_function_t =
8101 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
8102
8103 template<typename T>
8104 using end_array_function_t = decltype(std::declval<T&>().end_array());
8105
8106 template<typename T, typename Exception>
8107 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
8108 std::declval<std::size_t>(), std::declval<const std::string&>(),
8109 std::declval<const Exception&>()));
8110
8111 template<typename SAX, typename BasicJsonType>
8112 struct is_sax
8113 {
8114 private:
8115 static_assert(is_basic_json<BasicJsonType>::value,
8116 "BasicJsonType must be of type basic_json<...>");
8117
8118 using number_integer_t = typename BasicJsonType::number_integer_t;
8119 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8120 using number_float_t = typename BasicJsonType::number_float_t;
8121 using string_t = typename BasicJsonType::string_t;
8122 using binary_t = typename BasicJsonType::binary_t;
8123 using exception_t = typename BasicJsonType::exception;
8124
8125 public:
8126 static constexpr bool value =
8127 is_detected_exact<bool, null_function_t, SAX>::value &&
8128 is_detected_exact<bool, boolean_function_t, SAX>::value &&
8129 is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
8130 is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
8131 is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
8132 is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
8133 is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
8134 is_detected_exact<bool, start_object_function_t, SAX>::value &&
8135 is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
8136 is_detected_exact<bool, end_object_function_t, SAX>::value &&
8137 is_detected_exact<bool, start_array_function_t, SAX>::value &&
8138 is_detected_exact<bool, end_array_function_t, SAX>::value &&
8139 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
8140 };
8141
8142 template<typename SAX, typename BasicJsonType>
8143 struct is_sax_static_asserts
8144 {
8145 private:
8146 static_assert(is_basic_json<BasicJsonType>::value,
8147 "BasicJsonType must be of type basic_json<...>");
8148
8149 using number_integer_t = typename BasicJsonType::number_integer_t;
8150 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8151 using number_float_t = typename BasicJsonType::number_float_t;
8152 using string_t = typename BasicJsonType::string_t;
8153 using binary_t = typename BasicJsonType::binary_t;
8154 using exception_t = typename BasicJsonType::exception;
8155
8156 public:
8157 static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
8158 "Missing/invalid function: bool null()");
8159 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
8160 "Missing/invalid function: bool boolean(bool)");
8161 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
8162 "Missing/invalid function: bool boolean(bool)");
8163 static_assert(
8164 is_detected_exact<bool, number_integer_function_t, SAX,
8165 number_integer_t>::value,
8166 "Missing/invalid function: bool number_integer(number_integer_t)");
8167 static_assert(
8168 is_detected_exact<bool, number_unsigned_function_t, SAX,
8169 number_unsigned_t>::value,
8170 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
8171 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
8172 number_float_t, string_t>::value,
8173 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
8174 static_assert(
8175 is_detected_exact<bool, string_function_t, SAX, string_t>::value,
8176 "Missing/invalid function: bool string(string_t&)");
8177 static_assert(
8178 is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,
8179 "Missing/invalid function: bool binary(binary_t&)");
8180 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
8181 "Missing/invalid function: bool start_object(std::size_t)");
8182 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
8183 "Missing/invalid function: bool key(string_t&)");
8184 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
8185 "Missing/invalid function: bool end_object()");
8186 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
8187 "Missing/invalid function: bool start_array(std::size_t)");
8188 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
8189 "Missing/invalid function: bool end_array()");
8190 static_assert(
8191 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
8192 "Missing/invalid function: bool parse_error(std::size_t, const "
8193 "std::string&, const exception&)");
8194 };
8195 } // namespace detail
8196 } // namespace nlohmann
8197
8198 // #include <nlohmann/detail/value_t.hpp>
8199
8200
8201 namespace nlohmann
8202 {
8203 namespace detail
8204 {
8205
8207 enum class cbor_tag_handler_t
8208 {
8209 error,
8210 ignore
8211 };
8212
8220 static inline bool little_endianess(int num = 1) noexcept
8221 {
8222 return *reinterpret_cast<char*>(&num) == 1;
8223 }
8224
8225
8227 // binary reader //
8229
8233 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
8234 class binary_reader
8235 {
8236 using number_integer_t = typename BasicJsonType::number_integer_t;
8237 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8238 using number_float_t = typename BasicJsonType::number_float_t;
8239 using string_t = typename BasicJsonType::string_t;
8240 using binary_t = typename BasicJsonType::binary_t;
8241 using json_sax_t = SAX;
8242 using char_type = typename InputAdapterType::char_type;
8243 using char_int_type = typename std::char_traits<char_type>::int_type;
8244
8245 public:
8251 explicit binary_reader(InputAdapterType&& adapter) noexcept : ia(std::move(adapter))
8252 {
8253 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
8254 }
8255
8256 // make class move-only
8257 binary_reader(const binary_reader&) = delete;
8258 binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8259 binary_reader& operator=(const binary_reader&) = delete;
8260 binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8261 ~binary_reader() = default;
8262
8271 JSON_HEDLEY_NON_NULL(3)
8272 bool sax_parse(const input_format_t format,
8273 json_sax_t* sax_,
8274 const bool strict = true,
8275 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
8276 {
8277 sax = sax_;
8278 bool result = false;
8279
8280 switch (format)
8281 {
8282 case input_format_t::bson:
8283 result = parse_bson_internal();
8284 break;
8285
8286 case input_format_t::cbor:
8287 result = parse_cbor_internal(true, tag_handler);
8288 break;
8289
8290 case input_format_t::msgpack:
8291 result = parse_msgpack_internal();
8292 break;
8293
8294 case input_format_t::ubjson:
8295 result = parse_ubjson_internal();
8296 break;
8297
8298 default: // LCOV_EXCL_LINE
8299 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8300 }
8301
8302 // strict mode: next byte must be EOF
8303 if (result && strict)
8304 {
8305 if (format == input_format_t::ubjson)
8306 {
8307 get_ignore_noop();
8308 }
8309 else
8310 {
8311 get();
8312 }
8313
8314 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
8315 {
8316 return sax->parse_error(chars_read, get_token_string(),
8317 parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value"), BasicJsonType()));
8318 }
8319 }
8320
8321 return result;
8322 }
8323
8324 private:
8326 // BSON //
8328
8333 bool parse_bson_internal()
8334 {
8335 std::int32_t document_size{};
8336 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8337
8338 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
8339 {
8340 return false;
8341 }
8342
8343 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
8344 {
8345 return false;
8346 }
8347
8348 return sax->end_object();
8349 }
8350
8358 bool get_bson_cstr(string_t& result)
8359 {
8360 auto out = std::back_inserter(result);
8361 while (true)
8362 {
8363 get();
8364 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
8365 {
8366 return false;
8367 }
8368 if (current == 0x00)
8369 {
8370 return true;
8371 }
8372 *out++ = static_cast<typename string_t::value_type>(current);
8373 }
8374 }
8375
8387 template<typename NumberType>
8388 bool get_bson_string(const NumberType len, string_t& result)
8389 {
8390 if (JSON_HEDLEY_UNLIKELY(len < 1))
8391 {
8392 auto last_token = get_token_string();
8393 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string"), BasicJsonType()));
8394 }
8395
8396 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
8397 }
8398
8408 template<typename NumberType>
8409 bool get_bson_binary(const NumberType len, binary_t& result)
8410 {
8411 if (JSON_HEDLEY_UNLIKELY(len < 0))
8412 {
8413 auto last_token = get_token_string();
8414 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary"), BasicJsonType()));
8415 }
8416
8417 // All BSON binary values have a subtype
8418 std::uint8_t subtype{};
8419 get_number<std::uint8_t>(input_format_t::bson, subtype);
8420 result.set_subtype(subtype);
8421
8422 return get_binary(input_format_t::bson, len, result);
8423 }
8424
8435 bool parse_bson_element_internal(const char_int_type element_type,
8436 const std::size_t element_type_parse_position)
8437 {
8438 switch (element_type)
8439 {
8440 case 0x01: // double
8441 {
8442 double number{};
8443 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
8444 }
8445
8446 case 0x02: // string
8447 {
8448 std::int32_t len{};
8449 string_t value;
8450 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
8451 }
8452
8453 case 0x03: // object
8454 {
8455 return parse_bson_internal();
8456 }
8457
8458 case 0x04: // array
8459 {
8460 return parse_bson_array();
8461 }
8462
8463 case 0x05: // binary
8464 {
8465 std::int32_t len{};
8466 binary_t value;
8467 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
8468 }
8469
8470 case 0x08: // boolean
8471 {
8472 return sax->boolean(get() != 0);
8473 }
8474
8475 case 0x0A: // null
8476 {
8477 return sax->null();
8478 }
8479
8480 case 0x10: // int32
8481 {
8482 std::int32_t value{};
8483 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8484 }
8485
8486 case 0x12: // int64
8487 {
8488 std::int64_t value{};
8489 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8490 }
8491
8492 default: // anything else not supported (yet)
8493 {
8494 std::array<char, 3> cr{{}};
8495 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8496 return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data()), BasicJsonType()));
8497 }
8498 }
8499 }
8500
8513 bool parse_bson_element_list(const bool is_array)
8514 {
8515 string_t key;
8516
8517 while (auto element_type = get())
8518 {
8519 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
8520 {
8521 return false;
8522 }
8523
8524 const std::size_t element_type_parse_position = chars_read;
8525 if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
8526 {
8527 return false;
8528 }
8529
8530 if (!is_array && !sax->key(key))
8531 {
8532 return false;
8533 }
8534
8535 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
8536 {
8537 return false;
8538 }
8539
8540 // get_bson_cstr only appends
8541 key.clear();
8542 }
8543
8544 return true;
8545 }
8546
8551 bool parse_bson_array()
8552 {
8553 std::int32_t document_size{};
8554 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8555
8556 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
8557 {
8558 return false;
8559 }
8560
8561 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8562 {
8563 return false;
8564 }
8565
8566 return sax->end_array();
8567 }
8568
8570 // CBOR //
8572
8581 bool parse_cbor_internal(const bool get_char,
8582 const cbor_tag_handler_t tag_handler)
8583 {
8584 switch (get_char ? get() : current)
8585 {
8586 // EOF
8587 case std::char_traits<char_type>::eof():
8588 return unexpect_eof(input_format_t::cbor, "value");
8589
8590 // Integer 0x00..0x17 (0..23)
8591 case 0x00:
8592 case 0x01:
8593 case 0x02:
8594 case 0x03:
8595 case 0x04:
8596 case 0x05:
8597 case 0x06:
8598 case 0x07:
8599 case 0x08:
8600 case 0x09:
8601 case 0x0A:
8602 case 0x0B:
8603 case 0x0C:
8604 case 0x0D:
8605 case 0x0E:
8606 case 0x0F:
8607 case 0x10:
8608 case 0x11:
8609 case 0x12:
8610 case 0x13:
8611 case 0x14:
8612 case 0x15:
8613 case 0x16:
8614 case 0x17:
8615 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8616
8617 case 0x18: // Unsigned integer (one-byte uint8_t follows)
8618 {
8619 std::uint8_t number{};
8620 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8621 }
8622
8623 case 0x19: // Unsigned integer (two-byte uint16_t follows)
8624 {
8625 std::uint16_t number{};
8626 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8627 }
8628
8629 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8630 {
8631 std::uint32_t number{};
8632 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8633 }
8634
8635 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8636 {
8637 std::uint64_t number{};
8638 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8639 }
8640
8641 // Negative integer -1-0x00..-1-0x17 (-1..-24)
8642 case 0x20:
8643 case 0x21:
8644 case 0x22:
8645 case 0x23:
8646 case 0x24:
8647 case 0x25:
8648 case 0x26:
8649 case 0x27:
8650 case 0x28:
8651 case 0x29:
8652 case 0x2A:
8653 case 0x2B:
8654 case 0x2C:
8655 case 0x2D:
8656 case 0x2E:
8657 case 0x2F:
8658 case 0x30:
8659 case 0x31:
8660 case 0x32:
8661 case 0x33:
8662 case 0x34:
8663 case 0x35:
8664 case 0x36:
8665 case 0x37:
8666 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8667
8668 case 0x38: // Negative integer (one-byte uint8_t follows)
8669 {
8670 std::uint8_t number{};
8671 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8672 }
8673
8674 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8675 {
8676 std::uint16_t number{};
8677 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8678 }
8679
8680 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8681 {
8682 std::uint32_t number{};
8683 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8684 }
8685
8686 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8687 {
8688 std::uint64_t number{};
8689 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8690 - static_cast<number_integer_t>(number));
8691 }
8692
8693 // Binary data (0x00..0x17 bytes follow)
8694 case 0x40:
8695 case 0x41:
8696 case 0x42:
8697 case 0x43:
8698 case 0x44:
8699 case 0x45:
8700 case 0x46:
8701 case 0x47:
8702 case 0x48:
8703 case 0x49:
8704 case 0x4A:
8705 case 0x4B:
8706 case 0x4C:
8707 case 0x4D:
8708 case 0x4E:
8709 case 0x4F:
8710 case 0x50:
8711 case 0x51:
8712 case 0x52:
8713 case 0x53:
8714 case 0x54:
8715 case 0x55:
8716 case 0x56:
8717 case 0x57:
8718 case 0x58: // Binary data (one-byte uint8_t for n follows)
8719 case 0x59: // Binary data (two-byte uint16_t for n follow)
8720 case 0x5A: // Binary data (four-byte uint32_t for n follow)
8721 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8722 case 0x5F: // Binary data (indefinite length)
8723 {
8724 binary_t b;
8725 return get_cbor_binary(b) && sax->binary(b);
8726 }
8727
8728 // UTF-8 string (0x00..0x17 bytes follow)
8729 case 0x60:
8730 case 0x61:
8731 case 0x62:
8732 case 0x63:
8733 case 0x64:
8734 case 0x65:
8735 case 0x66:
8736 case 0x67:
8737 case 0x68:
8738 case 0x69:
8739 case 0x6A:
8740 case 0x6B:
8741 case 0x6C:
8742 case 0x6D:
8743 case 0x6E:
8744 case 0x6F:
8745 case 0x70:
8746 case 0x71:
8747 case 0x72:
8748 case 0x73:
8749 case 0x74:
8750 case 0x75:
8751 case 0x76:
8752 case 0x77:
8753 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8754 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8755 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8756 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8757 case 0x7F: // UTF-8 string (indefinite length)
8758 {
8759 string_t s;
8760 return get_cbor_string(s) && sax->string(s);
8761 }
8762
8763 // array (0x00..0x17 data items follow)
8764 case 0x80:
8765 case 0x81:
8766 case 0x82:
8767 case 0x83:
8768 case 0x84:
8769 case 0x85:
8770 case 0x86:
8771 case 0x87:
8772 case 0x88:
8773 case 0x89:
8774 case 0x8A:
8775 case 0x8B:
8776 case 0x8C:
8777 case 0x8D:
8778 case 0x8E:
8779 case 0x8F:
8780 case 0x90:
8781 case 0x91:
8782 case 0x92:
8783 case 0x93:
8784 case 0x94:
8785 case 0x95:
8786 case 0x96:
8787 case 0x97:
8788 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8789
8790 case 0x98: // array (one-byte uint8_t for n follows)
8791 {
8792 std::uint8_t len{};
8793 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8794 }
8795
8796 case 0x99: // array (two-byte uint16_t for n follow)
8797 {
8798 std::uint16_t len{};
8799 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8800 }
8801
8802 case 0x9A: // array (four-byte uint32_t for n follow)
8803 {
8804 std::uint32_t len{};
8805 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8806 }
8807
8808 case 0x9B: // array (eight-byte uint64_t for n follow)
8809 {
8810 std::uint64_t len{};
8811 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8812 }
8813
8814 case 0x9F: // array (indefinite length)
8815 return get_cbor_array(std::size_t(-1), tag_handler);
8816
8817 // map (0x00..0x17 pairs of data items follow)
8818 case 0xA0:
8819 case 0xA1:
8820 case 0xA2:
8821 case 0xA3:
8822 case 0xA4:
8823 case 0xA5:
8824 case 0xA6:
8825 case 0xA7:
8826 case 0xA8:
8827 case 0xA9:
8828 case 0xAA:
8829 case 0xAB:
8830 case 0xAC:
8831 case 0xAD:
8832 case 0xAE:
8833 case 0xAF:
8834 case 0xB0:
8835 case 0xB1:
8836 case 0xB2:
8837 case 0xB3:
8838 case 0xB4:
8839 case 0xB5:
8840 case 0xB6:
8841 case 0xB7:
8842 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8843
8844 case 0xB8: // map (one-byte uint8_t for n follows)
8845 {
8846 std::uint8_t len{};
8847 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8848 }
8849
8850 case 0xB9: // map (two-byte uint16_t for n follow)
8851 {
8852 std::uint16_t len{};
8853 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8854 }
8855
8856 case 0xBA: // map (four-byte uint32_t for n follow)
8857 {
8858 std::uint32_t len{};
8859 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8860 }
8861
8862 case 0xBB: // map (eight-byte uint64_t for n follow)
8863 {
8864 std::uint64_t len{};
8865 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8866 }
8867
8868 case 0xBF: // map (indefinite length)
8869 return get_cbor_object(std::size_t(-1), tag_handler);
8870
8871 case 0xC6: // tagged item
8872 case 0xC7:
8873 case 0xC8:
8874 case 0xC9:
8875 case 0xCA:
8876 case 0xCB:
8877 case 0xCC:
8878 case 0xCD:
8879 case 0xCE:
8880 case 0xCF:
8881 case 0xD0:
8882 case 0xD1:
8883 case 0xD2:
8884 case 0xD3:
8885 case 0xD4:
8886 case 0xD8: // tagged item (1 bytes follow)
8887 case 0xD9: // tagged item (2 bytes follow)
8888 case 0xDA: // tagged item (4 bytes follow)
8889 case 0xDB: // tagged item (8 bytes follow)
8890 {
8891 switch (tag_handler)
8892 {
8893 case cbor_tag_handler_t::error:
8894 {
8895 auto last_token = get_token_string();
8896 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
8897 }
8898
8899 case cbor_tag_handler_t::ignore:
8900 {
8901 switch (current)
8902 {
8903 case 0xD8:
8904 {
8905 std::uint8_t len{};
8906 get_number(input_format_t::cbor, len);
8907 break;
8908 }
8909 case 0xD9:
8910 {
8911 std::uint16_t len{};
8912 get_number(input_format_t::cbor, len);
8913 break;
8914 }
8915 case 0xDA:
8916 {
8917 std::uint32_t len{};
8918 get_number(input_format_t::cbor, len);
8919 break;
8920 }
8921 case 0xDB:
8922 {
8923 std::uint64_t len{};
8924 get_number(input_format_t::cbor, len);
8925 break;
8926 }
8927 default:
8928 break;
8929 }
8930 return parse_cbor_internal(true, tag_handler);
8931 }
8932
8933 default: // LCOV_EXCL_LINE
8934 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8935 return false; // LCOV_EXCL_LINE
8936 }
8937 }
8938
8939 case 0xF4: // false
8940 return sax->boolean(false);
8941
8942 case 0xF5: // true
8943 return sax->boolean(true);
8944
8945 case 0xF6: // null
8946 return sax->null();
8947
8948 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
8949 {
8950 const auto byte1_raw = get();
8951 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
8952 {
8953 return false;
8954 }
8955 const auto byte2_raw = get();
8956 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
8957 {
8958 return false;
8959 }
8960
8961 const auto byte1 = static_cast<unsigned char>(byte1_raw);
8962 const auto byte2 = static_cast<unsigned char>(byte2_raw);
8963
8964 // code from RFC 7049, Appendix D, Figure 3:
8965 // As half-precision floating-point numbers were only added
8966 // to IEEE 754 in 2008, today's programming platforms often
8967 // still only have limited support for them. It is very
8968 // easy to include at least decoding support for them even
8969 // without such support. An example of a small decoder for
8970 // half-precision floating-point numbers in the C language
8971 // is shown in Fig. 3.
8972 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
8973 const double val = [&half]
8974 {
8975 const int exp = (half >> 10u) & 0x1Fu;
8976 const unsigned int mant = half & 0x3FFu;
8977 JSON_ASSERT(0 <= exp&& exp <= 32);
8978 JSON_ASSERT(mant <= 1024);
8979 switch (exp)
8980 {
8981 case 0:
8982 return std::ldexp(mant, -24);
8983 case 31:
8984 return (mant == 0)
8985 ? std::numeric_limits<double>::infinity()
8986 : std::numeric_limits<double>::quiet_NaN();
8987 default:
8988 return std::ldexp(mant + 1024, exp - 25);
8989 }
8990 }();
8991 return sax->number_float((half & 0x8000u) != 0
8992 ? static_cast<number_float_t>(-val)
8993 : static_cast<number_float_t>(val), "");
8994 }
8995
8996 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
8997 {
8998 float number{};
8999 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9000 }
9001
9002 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9003 {
9004 double number{};
9005 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9006 }
9007
9008 default: // anything else (0xFF is handled inside the other types)
9009 {
9010 auto last_token = get_token_string();
9011 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
9012 }
9013 }
9014 }
9015
9027 bool get_cbor_string(string_t& result)
9028 {
9029 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
9030 {
9031 return false;
9032 }
9033
9034 switch (current)
9035 {
9036 // UTF-8 string (0x00..0x17 bytes follow)
9037 case 0x60:
9038 case 0x61:
9039 case 0x62:
9040 case 0x63:
9041 case 0x64:
9042 case 0x65:
9043 case 0x66:
9044 case 0x67:
9045 case 0x68:
9046 case 0x69:
9047 case 0x6A:
9048 case 0x6B:
9049 case 0x6C:
9050 case 0x6D:
9051 case 0x6E:
9052 case 0x6F:
9053 case 0x70:
9054 case 0x71:
9055 case 0x72:
9056 case 0x73:
9057 case 0x74:
9058 case 0x75:
9059 case 0x76:
9060 case 0x77:
9061 {
9062 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9063 }
9064
9065 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9066 {
9067 std::uint8_t len{};
9068 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9069 }
9070
9071 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9072 {
9073 std::uint16_t len{};
9074 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9075 }
9076
9077 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9078 {
9079 std::uint32_t len{};
9080 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9081 }
9082
9083 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9084 {
9085 std::uint64_t len{};
9086 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9087 }
9088
9089 case 0x7F: // UTF-8 string (indefinite length)
9090 {
9091 while (get() != 0xFF)
9092 {
9093 string_t chunk;
9094 if (!get_cbor_string(chunk))
9095 {
9096 return false;
9097 }
9098 result.append(chunk);
9099 }
9100 return true;
9101 }
9102
9103 default:
9104 {
9105 auto last_token = get_token_string();
9106 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string"), BasicJsonType()));
9107 }
9108 }
9109 }
9110
9122 bool get_cbor_binary(binary_t& result)
9123 {
9124 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
9125 {
9126 return false;
9127 }
9128
9129 switch (current)
9130 {
9131 // Binary data (0x00..0x17 bytes follow)
9132 case 0x40:
9133 case 0x41:
9134 case 0x42:
9135 case 0x43:
9136 case 0x44:
9137 case 0x45:
9138 case 0x46:
9139 case 0x47:
9140 case 0x48:
9141 case 0x49:
9142 case 0x4A:
9143 case 0x4B:
9144 case 0x4C:
9145 case 0x4D:
9146 case 0x4E:
9147 case 0x4F:
9148 case 0x50:
9149 case 0x51:
9150 case 0x52:
9151 case 0x53:
9152 case 0x54:
9153 case 0x55:
9154 case 0x56:
9155 case 0x57:
9156 {
9157 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9158 }
9159
9160 case 0x58: // Binary data (one-byte uint8_t for n follows)
9161 {
9162 std::uint8_t len{};
9163 return get_number(input_format_t::cbor, len) &&
9164 get_binary(input_format_t::cbor, len, result);
9165 }
9166
9167 case 0x59: // Binary data (two-byte uint16_t for n follow)
9168 {
9169 std::uint16_t len{};
9170 return get_number(input_format_t::cbor, len) &&
9171 get_binary(input_format_t::cbor, len, result);
9172 }
9173
9174 case 0x5A: // Binary data (four-byte uint32_t for n follow)
9175 {
9176 std::uint32_t len{};
9177 return get_number(input_format_t::cbor, len) &&
9178 get_binary(input_format_t::cbor, len, result);
9179 }
9180
9181 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9182 {
9183 std::uint64_t len{};
9184 return get_number(input_format_t::cbor, len) &&
9185 get_binary(input_format_t::cbor, len, result);
9186 }
9187
9188 case 0x5F: // Binary data (indefinite length)
9189 {
9190 while (get() != 0xFF)
9191 {
9192 binary_t chunk;
9193 if (!get_cbor_binary(chunk))
9194 {
9195 return false;
9196 }
9197 result.insert(result.end(), chunk.begin(), chunk.end());
9198 }
9199 return true;
9200 }
9201
9202 default:
9203 {
9204 auto last_token = get_token_string();
9205 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token, "binary"), BasicJsonType()));
9206 }
9207 }
9208 }
9209
9216 bool get_cbor_array(const std::size_t len,
9217 const cbor_tag_handler_t tag_handler)
9218 {
9219 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9220 {
9221 return false;
9222 }
9223
9224 if (len != std::size_t(-1))
9225 {
9226 for (std::size_t i = 0; i < len; ++i)
9227 {
9228 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9229 {
9230 return false;
9231 }
9232 }
9233 }
9234 else
9235 {
9236 while (get() != 0xFF)
9237 {
9238 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
9239 {
9240 return false;
9241 }
9242 }
9243 }
9244
9245 return sax->end_array();
9246 }
9247
9254 bool get_cbor_object(const std::size_t len,
9255 const cbor_tag_handler_t tag_handler)
9256 {
9257 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9258 {
9259 return false;
9260 }
9261
9262 string_t key;
9263 if (len != std::size_t(-1))
9264 {
9265 for (std::size_t i = 0; i < len; ++i)
9266 {
9267 get();
9268 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9269 {
9270 return false;
9271 }
9272
9273 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9274 {
9275 return false;
9276 }
9277 key.clear();
9278 }
9279 }
9280 else
9281 {
9282 while (get() != 0xFF)
9283 {
9284 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9285 {
9286 return false;
9287 }
9288
9289 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9290 {
9291 return false;
9292 }
9293 key.clear();
9294 }
9295 }
9296
9297 return sax->end_object();
9298 }
9299
9301 // MsgPack //
9303
9307 bool parse_msgpack_internal()
9308 {
9309 switch (get())
9310 {
9311 // EOF
9312 case std::char_traits<char_type>::eof():
9313 return unexpect_eof(input_format_t::msgpack, "value");
9314
9315 // positive fixint
9316 case 0x00:
9317 case 0x01:
9318 case 0x02:
9319 case 0x03:
9320 case 0x04:
9321 case 0x05:
9322 case 0x06:
9323 case 0x07:
9324 case 0x08:
9325 case 0x09:
9326 case 0x0A:
9327 case 0x0B:
9328 case 0x0C:
9329 case 0x0D:
9330 case 0x0E:
9331 case 0x0F:
9332 case 0x10:
9333 case 0x11:
9334 case 0x12:
9335 case 0x13:
9336 case 0x14:
9337 case 0x15:
9338 case 0x16:
9339 case 0x17:
9340 case 0x18:
9341 case 0x19:
9342 case 0x1A:
9343 case 0x1B:
9344 case 0x1C:
9345 case 0x1D:
9346 case 0x1E:
9347 case 0x1F:
9348 case 0x20:
9349 case 0x21:
9350 case 0x22:
9351 case 0x23:
9352 case 0x24:
9353 case 0x25:
9354 case 0x26:
9355 case 0x27:
9356 case 0x28:
9357 case 0x29:
9358 case 0x2A:
9359 case 0x2B:
9360 case 0x2C:
9361 case 0x2D:
9362 case 0x2E:
9363 case 0x2F:
9364 case 0x30:
9365 case 0x31:
9366 case 0x32:
9367 case 0x33:
9368 case 0x34:
9369 case 0x35:
9370 case 0x36:
9371 case 0x37:
9372 case 0x38:
9373 case 0x39:
9374 case 0x3A:
9375 case 0x3B:
9376 case 0x3C:
9377 case 0x3D:
9378 case 0x3E:
9379 case 0x3F:
9380 case 0x40:
9381 case 0x41:
9382 case 0x42:
9383 case 0x43:
9384 case 0x44:
9385 case 0x45:
9386 case 0x46:
9387 case 0x47:
9388 case 0x48:
9389 case 0x49:
9390 case 0x4A:
9391 case 0x4B:
9392 case 0x4C:
9393 case 0x4D:
9394 case 0x4E:
9395 case 0x4F:
9396 case 0x50:
9397 case 0x51:
9398 case 0x52:
9399 case 0x53:
9400 case 0x54:
9401 case 0x55:
9402 case 0x56:
9403 case 0x57:
9404 case 0x58:
9405 case 0x59:
9406 case 0x5A:
9407 case 0x5B:
9408 case 0x5C:
9409 case 0x5D:
9410 case 0x5E:
9411 case 0x5F:
9412 case 0x60:
9413 case 0x61:
9414 case 0x62:
9415 case 0x63:
9416 case 0x64:
9417 case 0x65:
9418 case 0x66:
9419 case 0x67:
9420 case 0x68:
9421 case 0x69:
9422 case 0x6A:
9423 case 0x6B:
9424 case 0x6C:
9425 case 0x6D:
9426 case 0x6E:
9427 case 0x6F:
9428 case 0x70:
9429 case 0x71:
9430 case 0x72:
9431 case 0x73:
9432 case 0x74:
9433 case 0x75:
9434 case 0x76:
9435 case 0x77:
9436 case 0x78:
9437 case 0x79:
9438 case 0x7A:
9439 case 0x7B:
9440 case 0x7C:
9441 case 0x7D:
9442 case 0x7E:
9443 case 0x7F:
9444 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9445
9446 // fixmap
9447 case 0x80:
9448 case 0x81:
9449 case 0x82:
9450 case 0x83:
9451 case 0x84:
9452 case 0x85:
9453 case 0x86:
9454 case 0x87:
9455 case 0x88:
9456 case 0x89:
9457 case 0x8A:
9458 case 0x8B:
9459 case 0x8C:
9460 case 0x8D:
9461 case 0x8E:
9462 case 0x8F:
9463 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9464
9465 // fixarray
9466 case 0x90:
9467 case 0x91:
9468 case 0x92:
9469 case 0x93:
9470 case 0x94:
9471 case 0x95:
9472 case 0x96:
9473 case 0x97:
9474 case 0x98:
9475 case 0x99:
9476 case 0x9A:
9477 case 0x9B:
9478 case 0x9C:
9479 case 0x9D:
9480 case 0x9E:
9481 case 0x9F:
9482 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9483
9484 // fixstr
9485 case 0xA0:
9486 case 0xA1:
9487 case 0xA2:
9488 case 0xA3:
9489 case 0xA4:
9490 case 0xA5:
9491 case 0xA6:
9492 case 0xA7:
9493 case 0xA8:
9494 case 0xA9:
9495 case 0xAA:
9496 case 0xAB:
9497 case 0xAC:
9498 case 0xAD:
9499 case 0xAE:
9500 case 0xAF:
9501 case 0xB0:
9502 case 0xB1:
9503 case 0xB2:
9504 case 0xB3:
9505 case 0xB4:
9506 case 0xB5:
9507 case 0xB6:
9508 case 0xB7:
9509 case 0xB8:
9510 case 0xB9:
9511 case 0xBA:
9512 case 0xBB:
9513 case 0xBC:
9514 case 0xBD:
9515 case 0xBE:
9516 case 0xBF:
9517 case 0xD9: // str 8
9518 case 0xDA: // str 16
9519 case 0xDB: // str 32
9520 {
9521 string_t s;
9522 return get_msgpack_string(s) && sax->string(s);
9523 }
9524
9525 case 0xC0: // nil
9526 return sax->null();
9527
9528 case 0xC2: // false
9529 return sax->boolean(false);
9530
9531 case 0xC3: // true
9532 return sax->boolean(true);
9533
9534 case 0xC4: // bin 8
9535 case 0xC5: // bin 16
9536 case 0xC6: // bin 32
9537 case 0xC7: // ext 8
9538 case 0xC8: // ext 16
9539 case 0xC9: // ext 32
9540 case 0xD4: // fixext 1
9541 case 0xD5: // fixext 2
9542 case 0xD6: // fixext 4
9543 case 0xD7: // fixext 8
9544 case 0xD8: // fixext 16
9545 {
9546 binary_t b;
9547 return get_msgpack_binary(b) && sax->binary(b);
9548 }
9549
9550 case 0xCA: // float 32
9551 {
9552 float number{};
9553 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9554 }
9555
9556 case 0xCB: // float 64
9557 {
9558 double number{};
9559 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9560 }
9561
9562 case 0xCC: // uint 8
9563 {
9564 std::uint8_t number{};
9565 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9566 }
9567
9568 case 0xCD: // uint 16
9569 {
9570 std::uint16_t number{};
9571 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9572 }
9573
9574 case 0xCE: // uint 32
9575 {
9576 std::uint32_t number{};
9577 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9578 }
9579
9580 case 0xCF: // uint 64
9581 {
9582 std::uint64_t number{};
9583 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9584 }
9585
9586 case 0xD0: // int 8
9587 {
9588 std::int8_t number{};
9589 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9590 }
9591
9592 case 0xD1: // int 16
9593 {
9594 std::int16_t number{};
9595 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9596 }
9597
9598 case 0xD2: // int 32
9599 {
9600 std::int32_t number{};
9601 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9602 }
9603
9604 case 0xD3: // int 64
9605 {
9606 std::int64_t number{};
9607 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9608 }
9609
9610 case 0xDC: // array 16
9611 {
9612 std::uint16_t len{};
9613 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9614 }
9615
9616 case 0xDD: // array 32
9617 {
9618 std::uint32_t len{};
9619 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9620 }
9621
9622 case 0xDE: // map 16
9623 {
9624 std::uint16_t len{};
9625 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9626 }
9627
9628 case 0xDF: // map 32
9629 {
9630 std::uint32_t len{};
9631 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9632 }
9633
9634 // negative fixint
9635 case 0xE0:
9636 case 0xE1:
9637 case 0xE2:
9638 case 0xE3:
9639 case 0xE4:
9640 case 0xE5:
9641 case 0xE6:
9642 case 0xE7:
9643 case 0xE8:
9644 case 0xE9:
9645 case 0xEA:
9646 case 0xEB:
9647 case 0xEC:
9648 case 0xED:
9649 case 0xEE:
9650 case 0xEF:
9651 case 0xF0:
9652 case 0xF1:
9653 case 0xF2:
9654 case 0xF3:
9655 case 0xF4:
9656 case 0xF5:
9657 case 0xF6:
9658 case 0xF7:
9659 case 0xF8:
9660 case 0xF9:
9661 case 0xFA:
9662 case 0xFB:
9663 case 0xFC:
9664 case 0xFD:
9665 case 0xFE:
9666 case 0xFF:
9667 return sax->number_integer(static_cast<std::int8_t>(current));
9668
9669 default: // anything else
9670 {
9671 auto last_token = get_token_string();
9672 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
9673 }
9674 }
9675 }
9676
9687 bool get_msgpack_string(string_t& result)
9688 {
9689 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
9690 {
9691 return false;
9692 }
9693
9694 switch (current)
9695 {
9696 // fixstr
9697 case 0xA0:
9698 case 0xA1:
9699 case 0xA2:
9700 case 0xA3:
9701 case 0xA4:
9702 case 0xA5:
9703 case 0xA6:
9704 case 0xA7:
9705 case 0xA8:
9706 case 0xA9:
9707 case 0xAA:
9708 case 0xAB:
9709 case 0xAC:
9710 case 0xAD:
9711 case 0xAE:
9712 case 0xAF:
9713 case 0xB0:
9714 case 0xB1:
9715 case 0xB2:
9716 case 0xB3:
9717 case 0xB4:
9718 case 0xB5:
9719 case 0xB6:
9720 case 0xB7:
9721 case 0xB8:
9722 case 0xB9:
9723 case 0xBA:
9724 case 0xBB:
9725 case 0xBC:
9726 case 0xBD:
9727 case 0xBE:
9728 case 0xBF:
9729 {
9730 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
9731 }
9732
9733 case 0xD9: // str 8
9734 {
9735 std::uint8_t len{};
9736 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9737 }
9738
9739 case 0xDA: // str 16
9740 {
9741 std::uint16_t len{};
9742 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9743 }
9744
9745 case 0xDB: // str 32
9746 {
9747 std::uint32_t len{};
9748 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9749 }
9750
9751 default:
9752 {
9753 auto last_token = get_token_string();
9754 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string"), BasicJsonType()));
9755 }
9756 }
9757 }
9758
9769 bool get_msgpack_binary(binary_t& result)
9770 {
9771 // helper function to set the subtype
9772 auto assign_and_return_true = [&result](std::int8_t subtype)
9773 {
9774 result.set_subtype(static_cast<std::uint8_t>(subtype));
9775 return true;
9776 };
9777
9778 switch (current)
9779 {
9780 case 0xC4: // bin 8
9781 {
9782 std::uint8_t len{};
9783 return get_number(input_format_t::msgpack, len) &&
9784 get_binary(input_format_t::msgpack, len, result);
9785 }
9786
9787 case 0xC5: // bin 16
9788 {
9789 std::uint16_t len{};
9790 return get_number(input_format_t::msgpack, len) &&
9791 get_binary(input_format_t::msgpack, len, result);
9792 }
9793
9794 case 0xC6: // bin 32
9795 {
9796 std::uint32_t len{};
9797 return get_number(input_format_t::msgpack, len) &&
9798 get_binary(input_format_t::msgpack, len, result);
9799 }
9800
9801 case 0xC7: // ext 8
9802 {
9803 std::uint8_t len{};
9804 std::int8_t subtype{};
9805 return get_number(input_format_t::msgpack, len) &&
9806 get_number(input_format_t::msgpack, subtype) &&
9807 get_binary(input_format_t::msgpack, len, result) &&
9808 assign_and_return_true(subtype);
9809 }
9810
9811 case 0xC8: // ext 16
9812 {
9813 std::uint16_t len{};
9814 std::int8_t subtype{};
9815 return get_number(input_format_t::msgpack, len) &&
9816 get_number(input_format_t::msgpack, subtype) &&
9817 get_binary(input_format_t::msgpack, len, result) &&
9818 assign_and_return_true(subtype);
9819 }
9820
9821 case 0xC9: // ext 32
9822 {
9823 std::uint32_t len{};
9824 std::int8_t subtype{};
9825 return get_number(input_format_t::msgpack, len) &&
9826 get_number(input_format_t::msgpack, subtype) &&
9827 get_binary(input_format_t::msgpack, len, result) &&
9828 assign_and_return_true(subtype);
9829 }
9830
9831 case 0xD4: // fixext 1
9832 {
9833 std::int8_t subtype{};
9834 return get_number(input_format_t::msgpack, subtype) &&
9835 get_binary(input_format_t::msgpack, 1, result) &&
9836 assign_and_return_true(subtype);
9837 }
9838
9839 case 0xD5: // fixext 2
9840 {
9841 std::int8_t subtype{};
9842 return get_number(input_format_t::msgpack, subtype) &&
9843 get_binary(input_format_t::msgpack, 2, result) &&
9844 assign_and_return_true(subtype);
9845 }
9846
9847 case 0xD6: // fixext 4
9848 {
9849 std::int8_t subtype{};
9850 return get_number(input_format_t::msgpack, subtype) &&
9851 get_binary(input_format_t::msgpack, 4, result) &&
9852 assign_and_return_true(subtype);
9853 }
9854
9855 case 0xD7: // fixext 8
9856 {
9857 std::int8_t subtype{};
9858 return get_number(input_format_t::msgpack, subtype) &&
9859 get_binary(input_format_t::msgpack, 8, result) &&
9860 assign_and_return_true(subtype);
9861 }
9862
9863 case 0xD8: // fixext 16
9864 {
9865 std::int8_t subtype{};
9866 return get_number(input_format_t::msgpack, subtype) &&
9867 get_binary(input_format_t::msgpack, 16, result) &&
9868 assign_and_return_true(subtype);
9869 }
9870
9871 default: // LCOV_EXCL_LINE
9872 return false; // LCOV_EXCL_LINE
9873 }
9874 }
9875
9880 bool get_msgpack_array(const std::size_t len)
9881 {
9882 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9883 {
9884 return false;
9885 }
9886
9887 for (std::size_t i = 0; i < len; ++i)
9888 {
9889 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
9890 {
9891 return false;
9892 }
9893 }
9894
9895 return sax->end_array();
9896 }
9897
9902 bool get_msgpack_object(const std::size_t len)
9903 {
9904 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9905 {
9906 return false;
9907 }
9908
9909 string_t key;
9910 for (std::size_t i = 0; i < len; ++i)
9911 {
9912 get();
9913 if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
9914 {
9915 return false;
9916 }
9917
9918 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
9919 {
9920 return false;
9921 }
9922 key.clear();
9923 }
9924
9925 return sax->end_object();
9926 }
9927
9929 // UBJSON //
9931
9939 bool parse_ubjson_internal(const bool get_char = true)
9940 {
9941 return get_ubjson_value(get_char ? get_ignore_noop() : current);
9942 }
9943
9958 bool get_ubjson_string(string_t& result, const bool get_char = true)
9959 {
9960 if (get_char)
9961 {
9962 get(); // TODO(niels): may we ignore N here?
9963 }
9964
9965 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
9966 {
9967 return false;
9968 }
9969
9970 switch (current)
9971 {
9972 case 'U':
9973 {
9974 std::uint8_t len{};
9975 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9976 }
9977
9978 case 'i':
9979 {
9980 std::int8_t len{};
9981 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9982 }
9983
9984 case 'I':
9985 {
9986 std::int16_t len{};
9987 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9988 }
9989
9990 case 'l':
9991 {
9992 std::int32_t len{};
9993 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9994 }
9995
9996 case 'L':
9997 {
9998 std::int64_t len{};
9999 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10000 }
10001
10002 default:
10003 auto last_token = get_token_string();
10004 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string"), BasicJsonType()));
10005 }
10006 }
10007
10012 bool get_ubjson_size_value(std::size_t& result)
10013 {
10014 switch (get_ignore_noop())
10015 {
10016 case 'U':
10017 {
10018 std::uint8_t number{};
10019 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10020 {
10021 return false;
10022 }
10023 result = static_cast<std::size_t>(number);
10024 return true;
10025 }
10026
10027 case 'i':
10028 {
10029 std::int8_t number{};
10030 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10031 {
10032 return false;
10033 }
10034 result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
10035 return true;
10036 }
10037
10038 case 'I':
10039 {
10040 std::int16_t number{};
10041 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10042 {
10043 return false;
10044 }
10045 result = static_cast<std::size_t>(number);
10046 return true;
10047 }
10048
10049 case 'l':
10050 {
10051 std::int32_t number{};
10052 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10053 {
10054 return false;
10055 }
10056 result = static_cast<std::size_t>(number);
10057 return true;
10058 }
10059
10060 case 'L':
10061 {
10062 std::int64_t number{};
10063 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10064 {
10065 return false;
10066 }
10067 result = static_cast<std::size_t>(number);
10068 return true;
10069 }
10070
10071 default:
10072 {
10073 auto last_token = get_token_string();
10074 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size"), BasicJsonType()));
10075 }
10076 }
10077 }
10078
10089 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
10090 {
10091 result.first = string_t::npos; // size
10092 result.second = 0; // type
10093
10094 get_ignore_noop();
10095
10096 if (current == '$')
10097 {
10098 result.second = get(); // must not ignore 'N', because 'N' maybe the type
10099 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type")))
10100 {
10101 return false;
10102 }
10103
10104 get_ignore_noop();
10105 if (JSON_HEDLEY_UNLIKELY(current != '#'))
10106 {
10107 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
10108 {
10109 return false;
10110 }
10111 auto last_token = get_token_string();
10112 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size"), BasicJsonType()));
10113 }
10114
10115 return get_ubjson_size_value(result.first);
10116 }
10117
10118 if (current == '#')
10119 {
10120 return get_ubjson_size_value(result.first);
10121 }
10122
10123 return true;
10124 }
10125
10130 bool get_ubjson_value(const char_int_type prefix)
10131 {
10132 switch (prefix)
10133 {
10134 case std::char_traits<char_type>::eof(): // EOF
10135 return unexpect_eof(input_format_t::ubjson, "value");
10136
10137 case 'T': // true
10138 return sax->boolean(true);
10139 case 'F': // false
10140 return sax->boolean(false);
10141
10142 case 'Z': // null
10143 return sax->null();
10144
10145 case 'U':
10146 {
10147 std::uint8_t number{};
10148 return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
10149 }
10150
10151 case 'i':
10152 {
10153 std::int8_t number{};
10154 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10155 }
10156
10157 case 'I':
10158 {
10159 std::int16_t number{};
10160 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10161 }
10162
10163 case 'l':
10164 {
10165 std::int32_t number{};
10166 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10167 }
10168
10169 case 'L':
10170 {
10171 std::int64_t number{};
10172 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10173 }
10174
10175 case 'd':
10176 {
10177 float number{};
10178 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10179 }
10180
10181 case 'D':
10182 {
10183 double number{};
10184 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10185 }
10186
10187 case 'H':
10188 {
10189 return get_ubjson_high_precision_number();
10190 }
10191
10192 case 'C': // char
10193 {
10194 get();
10195 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char")))
10196 {
10197 return false;
10198 }
10199 if (JSON_HEDLEY_UNLIKELY(current > 127))
10200 {
10201 auto last_token = get_token_string();
10202 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char"), BasicJsonType()));
10203 }
10204 string_t s(1, static_cast<typename string_t::value_type>(current));
10205 return sax->string(s);
10206 }
10207
10208 case 'S': // string
10209 {
10210 string_t s;
10211 return get_ubjson_string(s) && sax->string(s);
10212 }
10213
10214 case '[': // array
10215 return get_ubjson_array();
10216
10217 case '{': // object
10218 return get_ubjson_object();
10219
10220 default: // anything else
10221 {
10222 auto last_token = get_token_string();
10223 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
10224 }
10225 }
10226 }
10227
10231 bool get_ubjson_array()
10232 {
10233 std::pair<std::size_t, char_int_type> size_and_type;
10234 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10235 {
10236 return false;
10237 }
10238
10239 if (size_and_type.first != string_t::npos)
10240 {
10241 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
10242 {
10243 return false;
10244 }
10245
10246 if (size_and_type.second != 0)
10247 {
10248 if (size_and_type.second != 'N')
10249 {
10250 for (std::size_t i = 0; i < size_and_type.first; ++i)
10251 {
10252 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10253 {
10254 return false;
10255 }
10256 }
10257 }
10258 }
10259 else
10260 {
10261 for (std::size_t i = 0; i < size_and_type.first; ++i)
10262 {
10263 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10264 {
10265 return false;
10266 }
10267 }
10268 }
10269 }
10270 else
10271 {
10272 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10273 {
10274 return false;
10275 }
10276
10277 while (current != ']')
10278 {
10279 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
10280 {
10281 return false;
10282 }
10283 get_ignore_noop();
10284 }
10285 }
10286
10287 return sax->end_array();
10288 }
10289
10293 bool get_ubjson_object()
10294 {
10295 std::pair<std::size_t, char_int_type> size_and_type;
10296 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10297 {
10298 return false;
10299 }
10300
10301 string_t key;
10302 if (size_and_type.first != string_t::npos)
10303 {
10304 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
10305 {
10306 return false;
10307 }
10308
10309 if (size_and_type.second != 0)
10310 {
10311 for (std::size_t i = 0; i < size_and_type.first; ++i)
10312 {
10313 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10314 {
10315 return false;
10316 }
10317 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10318 {
10319 return false;
10320 }
10321 key.clear();
10322 }
10323 }
10324 else
10325 {
10326 for (std::size_t i = 0; i < size_and_type.first; ++i)
10327 {
10328 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10329 {
10330 return false;
10331 }
10332 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10333 {
10334 return false;
10335 }
10336 key.clear();
10337 }
10338 }
10339 }
10340 else
10341 {
10342 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10343 {
10344 return false;
10345 }
10346
10347 while (current != '}')
10348 {
10349 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
10350 {
10351 return false;
10352 }
10353 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10354 {
10355 return false;
10356 }
10357 get_ignore_noop();
10358 key.clear();
10359 }
10360 }
10361
10362 return sax->end_object();
10363 }
10364
10365 // Note, no reader for UBJSON binary types is implemented because they do
10366 // not exist
10367
10368 bool get_ubjson_high_precision_number()
10369 {
10370 // get size of following number string
10371 std::size_t size{};
10372 auto res = get_ubjson_size_value(size);
10373 if (JSON_HEDLEY_UNLIKELY(!res))
10374 {
10375 return res;
10376 }
10377
10378 // get number string
10379 std::vector<char> number_vector;
10380 for (std::size_t i = 0; i < size; ++i)
10381 {
10382 get();
10383 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number")))
10384 {
10385 return false;
10386 }
10387 number_vector.push_back(static_cast<char>(current));
10388 }
10389
10390 // parse number string
10391 using ia_type = decltype(detail::input_adapter(number_vector));
10392 auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
10393 const auto result_number = number_lexer.scan();
10394 const auto number_string = number_lexer.get_token_string();
10395 const auto result_remainder = number_lexer.scan();
10396
10397 using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
10398
10399 if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
10400 {
10401 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType()));
10402 }
10403
10404 switch (result_number)
10405 {
10406 case token_type::value_integer:
10407 return sax->number_integer(number_lexer.get_number_integer());
10408 case token_type::value_unsigned:
10409 return sax->number_unsigned(number_lexer.get_number_unsigned());
10410 case token_type::value_float:
10411 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
10412 default:
10413 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType()));
10414 }
10415 }
10416
10418 // Utility functions //
10420
10430 char_int_type get()
10431 {
10432 ++chars_read;
10433 return current = ia.get_character();
10434 }
10435
10439 char_int_type get_ignore_noop()
10440 {
10441 do
10442 {
10443 get();
10444 }
10445 while (current == 'N');
10446
10447 return current;
10448 }
10449
10450 /*
10451 @brief read a number from the input
10452
10453 @tparam NumberType the type of the number
10454 @param[in] format the current format (for diagnostics)
10455 @param[out] result number of type @a NumberType
10456
10457 @return whether conversion completed
10458
10459 @note This function needs to respect the system's endianess, because
10460 bytes in CBOR, MessagePack, and UBJSON are stored in network order
10461 (big endian) and therefore need reordering on little endian systems.
10462 */
10463 template<typename NumberType, bool InputIsLittleEndian = false>
10464 bool get_number(const input_format_t format, NumberType& result)
10465 {
10466 // step 1: read input into array with system's byte order
10467 std::array<std::uint8_t, sizeof(NumberType)> vec{};
10468 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
10469 {
10470 get();
10471 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
10472 {
10473 return false;
10474 }
10475
10476 // reverse byte order prior to conversion if necessary
10477 if (is_little_endian != InputIsLittleEndian)
10478 {
10479 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
10480 }
10481 else
10482 {
10483 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
10484 }
10485 }
10486
10487 // step 2: convert array into number of type T and return
10488 std::memcpy(&result, vec.data(), sizeof(NumberType));
10489 return true;
10490 }
10491
10506 template<typename NumberType>
10507 bool get_string(const input_format_t format,
10508 const NumberType len,
10509 string_t& result)
10510 {
10511 bool success = true;
10512 for (NumberType i = 0; i < len; i++)
10513 {
10514 get();
10515 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
10516 {
10517 success = false;
10518 break;
10519 }
10520 result.push_back(static_cast<typename string_t::value_type>(current));
10521 }
10522 return success;
10523 }
10524
10539 template<typename NumberType>
10540 bool get_binary(const input_format_t format,
10541 const NumberType len,
10542 binary_t& result)
10543 {
10544 bool success = true;
10545 for (NumberType i = 0; i < len; i++)
10546 {
10547 get();
10548 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10549 {
10550 success = false;
10551 break;
10552 }
10553 result.push_back(static_cast<std::uint8_t>(current));
10554 }
10555 return success;
10556 }
10557
10563 JSON_HEDLEY_NON_NULL(3)
10564 bool unexpect_eof(const input_format_t format, const char* context) const
10565 {
10566 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
10567 {
10568 return sax->parse_error(chars_read, "<end of file>",
10569 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), BasicJsonType()));
10570 }
10571 return true;
10572 }
10573
10577 std::string get_token_string() const
10578 {
10579 std::array<char, 3> cr{{}};
10580 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
10581 return std::string{cr.data()};
10582 }
10583
10590 std::string exception_message(const input_format_t format,
10591 const std::string& detail,
10592 const std::string& context) const
10593 {
10594 std::string error_msg = "syntax error while parsing ";
10595
10596 switch (format)
10597 {
10598 case input_format_t::cbor:
10599 error_msg += "CBOR";
10600 break;
10601
10602 case input_format_t::msgpack:
10603 error_msg += "MessagePack";
10604 break;
10605
10606 case input_format_t::ubjson:
10607 error_msg += "UBJSON";
10608 break;
10609
10610 case input_format_t::bson:
10611 error_msg += "BSON";
10612 break;
10613
10614 default: // LCOV_EXCL_LINE
10615 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
10616 }
10617
10618 return error_msg + " " + context + ": " + detail;
10619 }
10620
10621 private:
10623 InputAdapterType ia;
10624
10626 char_int_type current = std::char_traits<char_type>::eof();
10627
10629 std::size_t chars_read = 0;
10630
10632 const bool is_little_endian = little_endianess();
10633
10635 json_sax_t* sax = nullptr;
10636 };
10637 } // namespace detail
10638 } // namespace nlohmann
10639
10640 // #include <nlohmann/detail/input/input_adapters.hpp>
10641
10642 // #include <nlohmann/detail/input/lexer.hpp>
10643
10644 // #include <nlohmann/detail/input/parser.hpp>
10645
10646
10647 #include <cmath> // isfinite
10648 #include <cstdint> // uint8_t
10649 #include <functional> // function
10650 #include <string> // string
10651 #include <utility> // move
10652 #include <vector> // vector
10653
10654 // #include <nlohmann/detail/exceptions.hpp>
10655
10656 // #include <nlohmann/detail/input/input_adapters.hpp>
10657
10658 // #include <nlohmann/detail/input/json_sax.hpp>
10659
10660 // #include <nlohmann/detail/input/lexer.hpp>
10661
10662 // #include <nlohmann/detail/macro_scope.hpp>
10663
10664 // #include <nlohmann/detail/meta/is_sax.hpp>
10665
10666 // #include <nlohmann/detail/value_t.hpp>
10667
10668
10669 namespace nlohmann
10670 {
10671 namespace detail
10672 {
10674 // parser //
10676
10677 enum class parse_event_t : uint8_t
10678 {
10680 object_start,
10682 object_end,
10684 array_start,
10686 array_end,
10688 key,
10690 value
10691 };
10692
10693 template<typename BasicJsonType>
10694 using parser_callback_t =
10695 std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
10696
10702 template<typename BasicJsonType, typename InputAdapterType>
10703 class parser
10704 {
10705 using number_integer_t = typename BasicJsonType::number_integer_t;
10706 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10707 using number_float_t = typename BasicJsonType::number_float_t;
10708 using string_t = typename BasicJsonType::string_t;
10709 using lexer_t = lexer<BasicJsonType, InputAdapterType>;
10710 using token_type = typename lexer_t::token_type;
10711
10712 public:
10714 explicit parser(InputAdapterType&& adapter,
10715 const parser_callback_t<BasicJsonType> cb = nullptr,
10716 const bool allow_exceptions_ = true,
10717 const bool skip_comments = false)
10718 : callback(cb)
10719 , m_lexer(std::move(adapter), skip_comments)
10720 , allow_exceptions(allow_exceptions_)
10721 {
10722 // read first token
10723 get_token();
10724 }
10725
10736 void parse(const bool strict, BasicJsonType& result)
10737 {
10738 if (callback)
10739 {
10740 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
10741 sax_parse_internal(&sdp);
10742
10743 // in strict mode, input must be completely read
10744 if (strict && (get_token() != token_type::end_of_input))
10745 {
10746 sdp.parse_error(m_lexer.get_position(),
10747 m_lexer.get_token_string(),
10748 parse_error::create(101, m_lexer.get_position(),
10749 exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10750 }
10751
10752 // in case of an error, return discarded value
10753 if (sdp.is_errored())
10754 {
10755 result = value_t::discarded;
10756 return;
10757 }
10758
10759 // set top-level value to null if it was discarded by the callback
10760 // function
10761 if (result.is_discarded())
10762 {
10763 result = nullptr;
10764 }
10765 }
10766 else
10767 {
10768 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
10769 sax_parse_internal(&sdp);
10770
10771 // in strict mode, input must be completely read
10772 if (strict && (get_token() != token_type::end_of_input))
10773 {
10774 sdp.parse_error(m_lexer.get_position(),
10775 m_lexer.get_token_string(),
10776 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10777 }
10778
10779 // in case of an error, return discarded value
10780 if (sdp.is_errored())
10781 {
10782 result = value_t::discarded;
10783 return;
10784 }
10785 }
10786
10787 result.assert_invariant();
10788 }
10789
10796 bool accept(const bool strict = true)
10797 {
10798 json_sax_acceptor<BasicJsonType> sax_acceptor;
10799 return sax_parse(&sax_acceptor, strict);
10800 }
10801
10802 template<typename SAX>
10803 JSON_HEDLEY_NON_NULL(2)
10804 bool sax_parse(SAX* sax, const bool strict = true)
10805 {
10806 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
10807 const bool result = sax_parse_internal(sax);
10808
10809 // strict mode: next byte must be EOF
10810 if (result && strict && (get_token() != token_type::end_of_input))
10811 {
10812 return sax->parse_error(m_lexer.get_position(),
10813 m_lexer.get_token_string(),
10814 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10815 }
10816
10817 return result;
10818 }
10819
10820 private:
10821 template<typename SAX>
10822 JSON_HEDLEY_NON_NULL(2)
10823 bool sax_parse_internal(SAX* sax)
10824 {
10825 // stack to remember the hierarchy of structured values we are parsing
10826 // true = array; false = object
10827 std::vector<bool> states;
10828 // value to avoid a goto (see comment where set to true)
10829 bool skip_to_state_evaluation = false;
10830
10831 while (true)
10832 {
10833 if (!skip_to_state_evaluation)
10834 {
10835 // invariant: get_token() was called before each iteration
10836 switch (last_token)
10837 {
10838 case token_type::begin_object:
10839 {
10840 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10841 {
10842 return false;
10843 }
10844
10845 // closing } -> we are done
10846 if (get_token() == token_type::end_object)
10847 {
10848 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
10849 {
10850 return false;
10851 }
10852 break;
10853 }
10854
10855 // parse key
10856 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
10857 {
10858 return sax->parse_error(m_lexer.get_position(),
10859 m_lexer.get_token_string(),
10860 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
10861 }
10862 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
10863 {
10864 return false;
10865 }
10866
10867 // parse separator (:)
10868 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10869 {
10870 return sax->parse_error(m_lexer.get_position(),
10871 m_lexer.get_token_string(),
10872 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
10873 }
10874
10875 // remember we are now inside an object
10876 states.push_back(false);
10877
10878 // parse values
10879 get_token();
10880 continue;
10881 }
10882
10883 case token_type::begin_array:
10884 {
10885 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10886 {
10887 return false;
10888 }
10889
10890 // closing ] -> we are done
10891 if (get_token() == token_type::end_array)
10892 {
10893 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
10894 {
10895 return false;
10896 }
10897 break;
10898 }
10899
10900 // remember we are now inside an array
10901 states.push_back(true);
10902
10903 // parse values (no need to call get_token)
10904 continue;
10905 }
10906
10907 case token_type::value_float:
10908 {
10909 const auto res = m_lexer.get_number_float();
10910
10911 if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
10912 {
10913 return sax->parse_error(m_lexer.get_position(),
10914 m_lexer.get_token_string(),
10915 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType()));
10916 }
10917
10918 if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
10919 {
10920 return false;
10921 }
10922
10923 break;
10924 }
10925
10926 case token_type::literal_false:
10927 {
10928 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
10929 {
10930 return false;
10931 }
10932 break;
10933 }
10934
10935 case token_type::literal_null:
10936 {
10937 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
10938 {
10939 return false;
10940 }
10941 break;
10942 }
10943
10944 case token_type::literal_true:
10945 {
10946 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
10947 {
10948 return false;
10949 }
10950 break;
10951 }
10952
10953 case token_type::value_integer:
10954 {
10955 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
10956 {
10957 return false;
10958 }
10959 break;
10960 }
10961
10962 case token_type::value_string:
10963 {
10964 if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
10965 {
10966 return false;
10967 }
10968 break;
10969 }
10970
10971 case token_type::value_unsigned:
10972 {
10973 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
10974 {
10975 return false;
10976 }
10977 break;
10978 }
10979
10980 case token_type::parse_error:
10981 {
10982 // using "uninitialized" to avoid "expected" message
10983 return sax->parse_error(m_lexer.get_position(),
10984 m_lexer.get_token_string(),
10985 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType()));
10986 }
10987
10988 default: // the last token was unexpected
10989 {
10990 return sax->parse_error(m_lexer.get_position(),
10991 m_lexer.get_token_string(),
10992 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), BasicJsonType()));
10993 }
10994 }
10995 }
10996 else
10997 {
10998 skip_to_state_evaluation = false;
10999 }
11000
11001 // we reached this line after we successfully parsed a value
11002 if (states.empty())
11003 {
11004 // empty stack: we reached the end of the hierarchy: done
11005 return true;
11006 }
11007
11008 if (states.back()) // array
11009 {
11010 // comma -> next value
11011 if (get_token() == token_type::value_separator)
11012 {
11013 // parse a new value
11014 get_token();
11015 continue;
11016 }
11017
11018 // closing ]
11019 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
11020 {
11021 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11022 {
11023 return false;
11024 }
11025
11026 // We are done with this array. Before we can parse a
11027 // new value, we need to evaluate the new state first.
11028 // By setting skip_to_state_evaluation to false, we
11029 // are effectively jumping to the beginning of this if.
11030 JSON_ASSERT(!states.empty());
11031 states.pop_back();
11032 skip_to_state_evaluation = true;
11033 continue;
11034 }
11035
11036 return sax->parse_error(m_lexer.get_position(),
11037 m_lexer.get_token_string(),
11038 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), BasicJsonType()));
11039 }
11040
11041 // states.back() is false -> object
11042
11043 // comma -> next value
11044 if (get_token() == token_type::value_separator)
11045 {
11046 // parse key
11047 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
11048 {
11049 return sax->parse_error(m_lexer.get_position(),
11050 m_lexer.get_token_string(),
11051 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11052 }
11053
11054 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11055 {
11056 return false;
11057 }
11058
11059 // parse separator (:)
11060 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11061 {
11062 return sax->parse_error(m_lexer.get_position(),
11063 m_lexer.get_token_string(),
11064 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11065 }
11066
11067 // parse values
11068 get_token();
11069 continue;
11070 }
11071
11072 // closing }
11073 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
11074 {
11075 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11076 {
11077 return false;
11078 }
11079
11080 // We are done with this object. Before we can parse a
11081 // new value, we need to evaluate the new state first.
11082 // By setting skip_to_state_evaluation to false, we
11083 // are effectively jumping to the beginning of this if.
11084 JSON_ASSERT(!states.empty());
11085 states.pop_back();
11086 skip_to_state_evaluation = true;
11087 continue;
11088 }
11089
11090 return sax->parse_error(m_lexer.get_position(),
11091 m_lexer.get_token_string(),
11092 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), BasicJsonType()));
11093 }
11094 }
11095
11097 token_type get_token()
11098 {
11099 return last_token = m_lexer.scan();
11100 }
11101
11102 std::string exception_message(const token_type expected, const std::string& context)
11103 {
11104 std::string error_msg = "syntax error ";
11105
11106 if (!context.empty())
11107 {
11108 error_msg += "while parsing " + context + " ";
11109 }
11110
11111 error_msg += "- ";
11112
11113 if (last_token == token_type::parse_error)
11114 {
11115 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
11116 m_lexer.get_token_string() + "'";
11117 }
11118 else
11119 {
11120 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
11121 }
11122
11123 if (expected != token_type::uninitialized)
11124 {
11125 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
11126 }
11127
11128 return error_msg;
11129 }
11130
11131 private:
11133 const parser_callback_t<BasicJsonType> callback = nullptr;
11135 token_type last_token = token_type::uninitialized;
11137 lexer_t m_lexer;
11139 const bool allow_exceptions = true;
11140 };
11141
11142 } // namespace detail
11143 } // namespace nlohmann
11144
11145 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
11146
11147
11148 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11149
11150
11151 #include <cstddef> // ptrdiff_t
11152 #include <limits> // numeric_limits
11153
11154 // #include <nlohmann/detail/macro_scope.hpp>
11155
11156
11157 namespace nlohmann
11158 {
11159 namespace detail
11160 {
11161 /*
11162 @brief an iterator for primitive JSON types
11163
11164 This class models an iterator for primitive JSON types (boolean, number,
11165 string). It's only purpose is to allow the iterator/const_iterator classes
11166 to "iterate" over primitive values. Internally, the iterator is modeled by
11167 a `difference_type` variable. Value begin_value (`0`) models the begin,
11168 end_value (`1`) models past the end.
11169 */
11170 class primitive_iterator_t
11171 {
11172 private:
11173 using difference_type = std::ptrdiff_t;
11174 static constexpr difference_type begin_value = 0;
11175 static constexpr difference_type end_value = begin_value + 1;
11176
11177 JSON_PRIVATE_UNLESS_TESTED:
11179 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
11180
11181 public:
11182 constexpr difference_type get_value() const noexcept
11183 {
11184 return m_it;
11185 }
11186
11188 void set_begin() noexcept
11189 {
11190 m_it = begin_value;
11191 }
11192
11194 void set_end() noexcept
11195 {
11196 m_it = end_value;
11197 }
11198
11200 constexpr bool is_begin() const noexcept
11201 {
11202 return m_it == begin_value;
11203 }
11204
11206 constexpr bool is_end() const noexcept
11207 {
11208 return m_it == end_value;
11209 }
11210
11211 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11212 {
11213 return lhs.m_it == rhs.m_it;
11214 }
11215
11216 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11217 {
11218 return lhs.m_it < rhs.m_it;
11219 }
11220
11221 primitive_iterator_t operator+(difference_type n) noexcept
11222 {
11223 auto result = *this;
11224 result += n;
11225 return result;
11226 }
11227
11228 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11229 {
11230 return lhs.m_it - rhs.m_it;
11231 }
11232
11233 primitive_iterator_t& operator++() noexcept
11234 {
11235 ++m_it;
11236 return *this;
11237 }
11238
11239 primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)
11240 {
11241 auto result = *this;
11242 ++m_it;
11243 return result;
11244 }
11245
11246 primitive_iterator_t& operator--() noexcept
11247 {
11248 --m_it;
11249 return *this;
11250 }
11251
11252 primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)
11253 {
11254 auto result = *this;
11255 --m_it;
11256 return result;
11257 }
11258
11259 primitive_iterator_t& operator+=(difference_type n) noexcept
11260 {
11261 m_it += n;
11262 return *this;
11263 }
11264
11265 primitive_iterator_t& operator-=(difference_type n) noexcept
11266 {
11267 m_it -= n;
11268 return *this;
11269 }
11270 };
11271 } // namespace detail
11272 } // namespace nlohmann
11273
11274
11275 namespace nlohmann
11276 {
11277 namespace detail
11278 {
11285 template<typename BasicJsonType> struct internal_iterator
11286 {
11288 typename BasicJsonType::object_t::iterator object_iterator {};
11290 typename BasicJsonType::array_t::iterator array_iterator {};
11292 primitive_iterator_t primitive_iterator {};
11293 };
11294 } // namespace detail
11295 } // namespace nlohmann
11296
11297 // #include <nlohmann/detail/iterators/iter_impl.hpp>
11298
11299
11300 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
11301 #include <type_traits> // conditional, is_const, remove_const
11302
11303 // #include <nlohmann/detail/exceptions.hpp>
11304
11305 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
11306
11307 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11308
11309 // #include <nlohmann/detail/macro_scope.hpp>
11310
11311 // #include <nlohmann/detail/meta/cpp_future.hpp>
11312
11313 // #include <nlohmann/detail/meta/type_traits.hpp>
11314
11315 // #include <nlohmann/detail/value_t.hpp>
11316
11317
11318 namespace nlohmann
11319 {
11320 namespace detail
11321 {
11322 // forward declare, to be able to friend it later on
11323 template<typename IteratorType> class iteration_proxy;
11324 template<typename IteratorType> class iteration_proxy_value;
11325
11342 template<typename BasicJsonType>
11343 class iter_impl
11344 {
11346 using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
11348 friend other_iter_impl;
11349 friend BasicJsonType;
11350 friend iteration_proxy<iter_impl>;
11351 friend iteration_proxy_value<iter_impl>;
11352
11353 using object_t = typename BasicJsonType::object_t;
11354 using array_t = typename BasicJsonType::array_t;
11355 // make sure BasicJsonType is basic_json or const basic_json
11356 static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
11357 "iter_impl only accepts (const) basic_json");
11358
11359 public:
11360
11366 using iterator_category = std::bidirectional_iterator_tag;
11367
11369 using value_type = typename BasicJsonType::value_type;
11371 using difference_type = typename BasicJsonType::difference_type;
11373 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
11374 typename BasicJsonType::const_pointer,
11375 typename BasicJsonType::pointer>::type;
11377 using reference =
11378 typename std::conditional<std::is_const<BasicJsonType>::value,
11379 typename BasicJsonType::const_reference,
11380 typename BasicJsonType::reference>::type;
11381
11382 iter_impl() = default;
11383 ~iter_impl() = default;
11384 iter_impl(iter_impl&&) noexcept = default;
11385 iter_impl& operator=(iter_impl&&) noexcept = default;
11386
11393 explicit iter_impl(pointer object) noexcept : m_object(object)
11394 {
11395 JSON_ASSERT(m_object != nullptr);
11396
11397 switch (m_object->m_type)
11398 {
11399 case value_t::object:
11400 {
11401 m_it.object_iterator = typename object_t::iterator();
11402 break;
11403 }
11404
11405 case value_t::array:
11406 {
11407 m_it.array_iterator = typename array_t::iterator();
11408 break;
11409 }
11410
11411 default:
11412 {
11413 m_it.primitive_iterator = primitive_iterator_t();
11414 break;
11415 }
11416 }
11417 }
11418
11435 iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
11436 : m_object(other.m_object), m_it(other.m_it)
11437 {}
11438
11445 iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
11446 {
11447 if (&other != this)
11448 {
11449 m_object = other.m_object;
11450 m_it = other.m_it;
11451 }
11452 return *this;
11453 }
11454
11460 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
11461 : m_object(other.m_object), m_it(other.m_it)
11462 {}
11463
11470 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
11471 {
11472 m_object = other.m_object;
11473 m_it = other.m_it;
11474 return *this;
11475 }
11476
11477 JSON_PRIVATE_UNLESS_TESTED:
11482 void set_begin() noexcept
11483 {
11484 JSON_ASSERT(m_object != nullptr);
11485
11486 switch (m_object->m_type)
11487 {
11488 case value_t::object:
11489 {
11490 m_it.object_iterator = m_object->m_value.object->begin();
11491 break;
11492 }
11493
11494 case value_t::array:
11495 {
11496 m_it.array_iterator = m_object->m_value.array->begin();
11497 break;
11498 }
11499
11500 case value_t::null:
11501 {
11502 // set to end so begin()==end() is true: null is empty
11503 m_it.primitive_iterator.set_end();
11504 break;
11505 }
11506
11507 default:
11508 {
11509 m_it.primitive_iterator.set_begin();
11510 break;
11511 }
11512 }
11513 }
11514
11519 void set_end() noexcept
11520 {
11521 JSON_ASSERT(m_object != nullptr);
11522
11523 switch (m_object->m_type)
11524 {
11525 case value_t::object:
11526 {
11527 m_it.object_iterator = m_object->m_value.object->end();
11528 break;
11529 }
11530
11531 case value_t::array:
11532 {
11533 m_it.array_iterator = m_object->m_value.array->end();
11534 break;
11535 }
11536
11537 default:
11538 {
11539 m_it.primitive_iterator.set_end();
11540 break;
11541 }
11542 }
11543 }
11544
11545 public:
11550 reference operator*() const
11551 {
11552 JSON_ASSERT(m_object != nullptr);
11553
11554 switch (m_object->m_type)
11555 {
11556 case value_t::object:
11557 {
11558 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11559 return m_it.object_iterator->second;
11560 }
11561
11562 case value_t::array:
11563 {
11564 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11565 return *m_it.array_iterator;
11566 }
11567
11568 case value_t::null:
11569 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11570
11571 default:
11572 {
11573 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11574 {
11575 return *m_object;
11576 }
11577
11578 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11579 }
11580 }
11581 }
11582
11587 pointer operator->() const
11588 {
11589 JSON_ASSERT(m_object != nullptr);
11590
11591 switch (m_object->m_type)
11592 {
11593 case value_t::object:
11594 {
11595 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11596 return &(m_it.object_iterator->second);
11597 }
11598
11599 case value_t::array:
11600 {
11601 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11602 return &*m_it.array_iterator;
11603 }
11604
11605 default:
11606 {
11607 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11608 {
11609 return m_object;
11610 }
11611
11612 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11613 }
11614 }
11615 }
11616
11621 iter_impl const operator++(int) // NOLINT(readability-const-return-type)
11622 {
11623 auto result = *this;
11624 ++(*this);
11625 return result;
11626 }
11627
11632 iter_impl& operator++()
11633 {
11634 JSON_ASSERT(m_object != nullptr);
11635
11636 switch (m_object->m_type)
11637 {
11638 case value_t::object:
11639 {
11640 std::advance(m_it.object_iterator, 1);
11641 break;
11642 }
11643
11644 case value_t::array:
11645 {
11646 std::advance(m_it.array_iterator, 1);
11647 break;
11648 }
11649
11650 default:
11651 {
11652 ++m_it.primitive_iterator;
11653 break;
11654 }
11655 }
11656
11657 return *this;
11658 }
11659
11664 iter_impl const operator--(int) // NOLINT(readability-const-return-type)
11665 {
11666 auto result = *this;
11667 --(*this);
11668 return result;
11669 }
11670
11675 iter_impl& operator--()
11676 {
11677 JSON_ASSERT(m_object != nullptr);
11678
11679 switch (m_object->m_type)
11680 {
11681 case value_t::object:
11682 {
11683 std::advance(m_it.object_iterator, -1);
11684 break;
11685 }
11686
11687 case value_t::array:
11688 {
11689 std::advance(m_it.array_iterator, -1);
11690 break;
11691 }
11692
11693 default:
11694 {
11695 --m_it.primitive_iterator;
11696 break;
11697 }
11698 }
11699
11700 return *this;
11701 }
11702
11707 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 >
11708 bool operator==(const IterImpl& other) const
11709 {
11710 // if objects are not the same, the comparison is undefined
11711 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11712 {
11713 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
11714 }
11715
11716 JSON_ASSERT(m_object != nullptr);
11717
11718 switch (m_object->m_type)
11719 {
11720 case value_t::object:
11721 return (m_it.object_iterator == other.m_it.object_iterator);
11722
11723 case value_t::array:
11724 return (m_it.array_iterator == other.m_it.array_iterator);
11725
11726 default:
11727 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
11728 }
11729 }
11730
11735 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 >
11736 bool operator!=(const IterImpl& other) const
11737 {
11738 return !operator==(other);
11739 }
11740
11745 bool operator<(const iter_impl& other) const
11746 {
11747 // if objects are not the same, the comparison is undefined
11748 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11749 {
11750 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
11751 }
11752
11753 JSON_ASSERT(m_object != nullptr);
11754
11755 switch (m_object->m_type)
11756 {
11757 case value_t::object:
11758 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", *m_object));
11759
11760 case value_t::array:
11761 return (m_it.array_iterator < other.m_it.array_iterator);
11762
11763 default:
11764 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
11765 }
11766 }
11767
11772 bool operator<=(const iter_impl& other) const
11773 {
11774 return !other.operator < (*this);
11775 }
11776
11781 bool operator>(const iter_impl& other) const
11782 {
11783 return !operator<=(other);
11784 }
11785
11790 bool operator>=(const iter_impl& other) const
11791 {
11792 return !operator<(other);
11793 }
11794
11799 iter_impl& operator+=(difference_type i)
11800 {
11801 JSON_ASSERT(m_object != nullptr);
11802
11803 switch (m_object->m_type)
11804 {
11805 case value_t::object:
11806 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
11807
11808 case value_t::array:
11809 {
11810 std::advance(m_it.array_iterator, i);
11811 break;
11812 }
11813
11814 default:
11815 {
11816 m_it.primitive_iterator += i;
11817 break;
11818 }
11819 }
11820
11821 return *this;
11822 }
11823
11828 iter_impl& operator-=(difference_type i)
11829 {
11830 return operator+=(-i);
11831 }
11832
11837 iter_impl operator+(difference_type i) const
11838 {
11839 auto result = *this;
11840 result += i;
11841 return result;
11842 }
11843
11848 friend iter_impl operator+(difference_type i, const iter_impl& it)
11849 {
11850 auto result = it;
11851 result += i;
11852 return result;
11853 }
11854
11859 iter_impl operator-(difference_type i) const
11860 {
11861 auto result = *this;
11862 result -= i;
11863 return result;
11864 }
11865
11870 difference_type operator-(const iter_impl& other) const
11871 {
11872 JSON_ASSERT(m_object != nullptr);
11873
11874 switch (m_object->m_type)
11875 {
11876 case value_t::object:
11877 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
11878
11879 case value_t::array:
11880 return m_it.array_iterator - other.m_it.array_iterator;
11881
11882 default:
11883 return m_it.primitive_iterator - other.m_it.primitive_iterator;
11884 }
11885 }
11886
11891 reference operator[](difference_type n) const
11892 {
11893 JSON_ASSERT(m_object != nullptr);
11894
11895 switch (m_object->m_type)
11896 {
11897 case value_t::object:
11898 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", *m_object));
11899
11900 case value_t::array:
11901 return *std::next(m_it.array_iterator, n);
11902
11903 case value_t::null:
11904 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11905
11906 default:
11907 {
11908 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
11909 {
11910 return *m_object;
11911 }
11912
11913 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11914 }
11915 }
11916 }
11917
11922 const typename object_t::key_type& key() const
11923 {
11924 JSON_ASSERT(m_object != nullptr);
11925
11926 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
11927 {
11928 return m_it.object_iterator->first;
11929 }
11930
11931 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", *m_object));
11932 }
11933
11938 reference value() const
11939 {
11940 return operator*();
11941 }
11942
11943 JSON_PRIVATE_UNLESS_TESTED:
11945 pointer m_object = nullptr;
11947 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
11948 };
11949 } // namespace detail
11950 } // namespace nlohmann
11951
11952 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
11953
11954 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
11955
11956
11957 #include <cstddef> // ptrdiff_t
11958 #include <iterator> // reverse_iterator
11959 #include <utility> // declval
11960
11961 namespace nlohmann
11962 {
11963 namespace detail
11964 {
11966 // reverse_iterator //
11968
11987 template<typename Base>
11988 class json_reverse_iterator : public std::reverse_iterator<Base>
11989 {
11990 public:
11991 using difference_type = std::ptrdiff_t;
11993 using base_iterator = std::reverse_iterator<Base>;
11995 using reference = typename Base::reference;
11996
11998 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
11999 : base_iterator(it) {}
12000
12002 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
12003
12005 json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)
12006 {
12007 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
12008 }
12009
12011 json_reverse_iterator& operator++()
12012 {
12013 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
12014 }
12015
12017 json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)
12018 {
12019 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
12020 }
12021
12023 json_reverse_iterator& operator--()
12024 {
12025 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
12026 }
12027
12029 json_reverse_iterator& operator+=(difference_type i)
12030 {
12031 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
12032 }
12033
12035 json_reverse_iterator operator+(difference_type i) const
12036 {
12037 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
12038 }
12039
12041 json_reverse_iterator operator-(difference_type i) const
12042 {
12043 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
12044 }
12045
12047 difference_type operator-(const json_reverse_iterator& other) const
12048 {
12049 return base_iterator(*this) - base_iterator(other);
12050 }
12051
12053 reference operator[](difference_type n) const
12054 {
12055 return *(this->operator+(n));
12056 }
12057
12059 auto key() const -> decltype(std::declval<Base>().key())
12060 {
12061 auto it = --this->base();
12062 return it.key();
12063 }
12064
12066 reference value() const
12067 {
12068 auto it = --this->base();
12069 return it.operator * ();
12070 }
12071 };
12072 } // namespace detail
12073 } // namespace nlohmann
12074
12075 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12076
12077 // #include <nlohmann/detail/json_pointer.hpp>
12078
12079
12080 #include <algorithm> // all_of
12081 #include <cctype> // isdigit
12082 #include <limits> // max
12083 #include <numeric> // accumulate
12084 #include <string> // string
12085 #include <utility> // move
12086 #include <vector> // vector
12087
12088 // #include <nlohmann/detail/exceptions.hpp>
12089
12090 // #include <nlohmann/detail/macro_scope.hpp>
12091
12092 // #include <nlohmann/detail/string_escape.hpp>
12093
12094 // #include <nlohmann/detail/value_t.hpp>
12095
12096
12097 namespace nlohmann
12098 {
12099 template<typename BasicJsonType>
12100 class json_pointer
12101 {
12102 // allow basic_json to access private members
12103 NLOHMANN_BASIC_JSON_TPL_DECLARATION
12104 friend class basic_json;
12105
12106 public:
12128 explicit json_pointer(const std::string& s = "")
12129 : reference_tokens(split(s))
12130 {}
12131
12146 std::string to_string() const
12147 {
12148 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
12149 std::string{},
12150 [](const std::string & a, const std::string & b)
12151 {
12152 return a + "/" + detail::escape(b);
12153 });
12154 }
12155
12157 operator std::string() const
12158 {
12159 return to_string();
12160 }
12161
12178 json_pointer& operator/=(const json_pointer& ptr)
12179 {
12180 reference_tokens.insert(reference_tokens.end(),
12181 ptr.reference_tokens.begin(),
12182 ptr.reference_tokens.end());
12183 return *this;
12184 }
12185
12202 json_pointer& operator/=(std::string token)
12203 {
12204 push_back(std::move(token));
12205 return *this;
12206 }
12207
12224 json_pointer& operator/=(std::size_t array_idx)
12225 {
12226 return *this /= std::to_string(array_idx);
12227 }
12228
12244 friend json_pointer operator/(const json_pointer& lhs,
12245 const json_pointer& rhs)
12246 {
12247 return json_pointer(lhs) /= rhs;
12248 }
12249
12265 friend json_pointer operator/(const json_pointer& ptr, std::string token) // NOLINT(performance-unnecessary-value-param)
12266 {
12267 return json_pointer(ptr) /= std::move(token);
12268 }
12269
12285 friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
12286 {
12287 return json_pointer(ptr) /= array_idx;
12288 }
12289
12303 json_pointer parent_pointer() const
12304 {
12305 if (empty())
12306 {
12307 return *this;
12308 }
12309
12310 json_pointer res = *this;
12311 res.pop_back();
12312 return res;
12313 }
12314
12328 void pop_back()
12329 {
12330 if (JSON_HEDLEY_UNLIKELY(empty()))
12331 {
12332 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12333 }
12334
12335 reference_tokens.pop_back();
12336 }
12337
12352 const std::string& back() const
12353 {
12354 if (JSON_HEDLEY_UNLIKELY(empty()))
12355 {
12356 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12357 }
12358
12359 return reference_tokens.back();
12360 }
12361
12374 void push_back(const std::string& token)
12375 {
12376 reference_tokens.push_back(token);
12377 }
12378
12380 void push_back(std::string&& token)
12381 {
12382 reference_tokens.push_back(std::move(token));
12383 }
12384
12399 bool empty() const noexcept
12400 {
12401 return reference_tokens.empty();
12402 }
12403
12404 private:
12415 static typename BasicJsonType::size_type array_index(const std::string& s)
12416 {
12417 using size_type = typename BasicJsonType::size_type;
12418
12419 // error condition (cf. RFC 6901, Sect. 4)
12420 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
12421 {
12422 JSON_THROW(detail::parse_error::create(106, 0, "array index '" + s + "' must not begin with '0'", BasicJsonType()));
12423 }
12424
12425 // error condition (cf. RFC 6901, Sect. 4)
12426 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
12427 {
12428 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number", BasicJsonType()));
12429 }
12430
12431 std::size_t processed_chars = 0;
12432 unsigned long long res = 0; // NOLINT(runtime/int)
12433 JSON_TRY
12434 {
12435 res = std::stoull(s, &processed_chars);
12436 }
12437 JSON_CATCH(std::out_of_range&)
12438 {
12439 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12440 }
12441
12442 // check if the string was completely read
12443 if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
12444 {
12445 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12446 }
12447
12448 // only triggered on special platforms (like 32bit), see also
12449 // https://github.com/nlohmann/json/pull/2203
12450 if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
12451 {
12452 JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type", BasicJsonType())); // LCOV_EXCL_LINE
12453 }
12454
12455 return static_cast<size_type>(res);
12456 }
12457
12458 JSON_PRIVATE_UNLESS_TESTED:
12459 json_pointer top() const
12460 {
12461 if (JSON_HEDLEY_UNLIKELY(empty()))
12462 {
12463 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12464 }
12465
12466 json_pointer result = *this;
12467 result.reference_tokens = {reference_tokens[0]};
12468 return result;
12469 }
12470
12471 private:
12480 BasicJsonType& get_and_create(BasicJsonType& j) const
12481 {
12482 auto* result = &j;
12483
12484 // in case no reference tokens exist, return a reference to the JSON value
12485 // j which will be overwritten by a primitive value
12486 for (const auto& reference_token : reference_tokens)
12487 {
12488 switch (result->type())
12489 {
12490 case detail::value_t::null:
12491 {
12492 if (reference_token == "0")
12493 {
12494 // start a new array if reference token is 0
12495 result = &result->operator[](0);
12496 }
12497 else
12498 {
12499 // start a new object otherwise
12500 result = &result->operator[](reference_token);
12501 }
12502 break;
12503 }
12504
12505 case detail::value_t::object:
12506 {
12507 // create an entry in the object
12508 result = &result->operator[](reference_token);
12509 break;
12510 }
12511
12512 case detail::value_t::array:
12513 {
12514 // create an entry in the array
12515 result = &result->operator[](array_index(reference_token));
12516 break;
12517 }
12518
12519 /*
12520 The following code is only reached if there exists a reference
12521 token _and_ the current value is primitive. In this case, we have
12522 an error situation, because primitive values may only occur as
12523 single value; that is, with an empty list of reference tokens.
12524 */
12525 default:
12526 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j));
12527 }
12528 }
12529
12530 return *result;
12531 }
12532
12552 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
12553 {
12554 for (const auto& reference_token : reference_tokens)
12555 {
12556 // convert null values to arrays or objects before continuing
12557 if (ptr->is_null())
12558 {
12559 // check if reference token is a number
12560 const bool nums =
12561 std::all_of(reference_token.begin(), reference_token.end(),
12562 [](const unsigned char x)
12563 {
12564 return std::isdigit(x);
12565 });
12566
12567 // change value to array for numbers or "-" or to object otherwise
12568 *ptr = (nums || reference_token == "-")
12569 ? detail::value_t::array
12570 : detail::value_t::object;
12571 }
12572
12573 switch (ptr->type())
12574 {
12575 case detail::value_t::object:
12576 {
12577 // use unchecked object access
12578 ptr = &ptr->operator[](reference_token);
12579 break;
12580 }
12581
12582 case detail::value_t::array:
12583 {
12584 if (reference_token == "-")
12585 {
12586 // explicitly treat "-" as index beyond the end
12587 ptr = &ptr->operator[](ptr->m_value.array->size());
12588 }
12589 else
12590 {
12591 // convert array index to number; unchecked access
12592 ptr = &ptr->operator[](array_index(reference_token));
12593 }
12594 break;
12595 }
12596
12597 default:
12598 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12599 }
12600 }
12601
12602 return *ptr;
12603 }
12604
12611 BasicJsonType& get_checked(BasicJsonType* ptr) const
12612 {
12613 for (const auto& reference_token : reference_tokens)
12614 {
12615 switch (ptr->type())
12616 {
12617 case detail::value_t::object:
12618 {
12619 // note: at performs range check
12620 ptr = &ptr->at(reference_token);
12621 break;
12622 }
12623
12624 case detail::value_t::array:
12625 {
12626 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12627 {
12628 // "-" always fails the range check
12629 JSON_THROW(detail::out_of_range::create(402,
12630 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12631 ") is out of range", *ptr));
12632 }
12633
12634 // note: at performs range check
12635 ptr = &ptr->at(array_index(reference_token));
12636 break;
12637 }
12638
12639 default:
12640 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12641 }
12642 }
12643
12644 return *ptr;
12645 }
12646
12660 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
12661 {
12662 for (const auto& reference_token : reference_tokens)
12663 {
12664 switch (ptr->type())
12665 {
12666 case detail::value_t::object:
12667 {
12668 // use unchecked object access
12669 ptr = &ptr->operator[](reference_token);
12670 break;
12671 }
12672
12673 case detail::value_t::array:
12674 {
12675 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12676 {
12677 // "-" cannot be used for const access
12678 JSON_THROW(detail::out_of_range::create(402, "array index '-' (" + std::to_string(ptr->m_value.array->size()) + ") is out of range", *ptr));
12679 }
12680
12681 // use unchecked array access
12682 ptr = &ptr->operator[](array_index(reference_token));
12683 break;
12684 }
12685
12686 default:
12687 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12688 }
12689 }
12690
12691 return *ptr;
12692 }
12693
12700 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
12701 {
12702 for (const auto& reference_token : reference_tokens)
12703 {
12704 switch (ptr->type())
12705 {
12706 case detail::value_t::object:
12707 {
12708 // note: at performs range check
12709 ptr = &ptr->at(reference_token);
12710 break;
12711 }
12712
12713 case detail::value_t::array:
12714 {
12715 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12716 {
12717 // "-" always fails the range check
12718 JSON_THROW(detail::out_of_range::create(402,
12719 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12720 ") is out of range", *ptr));
12721 }
12722
12723 // note: at performs range check
12724 ptr = &ptr->at(array_index(reference_token));
12725 break;
12726 }
12727
12728 default:
12729 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12730 }
12731 }
12732
12733 return *ptr;
12734 }
12735
12740 bool contains(const BasicJsonType* ptr) const
12741 {
12742 for (const auto& reference_token : reference_tokens)
12743 {
12744 switch (ptr->type())
12745 {
12746 case detail::value_t::object:
12747 {
12748 if (!ptr->contains(reference_token))
12749 {
12750 // we did not find the key in the object
12751 return false;
12752 }
12753
12754 ptr = &ptr->operator[](reference_token);
12755 break;
12756 }
12757
12758 case detail::value_t::array:
12759 {
12760 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12761 {
12762 // "-" always fails the range check
12763 return false;
12764 }
12765 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
12766 {
12767 // invalid char
12768 return false;
12769 }
12770 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
12771 {
12772 if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
12773 {
12774 // first char should be between '1' and '9'
12775 return false;
12776 }
12777 for (std::size_t i = 1; i < reference_token.size(); i++)
12778 {
12779 if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
12780 {
12781 // other char should be between '0' and '9'
12782 return false;
12783 }
12784 }
12785 }
12786
12787 const auto idx = array_index(reference_token);
12788 if (idx >= ptr->size())
12789 {
12790 // index out of range
12791 return false;
12792 }
12793
12794 ptr = &ptr->operator[](idx);
12795 break;
12796 }
12797
12798 default:
12799 {
12800 // we do not expect primitive values if there is still a
12801 // reference token to process
12802 return false;
12803 }
12804 }
12805 }
12806
12807 // no reference token left means we found a primitive value
12808 return true;
12809 }
12810
12820 static std::vector<std::string> split(const std::string& reference_string)
12821 {
12822 std::vector<std::string> result;
12823
12824 // special case: empty reference string -> no reference tokens
12825 if (reference_string.empty())
12826 {
12827 return result;
12828 }
12829
12830 // check if nonempty reference string begins with slash
12831 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
12832 {
12833 JSON_THROW(detail::parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'", BasicJsonType()));
12834 }
12835
12836 // extract the reference tokens:
12837 // - slash: position of the last read slash (or end of string)
12838 // - start: position after the previous slash
12839 for (
12840 // search for the first slash after the first character
12841 std::size_t slash = reference_string.find_first_of('/', 1),
12842 // set the beginning of the first reference token
12843 start = 1;
12844 // we can stop if start == 0 (if slash == std::string::npos)
12845 start != 0;
12846 // set the beginning of the next reference token
12847 // (will eventually be 0 if slash == std::string::npos)
12848 start = (slash == std::string::npos) ? 0 : slash + 1,
12849 // find next slash
12850 slash = reference_string.find_first_of('/', start))
12851 {
12852 // use the text between the beginning of the reference token
12853 // (start) and the last slash (slash).
12854 auto reference_token = reference_string.substr(start, slash - start);
12855
12856 // check reference tokens are properly escaped
12857 for (std::size_t pos = reference_token.find_first_of('~');
12858 pos != std::string::npos;
12859 pos = reference_token.find_first_of('~', pos + 1))
12860 {
12861 JSON_ASSERT(reference_token[pos] == '~');
12862
12863 // ~ must be followed by 0 or 1
12864 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
12865 (reference_token[pos + 1] != '0' &&
12866 reference_token[pos + 1] != '1')))
12867 {
12868 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", BasicJsonType()));
12869 }
12870 }
12871
12872 // finally, store the reference token
12873 detail::unescape(reference_token);
12874 result.push_back(reference_token);
12875 }
12876
12877 return result;
12878 }
12879
12880 private:
12888 static void flatten(const std::string& reference_string,
12889 const BasicJsonType& value,
12890 BasicJsonType& result)
12891 {
12892 switch (value.type())
12893 {
12894 case detail::value_t::array:
12895 {
12896 if (value.m_value.array->empty())
12897 {
12898 // flatten empty array as null
12899 result[reference_string] = nullptr;
12900 }
12901 else
12902 {
12903 // iterate array and use index as reference string
12904 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
12905 {
12906 flatten(reference_string + "/" + std::to_string(i),
12907 value.m_value.array->operator[](i), result);
12908 }
12909 }
12910 break;
12911 }
12912
12913 case detail::value_t::object:
12914 {
12915 if (value.m_value.object->empty())
12916 {
12917 // flatten empty object as null
12918 result[reference_string] = nullptr;
12919 }
12920 else
12921 {
12922 // iterate object and use keys as reference string
12923 for (const auto& element : *value.m_value.object)
12924 {
12925 flatten(reference_string + "/" + detail::escape(element.first), element.second, result);
12926 }
12927 }
12928 break;
12929 }
12930
12931 default:
12932 {
12933 // add primitive value with its reference string
12934 result[reference_string] = value;
12935 break;
12936 }
12937 }
12938 }
12939
12950 static BasicJsonType
12951 unflatten(const BasicJsonType& value)
12952 {
12953 if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
12954 {
12955 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", value));
12956 }
12957
12958 BasicJsonType result;
12959
12960 // iterate the JSON object values
12961 for (const auto& element : *value.m_value.object)
12962 {
12963 if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
12964 {
12965 JSON_THROW(detail::type_error::create(315, "values in object must be primitive", element.second));
12966 }
12967
12968 // assign value to reference pointed to by JSON pointer; Note that if
12969 // the JSON pointer is "" (i.e., points to the whole value), function
12970 // get_and_create returns a reference to result itself. An assignment
12971 // will then create a primitive value.
12972 json_pointer(element.first).get_and_create(result) = element.second;
12973 }
12974
12975 return result;
12976 }
12977
12989 friend bool operator==(json_pointer const& lhs,
12990 json_pointer const& rhs) noexcept
12991 {
12992 return lhs.reference_tokens == rhs.reference_tokens;
12993 }
12994
13006 friend bool operator!=(json_pointer const& lhs,
13007 json_pointer const& rhs) noexcept
13008 {
13009 return !(lhs == rhs);
13010 }
13011
13013 std::vector<std::string> reference_tokens;
13014 };
13015 } // namespace nlohmann
13016
13017 // #include <nlohmann/detail/json_ref.hpp>
13018
13019
13020 #include <initializer_list>
13021 #include <utility>
13022
13023 // #include <nlohmann/detail/meta/type_traits.hpp>
13024
13025
13026 namespace nlohmann
13027 {
13028 namespace detail
13029 {
13030 template<typename BasicJsonType>
13031 class json_ref
13032 {
13033 public:
13034 using value_type = BasicJsonType;
13035
13036 json_ref(value_type&& value)
13037 : owned_value(std::move(value))
13038 {}
13039
13040 json_ref(const value_type& value)
13041 : value_ref(&value)
13042 {}
13043
13044 json_ref(std::initializer_list<json_ref> init)
13045 : owned_value(init)
13046 {}
13047
13048 template <
13049 class... Args,
13050 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
13051 json_ref(Args && ... args)
13052 : owned_value(std::forward<Args>(args)...)
13053 {}
13054
13055 // class should be movable only
13056 json_ref(json_ref&&) noexcept = default;
13057 json_ref(const json_ref&) = delete;
13058 json_ref& operator=(const json_ref&) = delete;
13059 json_ref& operator=(json_ref&&) = delete;
13060 ~json_ref() = default;
13061
13062 value_type moved_or_copied() const
13063 {
13064 if (value_ref == nullptr)
13065 {
13066 return std::move(owned_value);
13067 }
13068 return *value_ref;
13069 }
13070
13071 value_type const& operator*() const
13072 {
13073 return value_ref ? *value_ref : owned_value;
13074 }
13075
13076 value_type const* operator->() const
13077 {
13078 return &** this;
13079 }
13080
13081 private:
13082 mutable value_type owned_value = nullptr;
13083 value_type const* value_ref = nullptr;
13084 };
13085 } // namespace detail
13086 } // namespace nlohmann
13087
13088 // #include <nlohmann/detail/macro_scope.hpp>
13089
13090 // #include <nlohmann/detail/string_escape.hpp>
13091
13092 // #include <nlohmann/detail/meta/cpp_future.hpp>
13093
13094 // #include <nlohmann/detail/meta/type_traits.hpp>
13095
13096 // #include <nlohmann/detail/output/binary_writer.hpp>
13097
13098
13099 #include <algorithm> // reverse
13100 #include <array> // array
13101 #include <cmath> // isnan, isinf
13102 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
13103 #include <cstring> // memcpy
13104 #include <limits> // numeric_limits
13105 #include <string> // string
13106 #include <utility> // move
13107
13108 // #include <nlohmann/detail/input/binary_reader.hpp>
13109
13110 // #include <nlohmann/detail/macro_scope.hpp>
13111
13112 // #include <nlohmann/detail/output/output_adapters.hpp>
13113
13114
13115 #include <algorithm> // copy
13116 #include <cstddef> // size_t
13117 #include <ios> // streamsize
13118 #include <iterator> // back_inserter
13119 #include <memory> // shared_ptr, make_shared
13120 #include <ostream> // basic_ostream
13121 #include <string> // basic_string
13122 #include <vector> // vector
13123 // #include <nlohmann/detail/macro_scope.hpp>
13124
13125
13126 namespace nlohmann
13127 {
13128 namespace detail
13129 {
13131 template<typename CharType> struct output_adapter_protocol
13132 {
13133 virtual void write_character(CharType c) = 0;
13134 virtual void write_characters(const CharType* s, std::size_t length) = 0;
13135 virtual ~output_adapter_protocol() = default;
13136
13137 output_adapter_protocol() = default;
13138 output_adapter_protocol(const output_adapter_protocol&) = default;
13139 output_adapter_protocol(output_adapter_protocol&&) noexcept = default;
13140 output_adapter_protocol& operator=(const output_adapter_protocol&) = default;
13141 output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
13142 };
13143
13145 template<typename CharType>
13146 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
13147
13149 template<typename CharType>
13150 class output_vector_adapter : public output_adapter_protocol<CharType>
13151 {
13152 public:
13153 explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
13154 : v(vec)
13155 {}
13156
13157 void write_character(CharType c) override
13158 {
13159 v.push_back(c);
13160 }
13161
13162 JSON_HEDLEY_NON_NULL(2)
13163 void write_characters(const CharType* s, std::size_t length) override
13164 {
13165 std::copy(s, s + length, std::back_inserter(v));
13166 }
13167
13168 private:
13169 std::vector<CharType>& v;
13170 };
13171
13173 template<typename CharType>
13174 class output_stream_adapter : public output_adapter_protocol<CharType>
13175 {
13176 public:
13177 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
13178 : stream(s)
13179 {}
13180
13181 void write_character(CharType c) override
13182 {
13183 stream.put(c);
13184 }
13185
13186 JSON_HEDLEY_NON_NULL(2)
13187 void write_characters(const CharType* s, std::size_t length) override
13188 {
13189 stream.write(s, static_cast<std::streamsize>(length));
13190 }
13191
13192 private:
13193 std::basic_ostream<CharType>& stream;
13194 };
13195
13197 template<typename CharType, typename StringType = std::basic_string<CharType>>
13198 class output_string_adapter : public output_adapter_protocol<CharType>
13199 {
13200 public:
13201 explicit output_string_adapter(StringType& s) noexcept
13202 : str(s)
13203 {}
13204
13205 void write_character(CharType c) override
13206 {
13207 str.push_back(c);
13208 }
13209
13210 JSON_HEDLEY_NON_NULL(2)
13211 void write_characters(const CharType* s, std::size_t length) override
13212 {
13213 str.append(s, length);
13214 }
13215
13216 private:
13217 StringType& str;
13218 };
13219
13220 template<typename CharType, typename StringType = std::basic_string<CharType>>
13221 class output_adapter
13222 {
13223 public:
13224 output_adapter(std::vector<CharType>& vec)
13225 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
13226
13227 output_adapter(std::basic_ostream<CharType>& s)
13228 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
13229
13230 output_adapter(StringType& s)
13231 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
13232
13233 operator output_adapter_t<CharType>()
13234 {
13235 return oa;
13236 }
13237
13238 private:
13239 output_adapter_t<CharType> oa = nullptr;
13240 };
13241 } // namespace detail
13242 } // namespace nlohmann
13243
13244
13245 namespace nlohmann
13246 {
13247 namespace detail
13248 {
13250 // binary writer //
13252
13256 template<typename BasicJsonType, typename CharType>
13257 class binary_writer
13258 {
13259 using string_t = typename BasicJsonType::string_t;
13260 using binary_t = typename BasicJsonType::binary_t;
13261 using number_float_t = typename BasicJsonType::number_float_t;
13262
13263 public:
13269 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
13270 {
13271 JSON_ASSERT(oa);
13272 }
13273
13278 void write_bson(const BasicJsonType& j)
13279 {
13280 switch (j.type())
13281 {
13282 case value_t::object:
13283 {
13284 write_bson_object(*j.m_value.object);
13285 break;
13286 }
13287
13288 default:
13289 {
13290 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));;
13291 }
13292 }
13293 }
13294
13298 void write_cbor(const BasicJsonType& j)
13299 {
13300 switch (j.type())
13301 {
13302 case value_t::null:
13303 {
13304 oa->write_character(to_char_type(0xF6));
13305 break;
13306 }
13307
13308 case value_t::boolean:
13309 {
13310 oa->write_character(j.m_value.boolean
13311 ? to_char_type(0xF5)
13312 : to_char_type(0xF4));
13313 break;
13314 }
13315
13316 case value_t::number_integer:
13317 {
13318 if (j.m_value.number_integer >= 0)
13319 {
13320 // CBOR does not differentiate between positive signed
13321 // integers and unsigned integers. Therefore, we used the
13322 // code from the value_t::number_unsigned case here.
13323 if (j.m_value.number_integer <= 0x17)
13324 {
13325 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13326 }
13327 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
13328 {
13329 oa->write_character(to_char_type(0x18));
13330 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13331 }
13332 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
13333 {
13334 oa->write_character(to_char_type(0x19));
13335 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13336 }
13337 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
13338 {
13339 oa->write_character(to_char_type(0x1A));
13340 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13341 }
13342 else
13343 {
13344 oa->write_character(to_char_type(0x1B));
13345 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13346 }
13347 }
13348 else
13349 {
13350 // The conversions below encode the sign in the first
13351 // byte, and the value is converted to a positive number.
13352 const auto positive_number = -1 - j.m_value.number_integer;
13353 if (j.m_value.number_integer >= -24)
13354 {
13355 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
13356 }
13357 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
13358 {
13359 oa->write_character(to_char_type(0x38));
13360 write_number(static_cast<std::uint8_t>(positive_number));
13361 }
13362 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
13363 {
13364 oa->write_character(to_char_type(0x39));
13365 write_number(static_cast<std::uint16_t>(positive_number));
13366 }
13367 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
13368 {
13369 oa->write_character(to_char_type(0x3A));
13370 write_number(static_cast<std::uint32_t>(positive_number));
13371 }
13372 else
13373 {
13374 oa->write_character(to_char_type(0x3B));
13375 write_number(static_cast<std::uint64_t>(positive_number));
13376 }
13377 }
13378 break;
13379 }
13380
13381 case value_t::number_unsigned:
13382 {
13383 if (j.m_value.number_unsigned <= 0x17)
13384 {
13385 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13386 }
13387 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13388 {
13389 oa->write_character(to_char_type(0x18));
13390 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13391 }
13392 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13393 {
13394 oa->write_character(to_char_type(0x19));
13395 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
13396 }
13397 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13398 {
13399 oa->write_character(to_char_type(0x1A));
13400 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
13401 }
13402 else
13403 {
13404 oa->write_character(to_char_type(0x1B));
13405 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
13406 }
13407 break;
13408 }
13409
13410 case value_t::number_float:
13411 {
13412 if (std::isnan(j.m_value.number_float))
13413 {
13414 // NaN is 0xf97e00 in CBOR
13415 oa->write_character(to_char_type(0xF9));
13416 oa->write_character(to_char_type(0x7E));
13417 oa->write_character(to_char_type(0x00));
13418 }
13419 else if (std::isinf(j.m_value.number_float))
13420 {
13421 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
13422 oa->write_character(to_char_type(0xf9));
13423 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
13424 oa->write_character(to_char_type(0x00));
13425 }
13426 else
13427 {
13428 write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
13429 }
13430 break;
13431 }
13432
13433 case value_t::string:
13434 {
13435 // step 1: write control byte and the string length
13436 const auto N = j.m_value.string->size();
13437 if (N <= 0x17)
13438 {
13439 write_number(static_cast<std::uint8_t>(0x60 + N));
13440 }
13441 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13442 {
13443 oa->write_character(to_char_type(0x78));
13444 write_number(static_cast<std::uint8_t>(N));
13445 }
13446 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13447 {
13448 oa->write_character(to_char_type(0x79));
13449 write_number(static_cast<std::uint16_t>(N));
13450 }
13451 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13452 {
13453 oa->write_character(to_char_type(0x7A));
13454 write_number(static_cast<std::uint32_t>(N));
13455 }
13456 // LCOV_EXCL_START
13457 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13458 {
13459 oa->write_character(to_char_type(0x7B));
13460 write_number(static_cast<std::uint64_t>(N));
13461 }
13462 // LCOV_EXCL_STOP
13463
13464 // step 2: write the string
13465 oa->write_characters(
13466 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13467 j.m_value.string->size());
13468 break;
13469 }
13470
13471 case value_t::array:
13472 {
13473 // step 1: write control byte and the array size
13474 const auto N = j.m_value.array->size();
13475 if (N <= 0x17)
13476 {
13477 write_number(static_cast<std::uint8_t>(0x80 + N));
13478 }
13479 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13480 {
13481 oa->write_character(to_char_type(0x98));
13482 write_number(static_cast<std::uint8_t>(N));
13483 }
13484 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13485 {
13486 oa->write_character(to_char_type(0x99));
13487 write_number(static_cast<std::uint16_t>(N));
13488 }
13489 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13490 {
13491 oa->write_character(to_char_type(0x9A));
13492 write_number(static_cast<std::uint32_t>(N));
13493 }
13494 // LCOV_EXCL_START
13495 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13496 {
13497 oa->write_character(to_char_type(0x9B));
13498 write_number(static_cast<std::uint64_t>(N));
13499 }
13500 // LCOV_EXCL_STOP
13501
13502 // step 2: write each element
13503 for (const auto& el : *j.m_value.array)
13504 {
13505 write_cbor(el);
13506 }
13507 break;
13508 }
13509
13510 case value_t::binary:
13511 {
13512 if (j.m_value.binary->has_subtype())
13513 {
13514 write_number(static_cast<std::uint8_t>(0xd8));
13515 write_number(j.m_value.binary->subtype());
13516 }
13517
13518 // step 1: write control byte and the binary array size
13519 const auto N = j.m_value.binary->size();
13520 if (N <= 0x17)
13521 {
13522 write_number(static_cast<std::uint8_t>(0x40 + N));
13523 }
13524 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13525 {
13526 oa->write_character(to_char_type(0x58));
13527 write_number(static_cast<std::uint8_t>(N));
13528 }
13529 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13530 {
13531 oa->write_character(to_char_type(0x59));
13532 write_number(static_cast<std::uint16_t>(N));
13533 }
13534 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13535 {
13536 oa->write_character(to_char_type(0x5A));
13537 write_number(static_cast<std::uint32_t>(N));
13538 }
13539 // LCOV_EXCL_START
13540 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13541 {
13542 oa->write_character(to_char_type(0x5B));
13543 write_number(static_cast<std::uint64_t>(N));
13544 }
13545 // LCOV_EXCL_STOP
13546
13547 // step 2: write each element
13548 oa->write_characters(
13549 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13550 N);
13551
13552 break;
13553 }
13554
13555 case value_t::object:
13556 {
13557 // step 1: write control byte and the object size
13558 const auto N = j.m_value.object->size();
13559 if (N <= 0x17)
13560 {
13561 write_number(static_cast<std::uint8_t>(0xA0 + N));
13562 }
13563 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13564 {
13565 oa->write_character(to_char_type(0xB8));
13566 write_number(static_cast<std::uint8_t>(N));
13567 }
13568 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13569 {
13570 oa->write_character(to_char_type(0xB9));
13571 write_number(static_cast<std::uint16_t>(N));
13572 }
13573 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13574 {
13575 oa->write_character(to_char_type(0xBA));
13576 write_number(static_cast<std::uint32_t>(N));
13577 }
13578 // LCOV_EXCL_START
13579 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13580 {
13581 oa->write_character(to_char_type(0xBB));
13582 write_number(static_cast<std::uint64_t>(N));
13583 }
13584 // LCOV_EXCL_STOP
13585
13586 // step 2: write each element
13587 for (const auto& el : *j.m_value.object)
13588 {
13589 write_cbor(el.first);
13590 write_cbor(el.second);
13591 }
13592 break;
13593 }
13594
13595 default:
13596 break;
13597 }
13598 }
13599
13603 void write_msgpack(const BasicJsonType& j)
13604 {
13605 switch (j.type())
13606 {
13607 case value_t::null: // nil
13608 {
13609 oa->write_character(to_char_type(0xC0));
13610 break;
13611 }
13612
13613 case value_t::boolean: // true and false
13614 {
13615 oa->write_character(j.m_value.boolean
13616 ? to_char_type(0xC3)
13617 : to_char_type(0xC2));
13618 break;
13619 }
13620
13621 case value_t::number_integer:
13622 {
13623 if (j.m_value.number_integer >= 0)
13624 {
13625 // MessagePack does not differentiate between positive
13626 // signed integers and unsigned integers. Therefore, we used
13627 // the code from the value_t::number_unsigned case here.
13628 if (j.m_value.number_unsigned < 128)
13629 {
13630 // positive fixnum
13631 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13632 }
13633 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13634 {
13635 // uint 8
13636 oa->write_character(to_char_type(0xCC));
13637 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13638 }
13639 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13640 {
13641 // uint 16
13642 oa->write_character(to_char_type(0xCD));
13643 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13644 }
13645 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13646 {
13647 // uint 32
13648 oa->write_character(to_char_type(0xCE));
13649 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13650 }
13651 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
13652 {
13653 // uint 64
13654 oa->write_character(to_char_type(0xCF));
13655 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13656 }
13657 }
13658 else
13659 {
13660 if (j.m_value.number_integer >= -32)
13661 {
13662 // negative fixnum
13663 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
13664 }
13665 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
13666 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
13667 {
13668 // int 8
13669 oa->write_character(to_char_type(0xD0));
13670 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
13671 }
13672 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
13673 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
13674 {
13675 // int 16
13676 oa->write_character(to_char_type(0xD1));
13677 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
13678 }
13679 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
13680 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
13681 {
13682 // int 32
13683 oa->write_character(to_char_type(0xD2));
13684 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
13685 }
13686 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
13687 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
13688 {
13689 // int 64
13690 oa->write_character(to_char_type(0xD3));
13691 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
13692 }
13693 }
13694 break;
13695 }
13696
13697 case value_t::number_unsigned:
13698 {
13699 if (j.m_value.number_unsigned < 128)
13700 {
13701 // positive fixnum
13702 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13703 }
13704 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13705 {
13706 // uint 8
13707 oa->write_character(to_char_type(0xCC));
13708 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13709 }
13710 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13711 {
13712 // uint 16
13713 oa->write_character(to_char_type(0xCD));
13714 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13715 }
13716 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13717 {
13718 // uint 32
13719 oa->write_character(to_char_type(0xCE));
13720 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13721 }
13722 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
13723 {
13724 // uint 64
13725 oa->write_character(to_char_type(0xCF));
13726 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13727 }
13728 break;
13729 }
13730
13731 case value_t::number_float:
13732 {
13733 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
13734 break;
13735 }
13736
13737 case value_t::string:
13738 {
13739 // step 1: write control byte and the string length
13740 const auto N = j.m_value.string->size();
13741 if (N <= 31)
13742 {
13743 // fixstr
13744 write_number(static_cast<std::uint8_t>(0xA0 | N));
13745 }
13746 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13747 {
13748 // str 8
13749 oa->write_character(to_char_type(0xD9));
13750 write_number(static_cast<std::uint8_t>(N));
13751 }
13752 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13753 {
13754 // str 16
13755 oa->write_character(to_char_type(0xDA));
13756 write_number(static_cast<std::uint16_t>(N));
13757 }
13758 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13759 {
13760 // str 32
13761 oa->write_character(to_char_type(0xDB));
13762 write_number(static_cast<std::uint32_t>(N));
13763 }
13764
13765 // step 2: write the string
13766 oa->write_characters(
13767 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13768 j.m_value.string->size());
13769 break;
13770 }
13771
13772 case value_t::array:
13773 {
13774 // step 1: write control byte and the array size
13775 const auto N = j.m_value.array->size();
13776 if (N <= 15)
13777 {
13778 // fixarray
13779 write_number(static_cast<std::uint8_t>(0x90 | N));
13780 }
13781 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13782 {
13783 // array 16
13784 oa->write_character(to_char_type(0xDC));
13785 write_number(static_cast<std::uint16_t>(N));
13786 }
13787 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13788 {
13789 // array 32
13790 oa->write_character(to_char_type(0xDD));
13791 write_number(static_cast<std::uint32_t>(N));
13792 }
13793
13794 // step 2: write each element
13795 for (const auto& el : *j.m_value.array)
13796 {
13797 write_msgpack(el);
13798 }
13799 break;
13800 }
13801
13802 case value_t::binary:
13803 {
13804 // step 0: determine if the binary type has a set subtype to
13805 // determine whether or not to use the ext or fixext types
13806 const bool use_ext = j.m_value.binary->has_subtype();
13807
13808 // step 1: write control byte and the byte string length
13809 const auto N = j.m_value.binary->size();
13810 if (N <= (std::numeric_limits<std::uint8_t>::max)())
13811 {
13812 std::uint8_t output_type{};
13813 bool fixed = true;
13814 if (use_ext)
13815 {
13816 switch (N)
13817 {
13818 case 1:
13819 output_type = 0xD4; // fixext 1
13820 break;
13821 case 2:
13822 output_type = 0xD5; // fixext 2
13823 break;
13824 case 4:
13825 output_type = 0xD6; // fixext 4
13826 break;
13827 case 8:
13828 output_type = 0xD7; // fixext 8
13829 break;
13830 case 16:
13831 output_type = 0xD8; // fixext 16
13832 break;
13833 default:
13834 output_type = 0xC7; // ext 8
13835 fixed = false;
13836 break;
13837 }
13838
13839 }
13840 else
13841 {
13842 output_type = 0xC4; // bin 8
13843 fixed = false;
13844 }
13845
13846 oa->write_character(to_char_type(output_type));
13847 if (!fixed)
13848 {
13849 write_number(static_cast<std::uint8_t>(N));
13850 }
13851 }
13852 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13853 {
13854 std::uint8_t output_type = use_ext
13855 ? 0xC8 // ext 16
13856 : 0xC5; // bin 16
13857
13858 oa->write_character(to_char_type(output_type));
13859 write_number(static_cast<std::uint16_t>(N));
13860 }
13861 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13862 {
13863 std::uint8_t output_type = use_ext
13864 ? 0xC9 // ext 32
13865 : 0xC6; // bin 32
13866
13867 oa->write_character(to_char_type(output_type));
13868 write_number(static_cast<std::uint32_t>(N));
13869 }
13870
13871 // step 1.5: if this is an ext type, write the subtype
13872 if (use_ext)
13873 {
13874 write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
13875 }
13876
13877 // step 2: write the byte string
13878 oa->write_characters(
13879 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13880 N);
13881
13882 break;
13883 }
13884
13885 case value_t::object:
13886 {
13887 // step 1: write control byte and the object size
13888 const auto N = j.m_value.object->size();
13889 if (N <= 15)
13890 {
13891 // fixmap
13892 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
13893 }
13894 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13895 {
13896 // map 16
13897 oa->write_character(to_char_type(0xDE));
13898 write_number(static_cast<std::uint16_t>(N));
13899 }
13900 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13901 {
13902 // map 32
13903 oa->write_character(to_char_type(0xDF));
13904 write_number(static_cast<std::uint32_t>(N));
13905 }
13906
13907 // step 2: write each element
13908 for (const auto& el : *j.m_value.object)
13909 {
13910 write_msgpack(el.first);
13911 write_msgpack(el.second);
13912 }
13913 break;
13914 }
13915
13916 default:
13917 break;
13918 }
13919 }
13920
13927 void write_ubjson(const BasicJsonType& j, const bool use_count,
13928 const bool use_type, const bool add_prefix = true)
13929 {
13930 switch (j.type())
13931 {
13932 case value_t::null:
13933 {
13934 if (add_prefix)
13935 {
13936 oa->write_character(to_char_type('Z'));
13937 }
13938 break;
13939 }
13940
13941 case value_t::boolean:
13942 {
13943 if (add_prefix)
13944 {
13945 oa->write_character(j.m_value.boolean
13946 ? to_char_type('T')
13947 : to_char_type('F'));
13948 }
13949 break;
13950 }
13951
13952 case value_t::number_integer:
13953 {
13954 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
13955 break;
13956 }
13957
13958 case value_t::number_unsigned:
13959 {
13960 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
13961 break;
13962 }
13963
13964 case value_t::number_float:
13965 {
13966 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
13967 break;
13968 }
13969
13970 case value_t::string:
13971 {
13972 if (add_prefix)
13973 {
13974 oa->write_character(to_char_type('S'));
13975 }
13976 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
13977 oa->write_characters(
13978 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13979 j.m_value.string->size());
13980 break;
13981 }
13982
13983 case value_t::array:
13984 {
13985 if (add_prefix)
13986 {
13987 oa->write_character(to_char_type('['));
13988 }
13989
13990 bool prefix_required = true;
13991 if (use_type && !j.m_value.array->empty())
13992 {
13993 JSON_ASSERT(use_count);
13994 const CharType first_prefix = ubjson_prefix(j.front());
13995 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
13996 [this, first_prefix](const BasicJsonType & v)
13997 {
13998 return ubjson_prefix(v) == first_prefix;
13999 });
14000
14001 if (same_prefix)
14002 {
14003 prefix_required = false;
14004 oa->write_character(to_char_type('$'));
14005 oa->write_character(first_prefix);
14006 }
14007 }
14008
14009 if (use_count)
14010 {
14011 oa->write_character(to_char_type('#'));
14012 write_number_with_ubjson_prefix(j.m_value.array->size(), true);
14013 }
14014
14015 for (const auto& el : *j.m_value.array)
14016 {
14017 write_ubjson(el, use_count, use_type, prefix_required);
14018 }
14019
14020 if (!use_count)
14021 {
14022 oa->write_character(to_char_type(']'));
14023 }
14024
14025 break;
14026 }
14027
14028 case value_t::binary:
14029 {
14030 if (add_prefix)
14031 {
14032 oa->write_character(to_char_type('['));
14033 }
14034
14035 if (use_type && !j.m_value.binary->empty())
14036 {
14037 JSON_ASSERT(use_count);
14038 oa->write_character(to_char_type('$'));
14039 oa->write_character('U');
14040 }
14041
14042 if (use_count)
14043 {
14044 oa->write_character(to_char_type('#'));
14045 write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
14046 }
14047
14048 if (use_type)
14049 {
14050 oa->write_characters(
14051 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14052 j.m_value.binary->size());
14053 }
14054 else
14055 {
14056 for (size_t i = 0; i < j.m_value.binary->size(); ++i)
14057 {
14058 oa->write_character(to_char_type('U'));
14059 oa->write_character(j.m_value.binary->data()[i]);
14060 }
14061 }
14062
14063 if (!use_count)
14064 {
14065 oa->write_character(to_char_type(']'));
14066 }
14067
14068 break;
14069 }
14070
14071 case value_t::object:
14072 {
14073 if (add_prefix)
14074 {
14075 oa->write_character(to_char_type('{'));
14076 }
14077
14078 bool prefix_required = true;
14079 if (use_type && !j.m_value.object->empty())
14080 {
14081 JSON_ASSERT(use_count);
14082 const CharType first_prefix = ubjson_prefix(j.front());
14083 const bool same_prefix = std::all_of(j.begin(), j.end(),
14084 [this, first_prefix](const BasicJsonType & v)
14085 {
14086 return ubjson_prefix(v) == first_prefix;
14087 });
14088
14089 if (same_prefix)
14090 {
14091 prefix_required = false;
14092 oa->write_character(to_char_type('$'));
14093 oa->write_character(first_prefix);
14094 }
14095 }
14096
14097 if (use_count)
14098 {
14099 oa->write_character(to_char_type('#'));
14100 write_number_with_ubjson_prefix(j.m_value.object->size(), true);
14101 }
14102
14103 for (const auto& el : *j.m_value.object)
14104 {
14105 write_number_with_ubjson_prefix(el.first.size(), true);
14106 oa->write_characters(
14107 reinterpret_cast<const CharType*>(el.first.c_str()),
14108 el.first.size());
14109 write_ubjson(el.second, use_count, use_type, prefix_required);
14110 }
14111
14112 if (!use_count)
14113 {
14114 oa->write_character(to_char_type('}'));
14115 }
14116
14117 break;
14118 }
14119
14120 default:
14121 break;
14122 }
14123 }
14124
14125 private:
14127 // BSON //
14129
14134 static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
14135 {
14136 const auto it = name.find(static_cast<typename string_t::value_type>(0));
14137 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
14138 {
14139 JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j));
14140 }
14141
14142 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
14143 }
14144
14148 void write_bson_entry_header(const string_t& name,
14149 const std::uint8_t element_type)
14150 {
14151 oa->write_character(to_char_type(element_type)); // boolean
14152 oa->write_characters(
14153 reinterpret_cast<const CharType*>(name.c_str()),
14154 name.size() + 1u);
14155 }
14156
14160 void write_bson_boolean(const string_t& name,
14161 const bool value)
14162 {
14163 write_bson_entry_header(name, 0x08);
14164 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
14165 }
14166
14170 void write_bson_double(const string_t& name,
14171 const double value)
14172 {
14173 write_bson_entry_header(name, 0x01);
14174 write_number<double, true>(value);
14175 }
14176
14180 static std::size_t calc_bson_string_size(const string_t& value)
14181 {
14182 return sizeof(std::int32_t) + value.size() + 1ul;
14183 }
14184
14188 void write_bson_string(const string_t& name,
14189 const string_t& value)
14190 {
14191 write_bson_entry_header(name, 0x02);
14192
14193 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
14194 oa->write_characters(
14195 reinterpret_cast<const CharType*>(value.c_str()),
14196 value.size() + 1);
14197 }
14198
14202 void write_bson_null(const string_t& name)
14203 {
14204 write_bson_entry_header(name, 0x0A);
14205 }
14206
14210 static std::size_t calc_bson_integer_size(const std::int64_t value)
14211 {
14212 return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
14213 ? sizeof(std::int32_t)
14214 : sizeof(std::int64_t);
14215 }
14216
14220 void write_bson_integer(const string_t& name,
14221 const std::int64_t value)
14222 {
14223 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
14224 {
14225 write_bson_entry_header(name, 0x10); // int32
14226 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
14227 }
14228 else
14229 {
14230 write_bson_entry_header(name, 0x12); // int64
14231 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
14232 }
14233 }
14234
14238 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
14239 {
14240 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14241 ? sizeof(std::int32_t)
14242 : sizeof(std::int64_t);
14243 }
14244
14248 void write_bson_unsigned(const string_t& name,
14249 const BasicJsonType& j)
14250 {
14251 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14252 {
14253 write_bson_entry_header(name, 0x10 /* int32 */);
14254 write_number<std::int32_t, true>(static_cast<std::int32_t>(j.m_value.number_unsigned));
14255 }
14256 else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14257 {
14258 write_bson_entry_header(name, 0x12 /* int64 */);
14259 write_number<std::int64_t, true>(static_cast<std::int64_t>(j.m_value.number_unsigned));
14260 }
14261 else
14262 {
14263 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(j.m_value.number_unsigned) + " cannot be represented by BSON as it does not fit int64", j));
14264 }
14265 }
14266
14270 void write_bson_object_entry(const string_t& name,
14271 const typename BasicJsonType::object_t& value)
14272 {
14273 write_bson_entry_header(name, 0x03); // object
14274 write_bson_object(value);
14275 }
14276
14280 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
14281 {
14282 std::size_t array_index = 0ul;
14283
14284 const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
14285 {
14286 return result + calc_bson_element_size(std::to_string(array_index++), el);
14287 });
14288
14289 return sizeof(std::int32_t) + embedded_document_size + 1ul;
14290 }
14291
14295 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
14296 {
14297 return sizeof(std::int32_t) + value.size() + 1ul;
14298 }
14299
14303 void write_bson_array(const string_t& name,
14304 const typename BasicJsonType::array_t& value)
14305 {
14306 write_bson_entry_header(name, 0x04); // array
14307 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
14308
14309 std::size_t array_index = 0ul;
14310
14311 for (const auto& el : value)
14312 {
14313 write_bson_element(std::to_string(array_index++), el);
14314 }
14315
14316 oa->write_character(to_char_type(0x00));
14317 }
14318
14322 void write_bson_binary(const string_t& name,
14323 const binary_t& value)
14324 {
14325 write_bson_entry_header(name, 0x05);
14326
14327 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
14328 write_number(value.has_subtype() ? value.subtype() : std::uint8_t(0x00));
14329
14330 oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
14331 }
14332
14337 static std::size_t calc_bson_element_size(const string_t& name,
14338 const BasicJsonType& j)
14339 {
14340 const auto header_size = calc_bson_entry_header_size(name, j);
14341 switch (j.type())
14342 {
14343 case value_t::object:
14344 return header_size + calc_bson_object_size(*j.m_value.object);
14345
14346 case value_t::array:
14347 return header_size + calc_bson_array_size(*j.m_value.array);
14348
14349 case value_t::binary:
14350 return header_size + calc_bson_binary_size(*j.m_value.binary);
14351
14352 case value_t::boolean:
14353 return header_size + 1ul;
14354
14355 case value_t::number_float:
14356 return header_size + 8ul;
14357
14358 case value_t::number_integer:
14359 return header_size + calc_bson_integer_size(j.m_value.number_integer);
14360
14361 case value_t::number_unsigned:
14362 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
14363
14364 case value_t::string:
14365 return header_size + calc_bson_string_size(*j.m_value.string);
14366
14367 case value_t::null:
14368 return header_size + 0ul;
14369
14370 // LCOV_EXCL_START
14371 default:
14372 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14373 return 0ul;
14374 // LCOV_EXCL_STOP
14375 }
14376 }
14377
14384 void write_bson_element(const string_t& name,
14385 const BasicJsonType& j)
14386 {
14387 switch (j.type())
14388 {
14389 case value_t::object:
14390 return write_bson_object_entry(name, *j.m_value.object);
14391
14392 case value_t::array:
14393 return write_bson_array(name, *j.m_value.array);
14394
14395 case value_t::binary:
14396 return write_bson_binary(name, *j.m_value.binary);
14397
14398 case value_t::boolean:
14399 return write_bson_boolean(name, j.m_value.boolean);
14400
14401 case value_t::number_float:
14402 return write_bson_double(name, j.m_value.number_float);
14403
14404 case value_t::number_integer:
14405 return write_bson_integer(name, j.m_value.number_integer);
14406
14407 case value_t::number_unsigned:
14408 return write_bson_unsigned(name, j);
14409
14410 case value_t::string:
14411 return write_bson_string(name, *j.m_value.string);
14412
14413 case value_t::null:
14414 return write_bson_null(name);
14415
14416 // LCOV_EXCL_START
14417 default:
14418 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14419 return;
14420 // LCOV_EXCL_STOP
14421 }
14422 }
14423
14430 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
14431 {
14432 std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
14433 [](size_t result, const typename BasicJsonType::object_t::value_type & el)
14434 {
14435 return result += calc_bson_element_size(el.first, el.second);
14436 });
14437
14438 return sizeof(std::int32_t) + document_size + 1ul;
14439 }
14440
14445 void write_bson_object(const typename BasicJsonType::object_t& value)
14446 {
14447 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
14448
14449 for (const auto& el : value)
14450 {
14451 write_bson_element(el.first, el.second);
14452 }
14453
14454 oa->write_character(to_char_type(0x00));
14455 }
14456
14458 // CBOR //
14460
14461 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
14462 {
14463 return to_char_type(0xFA); // Single-Precision Float
14464 }
14465
14466 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
14467 {
14468 return to_char_type(0xFB); // Double-Precision Float
14469 }
14470
14472 // MsgPack //
14474
14475 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
14476 {
14477 return to_char_type(0xCA); // float 32
14478 }
14479
14480 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
14481 {
14482 return to_char_type(0xCB); // float 64
14483 }
14484
14486 // UBJSON //
14488
14489 // UBJSON: write number (floating point)
14490 template<typename NumberType, typename std::enable_if<
14491 std::is_floating_point<NumberType>::value, int>::type = 0>
14492 void write_number_with_ubjson_prefix(const NumberType n,
14493 const bool add_prefix)
14494 {
14495 if (add_prefix)
14496 {
14497 oa->write_character(get_ubjson_float_prefix(n));
14498 }
14499 write_number(n);
14500 }
14501
14502 // UBJSON: write number (unsigned integer)
14503 template<typename NumberType, typename std::enable_if<
14504 std::is_unsigned<NumberType>::value, int>::type = 0>
14505 void write_number_with_ubjson_prefix(const NumberType n,
14506 const bool add_prefix)
14507 {
14508 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14509 {
14510 if (add_prefix)
14511 {
14512 oa->write_character(to_char_type('i')); // int8
14513 }
14514 write_number(static_cast<std::uint8_t>(n));
14515 }
14516 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
14517 {
14518 if (add_prefix)
14519 {
14520 oa->write_character(to_char_type('U')); // uint8
14521 }
14522 write_number(static_cast<std::uint8_t>(n));
14523 }
14524 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14525 {
14526 if (add_prefix)
14527 {
14528 oa->write_character(to_char_type('I')); // int16
14529 }
14530 write_number(static_cast<std::int16_t>(n));
14531 }
14532 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14533 {
14534 if (add_prefix)
14535 {
14536 oa->write_character(to_char_type('l')); // int32
14537 }
14538 write_number(static_cast<std::int32_t>(n));
14539 }
14540 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14541 {
14542 if (add_prefix)
14543 {
14544 oa->write_character(to_char_type('L')); // int64
14545 }
14546 write_number(static_cast<std::int64_t>(n));
14547 }
14548 else
14549 {
14550 if (add_prefix)
14551 {
14552 oa->write_character(to_char_type('H')); // high-precision number
14553 }
14554
14555 const auto number = BasicJsonType(n).dump();
14556 write_number_with_ubjson_prefix(number.size(), true);
14557 for (std::size_t i = 0; i < number.size(); ++i)
14558 {
14559 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14560 }
14561 }
14562 }
14563
14564 // UBJSON: write number (signed integer)
14565 template < typename NumberType, typename std::enable_if <
14566 std::is_signed<NumberType>::value&&
14567 !std::is_floating_point<NumberType>::value, int >::type = 0 >
14568 void write_number_with_ubjson_prefix(const NumberType n,
14569 const bool add_prefix)
14570 {
14571 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
14572 {
14573 if (add_prefix)
14574 {
14575 oa->write_character(to_char_type('i')); // int8
14576 }
14577 write_number(static_cast<std::int8_t>(n));
14578 }
14579 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)()))
14580 {
14581 if (add_prefix)
14582 {
14583 oa->write_character(to_char_type('U')); // uint8
14584 }
14585 write_number(static_cast<std::uint8_t>(n));
14586 }
14587 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
14588 {
14589 if (add_prefix)
14590 {
14591 oa->write_character(to_char_type('I')); // int16
14592 }
14593 write_number(static_cast<std::int16_t>(n));
14594 }
14595 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
14596 {
14597 if (add_prefix)
14598 {
14599 oa->write_character(to_char_type('l')); // int32
14600 }
14601 write_number(static_cast<std::int32_t>(n));
14602 }
14603 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
14604 {
14605 if (add_prefix)
14606 {
14607 oa->write_character(to_char_type('L')); // int64
14608 }
14609 write_number(static_cast<std::int64_t>(n));
14610 }
14611 // LCOV_EXCL_START
14612 else
14613 {
14614 if (add_prefix)
14615 {
14616 oa->write_character(to_char_type('H')); // high-precision number
14617 }
14618
14619 const auto number = BasicJsonType(n).dump();
14620 write_number_with_ubjson_prefix(number.size(), true);
14621 for (std::size_t i = 0; i < number.size(); ++i)
14622 {
14623 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14624 }
14625 }
14626 // LCOV_EXCL_STOP
14627 }
14628
14632 CharType ubjson_prefix(const BasicJsonType& j) const noexcept
14633 {
14634 switch (j.type())
14635 {
14636 case value_t::null:
14637 return 'Z';
14638
14639 case value_t::boolean:
14640 return j.m_value.boolean ? 'T' : 'F';
14641
14642 case value_t::number_integer:
14643 {
14644 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)())
14645 {
14646 return 'i';
14647 }
14648 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)())
14649 {
14650 return 'U';
14651 }
14652 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)())
14653 {
14654 return 'I';
14655 }
14656 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)())
14657 {
14658 return 'l';
14659 }
14660 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)())
14661 {
14662 return 'L';
14663 }
14664 // anything else is treated as high-precision number
14665 return 'H'; // LCOV_EXCL_LINE
14666 }
14667
14668 case value_t::number_unsigned:
14669 {
14670 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14671 {
14672 return 'i';
14673 }
14674 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
14675 {
14676 return 'U';
14677 }
14678 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14679 {
14680 return 'I';
14681 }
14682 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14683 {
14684 return 'l';
14685 }
14686 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14687 {
14688 return 'L';
14689 }
14690 // anything else is treated as high-precision number
14691 return 'H'; // LCOV_EXCL_LINE
14692 }
14693
14694 case value_t::number_float:
14695 return get_ubjson_float_prefix(j.m_value.number_float);
14696
14697 case value_t::string:
14698 return 'S';
14699
14700 case value_t::array: // fallthrough
14701 case value_t::binary:
14702 return '[';
14703
14704 case value_t::object:
14705 return '{';
14706
14707 default: // discarded values
14708 return 'N';
14709 }
14710 }
14711
14712 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
14713 {
14714 return 'd'; // float 32
14715 }
14716
14717 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
14718 {
14719 return 'D'; // float 64
14720 }
14721
14723 // Utility functions //
14725
14726 /*
14727 @brief write a number to output input
14728 @param[in] n number of type @a NumberType
14729 @tparam NumberType the type of the number
14730 @tparam OutputIsLittleEndian Set to true if output data is
14731 required to be little endian
14732
14733 @note This function needs to respect the system's endianess, because bytes
14734 in CBOR, MessagePack, and UBJSON are stored in network order (big
14735 endian) and therefore need reordering on little endian systems.
14736 */
14737 template<typename NumberType, bool OutputIsLittleEndian = false>
14738 void write_number(const NumberType n)
14739 {
14740 // step 1: write number to array of length NumberType
14741 std::array<CharType, sizeof(NumberType)> vec{};
14742 std::memcpy(vec.data(), &n, sizeof(NumberType));
14743
14744 // step 2: write array to output (with possible reordering)
14745 if (is_little_endian != OutputIsLittleEndian)
14746 {
14747 // reverse byte order prior to conversion if necessary
14748 std::reverse(vec.begin(), vec.end());
14749 }
14750
14751 oa->write_characters(vec.data(), sizeof(NumberType));
14752 }
14753
14754 void write_compact_float(const number_float_t n, detail::input_format_t format)
14755 {
14756 if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
14757 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
14758 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
14759 {
14760 oa->write_character(format == detail::input_format_t::cbor
14761 ? get_cbor_float_prefix(static_cast<float>(n))
14762 : get_msgpack_float_prefix(static_cast<float>(n)));
14763 write_number(static_cast<float>(n));
14764 }
14765 else
14766 {
14767 oa->write_character(format == detail::input_format_t::cbor
14768 ? get_cbor_float_prefix(n)
14769 : get_msgpack_float_prefix(n));
14770 write_number(n);
14771 }
14772 }
14773
14774 public:
14775 // The following to_char_type functions are implement the conversion
14776 // between uint8_t and CharType. In case CharType is not unsigned,
14777 // such a conversion is required to allow values greater than 128.
14778 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
14779 template < typename C = CharType,
14780 enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
14781 static constexpr CharType to_char_type(std::uint8_t x) noexcept
14782 {
14783 return *reinterpret_cast<char*>(&x);
14784 }
14785
14786 template < typename C = CharType,
14787 enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
14788 static CharType to_char_type(std::uint8_t x) noexcept
14789 {
14790 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
14791 static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
14792 CharType result;
14793 std::memcpy(&result, &x, sizeof(x));
14794 return result;
14795 }
14796
14797 template<typename C = CharType,
14798 enable_if_t<std::is_unsigned<C>::value>* = nullptr>
14799 static constexpr CharType to_char_type(std::uint8_t x) noexcept
14800 {
14801 return x;
14802 }
14803
14804 template < typename InputCharType, typename C = CharType,
14805 enable_if_t <
14806 std::is_signed<C>::value &&
14807 std::is_signed<char>::value &&
14808 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
14809 > * = nullptr >
14810 static constexpr CharType to_char_type(InputCharType x) noexcept
14811 {
14812 return x;
14813 }
14814
14815 private:
14817 const bool is_little_endian = little_endianess();
14818
14820 output_adapter_t<CharType> oa = nullptr;
14821 };
14822 } // namespace detail
14823 } // namespace nlohmann
14824
14825 // #include <nlohmann/detail/output/output_adapters.hpp>
14826
14827 // #include <nlohmann/detail/output/serializer.hpp>
14828
14829
14830 #include <algorithm> // reverse, remove, fill, find, none_of
14831 #include <array> // array
14832 #include <clocale> // localeconv, lconv
14833 #include <cmath> // labs, isfinite, isnan, signbit
14834 #include <cstddef> // size_t, ptrdiff_t
14835 #include <cstdint> // uint8_t
14836 #include <cstdio> // snprintf
14837 #include <limits> // numeric_limits
14838 #include <string> // string, char_traits
14839 #include <type_traits> // is_same
14840 #include <utility> // move
14841
14842 // #include <nlohmann/detail/conversions/to_chars.hpp>
14843
14844
14845 #include <array> // array
14846 #include <cmath> // signbit, isfinite
14847 #include <cstdint> // intN_t, uintN_t
14848 #include <cstring> // memcpy, memmove
14849 #include <limits> // numeric_limits
14850 #include <type_traits> // conditional
14851
14852 // #include <nlohmann/detail/macro_scope.hpp>
14853
14854
14855 namespace nlohmann
14856 {
14857 namespace detail
14858 {
14859
14879 namespace dtoa_impl
14880 {
14881
14882 template<typename Target, typename Source>
14883 Target reinterpret_bits(const Source source)
14884 {
14885 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
14886
14887 Target target;
14888 std::memcpy(&target, &source, sizeof(Source));
14889 return target;
14890 }
14891
14892 struct diyfp // f * 2^e
14893 {
14894 static constexpr int kPrecision = 64; // = q
14895
14896 std::uint64_t f = 0;
14897 int e = 0;
14898
14899 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
14900
14905 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
14906 {
14907 JSON_ASSERT(x.e == y.e);
14908 JSON_ASSERT(x.f >= y.f);
14909
14910 return {x.f - y.f, x.e};
14911 }
14912
14917 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
14918 {
14919 static_assert(kPrecision == 64, "internal error");
14920
14921 // Computes:
14922 // f = round((x.f * y.f) / 2^q)
14923 // e = x.e + y.e + q
14924
14925 // Emulate the 64-bit * 64-bit multiplication:
14926 //
14927 // p = u * v
14928 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
14929 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
14930 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
14931 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
14932 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
14933 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
14934 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
14935 //
14936 // (Since Q might be larger than 2^32 - 1)
14937 //
14938 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
14939 //
14940 // (Q_hi + H does not overflow a 64-bit int)
14941 //
14942 // = p_lo + 2^64 p_hi
14943
14944 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
14945 const std::uint64_t u_hi = x.f >> 32u;
14946 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
14947 const std::uint64_t v_hi = y.f >> 32u;
14948
14949 const std::uint64_t p0 = u_lo * v_lo;
14950 const std::uint64_t p1 = u_lo * v_hi;
14951 const std::uint64_t p2 = u_hi * v_lo;
14952 const std::uint64_t p3 = u_hi * v_hi;
14953
14954 const std::uint64_t p0_hi = p0 >> 32u;
14955 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
14956 const std::uint64_t p1_hi = p1 >> 32u;
14957 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
14958 const std::uint64_t p2_hi = p2 >> 32u;
14959
14960 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
14961
14962 // The full product might now be computed as
14963 //
14964 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
14965 // p_lo = p0_lo + (Q << 32)
14966 //
14967 // But in this particular case here, the full p_lo is not required.
14968 // Effectively we only need to add the highest bit in p_lo to p_hi (and
14969 // Q_hi + 1 does not overflow).
14970
14971 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
14972
14973 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
14974
14975 return {h, x.e + y.e + 64};
14976 }
14977
14982 static diyfp normalize(diyfp x) noexcept
14983 {
14984 JSON_ASSERT(x.f != 0);
14985
14986 while ((x.f >> 63u) == 0)
14987 {
14988 x.f <<= 1u;
14989 x.e--;
14990 }
14991
14992 return x;
14993 }
14994
14999 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
15000 {
15001 const int delta = x.e - target_exponent;
15002
15003 JSON_ASSERT(delta >= 0);
15004 JSON_ASSERT(((x.f << delta) >> delta) == x.f);
15005
15006 return {x.f << delta, target_exponent};
15007 }
15008 };
15009
15010 struct boundaries
15011 {
15012 diyfp w;
15013 diyfp minus;
15014 diyfp plus;
15015 };
15016
15023 template<typename FloatType>
15024 boundaries compute_boundaries(FloatType value)
15025 {
15026 JSON_ASSERT(std::isfinite(value));
15027 JSON_ASSERT(value > 0);
15028
15029 // Convert the IEEE representation into a diyfp.
15030 //
15031 // If v is denormal:
15032 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
15033 // If v is normalized:
15034 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
15035
15036 static_assert(std::numeric_limits<FloatType>::is_iec559,
15037 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
15038
15039 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
15040 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
15041 constexpr int kMinExp = 1 - kBias;
15042 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
15043
15044 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
15045
15046 const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
15047 const std::uint64_t E = bits >> (kPrecision - 1);
15048 const std::uint64_t F = bits & (kHiddenBit - 1);
15049
15050 const bool is_denormal = E == 0;
15051 const diyfp v = is_denormal
15052 ? diyfp(F, kMinExp)
15053 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
15054
15055 // Compute the boundaries m- and m+ of the floating-point value
15056 // v = f * 2^e.
15057 //
15058 // Determine v- and v+, the floating-point predecessor and successor if v,
15059 // respectively.
15060 //
15061 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
15062 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
15063 //
15064 // v+ = v + 2^e
15065 //
15066 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
15067 // between m- and m+ round to v, regardless of how the input rounding
15068 // algorithm breaks ties.
15069 //
15070 // ---+-------------+-------------+-------------+-------------+--- (A)
15071 // v- m- v m+ v+
15072 //
15073 // -----------------+------+------+-------------+-------------+--- (B)
15074 // v- m- v m+ v+
15075
15076 const bool lower_boundary_is_closer = F == 0 && E > 1;
15077 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
15078 const diyfp m_minus = lower_boundary_is_closer
15079 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
15080 : diyfp(2 * v.f - 1, v.e - 1); // (A)
15081
15082 // Determine the normalized w+ = m+.
15083 const diyfp w_plus = diyfp::normalize(m_plus);
15084
15085 // Determine w- = m- such that e_(w-) = e_(w+).
15086 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
15087
15088 return {diyfp::normalize(v), w_minus, w_plus};
15089 }
15090
15091 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
15092 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
15093 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
15094 //
15095 // alpha <= e = e_c + e_w + q <= gamma
15096 //
15097 // or
15098 //
15099 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
15100 // <= f_c * f_w * 2^gamma
15101 //
15102 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
15103 //
15104 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
15105 //
15106 // or
15107 //
15108 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
15109 //
15110 // The choice of (alpha,gamma) determines the size of the table and the form of
15111 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
15112 // in practice:
15113 //
15114 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
15115 // processed independently: An integral part p1, and a fractional part p2:
15116 //
15117 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
15118 // = (f div 2^-e) + (f mod 2^-e) * 2^e
15119 // = p1 + p2 * 2^e
15120 //
15121 // The conversion of p1 into decimal form requires a series of divisions and
15122 // modulos by (a power of) 10. These operations are faster for 32-bit than for
15123 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
15124 // achieved by choosing
15125 //
15126 // -e >= 32 or e <= -32 := gamma
15127 //
15128 // In order to convert the fractional part
15129 //
15130 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
15131 //
15132 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
15133 // d[-i] are extracted in order:
15134 //
15135 // (10 * p2) div 2^-e = d[-1]
15136 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
15137 //
15138 // The multiplication by 10 must not overflow. It is sufficient to choose
15139 //
15140 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
15141 //
15142 // Since p2 = f mod 2^-e < 2^-e,
15143 //
15144 // -e <= 60 or e >= -60 := alpha
15145
15146 constexpr int kAlpha = -60;
15147 constexpr int kGamma = -32;
15148
15149 struct cached_power // c = f * 2^e ~= 10^k
15150 {
15151 std::uint64_t f;
15152 int e;
15153 int k;
15154 };
15155
15163 inline cached_power get_cached_power_for_binary_exponent(int e)
15164 {
15165 // Now
15166 //
15167 // alpha <= e_c + e + q <= gamma (1)
15168 // ==> f_c * 2^alpha <= c * 2^e * 2^q
15169 //
15170 // and since the c's are normalized, 2^(q-1) <= f_c,
15171 //
15172 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
15173 // ==> 2^(alpha - e - 1) <= c
15174 //
15175 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
15176 //
15177 // k = ceil( log_10( 2^(alpha - e - 1) ) )
15178 // = ceil( (alpha - e - 1) * log_10(2) )
15179 //
15180 // From the paper:
15181 // "In theory the result of the procedure could be wrong since c is rounded,
15182 // and the computation itself is approximated [...]. In practice, however,
15183 // this simple function is sufficient."
15184 //
15185 // For IEEE double precision floating-point numbers converted into
15186 // normalized diyfp's w = f * 2^e, with q = 64,
15187 //
15188 // e >= -1022 (min IEEE exponent)
15189 // -52 (p - 1)
15190 // -52 (p - 1, possibly normalize denormal IEEE numbers)
15191 // -11 (normalize the diyfp)
15192 // = -1137
15193 //
15194 // and
15195 //
15196 // e <= +1023 (max IEEE exponent)
15197 // -52 (p - 1)
15198 // -11 (normalize the diyfp)
15199 // = 960
15200 //
15201 // This binary exponent range [-1137,960] results in a decimal exponent
15202 // range [-307,324]. One does not need to store a cached power for each
15203 // k in this range. For each such k it suffices to find a cached power
15204 // such that the exponent of the product lies in [alpha,gamma].
15205 // This implies that the difference of the decimal exponents of adjacent
15206 // table entries must be less than or equal to
15207 //
15208 // floor( (gamma - alpha) * log_10(2) ) = 8.
15209 //
15210 // (A smaller distance gamma-alpha would require a larger table.)
15211
15212 // NB:
15213 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
15214
15215 constexpr int kCachedPowersMinDecExp = -300;
15216 constexpr int kCachedPowersDecStep = 8;
15217
15218 static constexpr std::array<cached_power, 79> kCachedPowers =
15219 {
15220 {
15221 { 0xAB70FE17C79AC6CA, -1060, -300 },
15222 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
15223 { 0xBE5691EF416BD60C, -1007, -284 },
15224 { 0x8DD01FAD907FFC3C, -980, -276 },
15225 { 0xD3515C2831559A83, -954, -268 },
15226 { 0x9D71AC8FADA6C9B5, -927, -260 },
15227 { 0xEA9C227723EE8BCB, -901, -252 },
15228 { 0xAECC49914078536D, -874, -244 },
15229 { 0x823C12795DB6CE57, -847, -236 },
15230 { 0xC21094364DFB5637, -821, -228 },
15231 { 0x9096EA6F3848984F, -794, -220 },
15232 { 0xD77485CB25823AC7, -768, -212 },
15233 { 0xA086CFCD97BF97F4, -741, -204 },
15234 { 0xEF340A98172AACE5, -715, -196 },
15235 { 0xB23867FB2A35B28E, -688, -188 },
15236 { 0x84C8D4DFD2C63F3B, -661, -180 },
15237 { 0xC5DD44271AD3CDBA, -635, -172 },
15238 { 0x936B9FCEBB25C996, -608, -164 },
15239 { 0xDBAC6C247D62A584, -582, -156 },
15240 { 0xA3AB66580D5FDAF6, -555, -148 },
15241 { 0xF3E2F893DEC3F126, -529, -140 },
15242 { 0xB5B5ADA8AAFF80B8, -502, -132 },
15243 { 0x87625F056C7C4A8B, -475, -124 },
15244 { 0xC9BCFF6034C13053, -449, -116 },
15245 { 0x964E858C91BA2655, -422, -108 },
15246 { 0xDFF9772470297EBD, -396, -100 },
15247 { 0xA6DFBD9FB8E5B88F, -369, -92 },
15248 { 0xF8A95FCF88747D94, -343, -84 },
15249 { 0xB94470938FA89BCF, -316, -76 },
15250 { 0x8A08F0F8BF0F156B, -289, -68 },
15251 { 0xCDB02555653131B6, -263, -60 },
15252 { 0x993FE2C6D07B7FAC, -236, -52 },
15253 { 0xE45C10C42A2B3B06, -210, -44 },
15254 { 0xAA242499697392D3, -183, -36 },
15255 { 0xFD87B5F28300CA0E, -157, -28 },
15256 { 0xBCE5086492111AEB, -130, -20 },
15257 { 0x8CBCCC096F5088CC, -103, -12 },
15258 { 0xD1B71758E219652C, -77, -4 },
15259 { 0x9C40000000000000, -50, 4 },
15260 { 0xE8D4A51000000000, -24, 12 },
15261 { 0xAD78EBC5AC620000, 3, 20 },
15262 { 0x813F3978F8940984, 30, 28 },
15263 { 0xC097CE7BC90715B3, 56, 36 },
15264 { 0x8F7E32CE7BEA5C70, 83, 44 },
15265 { 0xD5D238A4ABE98068, 109, 52 },
15266 { 0x9F4F2726179A2245, 136, 60 },
15267 { 0xED63A231D4C4FB27, 162, 68 },
15268 { 0xB0DE65388CC8ADA8, 189, 76 },
15269 { 0x83C7088E1AAB65DB, 216, 84 },
15270 { 0xC45D1DF942711D9A, 242, 92 },
15271 { 0x924D692CA61BE758, 269, 100 },
15272 { 0xDA01EE641A708DEA, 295, 108 },
15273 { 0xA26DA3999AEF774A, 322, 116 },
15274 { 0xF209787BB47D6B85, 348, 124 },
15275 { 0xB454E4A179DD1877, 375, 132 },
15276 { 0x865B86925B9BC5C2, 402, 140 },
15277 { 0xC83553C5C8965D3D, 428, 148 },
15278 { 0x952AB45CFA97A0B3, 455, 156 },
15279 { 0xDE469FBD99A05FE3, 481, 164 },
15280 { 0xA59BC234DB398C25, 508, 172 },
15281 { 0xF6C69A72A3989F5C, 534, 180 },
15282 { 0xB7DCBF5354E9BECE, 561, 188 },
15283 { 0x88FCF317F22241E2, 588, 196 },
15284 { 0xCC20CE9BD35C78A5, 614, 204 },
15285 { 0x98165AF37B2153DF, 641, 212 },
15286 { 0xE2A0B5DC971F303A, 667, 220 },
15287 { 0xA8D9D1535CE3B396, 694, 228 },
15288 { 0xFB9B7CD9A4A7443C, 720, 236 },
15289 { 0xBB764C4CA7A44410, 747, 244 },
15290 { 0x8BAB8EEFB6409C1A, 774, 252 },
15291 { 0xD01FEF10A657842C, 800, 260 },
15292 { 0x9B10A4E5E9913129, 827, 268 },
15293 { 0xE7109BFBA19C0C9D, 853, 276 },
15294 { 0xAC2820D9623BF429, 880, 284 },
15295 { 0x80444B5E7AA7CF85, 907, 292 },
15296 { 0xBF21E44003ACDD2D, 933, 300 },
15297 { 0x8E679C2F5E44FF8F, 960, 308 },
15298 { 0xD433179D9C8CB841, 986, 316 },
15299 { 0x9E19DB92B4E31BA9, 1013, 324 },
15300 }
15301 };
15302
15303 // This computation gives exactly the same results for k as
15304 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
15305 // for |e| <= 1500, but doesn't require floating-point operations.
15306 // NB: log_10(2) ~= 78913 / 2^18
15307 JSON_ASSERT(e >= -1500);
15308 JSON_ASSERT(e <= 1500);
15309 const int f = kAlpha - e - 1;
15310 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
15311
15312 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
15313 JSON_ASSERT(index >= 0);
15314 JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
15315
15316 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
15317 JSON_ASSERT(kAlpha <= cached.e + e + 64);
15318 JSON_ASSERT(kGamma >= cached.e + e + 64);
15319
15320 return cached;
15321 }
15322
15327 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
15328 {
15329 // LCOV_EXCL_START
15330 if (n >= 1000000000)
15331 {
15332 pow10 = 1000000000;
15333 return 10;
15334 }
15335 // LCOV_EXCL_STOP
15336 if (n >= 100000000)
15337 {
15338 pow10 = 100000000;
15339 return 9;
15340 }
15341 if (n >= 10000000)
15342 {
15343 pow10 = 10000000;
15344 return 8;
15345 }
15346 if (n >= 1000000)
15347 {
15348 pow10 = 1000000;
15349 return 7;
15350 }
15351 if (n >= 100000)
15352 {
15353 pow10 = 100000;
15354 return 6;
15355 }
15356 if (n >= 10000)
15357 {
15358 pow10 = 10000;
15359 return 5;
15360 }
15361 if (n >= 1000)
15362 {
15363 pow10 = 1000;
15364 return 4;
15365 }
15366 if (n >= 100)
15367 {
15368 pow10 = 100;
15369 return 3;
15370 }
15371 if (n >= 10)
15372 {
15373 pow10 = 10;
15374 return 2;
15375 }
15376
15377 pow10 = 1;
15378 return 1;
15379 }
15380
15381 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
15382 std::uint64_t rest, std::uint64_t ten_k)
15383 {
15384 JSON_ASSERT(len >= 1);
15385 JSON_ASSERT(dist <= delta);
15386 JSON_ASSERT(rest <= delta);
15387 JSON_ASSERT(ten_k > 0);
15388
15389 // <--------------------------- delta ---->
15390 // <---- dist --------->
15391 // --------------[------------------+-------------------]--------------
15392 // M- w M+
15393 //
15394 // ten_k
15395 // <------>
15396 // <---- rest ---->
15397 // --------------[------------------+----+--------------]--------------
15398 // w V
15399 // = buf * 10^k
15400 //
15401 // ten_k represents a unit-in-the-last-place in the decimal representation
15402 // stored in buf.
15403 // Decrement buf by ten_k while this takes buf closer to w.
15404
15405 // The tests are written in this order to avoid overflow in unsigned
15406 // integer arithmetic.
15407
15408 while (rest < dist
15409 && delta - rest >= ten_k
15410 && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
15411 {
15412 JSON_ASSERT(buf[len - 1] != '0');
15413 buf[len - 1]--;
15414 rest += ten_k;
15415 }
15416 }
15417
15422 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
15423 diyfp M_minus, diyfp w, diyfp M_plus)
15424 {
15425 static_assert(kAlpha >= -60, "internal error");
15426 static_assert(kGamma <= -32, "internal error");
15427
15428 // Generates the digits (and the exponent) of a decimal floating-point
15429 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
15430 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
15431 //
15432 // <--------------------------- delta ---->
15433 // <---- dist --------->
15434 // --------------[------------------+-------------------]--------------
15435 // M- w M+
15436 //
15437 // Grisu2 generates the digits of M+ from left to right and stops as soon as
15438 // V is in [M-,M+].
15439
15440 JSON_ASSERT(M_plus.e >= kAlpha);
15441 JSON_ASSERT(M_plus.e <= kGamma);
15442
15443 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
15444 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
15445
15446 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
15447 //
15448 // M+ = f * 2^e
15449 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
15450 // = ((p1 ) * 2^-e + (p2 )) * 2^e
15451 // = p1 + p2 * 2^e
15452
15453 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
15454
15455 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.)
15456 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
15457
15458 // 1)
15459 //
15460 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
15461
15462 JSON_ASSERT(p1 > 0);
15463
15464 std::uint32_t pow10{};
15465 const int k = find_largest_pow10(p1, pow10);
15466
15467 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
15468 //
15469 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
15470 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
15471 //
15472 // M+ = p1 + p2 * 2^e
15473 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
15474 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
15475 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
15476 //
15477 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
15478 //
15479 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
15480 //
15481 // but stop as soon as
15482 //
15483 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
15484
15485 int n = k;
15486 while (n > 0)
15487 {
15488 // Invariants:
15489 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
15490 // pow10 = 10^(n-1) <= p1 < 10^n
15491 //
15492 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
15493 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
15494 //
15495 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
15496 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
15497 //
15498 JSON_ASSERT(d <= 9);
15499 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15500 //
15501 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
15502 //
15503 p1 = r;
15504 n--;
15505 //
15506 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
15507 // pow10 = 10^n
15508 //
15509
15510 // Now check if enough digits have been generated.
15511 // Compute
15512 //
15513 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
15514 //
15515 // Note:
15516 // Since rest and delta share the same exponent e, it suffices to
15517 // compare the significands.
15518 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
15519 if (rest <= delta)
15520 {
15521 // V = buffer * 10^n, with M- <= V <= M+.
15522
15523 decimal_exponent += n;
15524
15525 // We may now just stop. But instead look if the buffer could be
15526 // decremented to bring V closer to w.
15527 //
15528 // pow10 = 10^n is now 1 ulp in the decimal representation V.
15529 // The rounding procedure works with diyfp's with an implicit
15530 // exponent of e.
15531 //
15532 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
15533 //
15534 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
15535 grisu2_round(buffer, length, dist, delta, rest, ten_n);
15536
15537 return;
15538 }
15539
15540 pow10 /= 10;
15541 //
15542 // pow10 = 10^(n-1) <= p1 < 10^n
15543 // Invariants restored.
15544 }
15545
15546 // 2)
15547 //
15548 // The digits of the integral part have been generated:
15549 //
15550 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
15551 // = buffer + p2 * 2^e
15552 //
15553 // Now generate the digits of the fractional part p2 * 2^e.
15554 //
15555 // Note:
15556 // No decimal point is generated: the exponent is adjusted instead.
15557 //
15558 // p2 actually represents the fraction
15559 //
15560 // p2 * 2^e
15561 // = p2 / 2^-e
15562 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
15563 //
15564 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
15565 //
15566 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
15567 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
15568 //
15569 // using
15570 //
15571 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
15572 // = ( d) * 2^-e + ( r)
15573 //
15574 // or
15575 // 10^m * p2 * 2^e = d + r * 2^e
15576 //
15577 // i.e.
15578 //
15579 // M+ = buffer + p2 * 2^e
15580 // = buffer + 10^-m * (d + r * 2^e)
15581 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
15582 //
15583 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
15584
15585 JSON_ASSERT(p2 > delta);
15586
15587 int m = 0;
15588 for (;;)
15589 {
15590 // Invariant:
15591 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
15592 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
15593 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
15594 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
15595 //
15596 JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
15597 p2 *= 10;
15598 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
15599 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
15600 //
15601 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
15602 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
15603 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
15604 //
15605 JSON_ASSERT(d <= 9);
15606 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15607 //
15608 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
15609 //
15610 p2 = r;
15611 m++;
15612 //
15613 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
15614 // Invariant restored.
15615
15616 // Check if enough digits have been generated.
15617 //
15618 // 10^-m * p2 * 2^e <= delta * 2^e
15619 // p2 * 2^e <= 10^m * delta * 2^e
15620 // p2 <= 10^m * delta
15621 delta *= 10;
15622 dist *= 10;
15623 if (p2 <= delta)
15624 {
15625 break;
15626 }
15627 }
15628
15629 // V = buffer * 10^-m, with M- <= V <= M+.
15630
15631 decimal_exponent -= m;
15632
15633 // 1 ulp in the decimal representation is now 10^-m.
15634 // Since delta and dist are now scaled by 10^m, we need to do the
15635 // same with ulp in order to keep the units in sync.
15636 //
15637 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
15638 //
15639 const std::uint64_t ten_m = one.f;
15640 grisu2_round(buffer, length, dist, delta, p2, ten_m);
15641
15642 // By construction this algorithm generates the shortest possible decimal
15643 // number (Loitsch, Theorem 6.2) which rounds back to w.
15644 // For an input number of precision p, at least
15645 //
15646 // N = 1 + ceil(p * log_10(2))
15647 //
15648 // decimal digits are sufficient to identify all binary floating-point
15649 // numbers (Matula, "In-and-Out conversions").
15650 // This implies that the algorithm does not produce more than N decimal
15651 // digits.
15652 //
15653 // N = 17 for p = 53 (IEEE double precision)
15654 // N = 9 for p = 24 (IEEE single precision)
15655 }
15656
15662 JSON_HEDLEY_NON_NULL(1)
15663 inline void grisu2(char* buf, int& len, int& decimal_exponent,
15664 diyfp m_minus, diyfp v, diyfp m_plus)
15665 {
15666 JSON_ASSERT(m_plus.e == m_minus.e);
15667 JSON_ASSERT(m_plus.e == v.e);
15668
15669 // --------(-----------------------+-----------------------)-------- (A)
15670 // m- v m+
15671 //
15672 // --------------------(-----------+-----------------------)-------- (B)
15673 // m- v m+
15674 //
15675 // First scale v (and m- and m+) such that the exponent is in the range
15676 // [alpha, gamma].
15677
15678 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
15679
15680 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
15681
15682 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
15683 const diyfp w = diyfp::mul(v, c_minus_k);
15684 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
15685 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
15686
15687 // ----(---+---)---------------(---+---)---------------(---+---)----
15688 // w- w w+
15689 // = c*m- = c*v = c*m+
15690 //
15691 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
15692 // w+ are now off by a small amount.
15693 // In fact:
15694 //
15695 // w - v * 10^k < 1 ulp
15696 //
15697 // To account for this inaccuracy, add resp. subtract 1 ulp.
15698 //
15699 // --------+---[---------------(---+---)---------------]---+--------
15700 // w- M- w M+ w+
15701 //
15702 // Now any number in [M-, M+] (bounds included) will round to w when input,
15703 // regardless of how the input rounding algorithm breaks ties.
15704 //
15705 // And digit_gen generates the shortest possible such number in [M-, M+].
15706 // Note that this does not mean that Grisu2 always generates the shortest
15707 // possible number in the interval (m-, m+).
15708 const diyfp M_minus(w_minus.f + 1, w_minus.e);
15709 const diyfp M_plus (w_plus.f - 1, w_plus.e );
15710
15711 decimal_exponent = -cached.k; // = -(-k) = k
15712
15713 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
15714 }
15715
15721 template<typename FloatType>
15722 JSON_HEDLEY_NON_NULL(1)
15723 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
15724 {
15725 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
15726 "internal error: not enough precision");
15727
15728 JSON_ASSERT(std::isfinite(value));
15729 JSON_ASSERT(value > 0);
15730
15731 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
15732 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
15733 // decimal representations are not exactly "short".
15734 //
15735 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
15736 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
15737 // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
15738 // does.
15739 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
15740 // representation using the corresponding std::from_chars function recovers value exactly". That
15741 // indicates that single precision floating-point numbers should be recovered using
15742 // 'std::strtof'.
15743 //
15744 // NB: If the neighbors are computed for single-precision numbers, there is a single float
15745 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
15746 // value is off by 1 ulp.
15747 #if 0
15748 const boundaries w = compute_boundaries(static_cast<double>(value));
15749 #else
15750 const boundaries w = compute_boundaries(value);
15751 #endif
15752
15753 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
15754 }
15755
15761 JSON_HEDLEY_NON_NULL(1)
15762
15763 inline char* append_exponent(char* buf, int e)
15764 {
15765 JSON_ASSERT(e > -1000);
15766 JSON_ASSERT(e < 1000);
15767
15768 if (e < 0)
15769 {
15770 e = -e;
15771 *buf++ = '-';
15772 }
15773 else
15774 {
15775 *buf++ = '+';
15776 }
15777
15778 auto k = static_cast<std::uint32_t>(e);
15779 if (k < 10)
15780 {
15781 // Always print at least two digits in the exponent.
15782 // This is for compatibility with printf("%g").
15783 *buf++ = '0';
15784 *buf++ = static_cast<char>('0' + k);
15785 }
15786 else if (k < 100)
15787 {
15788 *buf++ = static_cast<char>('0' + k / 10);
15789 k %= 10;
15790 *buf++ = static_cast<char>('0' + k);
15791 }
15792 else
15793 {
15794 *buf++ = static_cast<char>('0' + k / 100);
15795 k %= 100;
15796 *buf++ = static_cast<char>('0' + k / 10);
15797 k %= 10;
15798 *buf++ = static_cast<char>('0' + k);
15799 }
15800
15801 return buf;
15802 }
15803
15813 JSON_HEDLEY_NON_NULL(1)
15814
15815 inline char* format_buffer(char* buf, int len, int decimal_exponent,
15816 int min_exp, int max_exp)
15817 {
15818 JSON_ASSERT(min_exp < 0);
15819 JSON_ASSERT(max_exp > 0);
15820
15821 const int k = len;
15822 const int n = len + decimal_exponent;
15823
15824 // v = buf * 10^(n-k)
15825 // k is the length of the buffer (number of decimal digits)
15826 // n is the position of the decimal point relative to the start of the buffer.
15827
15828 if (k <= n && n <= max_exp)
15829 {
15830 // digits[000]
15831 // len <= max_exp + 2
15832
15833 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
15834 // Make it look like a floating-point number (#362, #378)
15835 buf[n + 0] = '.';
15836 buf[n + 1] = '0';
15837 return buf + (static_cast<size_t>(n) + 2);
15838 }
15839
15840 if (0 < n && n <= max_exp)
15841 {
15842 // dig.its
15843 // len <= max_digits10 + 1
15844
15845 JSON_ASSERT(k > n);
15846
15847 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
15848 buf[n] = '.';
15849 return buf + (static_cast<size_t>(k) + 1U);
15850 }
15851
15852 if (min_exp < n && n <= 0)
15853 {
15854 // 0.[000]digits
15855 // len <= 2 + (-min_exp - 1) + max_digits10
15856
15857 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
15858 buf[0] = '0';
15859 buf[1] = '.';
15860 std::memset(buf + 2, '0', static_cast<size_t>(-n));
15861 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
15862 }
15863
15864 if (k == 1)
15865 {
15866 // dE+123
15867 // len <= 1 + 5
15868
15869 buf += 1;
15870 }
15871 else
15872 {
15873 // d.igitsE+123
15874 // len <= max_digits10 + 1 + 5
15875
15876 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
15877 buf[1] = '.';
15878 buf += 1 + static_cast<size_t>(k);
15879 }
15880
15881 *buf++ = 'e';
15882 return append_exponent(buf, n - 1);
15883 }
15884
15885 } // namespace dtoa_impl
15886
15897 template<typename FloatType>
15898 JSON_HEDLEY_NON_NULL(1, 2)
15899
15900 char* to_chars(char* first, const char* last, FloatType value)
15901 {
15902 static_cast<void>(last); // maybe unused - fix warning
15903 JSON_ASSERT(std::isfinite(value));
15904
15905 // Use signbit(value) instead of (value < 0) since signbit works for -0.
15906 if (std::signbit(value))
15907 {
15908 value = -value;
15909 *first++ = '-';
15910 }
15911
15912 if (value == 0) // +-0
15913 {
15914 *first++ = '0';
15915 // Make it look like a floating-point number (#362, #378)
15916 *first++ = '.';
15917 *first++ = '0';
15918 return first;
15919 }
15920
15921 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
15922
15923 // Compute v = buffer * 10^decimal_exponent.
15924 // The decimal digits are stored in the buffer, which needs to be interpreted
15925 // as an unsigned decimal integer.
15926 // len is the length of the buffer, i.e. the number of decimal digits.
15927 int len = 0;
15928 int decimal_exponent = 0;
15929 dtoa_impl::grisu2(first, len, decimal_exponent, value);
15930
15931 JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
15932
15933 // Format the buffer like printf("%.*g", prec, value)
15934 constexpr int kMinExp = -4;
15935 // Use digits10 here to increase compatibility with version 2.
15936 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
15937
15938 JSON_ASSERT(last - first >= kMaxExp + 2);
15939 JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
15940 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
15941
15942 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
15943 }
15944
15945 } // namespace detail
15946 } // namespace nlohmann
15947
15948 // #include <nlohmann/detail/exceptions.hpp>
15949
15950 // #include <nlohmann/detail/macro_scope.hpp>
15951
15952 // #include <nlohmann/detail/meta/cpp_future.hpp>
15953
15954 // #include <nlohmann/detail/output/binary_writer.hpp>
15955
15956 // #include <nlohmann/detail/output/output_adapters.hpp>
15957
15958 // #include <nlohmann/detail/value_t.hpp>
15959
15960
15961 namespace nlohmann
15962 {
15963 namespace detail
15964 {
15966 // serialization //
15968
15970 enum class error_handler_t
15971 {
15972 strict,
15973 replace,
15974 ignore
15975 };
15976
15977 template<typename BasicJsonType>
15978 class serializer
15979 {
15980 using string_t = typename BasicJsonType::string_t;
15981 using number_float_t = typename BasicJsonType::number_float_t;
15982 using number_integer_t = typename BasicJsonType::number_integer_t;
15983 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
15984 using binary_char_t = typename BasicJsonType::binary_t::value_type;
15985 static constexpr std::uint8_t UTF8_ACCEPT = 0;
15986 static constexpr std::uint8_t UTF8_REJECT = 1;
15987
15988 public:
15994 serializer(output_adapter_t<char> s, const char ichar,
15995 error_handler_t error_handler_ = error_handler_t::strict)
15996 : o(std::move(s))
15997 , loc(std::localeconv())
15998 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
15999 , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
16000 , indent_char(ichar)
16001 , indent_string(512, indent_char)
16002 , error_handler(error_handler_)
16003 {}
16004
16005 // delete because of pointer members
16006 serializer(const serializer&) = delete;
16007 serializer& operator=(const serializer&) = delete;
16008 serializer(serializer&&) = delete;
16009 serializer& operator=(serializer&&) = delete;
16010 ~serializer() = default;
16011
16034 void dump(const BasicJsonType& val,
16035 const bool pretty_print,
16036 const bool ensure_ascii,
16037 const unsigned int indent_step,
16038 const unsigned int current_indent = 0)
16039 {
16040 switch (val.m_type)
16041 {
16042 case value_t::object:
16043 {
16044 if (val.m_value.object->empty())
16045 {
16046 o->write_characters("{}", 2);
16047 return;
16048 }
16049
16050 if (pretty_print)
16051 {
16052 o->write_characters("{\n", 2);
16053
16054 // variable to hold indentation for recursive calls
16055 const auto new_indent = current_indent + indent_step;
16056 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16057 {
16058 indent_string.resize(indent_string.size() * 2, ' ');
16059 }
16060
16061 // first n-1 elements
16062 auto i = val.m_value.object->cbegin();
16063 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16064 {
16065 o->write_characters(indent_string.c_str(), new_indent);
16066 o->write_character('\"');
16067 dump_escaped(i->first, ensure_ascii);
16068 o->write_characters("\": ", 3);
16069 dump(i->second, true, ensure_ascii, indent_step, new_indent);
16070 o->write_characters(",\n", 2);
16071 }
16072
16073 // last element
16074 JSON_ASSERT(i != val.m_value.object->cend());
16075 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16076 o->write_characters(indent_string.c_str(), new_indent);
16077 o->write_character('\"');
16078 dump_escaped(i->first, ensure_ascii);
16079 o->write_characters("\": ", 3);
16080 dump(i->second, true, ensure_ascii, indent_step, new_indent);
16081
16082 o->write_character('\n');
16083 o->write_characters(indent_string.c_str(), current_indent);
16084 o->write_character('}');
16085 }
16086 else
16087 {
16088 o->write_character('{');
16089
16090 // first n-1 elements
16091 auto i = val.m_value.object->cbegin();
16092 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16093 {
16094 o->write_character('\"');
16095 dump_escaped(i->first, ensure_ascii);
16096 o->write_characters("\":", 2);
16097 dump(i->second, false, ensure_ascii, indent_step, current_indent);
16098 o->write_character(',');
16099 }
16100
16101 // last element
16102 JSON_ASSERT(i != val.m_value.object->cend());
16103 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16104 o->write_character('\"');
16105 dump_escaped(i->first, ensure_ascii);
16106 o->write_characters("\":", 2);
16107 dump(i->second, false, ensure_ascii, indent_step, current_indent);
16108
16109 o->write_character('}');
16110 }
16111
16112 return;
16113 }
16114
16115 case value_t::array:
16116 {
16117 if (val.m_value.array->empty())
16118 {
16119 o->write_characters("[]", 2);
16120 return;
16121 }
16122
16123 if (pretty_print)
16124 {
16125 o->write_characters("[\n", 2);
16126
16127 // variable to hold indentation for recursive calls
16128 const auto new_indent = current_indent + indent_step;
16129 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16130 {
16131 indent_string.resize(indent_string.size() * 2, ' ');
16132 }
16133
16134 // first n-1 elements
16135 for (auto i = val.m_value.array->cbegin();
16136 i != val.m_value.array->cend() - 1; ++i)
16137 {
16138 o->write_characters(indent_string.c_str(), new_indent);
16139 dump(*i, true, ensure_ascii, indent_step, new_indent);
16140 o->write_characters(",\n", 2);
16141 }
16142
16143 // last element
16144 JSON_ASSERT(!val.m_value.array->empty());
16145 o->write_characters(indent_string.c_str(), new_indent);
16146 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
16147
16148 o->write_character('\n');
16149 o->write_characters(indent_string.c_str(), current_indent);
16150 o->write_character(']');
16151 }
16152 else
16153 {
16154 o->write_character('[');
16155
16156 // first n-1 elements
16157 for (auto i = val.m_value.array->cbegin();
16158 i != val.m_value.array->cend() - 1; ++i)
16159 {
16160 dump(*i, false, ensure_ascii, indent_step, current_indent);
16161 o->write_character(',');
16162 }
16163
16164 // last element
16165 JSON_ASSERT(!val.m_value.array->empty());
16166 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
16167
16168 o->write_character(']');
16169 }
16170
16171 return;
16172 }
16173
16174 case value_t::string:
16175 {
16176 o->write_character('\"');
16177 dump_escaped(*val.m_value.string, ensure_ascii);
16178 o->write_character('\"');
16179 return;
16180 }
16181
16182 case value_t::binary:
16183 {
16184 if (pretty_print)
16185 {
16186 o->write_characters("{\n", 2);
16187
16188 // variable to hold indentation for recursive calls
16189 const auto new_indent = current_indent + indent_step;
16190 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16191 {
16192 indent_string.resize(indent_string.size() * 2, ' ');
16193 }
16194
16195 o->write_characters(indent_string.c_str(), new_indent);
16196
16197 o->write_characters("\"bytes\": [", 10);
16198
16199 if (!val.m_value.binary->empty())
16200 {
16201 for (auto i = val.m_value.binary->cbegin();
16202 i != val.m_value.binary->cend() - 1; ++i)
16203 {
16204 dump_integer(*i);
16205 o->write_characters(", ", 2);
16206 }
16207 dump_integer(val.m_value.binary->back());
16208 }
16209
16210 o->write_characters("],\n", 3);
16211 o->write_characters(indent_string.c_str(), new_indent);
16212
16213 o->write_characters("\"subtype\": ", 11);
16214 if (val.m_value.binary->has_subtype())
16215 {
16216 dump_integer(val.m_value.binary->subtype());
16217 }
16218 else
16219 {
16220 o->write_characters("null", 4);
16221 }
16222 o->write_character('\n');
16223 o->write_characters(indent_string.c_str(), current_indent);
16224 o->write_character('}');
16225 }
16226 else
16227 {
16228 o->write_characters("{\"bytes\":[", 10);
16229
16230 if (!val.m_value.binary->empty())
16231 {
16232 for (auto i = val.m_value.binary->cbegin();
16233 i != val.m_value.binary->cend() - 1; ++i)
16234 {
16235 dump_integer(*i);
16236 o->write_character(',');
16237 }
16238 dump_integer(val.m_value.binary->back());
16239 }
16240
16241 o->write_characters("],\"subtype\":", 12);
16242 if (val.m_value.binary->has_subtype())
16243 {
16244 dump_integer(val.m_value.binary->subtype());
16245 o->write_character('}');
16246 }
16247 else
16248 {
16249 o->write_characters("null}", 5);
16250 }
16251 }
16252 return;
16253 }
16254
16255 case value_t::boolean:
16256 {
16257 if (val.m_value.boolean)
16258 {
16259 o->write_characters("true", 4);
16260 }
16261 else
16262 {
16263 o->write_characters("false", 5);
16264 }
16265 return;
16266 }
16267
16268 case value_t::number_integer:
16269 {
16270 dump_integer(val.m_value.number_integer);
16271 return;
16272 }
16273
16274 case value_t::number_unsigned:
16275 {
16276 dump_integer(val.m_value.number_unsigned);
16277 return;
16278 }
16279
16280 case value_t::number_float:
16281 {
16282 dump_float(val.m_value.number_float);
16283 return;
16284 }
16285
16286 case value_t::discarded:
16287 {
16288 o->write_characters("<discarded>", 11);
16289 return;
16290 }
16291
16292 case value_t::null:
16293 {
16294 o->write_characters("null", 4);
16295 return;
16296 }
16297
16298 default: // LCOV_EXCL_LINE
16299 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16300 }
16301 }
16302
16303 JSON_PRIVATE_UNLESS_TESTED:
16318 void dump_escaped(const string_t& s, const bool ensure_ascii)
16319 {
16320 std::uint32_t codepoint{};
16321 std::uint8_t state = UTF8_ACCEPT;
16322 std::size_t bytes = 0; // number of bytes written to string_buffer
16323
16324 // number of bytes written at the point of the last valid byte
16325 std::size_t bytes_after_last_accept = 0;
16326 std::size_t undumped_chars = 0;
16327
16328 for (std::size_t i = 0; i < s.size(); ++i)
16329 {
16330 const auto byte = static_cast<uint8_t>(s[i]);
16331
16332 switch (decode(state, codepoint, byte))
16333 {
16334 case UTF8_ACCEPT: // decode found a new code point
16335 {
16336 switch (codepoint)
16337 {
16338 case 0x08: // backspace
16339 {
16340 string_buffer[bytes++] = '\\';
16341 string_buffer[bytes++] = 'b';
16342 break;
16343 }
16344
16345 case 0x09: // horizontal tab
16346 {
16347 string_buffer[bytes++] = '\\';
16348 string_buffer[bytes++] = 't';
16349 break;
16350 }
16351
16352 case 0x0A: // newline
16353 {
16354 string_buffer[bytes++] = '\\';
16355 string_buffer[bytes++] = 'n';
16356 break;
16357 }
16358
16359 case 0x0C: // formfeed
16360 {
16361 string_buffer[bytes++] = '\\';
16362 string_buffer[bytes++] = 'f';
16363 break;
16364 }
16365
16366 case 0x0D: // carriage return
16367 {
16368 string_buffer[bytes++] = '\\';
16369 string_buffer[bytes++] = 'r';
16370 break;
16371 }
16372
16373 case 0x22: // quotation mark
16374 {
16375 string_buffer[bytes++] = '\\';
16376 string_buffer[bytes++] = '\"';
16377 break;
16378 }
16379
16380 case 0x5C: // reverse solidus
16381 {
16382 string_buffer[bytes++] = '\\';
16383 string_buffer[bytes++] = '\\';
16384 break;
16385 }
16386
16387 default:
16388 {
16389 // escape control characters (0x00..0x1F) or, if
16390 // ensure_ascii parameter is used, non-ASCII characters
16391 if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
16392 {
16393 if (codepoint <= 0xFFFF)
16394 {
16395 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16396 (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
16397 static_cast<std::uint16_t>(codepoint));
16398 bytes += 6;
16399 }
16400 else
16401 {
16402 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16403 (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
16404 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
16405 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
16406 bytes += 12;
16407 }
16408 }
16409 else
16410 {
16411 // copy byte to buffer (all previous bytes
16412 // been copied have in default case above)
16413 string_buffer[bytes++] = s[i];
16414 }
16415 break;
16416 }
16417 }
16418
16419 // write buffer and reset index; there must be 13 bytes
16420 // left, as this is the maximal number of bytes to be
16421 // written ("\uxxxx\uxxxx\0") for one code point
16422 if (string_buffer.size() - bytes < 13)
16423 {
16424 o->write_characters(string_buffer.data(), bytes);
16425 bytes = 0;
16426 }
16427
16428 // remember the byte position of this accept
16429 bytes_after_last_accept = bytes;
16430 undumped_chars = 0;
16431 break;
16432 }
16433
16434 case UTF8_REJECT: // decode found invalid UTF-8 byte
16435 {
16436 switch (error_handler)
16437 {
16438 case error_handler_t::strict:
16439 {
16440 std::string sn(3, '\0');
16441 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16442 (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
16443 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn, BasicJsonType()));
16444 }
16445
16446 case error_handler_t::ignore:
16447 case error_handler_t::replace:
16448 {
16449 // in case we saw this character the first time, we
16450 // would like to read it again, because the byte
16451 // may be OK for itself, but just not OK for the
16452 // previous sequence
16453 if (undumped_chars > 0)
16454 {
16455 --i;
16456 }
16457
16458 // reset length buffer to the last accepted index;
16459 // thus removing/ignoring the invalid characters
16460 bytes = bytes_after_last_accept;
16461
16462 if (error_handler == error_handler_t::replace)
16463 {
16464 // add a replacement character
16465 if (ensure_ascii)
16466 {
16467 string_buffer[bytes++] = '\\';
16468 string_buffer[bytes++] = 'u';
16469 string_buffer[bytes++] = 'f';
16470 string_buffer[bytes++] = 'f';
16471 string_buffer[bytes++] = 'f';
16472 string_buffer[bytes++] = 'd';
16473 }
16474 else
16475 {
16476 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
16477 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
16478 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
16479 }
16480
16481 // write buffer and reset index; there must be 13 bytes
16482 // left, as this is the maximal number of bytes to be
16483 // written ("\uxxxx\uxxxx\0") for one code point
16484 if (string_buffer.size() - bytes < 13)
16485 {
16486 o->write_characters(string_buffer.data(), bytes);
16487 bytes = 0;
16488 }
16489
16490 bytes_after_last_accept = bytes;
16491 }
16492
16493 undumped_chars = 0;
16494
16495 // continue processing the string
16496 state = UTF8_ACCEPT;
16497 break;
16498 }
16499
16500 default: // LCOV_EXCL_LINE
16501 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16502 }
16503 break;
16504 }
16505
16506 default: // decode found yet incomplete multi-byte code point
16507 {
16508 if (!ensure_ascii)
16509 {
16510 // code point will not be escaped - copy byte to buffer
16511 string_buffer[bytes++] = s[i];
16512 }
16513 ++undumped_chars;
16514 break;
16515 }
16516 }
16517 }
16518
16519 // we finished processing the string
16520 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
16521 {
16522 // write buffer
16523 if (bytes > 0)
16524 {
16525 o->write_characters(string_buffer.data(), bytes);
16526 }
16527 }
16528 else
16529 {
16530 // we finish reading, but do not accept: string was incomplete
16531 switch (error_handler)
16532 {
16533 case error_handler_t::strict:
16534 {
16535 std::string sn(3, '\0');
16536 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16537 (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
16538 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn, BasicJsonType()));
16539 }
16540
16541 case error_handler_t::ignore:
16542 {
16543 // write all accepted bytes
16544 o->write_characters(string_buffer.data(), bytes_after_last_accept);
16545 break;
16546 }
16547
16548 case error_handler_t::replace:
16549 {
16550 // write all accepted bytes
16551 o->write_characters(string_buffer.data(), bytes_after_last_accept);
16552 // add a replacement character
16553 if (ensure_ascii)
16554 {
16555 o->write_characters("\\ufffd", 6);
16556 }
16557 else
16558 {
16559 o->write_characters("\xEF\xBF\xBD", 3);
16560 }
16561 break;
16562 }
16563
16564 default: // LCOV_EXCL_LINE
16565 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16566 }
16567 }
16568 }
16569
16570 private:
16579 inline unsigned int count_digits(number_unsigned_t x) noexcept
16580 {
16581 unsigned int n_digits = 1;
16582 for (;;)
16583 {
16584 if (x < 10)
16585 {
16586 return n_digits;
16587 }
16588 if (x < 100)
16589 {
16590 return n_digits + 1;
16591 }
16592 if (x < 1000)
16593 {
16594 return n_digits + 2;
16595 }
16596 if (x < 10000)
16597 {
16598 return n_digits + 3;
16599 }
16600 x = x / 10000u;
16601 n_digits += 4;
16602 }
16603 }
16604
16614 template < typename NumberType, detail::enable_if_t <
16615 std::is_same<NumberType, number_unsigned_t>::value ||
16616 std::is_same<NumberType, number_integer_t>::value ||
16617 std::is_same<NumberType, binary_char_t>::value,
16618 int > = 0 >
16619 void dump_integer(NumberType x)
16620 {
16621 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
16622 {
16623 {
16624 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
16625 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
16626 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
16627 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
16628 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
16629 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
16630 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
16631 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
16632 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
16633 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
16634 }
16635 };
16636
16637 // special case for "0"
16638 if (x == 0)
16639 {
16640 o->write_character('0');
16641 return;
16642 }
16643
16644 // use a pointer to fill the buffer
16645 auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16646
16647 const bool is_negative = std::is_same<NumberType, number_integer_t>::value && !(x >= 0); // see issue #755
16648 number_unsigned_t abs_value;
16649
16650 unsigned int n_chars{};
16651
16652 if (is_negative)
16653 {
16654 *buffer_ptr = '-';
16655 abs_value = remove_sign(static_cast<number_integer_t>(x));
16656
16657 // account one more byte for the minus sign
16658 n_chars = 1 + count_digits(abs_value);
16659 }
16660 else
16661 {
16662 abs_value = static_cast<number_unsigned_t>(x);
16663 n_chars = count_digits(abs_value);
16664 }
16665
16666 // spare 1 byte for '\0'
16667 JSON_ASSERT(n_chars < number_buffer.size() - 1);
16668
16669 // jump to the end to generate the string from backward
16670 // so we later avoid reversing the result
16671 buffer_ptr += n_chars;
16672
16673 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
16674 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
16675 while (abs_value >= 100)
16676 {
16677 const auto digits_index = static_cast<unsigned>((abs_value % 100));
16678 abs_value /= 100;
16679 *(--buffer_ptr) = digits_to_99[digits_index][1];
16680 *(--buffer_ptr) = digits_to_99[digits_index][0];
16681 }
16682
16683 if (abs_value >= 10)
16684 {
16685 const auto digits_index = static_cast<unsigned>(abs_value);
16686 *(--buffer_ptr) = digits_to_99[digits_index][1];
16687 *(--buffer_ptr) = digits_to_99[digits_index][0];
16688 }
16689 else
16690 {
16691 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
16692 }
16693
16694 o->write_characters(number_buffer.data(), n_chars);
16695 }
16696
16705 void dump_float(number_float_t x)
16706 {
16707 // NaN / inf
16708 if (!std::isfinite(x))
16709 {
16710 o->write_characters("null", 4);
16711 return;
16712 }
16713
16714 // If number_float_t is an IEEE-754 single or double precision number,
16715 // use the Grisu2 algorithm to produce short numbers which are
16716 // guaranteed to round-trip, using strtof and strtod, resp.
16717 //
16718 // NB: The test below works if <long double> == <double>.
16719 static constexpr bool is_ieee_single_or_double
16720 = (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) ||
16721 (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);
16722
16723 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
16724 }
16725
16726 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
16727 {
16728 auto* begin = number_buffer.data();
16729 auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
16730
16731 o->write_characters(begin, static_cast<size_t>(end - begin));
16732 }
16733
16734 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
16735 {
16736 // get number of digits for a float -> text -> float round-trip
16737 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
16738
16739 // the actual conversion
16740 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16741 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
16742
16743 // negative value indicates an error
16744 JSON_ASSERT(len > 0);
16745 // check if buffer was large enough
16746 JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
16747
16748 // erase thousands separator
16749 if (thousands_sep != '\0')
16750 {
16751 auto* const end = std::remove(number_buffer.begin(),
16752 number_buffer.begin() + len, thousands_sep);
16753 std::fill(end, number_buffer.end(), '\0');
16754 JSON_ASSERT((end - number_buffer.begin()) <= len);
16755 len = (end - number_buffer.begin());
16756 }
16757
16758 // convert decimal point to '.'
16759 if (decimal_point != '\0' && decimal_point != '.')
16760 {
16761 auto* const dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
16762 if (dec_pos != number_buffer.end())
16763 {
16764 *dec_pos = '.';
16765 }
16766 }
16767
16768 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
16769
16770 // determine if need to append ".0"
16771 const bool value_is_int_like =
16772 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
16773 [](char c)
16774 {
16775 return c == '.' || c == 'e';
16776 });
16777
16778 if (value_is_int_like)
16779 {
16780 o->write_characters(".0", 2);
16781 }
16782 }
16783
16805 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
16806 {
16807 static const std::array<std::uint8_t, 400> utf8d =
16808 {
16809 {
16810 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
16811 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
16812 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
16813 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
16814 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
16815 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
16816 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
16817 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
16818 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
16819 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
16820 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
16821 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
16822 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
16823 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
16824 }
16825 };
16826
16827 JSON_ASSERT(byte < utf8d.size());
16828 const std::uint8_t type = utf8d[byte];
16829
16830 codep = (state != UTF8_ACCEPT)
16831 ? (byte & 0x3fu) | (codep << 6u)
16832 : (0xFFu >> type) & (byte);
16833
16834 std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
16835 JSON_ASSERT(index < 400);
16836 state = utf8d[index];
16837 return state;
16838 }
16839
16840 /*
16841 * Overload to make the compiler happy while it is instantiating
16842 * dump_integer for number_unsigned_t.
16843 * Must never be called.
16844 */
16845 number_unsigned_t remove_sign(number_unsigned_t x)
16846 {
16847 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16848 return x; // LCOV_EXCL_LINE
16849 }
16850
16851 /*
16852 * Helper function for dump_integer
16853 *
16854 * This function takes a negative signed integer and returns its absolute
16855 * value as unsigned integer. The plus/minus shuffling is necessary as we can
16856 * not directly remove the sign of an arbitrary signed integer as the
16857 * absolute values of INT_MIN and INT_MAX are usually not the same. See
16858 * #1708 for details.
16859 */
16860 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
16861 {
16862 JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
16863 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
16864 }
16865
16866 private:
16868 output_adapter_t<char> o = nullptr;
16869
16871 std::array<char, 64> number_buffer{{}};
16872
16874 const std::lconv* loc = nullptr;
16876 const char thousands_sep = '\0';
16878 const char decimal_point = '\0';
16879
16881 std::array<char, 512> string_buffer{{}};
16882
16884 const char indent_char;
16886 string_t indent_string;
16887
16889 const error_handler_t error_handler;
16890 };
16891 } // namespace detail
16892 } // namespace nlohmann
16893
16894 // #include <nlohmann/detail/value_t.hpp>
16895
16896 // #include <nlohmann/json_fwd.hpp>
16897
16898 // #include <nlohmann/ordered_map.hpp>
16899
16900
16901 #include <functional> // less
16902 #include <initializer_list> // initializer_list
16903 #include <iterator> // input_iterator_tag, iterator_traits
16904 #include <memory> // allocator
16905 #include <stdexcept> // for out_of_range
16906 #include <type_traits> // enable_if, is_convertible
16907 #include <utility> // pair
16908 #include <vector> // vector
16909
16910 // #include <nlohmann/detail/macro_scope.hpp>
16911
16912
16913 namespace nlohmann
16914 {
16915
16918 template <class Key, class T, class IgnoredLess = std::less<Key>,
16919 class Allocator = std::allocator<std::pair<const Key, T>>>
16920 struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
16921 {
16922 using key_type = Key;
16923 using mapped_type = T;
16924 using Container = std::vector<std::pair<const Key, T>, Allocator>;
16925 using typename Container::iterator;
16926 using typename Container::const_iterator;
16927 using typename Container::size_type;
16928 using typename Container::value_type;
16929
16930 // Explicit constructors instead of `using Container::Container`
16931 // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
16932 ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
16933 template <class It>
16934 ordered_map(It first, It last, const Allocator& alloc = Allocator())
16935 : Container{first, last, alloc} {}
16936 ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
16937 : Container{init, alloc} {}
16938
16939 std::pair<iterator, bool> emplace(const key_type& key, T&& t)
16940 {
16941 for (auto it = this->begin(); it != this->end(); ++it)
16942 {
16943 if (it->first == key)
16944 {
16945 return {it, false};
16946 }
16947 }
16948 Container::emplace_back(key, t);
16949 return {--this->end(), true};
16950 }
16951
16952 T& operator[](const Key& key)
16953 {
16954 return emplace(key, T{}).first->second;
16955 }
16956
16957 const T& operator[](const Key& key) const
16958 {
16959 return at(key);
16960 }
16961
16962 T& at(const Key& key)
16963 {
16964 for (auto it = this->begin(); it != this->end(); ++it)
16965 {
16966 if (it->first == key)
16967 {
16968 return it->second;
16969 }
16970 }
16971
16972 JSON_THROW(std::out_of_range("key not found"));
16973 }
16974
16975 const T& at(const Key& key) const
16976 {
16977 for (auto it = this->begin(); it != this->end(); ++it)
16978 {
16979 if (it->first == key)
16980 {
16981 return it->second;
16982 }
16983 }
16984
16985 JSON_THROW(std::out_of_range("key not found"));
16986 }
16987
16988 size_type erase(const Key& key)
16989 {
16990 for (auto it = this->begin(); it != this->end(); ++it)
16991 {
16992 if (it->first == key)
16993 {
16994 // Since we cannot move const Keys, re-construct them in place
16995 for (auto next = it; ++next != this->end(); ++it)
16996 {
16997 it->~value_type(); // Destroy but keep allocation
16998 new (&*it) value_type{std::move(*next)};
16999 }
17000 Container::pop_back();
17001 return 1;
17002 }
17003 }
17004 return 0;
17005 }
17006
17007 iterator erase(iterator pos)
17008 {
17009 auto it = pos;
17010
17011 // Since we cannot move const Keys, re-construct them in place
17012 for (auto next = it; ++next != this->end(); ++it)
17013 {
17014 it->~value_type(); // Destroy but keep allocation
17015 new (&*it) value_type{std::move(*next)};
17016 }
17017 Container::pop_back();
17018 return pos;
17019 }
17020
17021 size_type count(const Key& key) const
17022 {
17023 for (auto it = this->begin(); it != this->end(); ++it)
17024 {
17025 if (it->first == key)
17026 {
17027 return 1;
17028 }
17029 }
17030 return 0;
17031 }
17032
17033 iterator find(const Key& key)
17034 {
17035 for (auto it = this->begin(); it != this->end(); ++it)
17036 {
17037 if (it->first == key)
17038 {
17039 return it;
17040 }
17041 }
17042 return Container::end();
17043 }
17044
17045 const_iterator find(const Key& key) const
17046 {
17047 for (auto it = this->begin(); it != this->end(); ++it)
17048 {
17049 if (it->first == key)
17050 {
17051 return it;
17052 }
17053 }
17054 return Container::end();
17055 }
17056
17057 std::pair<iterator, bool> insert( value_type&& value )
17058 {
17059 return emplace(value.first, std::move(value.second));
17060 }
17061
17062 std::pair<iterator, bool> insert( const value_type& value )
17063 {
17064 for (auto it = this->begin(); it != this->end(); ++it)
17065 {
17066 if (it->first == value.first)
17067 {
17068 return {it, false};
17069 }
17070 }
17071 Container::push_back(value);
17072 return {--this->end(), true};
17073 }
17074
17075 template<typename InputIt>
17076 using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
17077 std::input_iterator_tag>::value>::type;
17078
17079 template<typename InputIt, typename = require_input_iter<InputIt>>
17080 void insert(InputIt first, InputIt last)
17081 {
17082 for (auto it = first; it != last; ++it)
17083 {
17084 insert(*it);
17085 }
17086 }
17087 };
17088
17089 } // namespace nlohmann
17090
17091
17092 #if defined(JSON_HAS_CPP_17)
17093 #include <string_view>
17094 #endif
17095
17101 namespace nlohmann
17102 {
17103
17188 NLOHMANN_BASIC_JSON_TPL_DECLARATION
17189 class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
17190 {
17191 private:
17192 template<detail::value_t> friend struct detail::external_constructor;
17193 friend ::nlohmann::json_pointer<basic_json>;
17194
17195 template<typename BasicJsonType, typename InputType>
17196 friend class ::nlohmann::detail::parser;
17197 friend ::nlohmann::detail::serializer<basic_json>;
17198 template<typename BasicJsonType>
17199 friend class ::nlohmann::detail::iter_impl;
17200 template<typename BasicJsonType, typename CharType>
17201 friend class ::nlohmann::detail::binary_writer;
17202 template<typename BasicJsonType, typename InputType, typename SAX>
17203 friend class ::nlohmann::detail::binary_reader;
17204 template<typename BasicJsonType>
17205 friend class ::nlohmann::detail::json_sax_dom_parser;
17206 template<typename BasicJsonType>
17207 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
17208 friend class ::nlohmann::detail::exception;
17209
17211 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
17212
17213 JSON_PRIVATE_UNLESS_TESTED:
17214 // convenience aliases for types residing in namespace detail;
17215 using lexer = ::nlohmann::detail::lexer_base<basic_json>;
17216
17217 template<typename InputAdapterType>
17218 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
17219 InputAdapterType adapter,
17220 detail::parser_callback_t<basic_json>cb = nullptr,
17221 const bool allow_exceptions = true,
17222 const bool ignore_comments = false
17223 )
17224 {
17225 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
17226 std::move(cb), allow_exceptions, ignore_comments);
17227 }
17228
17229 private:
17230 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
17231 template<typename BasicJsonType>
17232 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
17233 template<typename BasicJsonType>
17234 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
17235 template<typename Iterator>
17236 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
17237 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
17238
17239 template<typename CharType>
17240 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
17241
17242 template<typename InputType>
17243 using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
17244 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
17245
17246 JSON_PRIVATE_UNLESS_TESTED:
17247 using serializer = ::nlohmann::detail::serializer<basic_json>;
17248
17249 public:
17250 using value_t = detail::value_t;
17252 using json_pointer = ::nlohmann::json_pointer<basic_json>;
17253 template<typename T, typename SFINAE>
17254 using json_serializer = JSONSerializer<T, SFINAE>;
17256 using error_handler_t = detail::error_handler_t;
17258 using cbor_tag_handler_t = detail::cbor_tag_handler_t;
17260 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
17261
17262 using input_format_t = detail::input_format_t;
17264 using json_sax_t = json_sax<basic_json>;
17265
17267 // exceptions //
17269
17273
17275 using exception = detail::exception;
17277 using parse_error = detail::parse_error;
17279 using invalid_iterator = detail::invalid_iterator;
17281 using type_error = detail::type_error;
17283 using out_of_range = detail::out_of_range;
17285 using other_error = detail::other_error;
17286
17288
17289
17291 // container types //
17293
17298
17300 using value_type = basic_json;
17301
17303 using reference = value_type&;
17305 using const_reference = const value_type&;
17306
17308 using difference_type = std::ptrdiff_t;
17310 using size_type = std::size_t;
17311
17313 using allocator_type = AllocatorType<basic_json>;
17314
17316 using pointer = typename std::allocator_traits<allocator_type>::pointer;
17318 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
17319
17321 using iterator = iter_impl<basic_json>;
17323 using const_iterator = iter_impl<const basic_json>;
17325 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
17327 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
17328
17330
17331
17335 static allocator_type get_allocator()
17336 {
17337 return allocator_type();
17338 }
17339
17366
17367 static basic_json meta()
17368 {
17369 basic_json result;
17370
17371 result["copyright"] = "(C) 2013-2021 Niels Lohmann";
17372 result["name"] = "JSON for Modern C++";
17373 result["url"] = "https://github.com/nlohmann/json";
17374 result["version"]["string"] =
17375 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
17376 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
17377 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
17378 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
17379 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
17380 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
17381
17382 #ifdef _WIN32
17383 result["platform"] = "win32";
17384 #elif defined __linux__
17385 result["platform"] = "linux";
17386 #elif defined __APPLE__
17387 result["platform"] = "apple";
17388 #elif defined __unix__
17389 result["platform"] = "unix";
17390 #else
17391 result["platform"] = "unknown";
17392 #endif
17393
17394 #if defined(__ICC) || defined(__INTEL_COMPILER)
17395 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
17396 #elif defined(__clang__)
17397 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
17398 #elif defined(__GNUC__) || defined(__GNUG__)
17399 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
17400 #elif defined(__HP_cc) || defined(__HP_aCC)
17401 result["compiler"] = "hp"
17402 #elif defined(__IBMCPP__)
17403 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
17404 #elif defined(_MSC_VER)
17405 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
17406 #elif defined(__PGI)
17407 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
17408 #elif defined(__SUNPRO_CC)
17409 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
17410 #else
17411 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
17412 #endif
17413
17414 #ifdef __cplusplus
17415 result["compiler"]["c++"] = std::to_string(__cplusplus);
17416 #else
17417 result["compiler"]["c++"] = "unknown";
17418 #endif
17419 return result;
17420 }
17421
17422
17424 // JSON value data types //
17426
17431
17432 #if defined(JSON_HAS_CPP_14)
17433 // Use transparent comparator if possible, combined with perfect forwarding
17434 // on find() and count() calls prevents unnecessary string construction.
17435 using object_comparator_t = std::less<>;
17436 #else
17437 using object_comparator_t = std::less<StringType>;
17438 #endif
17439
17523 using object_t = ObjectType<StringType,
17524 basic_json,
17525 object_comparator_t,
17526 AllocatorType<std::pair<const StringType,
17527 basic_json>>>;
17528
17573 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
17574
17626 using string_t = StringType;
17627
17652 using boolean_t = BooleanType;
17653
17724 using number_integer_t = NumberIntegerType;
17725
17795 using number_unsigned_t = NumberUnsignedType;
17796
17863 using number_float_t = NumberFloatType;
17864
17934 using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
17936
17937 private:
17938
17940 template<typename T, typename... Args>
17941
17942 static T* create(Args&& ... args)
17943 {
17944 AllocatorType<T> alloc;
17945 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
17946
17947 auto deleter = [&](T * obj)
17948 {
17949 AllocatorTraits::deallocate(alloc, obj, 1);
17950 };
17951 std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
17952 AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
17953 JSON_ASSERT(obj != nullptr);
17954 return obj.release();
17955 }
17956
17958 // JSON value storage //
17960
17961 JSON_PRIVATE_UNLESS_TESTED:
17987 union json_value
17988 {
17990 object_t* object;
17992 array_t* array;
17994 string_t* string;
17996 binary_t* binary;
17998 boolean_t boolean;
18000 number_integer_t number_integer;
18002 number_unsigned_t number_unsigned;
18004 number_float_t number_float;
18005
18007 json_value() = default;
18009 json_value(boolean_t v) noexcept : boolean(v) {}
18011 json_value(number_integer_t v) noexcept : number_integer(v) {}
18013 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
18015 json_value(number_float_t v) noexcept : number_float(v) {}
18017 json_value(value_t t)
18018 {
18019 switch (t)
18020 {
18021 case value_t::object:
18022 {
18023 object = create<object_t>();
18024 break;
18025 }
18026
18027 case value_t::array:
18028 {
18029 array = create<array_t>();
18030 break;
18031 }
18032
18033 case value_t::string:
18034 {
18035 string = create<string_t>("");
18036 break;
18037 }
18038
18039 case value_t::binary:
18040 {
18041 binary = create<binary_t>();
18042 break;
18043 }
18044
18045 case value_t::boolean:
18046 {
18047 boolean = boolean_t(false);
18048 break;
18049 }
18050
18051 case value_t::number_integer:
18052 {
18053 number_integer = number_integer_t(0);
18054 break;
18055 }
18056
18057 case value_t::number_unsigned:
18058 {
18059 number_unsigned = number_unsigned_t(0);
18060 break;
18061 }
18062
18063 case value_t::number_float:
18064 {
18065 number_float = number_float_t(0.0);
18066 break;
18067 }
18068
18069 case value_t::null:
18070 {
18071 object = nullptr; // silence warning, see #821
18072 break;
18073 }
18074
18075 default:
18076 {
18077 object = nullptr; // silence warning, see #821
18078 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
18079 {
18080 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.9.1", basic_json())); // LCOV_EXCL_LINE
18081 }
18082 break;
18083 }
18084 }
18085 }
18086
18088 json_value(const string_t& value)
18089 {
18090 string = create<string_t>(value);
18091 }
18092
18094 json_value(string_t&& value)
18095 {
18096 string = create<string_t>(std::move(value));
18097 }
18098
18100 json_value(const object_t& value)
18101 {
18102 object = create<object_t>(value);
18103 }
18104
18106 json_value(object_t&& value)
18107 {
18108 object = create<object_t>(std::move(value));
18109 }
18110
18112 json_value(const array_t& value)
18113 {
18114 array = create<array_t>(value);
18115 }
18116
18118 json_value(array_t&& value)
18119 {
18120 array = create<array_t>(std::move(value));
18121 }
18122
18124 json_value(const typename binary_t::container_type& value)
18125 {
18126 binary = create<binary_t>(value);
18127 }
18128
18130 json_value(typename binary_t::container_type&& value)
18131 {
18132 binary = create<binary_t>(std::move(value));
18133 }
18134
18136 json_value(const binary_t& value)
18137 {
18138 binary = create<binary_t>(value);
18139 }
18140
18142 json_value(binary_t&& value)
18143 {
18144 binary = create<binary_t>(std::move(value));
18145 }
18146
18147 void destroy(value_t t) noexcept
18148 {
18149 // flatten the current json_value to a heap-allocated stack
18150 std::vector<basic_json> stack;
18151
18152 // move the top-level items to stack
18153 if (t == value_t::array)
18154 {
18155 stack.reserve(array->size());
18156 std::move(array->begin(), array->end(), std::back_inserter(stack));
18157 }
18158 else if (t == value_t::object)
18159 {
18160 stack.reserve(object->size());
18161 for (auto&& it : *object)
18162 {
18163 stack.push_back(std::move(it.second));
18164 }
18165 }
18166
18167 while (!stack.empty())
18168 {
18169 // move the last item to local variable to be processed
18170 basic_json current_item(std::move(stack.back()));
18171 stack.pop_back();
18172
18173 // if current_item is array/object, move
18174 // its children to the stack to be processed later
18175 if (current_item.is_array())
18176 {
18177 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
18178 std::back_inserter(stack));
18179
18180 current_item.m_value.array->clear();
18181 }
18182 else if (current_item.is_object())
18183 {
18184 for (auto&& it : *current_item.m_value.object)
18185 {
18186 stack.push_back(std::move(it.second));
18187 }
18188
18189 current_item.m_value.object->clear();
18190 }
18191
18192 // it's now safe that current_item get destructed
18193 // since it doesn't have any children
18194 }
18195
18196 switch (t)
18197 {
18198 case value_t::object:
18199 {
18200 AllocatorType<object_t> alloc;
18201 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
18202 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
18203 break;
18204 }
18205
18206 case value_t::array:
18207 {
18208 AllocatorType<array_t> alloc;
18209 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
18210 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
18211 break;
18212 }
18213
18214 case value_t::string:
18215 {
18216 AllocatorType<string_t> alloc;
18217 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
18218 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
18219 break;
18220 }
18221
18222 case value_t::binary:
18223 {
18224 AllocatorType<binary_t> alloc;
18225 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
18226 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
18227 break;
18228 }
18229
18230 default:
18231 {
18232 break;
18233 }
18234 }
18235 }
18236 };
18237
18238 private:
18257 void assert_invariant(bool check_parents = true) const noexcept
18258 {
18259 JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
18260 JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
18261 JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
18262 JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
18263
18264 #if JSON_DIAGNOSTICS
18265 JSON_TRY
18266 {
18267 // cppcheck-suppress assertWithSideEffect
18268 JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
18269 {
18270 return j.m_parent == this;
18271 }));
18272 }
18273 JSON_CATCH(...) {} // LCOV_EXCL_LINE
18274 #endif
18275 static_cast<void>(check_parents);
18276 }
18277
18278 void set_parents()
18279 {
18280 #if JSON_DIAGNOSTICS
18281 switch (m_type)
18282 {
18283 case value_t::array:
18284 {
18285 for (auto& element : *m_value.array)
18286 {
18287 element.m_parent = this;
18288 }
18289 break;
18290 }
18291
18292 case value_t::object:
18293 {
18294 for (auto& element : *m_value.object)
18295 {
18296 element.second.m_parent = this;
18297 }
18298 break;
18299 }
18300
18301 default:
18302 break;
18303 }
18304 #endif
18305 }
18306
18307 iterator set_parents(iterator it, typename iterator::difference_type count)
18308 {
18309 #if JSON_DIAGNOSTICS
18310 for (typename iterator::difference_type i = 0; i < count; ++i)
18311 {
18312 (it + i)->m_parent = this;
18313 }
18314 #else
18315 static_cast<void>(count);
18316 #endif
18317 return it;
18318 }
18319
18320 reference set_parent(reference j)
18321 {
18322 #if JSON_DIAGNOSTICS
18323 j.m_parent = this;
18324 #else
18325 static_cast<void>(j);
18326 #endif
18327 return j;
18328 }
18329
18330 public:
18332 // JSON parser callback //
18334
18350 using parse_event_t = detail::parse_event_t;
18351
18401 using parser_callback_t = detail::parser_callback_t<basic_json>;
18402
18404 // constructors //
18406
18411
18442 basic_json(const value_t v)
18443 : m_type(v), m_value(v)
18444 {
18445 assert_invariant();
18446 }
18447
18466 basic_json(std::nullptr_t = nullptr) noexcept
18467 : basic_json(value_t::null)
18468 {
18469 assert_invariant();
18470 }
18471
18534 template < typename CompatibleType,
18535 typename U = detail::uncvref_t<CompatibleType>,
18536 detail::enable_if_t <
18537 !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
18538 basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
18539 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
18540 std::forward<CompatibleType>(val))))
18541 {
18542 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
18543 set_parents();
18544 assert_invariant();
18545 }
18546
18573 template < typename BasicJsonType,
18574 detail::enable_if_t <
18575 detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
18576 basic_json(const BasicJsonType& val)
18577 {
18578 using other_boolean_t = typename BasicJsonType::boolean_t;
18579 using other_number_float_t = typename BasicJsonType::number_float_t;
18580 using other_number_integer_t = typename BasicJsonType::number_integer_t;
18581 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
18582 using other_string_t = typename BasicJsonType::string_t;
18583 using other_object_t = typename BasicJsonType::object_t;
18584 using other_array_t = typename BasicJsonType::array_t;
18585 using other_binary_t = typename BasicJsonType::binary_t;
18586
18587 switch (val.type())
18588 {
18589 case value_t::boolean:
18590 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
18591 break;
18592 case value_t::number_float:
18593 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
18594 break;
18595 case value_t::number_integer:
18596 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
18597 break;
18598 case value_t::number_unsigned:
18599 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
18600 break;
18601 case value_t::string:
18602 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
18603 break;
18604 case value_t::object:
18605 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
18606 break;
18607 case value_t::array:
18608 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
18609 break;
18610 case value_t::binary:
18611 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
18612 break;
18613 case value_t::null:
18614 *this = nullptr;
18615 break;
18616 case value_t::discarded:
18617 m_type = value_t::discarded;
18618 break;
18619 default: // LCOV_EXCL_LINE
18620 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18621 }
18622 set_parents();
18623 assert_invariant();
18624 }
18625
18700 basic_json(initializer_list_t init,
18701 bool type_deduction = true,
18702 value_t manual_type = value_t::array)
18703 {
18704 // check if each element is an array with two elements whose first
18705 // element is a string
18706 bool is_an_object = std::all_of(init.begin(), init.end(),
18707 [](const detail::json_ref<basic_json>& element_ref)
18708 {
18709 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
18710 });
18711
18712 // adjust type if type deduction is not wanted
18713 if (!type_deduction)
18714 {
18715 // if array is wanted, do not create an object though possible
18716 if (manual_type == value_t::array)
18717 {
18718 is_an_object = false;
18719 }
18720
18721 // if object is wanted but impossible, throw an exception
18722 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
18723 {
18724 JSON_THROW(type_error::create(301, "cannot create object from initializer list", basic_json()));
18725 }
18726 }
18727
18728 if (is_an_object)
18729 {
18730 // the initializer list is a list of pairs -> create object
18731 m_type = value_t::object;
18732 m_value = value_t::object;
18733
18734 for (auto& element_ref : init)
18735 {
18736 auto element = element_ref.moved_or_copied();
18737 m_value.object->emplace(
18738 std::move(*((*element.m_value.array)[0].m_value.string)),
18739 std::move((*element.m_value.array)[1]));
18740 }
18741 }
18742 else
18743 {
18744 // the initializer list describes an array -> create array
18745 m_type = value_t::array;
18746 m_value.array = create<array_t>(init.begin(), init.end());
18747 }
18748
18749 set_parents();
18750 assert_invariant();
18751 }
18752
18780
18781 static basic_json binary(const typename binary_t::container_type& init)
18782 {
18783 auto res = basic_json();
18784 res.m_type = value_t::binary;
18785 res.m_value = init;
18786 return res;
18787 }
18788
18817
18818 static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype)
18819 {
18820 auto res = basic_json();
18821 res.m_type = value_t::binary;
18822 res.m_value = binary_t(init, subtype);
18823 return res;
18824 }
18825
18827
18828 static basic_json binary(typename binary_t::container_type&& init)
18829 {
18830 auto res = basic_json();
18831 res.m_type = value_t::binary;
18832 res.m_value = std::move(init);
18833 return res;
18834 }
18835
18837
18838 static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype)
18839 {
18840 auto res = basic_json();
18841 res.m_type = value_t::binary;
18842 res.m_value = binary_t(std::move(init), subtype);
18843 return res;
18844 }
18845
18883
18884 static basic_json array(initializer_list_t init = {})
18885 {
18886 return basic_json(init, false, value_t::array);
18887 }
18888
18927
18928 static basic_json object(initializer_list_t init = {})
18929 {
18930 return basic_json(init, false, value_t::object);
18931 }
18932
18955 basic_json(size_type cnt, const basic_json& val)
18956 : m_type(value_t::array)
18957 {
18958 m_value.array = create<array_t>(cnt, val);
18959 set_parents();
18960 assert_invariant();
18961 }
18962
19018 template < class InputIT, typename std::enable_if <
19019 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
19020 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
19021 basic_json(InputIT first, InputIT last)
19022 {
19023 JSON_ASSERT(first.m_object != nullptr);
19024 JSON_ASSERT(last.m_object != nullptr);
19025
19026 // make sure iterator fits the current value
19027 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19028 {
19029 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", basic_json()));
19030 }
19031
19032 // copy type from first iterator
19033 m_type = first.m_object->m_type;
19034
19035 // check if iterator range is complete for primitive values
19036 switch (m_type)
19037 {
19038 case value_t::boolean:
19039 case value_t::number_float:
19040 case value_t::number_integer:
19041 case value_t::number_unsigned:
19042 case value_t::string:
19043 {
19044 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
19045 || !last.m_it.primitive_iterator.is_end()))
19046 {
19047 JSON_THROW(invalid_iterator::create(204, "iterators out of range", *first.m_object));
19048 }
19049 break;
19050 }
19051
19052 default:
19053 break;
19054 }
19055
19056 switch (m_type)
19057 {
19058 case value_t::number_integer:
19059 {
19060 m_value.number_integer = first.m_object->m_value.number_integer;
19061 break;
19062 }
19063
19064 case value_t::number_unsigned:
19065 {
19066 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
19067 break;
19068 }
19069
19070 case value_t::number_float:
19071 {
19072 m_value.number_float = first.m_object->m_value.number_float;
19073 break;
19074 }
19075
19076 case value_t::boolean:
19077 {
19078 m_value.boolean = first.m_object->m_value.boolean;
19079 break;
19080 }
19081
19082 case value_t::string:
19083 {
19084 m_value = *first.m_object->m_value.string;
19085 break;
19086 }
19087
19088 case value_t::object:
19089 {
19090 m_value.object = create<object_t>(first.m_it.object_iterator,
19091 last.m_it.object_iterator);
19092 break;
19093 }
19094
19095 case value_t::array:
19096 {
19097 m_value.array = create<array_t>(first.m_it.array_iterator,
19098 last.m_it.array_iterator);
19099 break;
19100 }
19101
19102 case value_t::binary:
19103 {
19104 m_value = *first.m_object->m_value.binary;
19105 break;
19106 }
19107
19108 default:
19109 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object));
19110 }
19111
19112 set_parents();
19113 assert_invariant();
19114 }
19115
19116
19118 // other constructors and destructor //
19120
19121 template<typename JsonRef,
19122 detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
19123 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
19124 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
19125
19151 basic_json(const basic_json& other)
19152 : m_type(other.m_type)
19153 {
19154 // check of passed value is valid
19155 other.assert_invariant();
19156
19157 switch (m_type)
19158 {
19159 case value_t::object:
19160 {
19161 m_value = *other.m_value.object;
19162 break;
19163 }
19164
19165 case value_t::array:
19166 {
19167 m_value = *other.m_value.array;
19168 break;
19169 }
19170
19171 case value_t::string:
19172 {
19173 m_value = *other.m_value.string;
19174 break;
19175 }
19176
19177 case value_t::boolean:
19178 {
19179 m_value = other.m_value.boolean;
19180 break;
19181 }
19182
19183 case value_t::number_integer:
19184 {
19185 m_value = other.m_value.number_integer;
19186 break;
19187 }
19188
19189 case value_t::number_unsigned:
19190 {
19191 m_value = other.m_value.number_unsigned;
19192 break;
19193 }
19194
19195 case value_t::number_float:
19196 {
19197 m_value = other.m_value.number_float;
19198 break;
19199 }
19200
19201 case value_t::binary:
19202 {
19203 m_value = *other.m_value.binary;
19204 break;
19205 }
19206
19207 default:
19208 break;
19209 }
19210
19211 set_parents();
19212 assert_invariant();
19213 }
19214
19241 basic_json(basic_json&& other) noexcept
19242 : m_type(std::move(other.m_type)),
19243 m_value(std::move(other.m_value))
19244 {
19245 // check that passed value is valid
19246 other.assert_invariant(false);
19247
19248 // invalidate payload
19249 other.m_type = value_t::null;
19250 other.m_value = {};
19251
19252 set_parents();
19253 assert_invariant();
19254 }
19255
19279 basic_json& operator=(basic_json other) noexcept (
19280 std::is_nothrow_move_constructible<value_t>::value&&
19281 std::is_nothrow_move_assignable<value_t>::value&&
19282 std::is_nothrow_move_constructible<json_value>::value&&
19283 std::is_nothrow_move_assignable<json_value>::value
19284 )
19285 {
19286 // check that passed value is valid
19287 other.assert_invariant();
19288
19289 using std::swap;
19290 swap(m_type, other.m_type);
19291 swap(m_value, other.m_value);
19292
19293 set_parents();
19294 assert_invariant();
19295 return *this;
19296 }
19297
19313 ~basic_json() noexcept
19314 {
19315 assert_invariant(false);
19316 m_value.destroy(m_type);
19317 }
19318
19320
19321 public:
19323 // object inspection //
19325
19329
19377 string_t dump(const int indent = -1,
19378 const char indent_char = ' ',
19379 const bool ensure_ascii = false,
19380 const error_handler_t error_handler = error_handler_t::strict) const
19381 {
19382 string_t result;
19383 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
19384
19385 if (indent >= 0)
19386 {
19387 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
19388 }
19389 else
19390 {
19391 s.dump(*this, false, ensure_ascii, 0);
19392 }
19393
19394 return result;
19395 }
19396
19430 constexpr value_t type() const noexcept
19431 {
19432 return m_type;
19433 }
19434
19461 constexpr bool is_primitive() const noexcept
19462 {
19463 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
19464 }
19465
19488 constexpr bool is_structured() const noexcept
19489 {
19490 return is_array() || is_object();
19491 }
19492
19510 constexpr bool is_null() const noexcept
19511 {
19512 return m_type == value_t::null;
19513 }
19514
19532 constexpr bool is_boolean() const noexcept
19533 {
19534 return m_type == value_t::boolean;
19535 }
19536
19562 constexpr bool is_number() const noexcept
19563 {
19564 return is_number_integer() || is_number_float();
19565 }
19566
19591 constexpr bool is_number_integer() const noexcept
19592 {
19593 return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
19594 }
19595
19619 constexpr bool is_number_unsigned() const noexcept
19620 {
19621 return m_type == value_t::number_unsigned;
19622 }
19623
19647 constexpr bool is_number_float() const noexcept
19648 {
19649 return m_type == value_t::number_float;
19650 }
19651
19669 constexpr bool is_object() const noexcept
19670 {
19671 return m_type == value_t::object;
19672 }
19673
19691 constexpr bool is_array() const noexcept
19692 {
19693 return m_type == value_t::array;
19694 }
19695
19713 constexpr bool is_string() const noexcept
19714 {
19715 return m_type == value_t::string;
19716 }
19717
19735 constexpr bool is_binary() const noexcept
19736 {
19737 return m_type == value_t::binary;
19738 }
19739
19762 constexpr bool is_discarded() const noexcept
19763 {
19764 return m_type == value_t::discarded;
19765 }
19766
19788 constexpr operator value_t() const noexcept
19789 {
19790 return m_type;
19791 }
19792
19794
19795 private:
19797 // value access //
19799
19801 boolean_t get_impl(boolean_t* /*unused*/) const
19802 {
19803 if (JSON_HEDLEY_LIKELY(is_boolean()))
19804 {
19805 return m_value.boolean;
19806 }
19807
19808 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()), *this));
19809 }
19810
19812 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
19813 {
19814 return is_object() ? m_value.object : nullptr;
19815 }
19816
19818 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
19819 {
19820 return is_object() ? m_value.object : nullptr;
19821 }
19822
19824 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
19825 {
19826 return is_array() ? m_value.array : nullptr;
19827 }
19828
19830 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
19831 {
19832 return is_array() ? m_value.array : nullptr;
19833 }
19834
19836 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
19837 {
19838 return is_string() ? m_value.string : nullptr;
19839 }
19840
19842 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
19843 {
19844 return is_string() ? m_value.string : nullptr;
19845 }
19846
19848 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
19849 {
19850 return is_boolean() ? &m_value.boolean : nullptr;
19851 }
19852
19854 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
19855 {
19856 return is_boolean() ? &m_value.boolean : nullptr;
19857 }
19858
19860 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
19861 {
19862 return is_number_integer() ? &m_value.number_integer : nullptr;
19863 }
19864
19866 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
19867 {
19868 return is_number_integer() ? &m_value.number_integer : nullptr;
19869 }
19870
19872 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
19873 {
19874 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19875 }
19876
19878 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
19879 {
19880 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19881 }
19882
19884 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
19885 {
19886 return is_number_float() ? &m_value.number_float : nullptr;
19887 }
19888
19890 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
19891 {
19892 return is_number_float() ? &m_value.number_float : nullptr;
19893 }
19894
19896 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
19897 {
19898 return is_binary() ? m_value.binary : nullptr;
19899 }
19900
19902 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
19903 {
19904 return is_binary() ? m_value.binary : nullptr;
19905 }
19906
19918 template<typename ReferenceType, typename ThisType>
19919 static ReferenceType get_ref_impl(ThisType& obj)
19920 {
19921 // delegate the call to get_ptr<>()
19922 auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
19923
19924 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
19925 {
19926 return *ptr;
19927 }
19928
19929 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()), obj));
19930 }
19931
19932 public:
19936
19963 template<typename PointerType, typename std::enable_if<
19964 std::is_pointer<PointerType>::value, int>::type = 0>
19965 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19966 {
19967 // delegate the call to get_impl_ptr<>()
19968 return get_impl_ptr(static_cast<PointerType>(nullptr));
19969 }
19970
19975 template < typename PointerType, typename std::enable_if <
19976 std::is_pointer<PointerType>::value&&
19977 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
19978 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19979 {
19980 // delegate the call to get_impl_ptr<>() const
19981 return get_impl_ptr(static_cast<PointerType>(nullptr));
19982 }
19983
19984 private:
20023 template < typename ValueType,
20024 detail::enable_if_t <
20025 detail::is_default_constructible<ValueType>::value&&
20026 detail::has_from_json<basic_json_t, ValueType>::value,
20027 int > = 0 >
20028 ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20029 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20030 {
20031 ValueType ret{};
20032 JSONSerializer<ValueType>::from_json(*this, ret);
20033 return ret;
20034 }
20035
20066 template < typename ValueType,
20067 detail::enable_if_t <
20068 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
20069 int > = 0 >
20070 ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20071 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20072 {
20073 return JSONSerializer<ValueType>::from_json(*this);
20074 }
20075
20091 template < typename BasicJsonType,
20092 detail::enable_if_t <
20093 detail::is_basic_json<BasicJsonType>::value,
20094 int > = 0 >
20095 BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20096 {
20097 return *this;
20098 }
20099
20114 template<typename BasicJsonType,
20115 detail::enable_if_t<
20116 std::is_same<BasicJsonType, basic_json_t>::value,
20117 int> = 0>
20118 basic_json get_impl(detail::priority_tag<3> /*unused*/) const
20119 {
20120 return *this;
20121 }
20122
20127 template<typename PointerType,
20128 detail::enable_if_t<
20129 std::is_pointer<PointerType>::value,
20130 int> = 0>
20131 constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
20132 -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
20133 {
20134 // delegate the call to get_ptr
20135 return get_ptr<PointerType>();
20136 }
20137
20138 public:
20162 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
20163 #if defined(JSON_HAS_CPP_14)
20164 constexpr
20165 #endif
20166 auto get() const noexcept(
20167 noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
20168 -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
20169 {
20170 // we cannot static_assert on ValueTypeCV being non-const, because
20171 // there is support for get<const basic_json_t>(), which is why we
20172 // still need the uncvref
20173 static_assert(!std::is_reference<ValueTypeCV>::value,
20174 "get() cannot be used with reference types, you might want to use get_ref()");
20175 return get_impl<ValueType>(detail::priority_tag<4> {});
20176 }
20177
20205 template<typename PointerType, typename std::enable_if<
20206 std::is_pointer<PointerType>::value, int>::type = 0>
20207 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
20208 {
20209 // delegate the call to get_ptr
20210 return get_ptr<PointerType>();
20211 }
20212
20246 template < typename ValueType,
20247 detail::enable_if_t <
20248 !detail::is_basic_json<ValueType>::value&&
20249 detail::has_from_json<basic_json_t, ValueType>::value,
20250 int > = 0 >
20251 ValueType & get_to(ValueType& v) const noexcept(noexcept(
20252 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
20253 {
20254 JSONSerializer<ValueType>::from_json(*this, v);
20255 return v;
20256 }
20257
20258 // specialization to allow to call get_to with a basic_json value
20259 // see https://github.com/nlohmann/json/issues/2175
20260 template<typename ValueType,
20261 detail::enable_if_t <
20262 detail::is_basic_json<ValueType>::value,
20263 int> = 0>
20264 ValueType & get_to(ValueType& v) const
20265 {
20266 v = *this;
20267 return v;
20268 }
20269
20270 template <
20271 typename T, std::size_t N,
20272 typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20273 detail::enable_if_t <
20274 detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
20275 Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20276 noexcept(noexcept(JSONSerializer<Array>::from_json(
20277 std::declval<const basic_json_t&>(), v)))
20278 {
20279 JSONSerializer<Array>::from_json(*this, v);
20280 return v;
20281 }
20282
20309 template<typename ReferenceType, typename std::enable_if<
20310 std::is_reference<ReferenceType>::value, int>::type = 0>
20311 ReferenceType get_ref()
20312 {
20313 // delegate call to get_ref_impl
20314 return get_ref_impl<ReferenceType>(*this);
20315 }
20316
20321 template < typename ReferenceType, typename std::enable_if <
20322 std::is_reference<ReferenceType>::value&&
20323 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
20324 ReferenceType get_ref() const
20325 {
20326 // delegate call to get_ref_impl
20327 return get_ref_impl<ReferenceType>(*this);
20328 }
20329
20359 template < typename ValueType, typename std::enable_if <
20360 !std::is_pointer<ValueType>::value&&
20361 !std::is_same<ValueType, detail::json_ref<basic_json>>::value&&
20362 !std::is_same<ValueType, typename string_t::value_type>::value&&
20363 !detail::is_basic_json<ValueType>::value
20364 && !std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
20365 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
20366 && !std::is_same<ValueType, typename std::string_view>::value
20367 #endif
20368 && detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
20369 , int >::type = 0 >
20370 JSON_EXPLICIT operator ValueType() const
20371 {
20372 // delegate the call to get<>() const
20373 return get<ValueType>();
20374 }
20375
20385 binary_t& get_binary()
20386 {
20387 if (!is_binary())
20388 {
20389 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20390 }
20391
20392 return *get_ptr<binary_t*>();
20393 }
20394
20396 const binary_t& get_binary() const
20397 {
20398 if (!is_binary())
20399 {
20400 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20401 }
20402
20403 return *get_ptr<const binary_t*>();
20404 }
20405
20407
20408
20410 // element access //
20412
20416
20443 reference at(size_type idx)
20444 {
20445 // at only works for arrays
20446 if (JSON_HEDLEY_LIKELY(is_array()))
20447 {
20448 JSON_TRY
20449 {
20450 return set_parent(m_value.array->at(idx));
20451 }
20452 JSON_CATCH (std::out_of_range&)
20453 {
20454 // create better exception explanation
20455 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
20456 }
20457 }
20458 else
20459 {
20460 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
20461 }
20462 }
20463
20490 const_reference at(size_type idx) const
20491 {
20492 // at only works for arrays
20493 if (JSON_HEDLEY_LIKELY(is_array()))
20494 {
20495 JSON_TRY
20496 {
20497 return m_value.array->at(idx);
20498 }
20499 JSON_CATCH (std::out_of_range&)
20500 {
20501 // create better exception explanation
20502 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
20503 }
20504 }
20505 else
20506 {
20507 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
20508 }
20509 }
20510
20541 reference at(const typename object_t::key_type& key)
20542 {
20543 // at only works for objects
20544 if (JSON_HEDLEY_LIKELY(is_object()))
20545 {
20546 JSON_TRY
20547 {
20548 return set_parent(m_value.object->at(key));
20549 }
20550 JSON_CATCH (std::out_of_range&)
20551 {
20552 // create better exception explanation
20553 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
20554 }
20555 }
20556 else
20557 {
20558 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
20559 }
20560 }
20561
20592 const_reference at(const typename object_t::key_type& key) const
20593 {
20594 // at only works for objects
20595 if (JSON_HEDLEY_LIKELY(is_object()))
20596 {
20597 JSON_TRY
20598 {
20599 return m_value.object->at(key);
20600 }
20601 JSON_CATCH (std::out_of_range&)
20602 {
20603 // create better exception explanation
20604 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
20605 }
20606 }
20607 else
20608 {
20609 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
20610 }
20611 }
20612
20638 reference operator[](size_type idx)
20639 {
20640 // implicitly convert null value to an empty array
20641 if (is_null())
20642 {
20643 m_type = value_t::array;
20644 m_value.array = create<array_t>();
20645 assert_invariant();
20646 }
20647
20648 // operator[] only works for arrays
20649 if (JSON_HEDLEY_LIKELY(is_array()))
20650 {
20651 // fill up array with null values if given idx is outside range
20652 if (idx >= m_value.array->size())
20653 {
20654 #if JSON_DIAGNOSTICS
20655 // remember array size before resizing
20656 const auto previous_size = m_value.array->size();
20657 #endif
20658 m_value.array->resize(idx + 1);
20659
20660 #if JSON_DIAGNOSTICS
20661 // set parent for values added above
20662 set_parents(begin() + static_cast<typename iterator::difference_type>(previous_size), static_cast<typename iterator::difference_type>(idx + 1 - previous_size));
20663 #endif
20664 }
20665
20666 return m_value.array->operator[](idx);
20667 }
20668
20669 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
20670 }
20671
20691 const_reference operator[](size_type idx) const
20692 {
20693 // const operator[] only works for arrays
20694 if (JSON_HEDLEY_LIKELY(is_array()))
20695 {
20696 return m_value.array->operator[](idx);
20697 }
20698
20699 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
20700 }
20701
20729 reference operator[](const typename object_t::key_type& key)
20730 {
20731 // implicitly convert null value to an empty object
20732 if (is_null())
20733 {
20734 m_type = value_t::object;
20735 m_value.object = create<object_t>();
20736 assert_invariant();
20737 }
20738
20739 // operator[] only works for objects
20740 if (JSON_HEDLEY_LIKELY(is_object()))
20741 {
20742 return set_parent(m_value.object->operator[](key));
20743 }
20744
20745 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
20746 }
20747
20778 const_reference operator[](const typename object_t::key_type& key) const
20779 {
20780 // const operator[] only works for objects
20781 if (JSON_HEDLEY_LIKELY(is_object()))
20782 {
20783 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20784 return m_value.object->find(key)->second;
20785 }
20786
20787 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
20788 }
20789
20817 template<typename T>
20818 JSON_HEDLEY_NON_NULL(2)
20819 reference operator[](T* key)
20820 {
20821 // implicitly convert null to object
20822 if (is_null())
20823 {
20824 m_type = value_t::object;
20825 m_value = value_t::object;
20826 assert_invariant();
20827 }
20828
20829 // at only works for objects
20830 if (JSON_HEDLEY_LIKELY(is_object()))
20831 {
20832 return set_parent(m_value.object->operator[](key));
20833 }
20834
20835 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
20836 }
20837
20868 template<typename T>
20869 JSON_HEDLEY_NON_NULL(2)
20870 const_reference operator[](T* key) const
20871 {
20872 // at only works for objects
20873 if (JSON_HEDLEY_LIKELY(is_object()))
20874 {
20875 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20876 return m_value.object->find(key)->second;
20877 }
20878
20879 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
20880 }
20881
20932 // using std::is_convertible in a std::enable_if will fail when using explicit conversions
20933 template < class ValueType, typename std::enable_if <
20934 detail::is_getable<basic_json_t, ValueType>::value
20935 && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
20936 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
20937 {
20938 // at only works for objects
20939 if (JSON_HEDLEY_LIKELY(is_object()))
20940 {
20941 // if key is found, return value and given default value otherwise
20942 const auto it = find(key);
20943 if (it != end())
20944 {
20945 return it->template get<ValueType>();
20946 }
20947
20948 return default_value;
20949 }
20950
20951 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
20952 }
20953
20958 string_t value(const typename object_t::key_type& key, const char* default_value) const
20959 {
20960 return value(key, string_t(default_value));
20961 }
20962
21006 template<class ValueType, typename std::enable_if<
21007 detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
21008 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
21009 {
21010 // at only works for objects
21011 if (JSON_HEDLEY_LIKELY(is_object()))
21012 {
21013 // if pointer resolves a value, return it or use default value
21014 JSON_TRY
21015 {
21016 return ptr.get_checked(this).template get<ValueType>();
21017 }
21018 JSON_INTERNAL_CATCH (out_of_range&)
21019 {
21020 return default_value;
21021 }
21022 }
21023
21024 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21025 }
21026
21031 JSON_HEDLEY_NON_NULL(3)
21032 string_t value(const json_pointer& ptr, const char* default_value) const
21033 {
21034 return value(ptr, string_t(default_value));
21035 }
21036
21062 reference front()
21063 {
21064 return *begin();
21065 }
21066
21070 const_reference front() const
21071 {
21072 return *cbegin();
21073 }
21074
21106 reference back()
21107 {
21108 auto tmp = end();
21109 --tmp;
21110 return *tmp;
21111 }
21112
21116 const_reference back() const
21117 {
21118 auto tmp = cend();
21119 --tmp;
21120 return *tmp;
21121 }
21122
21169 template < class IteratorType, typename std::enable_if <
21170 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21171 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21172 = 0 >
21173 IteratorType erase(IteratorType pos)
21174 {
21175 // make sure iterator fits the current value
21176 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21177 {
21178 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
21179 }
21180
21181 IteratorType result = end();
21182
21183 switch (m_type)
21184 {
21185 case value_t::boolean:
21186 case value_t::number_float:
21187 case value_t::number_integer:
21188 case value_t::number_unsigned:
21189 case value_t::string:
21190 case value_t::binary:
21191 {
21192 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
21193 {
21194 JSON_THROW(invalid_iterator::create(205, "iterator out of range", *this));
21195 }
21196
21197 if (is_string())
21198 {
21199 AllocatorType<string_t> alloc;
21200 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21201 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21202 m_value.string = nullptr;
21203 }
21204 else if (is_binary())
21205 {
21206 AllocatorType<binary_t> alloc;
21207 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21208 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21209 m_value.binary = nullptr;
21210 }
21211
21212 m_type = value_t::null;
21213 assert_invariant();
21214 break;
21215 }
21216
21217 case value_t::object:
21218 {
21219 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
21220 break;
21221 }
21222
21223 case value_t::array:
21224 {
21225 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
21226 break;
21227 }
21228
21229 default:
21230 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21231 }
21232
21233 return result;
21234 }
21235
21282 template < class IteratorType, typename std::enable_if <
21283 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21284 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21285 = 0 >
21286 IteratorType erase(IteratorType first, IteratorType last)
21287 {
21288 // make sure iterator fits the current value
21289 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
21290 {
21291 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", *this));
21292 }
21293
21294 IteratorType result = end();
21295
21296 switch (m_type)
21297 {
21298 case value_t::boolean:
21299 case value_t::number_float:
21300 case value_t::number_integer:
21301 case value_t::number_unsigned:
21302 case value_t::string:
21303 case value_t::binary:
21304 {
21305 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
21306 || !last.m_it.primitive_iterator.is_end()))
21307 {
21308 JSON_THROW(invalid_iterator::create(204, "iterators out of range", *this));
21309 }
21310
21311 if (is_string())
21312 {
21313 AllocatorType<string_t> alloc;
21314 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21315 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21316 m_value.string = nullptr;
21317 }
21318 else if (is_binary())
21319 {
21320 AllocatorType<binary_t> alloc;
21321 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21322 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21323 m_value.binary = nullptr;
21324 }
21325
21326 m_type = value_t::null;
21327 assert_invariant();
21328 break;
21329 }
21330
21331 case value_t::object:
21332 {
21333 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
21334 last.m_it.object_iterator);
21335 break;
21336 }
21337
21338 case value_t::array:
21339 {
21340 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
21341 last.m_it.array_iterator);
21342 break;
21343 }
21344
21345 default:
21346 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21347 }
21348
21349 return result;
21350 }
21351
21381 size_type erase(const typename object_t::key_type& key)
21382 {
21383 // this erase only works for objects
21384 if (JSON_HEDLEY_LIKELY(is_object()))
21385 {
21386 return m_value.object->erase(key);
21387 }
21388
21389 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21390 }
21391
21416 void erase(const size_type idx)
21417 {
21418 // this erase only works for arrays
21419 if (JSON_HEDLEY_LIKELY(is_array()))
21420 {
21421 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21422 {
21423 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21424 }
21425
21426 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
21427 }
21428 else
21429 {
21430 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21431 }
21432 }
21433
21435
21436
21438 // lookup //
21440
21443
21468 template<typename KeyT>
21469 iterator find(KeyT&& key)
21470 {
21471 auto result = end();
21472
21473 if (is_object())
21474 {
21475 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
21476 }
21477
21478 return result;
21479 }
21480
21485 template<typename KeyT>
21486 const_iterator find(KeyT&& key) const
21487 {
21488 auto result = cend();
21489
21490 if (is_object())
21491 {
21492 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
21493 }
21494
21495 return result;
21496 }
21497
21519 template<typename KeyT>
21520 size_type count(KeyT&& key) const
21521 {
21522 // return 0 for all nonobject types
21523 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
21524 }
21525
21551 template < typename KeyT, typename std::enable_if <
21552 !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
21553 bool contains(KeyT && key) const
21554 {
21555 return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
21556 }
21557
21584 bool contains(const json_pointer& ptr) const
21585 {
21586 return ptr.contains(this);
21587 }
21588
21590
21591
21593 // iterators //
21595
21598
21623 iterator begin() noexcept
21624 {
21625 iterator result(this);
21626 result.set_begin();
21627 return result;
21628 }
21629
21633 const_iterator begin() const noexcept
21634 {
21635 return cbegin();
21636 }
21637
21663 const_iterator cbegin() const noexcept
21664 {
21665 const_iterator result(this);
21666 result.set_begin();
21667 return result;
21668 }
21669
21694 iterator end() noexcept
21695 {
21696 iterator result(this);
21697 result.set_end();
21698 return result;
21699 }
21700
21704 const_iterator end() const noexcept
21705 {
21706 return cend();
21707 }
21708
21734 const_iterator cend() const noexcept
21735 {
21736 const_iterator result(this);
21737 result.set_end();
21738 return result;
21739 }
21740
21764 reverse_iterator rbegin() noexcept
21765 {
21766 return reverse_iterator(end());
21767 }
21768
21772 const_reverse_iterator rbegin() const noexcept
21773 {
21774 return crbegin();
21775 }
21776
21801 reverse_iterator rend() noexcept
21802 {
21803 return reverse_iterator(begin());
21804 }
21805
21809 const_reverse_iterator rend() const noexcept
21810 {
21811 return crend();
21812 }
21813
21838 const_reverse_iterator crbegin() const noexcept
21839 {
21840 return const_reverse_iterator(cend());
21841 }
21842
21867 const_reverse_iterator crend() const noexcept
21868 {
21869 return const_reverse_iterator(cbegin());
21870 }
21871
21872 public:
21930 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21931 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
21932 {
21933 return ref.items();
21934 }
21935
21939 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21940 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
21941 {
21942 return ref.items();
21943 }
21944
22013 iteration_proxy<iterator> items() noexcept
22014 {
22015 return iteration_proxy<iterator>(*this);
22016 }
22017
22021 iteration_proxy<const_iterator> items() const noexcept
22022 {
22023 return iteration_proxy<const_iterator>(*this);
22024 }
22025
22027
22028
22030 // capacity //
22032
22035
22078 bool empty() const noexcept
22079 {
22080 switch (m_type)
22081 {
22082 case value_t::null:
22083 {
22084 // null values are empty
22085 return true;
22086 }
22087
22088 case value_t::array:
22089 {
22090 // delegate call to array_t::empty()
22091 return m_value.array->empty();
22092 }
22093
22094 case value_t::object:
22095 {
22096 // delegate call to object_t::empty()
22097 return m_value.object->empty();
22098 }
22099
22100 default:
22101 {
22102 // all other types are nonempty
22103 return false;
22104 }
22105 }
22106 }
22107
22151 size_type size() const noexcept
22152 {
22153 switch (m_type)
22154 {
22155 case value_t::null:
22156 {
22157 // null values are empty
22158 return 0;
22159 }
22160
22161 case value_t::array:
22162 {
22163 // delegate call to array_t::size()
22164 return m_value.array->size();
22165 }
22166
22167 case value_t::object:
22168 {
22169 // delegate call to object_t::size()
22170 return m_value.object->size();
22171 }
22172
22173 default:
22174 {
22175 // all other types have size 1
22176 return 1;
22177 }
22178 }
22179 }
22180
22222 size_type max_size() const noexcept
22223 {
22224 switch (m_type)
22225 {
22226 case value_t::array:
22227 {
22228 // delegate call to array_t::max_size()
22229 return m_value.array->max_size();
22230 }
22231
22232 case value_t::object:
22233 {
22234 // delegate call to object_t::max_size()
22235 return m_value.object->max_size();
22236 }
22237
22238 default:
22239 {
22240 // all other types have max_size() == size()
22241 return size();
22242 }
22243 }
22244 }
22245
22247
22248
22250 // modifiers //
22252
22255
22293 void clear() noexcept
22294 {
22295 switch (m_type)
22296 {
22297 case value_t::number_integer:
22298 {
22299 m_value.number_integer = 0;
22300 break;
22301 }
22302
22303 case value_t::number_unsigned:
22304 {
22305 m_value.number_unsigned = 0;
22306 break;
22307 }
22308
22309 case value_t::number_float:
22310 {
22311 m_value.number_float = 0.0;
22312 break;
22313 }
22314
22315 case value_t::boolean:
22316 {
22317 m_value.boolean = false;
22318 break;
22319 }
22320
22321 case value_t::string:
22322 {
22323 m_value.string->clear();
22324 break;
22325 }
22326
22327 case value_t::binary:
22328 {
22329 m_value.binary->clear();
22330 break;
22331 }
22332
22333 case value_t::array:
22334 {
22335 m_value.array->clear();
22336 break;
22337 }
22338
22339 case value_t::object:
22340 {
22341 m_value.object->clear();
22342 break;
22343 }
22344
22345 default:
22346 break;
22347 }
22348 }
22349
22370 void push_back(basic_json&& val)
22371 {
22372 // push_back only works for null objects or arrays
22373 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22374 {
22375 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22376 }
22377
22378 // transform null object into an array
22379 if (is_null())
22380 {
22381 m_type = value_t::array;
22382 m_value = value_t::array;
22383 assert_invariant();
22384 }
22385
22386 // add element to array (move semantics)
22387 m_value.array->push_back(std::move(val));
22388 set_parent(m_value.array->back());
22389 // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
22390 }
22391
22396 reference operator+=(basic_json&& val)
22397 {
22398 push_back(std::move(val));
22399 return *this;
22400 }
22401
22406 void push_back(const basic_json& val)
22407 {
22408 // push_back only works for null objects or arrays
22409 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22410 {
22411 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22412 }
22413
22414 // transform null object into an array
22415 if (is_null())
22416 {
22417 m_type = value_t::array;
22418 m_value = value_t::array;
22419 assert_invariant();
22420 }
22421
22422 // add element to array
22423 m_value.array->push_back(val);
22424 set_parent(m_value.array->back());
22425 }
22426
22431 reference operator+=(const basic_json& val)
22432 {
22433 push_back(val);
22434 return *this;
22435 }
22436
22457 void push_back(const typename object_t::value_type& val)
22458 {
22459 // push_back only works for null objects or objects
22460 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22461 {
22462 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22463 }
22464
22465 // transform null object into an object
22466 if (is_null())
22467 {
22468 m_type = value_t::object;
22469 m_value = value_t::object;
22470 assert_invariant();
22471 }
22472
22473 // add element to object
22474 auto res = m_value.object->insert(val);
22475 set_parent(res.first->second);
22476 }
22477
22482 reference operator+=(const typename object_t::value_type& val)
22483 {
22484 push_back(val);
22485 return *this;
22486 }
22487
22513 void push_back(initializer_list_t init)
22514 {
22515 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
22516 {
22517 basic_json&& key = init.begin()->moved_or_copied();
22518 push_back(typename object_t::value_type(
22519 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
22520 }
22521 else
22522 {
22523 push_back(basic_json(init));
22524 }
22525 }
22526
22531 reference operator+=(initializer_list_t init)
22532 {
22533 push_back(init);
22534 return *this;
22535 }
22536
22560 template<class... Args>
22561 reference emplace_back(Args&& ... args)
22562 {
22563 // emplace_back only works for null objects or arrays
22564 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22565 {
22566 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()), *this));
22567 }
22568
22569 // transform null object into an array
22570 if (is_null())
22571 {
22572 m_type = value_t::array;
22573 m_value = value_t::array;
22574 assert_invariant();
22575 }
22576
22577 // add element to array (perfect forwarding)
22578 #ifdef JSON_HAS_CPP_17
22579 return set_parent(m_value.array->emplace_back(std::forward<Args>(args)...));
22580 #else
22581 m_value.array->emplace_back(std::forward<Args>(args)...);
22582 return set_parent(m_value.array->back());
22583 #endif
22584 }
22585
22613 template<class... Args>
22614 std::pair<iterator, bool> emplace(Args&& ... args)
22615 {
22616 // emplace only works for null objects or arrays
22617 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22618 {
22619 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()), *this));
22620 }
22621
22622 // transform null object into an object
22623 if (is_null())
22624 {
22625 m_type = value_t::object;
22626 m_value = value_t::object;
22627 assert_invariant();
22628 }
22629
22630 // add element to array (perfect forwarding)
22631 auto res = m_value.object->emplace(std::forward<Args>(args)...);
22632 set_parent(res.first->second);
22633
22634 // create result iterator and set iterator to the result of emplace
22635 auto it = begin();
22636 it.m_it.object_iterator = res.first;
22637
22638 // return pair of iterator and boolean
22639 return {it, res.second};
22640 }
22641
22645 template<typename... Args>
22646 iterator insert_iterator(const_iterator pos, Args&& ... args)
22647 {
22648 iterator result(this);
22649 JSON_ASSERT(m_value.array != nullptr);
22650
22651 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
22652 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
22653 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
22654
22655 // This could have been written as:
22656 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
22657 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
22658
22659 return result;
22660 }
22661
22684 iterator insert(const_iterator pos, const basic_json& val)
22685 {
22686 // insert only works for arrays
22687 if (JSON_HEDLEY_LIKELY(is_array()))
22688 {
22689 // check if iterator pos fits to this JSON value
22690 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22691 {
22692 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
22693 }
22694
22695 // insert to array and return iterator
22696 return set_parents(insert_iterator(pos, val), static_cast<typename iterator::difference_type>(1));
22697 }
22698
22699 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
22700 }
22701
22706 iterator insert(const_iterator pos, basic_json&& val)
22707 {
22708 return insert(pos, val);
22709 }
22710
22735 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
22736 {
22737 // insert only works for arrays
22738 if (JSON_HEDLEY_LIKELY(is_array()))
22739 {
22740 // check if iterator pos fits to this JSON value
22741 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22742 {
22743 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
22744 }
22745
22746 // insert to array and return iterator
22747 return set_parents(insert_iterator(pos, cnt, val), static_cast<typename iterator::difference_type>(cnt));
22748 }
22749
22750 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
22751 }
22752
22783 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
22784 {
22785 // insert only works for arrays
22786 if (JSON_HEDLEY_UNLIKELY(!is_array()))
22787 {
22788 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
22789 }
22790
22791 // check if iterator pos fits to this JSON value
22792 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22793 {
22794 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
22795 }
22796
22797 // check if range iterators belong to the same JSON object
22798 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22799 {
22800 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
22801 }
22802
22803 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
22804 {
22805 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", *this));
22806 }
22807
22808 // insert to array and return iterator
22809 return set_parents(insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator), std::distance(first, last));
22810 }
22811
22836 iterator insert(const_iterator pos, initializer_list_t ilist)
22837 {
22838 // insert only works for arrays
22839 if (JSON_HEDLEY_UNLIKELY(!is_array()))
22840 {
22841 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
22842 }
22843
22844 // check if iterator pos fits to this JSON value
22845 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22846 {
22847 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
22848 }
22849
22850 // insert to array and return iterator
22851 return set_parents(insert_iterator(pos, ilist.begin(), ilist.end()), static_cast<typename iterator::difference_type>(ilist.size()));
22852 }
22853
22877 void insert(const_iterator first, const_iterator last)
22878 {
22879 // insert only works for objects
22880 if (JSON_HEDLEY_UNLIKELY(!is_object()))
22881 {
22882 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
22883 }
22884
22885 // check if range iterators belong to the same JSON object
22886 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22887 {
22888 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
22889 }
22890
22891 // passed iterators must belong to objects
22892 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22893 {
22894 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
22895 }
22896
22897 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
22898 }
22899
22919 void update(const_reference j)
22920 {
22921 // implicitly convert null value to an empty object
22922 if (is_null())
22923 {
22924 m_type = value_t::object;
22925 m_value.object = create<object_t>();
22926 assert_invariant();
22927 }
22928
22929 if (JSON_HEDLEY_UNLIKELY(!is_object()))
22930 {
22931 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
22932 }
22933 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
22934 {
22935 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()), *this));
22936 }
22937
22938 for (auto it = j.cbegin(); it != j.cend(); ++it)
22939 {
22940 m_value.object->operator[](it.key()) = it.value();
22941 }
22942 }
22943
22970 void update(const_iterator first, const_iterator last)
22971 {
22972 // implicitly convert null value to an empty object
22973 if (is_null())
22974 {
22975 m_type = value_t::object;
22976 m_value.object = create<object_t>();
22977 assert_invariant();
22978 }
22979
22980 if (JSON_HEDLEY_UNLIKELY(!is_object()))
22981 {
22982 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
22983 }
22984
22985 // check if range iterators belong to the same JSON object
22986 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22987 {
22988 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
22989 }
22990
22991 // passed iterators must belong to objects
22992 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
22993 || !last.m_object->is_object()))
22994 {
22995 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
22996 }
22997
22998 for (auto it = first; it != last; ++it)
22999 {
23000 m_value.object->operator[](it.key()) = it.value();
23001 }
23002 }
23003
23021 void swap(reference other) noexcept (
23022 std::is_nothrow_move_constructible<value_t>::value&&
23023 std::is_nothrow_move_assignable<value_t>::value&&
23024 std::is_nothrow_move_constructible<json_value>::value&&
23025 std::is_nothrow_move_assignable<json_value>::value
23026 )
23027 {
23028 std::swap(m_type, other.m_type);
23029 std::swap(m_value, other.m_value);
23030
23031 set_parents();
23032 other.set_parents();
23033 assert_invariant();
23034 }
23035
23054 friend void swap(reference left, reference right) noexcept (
23055 std::is_nothrow_move_constructible<value_t>::value&&
23056 std::is_nothrow_move_assignable<value_t>::value&&
23057 std::is_nothrow_move_constructible<json_value>::value&&
23058 std::is_nothrow_move_assignable<json_value>::value
23059 )
23060 {
23061 left.swap(right);
23062 }
23063
23084 void swap(array_t& other) // NOLINT(bugprone-exception-escape)
23085 {
23086 // swap only works for arrays
23087 if (JSON_HEDLEY_LIKELY(is_array()))
23088 {
23089 std::swap(*(m_value.array), other);
23090 }
23091 else
23092 {
23093 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23094 }
23095 }
23096
23117 void swap(object_t& other) // NOLINT(bugprone-exception-escape)
23118 {
23119 // swap only works for objects
23120 if (JSON_HEDLEY_LIKELY(is_object()))
23121 {
23122 std::swap(*(m_value.object), other);
23123 }
23124 else
23125 {
23126 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23127 }
23128 }
23129
23150 void swap(string_t& other) // NOLINT(bugprone-exception-escape)
23151 {
23152 // swap only works for strings
23153 if (JSON_HEDLEY_LIKELY(is_string()))
23154 {
23155 std::swap(*(m_value.string), other);
23156 }
23157 else
23158 {
23159 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23160 }
23161 }
23162
23183 void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
23184 {
23185 // swap only works for strings
23186 if (JSON_HEDLEY_LIKELY(is_binary()))
23187 {
23188 std::swap(*(m_value.binary), other);
23189 }
23190 else
23191 {
23192 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23193 }
23194 }
23195
23197 void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
23198 {
23199 // swap only works for strings
23200 if (JSON_HEDLEY_LIKELY(is_binary()))
23201 {
23202 std::swap(*(m_value.binary), other);
23203 }
23204 else
23205 {
23206 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23207 }
23208 }
23209
23211
23212 public:
23214 // lexicographical comparison operators //
23216
23219
23275 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
23276 {
23277 const auto lhs_type = lhs.type();
23278 const auto rhs_type = rhs.type();
23279
23280 if (lhs_type == rhs_type)
23281 {
23282 switch (lhs_type)
23283 {
23284 case value_t::array:
23285 return *lhs.m_value.array == *rhs.m_value.array;
23286
23287 case value_t::object:
23288 return *lhs.m_value.object == *rhs.m_value.object;
23289
23290 case value_t::null:
23291 return true;
23292
23293 case value_t::string:
23294 return *lhs.m_value.string == *rhs.m_value.string;
23295
23296 case value_t::boolean:
23297 return lhs.m_value.boolean == rhs.m_value.boolean;
23298
23299 case value_t::number_integer:
23300 return lhs.m_value.number_integer == rhs.m_value.number_integer;
23301
23302 case value_t::number_unsigned:
23303 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
23304
23305 case value_t::number_float:
23306 return lhs.m_value.number_float == rhs.m_value.number_float;
23307
23308 case value_t::binary:
23309 return *lhs.m_value.binary == *rhs.m_value.binary;
23310
23311 default:
23312 return false;
23313 }
23314 }
23315 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
23316 {
23317 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
23318 }
23319 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
23320 {
23321 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
23322 }
23323 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
23324 {
23325 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
23326 }
23327 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
23328 {
23329 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
23330 }
23331 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
23332 {
23333 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
23334 }
23335 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
23336 {
23337 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
23338 }
23339
23340 return false;
23341 }
23342
23347 template<typename ScalarType, typename std::enable_if<
23348 std::is_scalar<ScalarType>::value, int>::type = 0>
23349 friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
23350 {
23351 return lhs == basic_json(rhs);
23352 }
23353
23358 template<typename ScalarType, typename std::enable_if<
23359 std::is_scalar<ScalarType>::value, int>::type = 0>
23360 friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
23361 {
23362 return basic_json(lhs) == rhs;
23363 }
23364
23383 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
23384 {
23385 return !(lhs == rhs);
23386 }
23387
23392 template<typename ScalarType, typename std::enable_if<
23393 std::is_scalar<ScalarType>::value, int>::type = 0>
23394 friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23395 {
23396 return lhs != basic_json(rhs);
23397 }
23398
23403 template<typename ScalarType, typename std::enable_if<
23404 std::is_scalar<ScalarType>::value, int>::type = 0>
23405 friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
23406 {
23407 return basic_json(lhs) != rhs;
23408 }
23409
23436 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
23437 {
23438 const auto lhs_type = lhs.type();
23439 const auto rhs_type = rhs.type();
23440
23441 if (lhs_type == rhs_type)
23442 {
23443 switch (lhs_type)
23444 {
23445 case value_t::array:
23446 // note parentheses are necessary, see
23447 // https://github.com/nlohmann/json/issues/1530
23448 return (*lhs.m_value.array) < (*rhs.m_value.array);
23449
23450 case value_t::object:
23451 return (*lhs.m_value.object) < (*rhs.m_value.object);
23452
23453 case value_t::null:
23454 return false;
23455
23456 case value_t::string:
23457 return (*lhs.m_value.string) < (*rhs.m_value.string);
23458
23459 case value_t::boolean:
23460 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
23461
23462 case value_t::number_integer:
23463 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
23464
23465 case value_t::number_unsigned:
23466 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
23467
23468 case value_t::number_float:
23469 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
23470
23471 case value_t::binary:
23472 return (*lhs.m_value.binary) < (*rhs.m_value.binary);
23473
23474 default:
23475 return false;
23476 }
23477 }
23478 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
23479 {
23480 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
23481 }
23482 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
23483 {
23484 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
23485 }
23486 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
23487 {
23488 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
23489 }
23490 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
23491 {
23492 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
23493 }
23494 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
23495 {
23496 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
23497 }
23498 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
23499 {
23500 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
23501 }
23502
23503 // We only reach this line if we cannot compare values. In that case,
23504 // we compare types. Note we have to call the operator explicitly,
23505 // because MSVC has problems otherwise.
23506 return operator<(lhs_type, rhs_type);
23507 }
23508
23513 template<typename ScalarType, typename std::enable_if<
23514 std::is_scalar<ScalarType>::value, int>::type = 0>
23515 friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
23516 {
23517 return lhs < basic_json(rhs);
23518 }
23519
23524 template<typename ScalarType, typename std::enable_if<
23525 std::is_scalar<ScalarType>::value, int>::type = 0>
23526 friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
23527 {
23528 return basic_json(lhs) < rhs;
23529 }
23530
23550 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
23551 {
23552 return !(rhs < lhs);
23553 }
23554
23559 template<typename ScalarType, typename std::enable_if<
23560 std::is_scalar<ScalarType>::value, int>::type = 0>
23561 friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
23562 {
23563 return lhs <= basic_json(rhs);
23564 }
23565
23570 template<typename ScalarType, typename std::enable_if<
23571 std::is_scalar<ScalarType>::value, int>::type = 0>
23572 friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
23573 {
23574 return basic_json(lhs) <= rhs;
23575 }
23576
23596 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
23597 {
23598 return !(lhs <= rhs);
23599 }
23600
23605 template<typename ScalarType, typename std::enable_if<
23606 std::is_scalar<ScalarType>::value, int>::type = 0>
23607 friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
23608 {
23609 return lhs > basic_json(rhs);
23610 }
23611
23616 template<typename ScalarType, typename std::enable_if<
23617 std::is_scalar<ScalarType>::value, int>::type = 0>
23618 friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
23619 {
23620 return basic_json(lhs) > rhs;
23621 }
23622
23642 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
23643 {
23644 return !(lhs < rhs);
23645 }
23646
23651 template<typename ScalarType, typename std::enable_if<
23652 std::is_scalar<ScalarType>::value, int>::type = 0>
23653 friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
23654 {
23655 return lhs >= basic_json(rhs);
23656 }
23657
23662 template<typename ScalarType, typename std::enable_if<
23663 std::is_scalar<ScalarType>::value, int>::type = 0>
23664 friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
23665 {
23666 return basic_json(lhs) >= rhs;
23667 }
23668
23670
23672 // serialization //
23674
23677
23709 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
23710 {
23711 // read width member and use it as indentation parameter if nonzero
23712 const bool pretty_print = o.width() > 0;
23713 const auto indentation = pretty_print ? o.width() : 0;
23714
23715 // reset width to 0 for subsequent calls to this stream
23716 o.width(0);
23717
23718 // do the actual serialization
23719 serializer s(detail::output_adapter<char>(o), o.fill());
23720 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
23721 return o;
23722 }
23723
23732 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
23733 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
23734 {
23735 return o << j;
23736 }
23737
23739
23740
23742 // deserialization //
23744
23747
23799 template<typename InputType>
23800
23801 static basic_json parse(InputType&& i,
23802 const parser_callback_t cb = nullptr,
23803 const bool allow_exceptions = true,
23804 const bool ignore_comments = false)
23805 {
23806 basic_json result;
23807 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
23808 return result;
23809 }
23810
23837 template<typename IteratorType>
23838
23839 static basic_json parse(IteratorType first,
23840 IteratorType last,
23841 const parser_callback_t cb = nullptr,
23842 const bool allow_exceptions = true,
23843 const bool ignore_comments = false)
23844 {
23845 basic_json result;
23846 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
23847 return result;
23848 }
23849
23850
23851 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
23852 static basic_json parse(detail::span_input_adapter&& i,
23853 const parser_callback_t cb = nullptr,
23854 const bool allow_exceptions = true,
23855 const bool ignore_comments = false)
23856 {
23857 basic_json result;
23858 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
23859 return result;
23860 }
23861
23892 template<typename InputType>
23893 static bool accept(InputType&& i,
23894 const bool ignore_comments = false)
23895 {
23896 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
23897 }
23898
23899 template<typename IteratorType>
23900 static bool accept(IteratorType first, IteratorType last,
23901 const bool ignore_comments = false)
23902 {
23903 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
23904 }
23905
23906
23907 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
23908 static bool accept(detail::span_input_adapter&& i,
23909 const bool ignore_comments = false)
23910 {
23911 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
23912 }
23913
23954 template <typename InputType, typename SAX>
23955 JSON_HEDLEY_NON_NULL(2)
23956 static bool sax_parse(InputType&& i, SAX* sax,
23957 input_format_t format = input_format_t::json,
23958 const bool strict = true,
23959 const bool ignore_comments = false)
23960 {
23961 auto ia = detail::input_adapter(std::forward<InputType>(i));
23962 return format == input_format_t::json
23963 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23964 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23965 }
23966
23967 template<class IteratorType, class SAX>
23968 JSON_HEDLEY_NON_NULL(3)
23969 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
23970 input_format_t format = input_format_t::json,
23971 const bool strict = true,
23972 const bool ignore_comments = false)
23973 {
23974 auto ia = detail::input_adapter(std::move(first), std::move(last));
23975 return format == input_format_t::json
23976 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23977 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23978 }
23979
23980 template <typename SAX>
23981 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
23982 JSON_HEDLEY_NON_NULL(2)
23983 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
23984 input_format_t format = input_format_t::json,
23985 const bool strict = true,
23986 const bool ignore_comments = false)
23987 {
23988 auto ia = i.get();
23989 return format == input_format_t::json
23990 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23991 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23992 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23993 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23994 }
23995
24004 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
24005 friend std::istream& operator<<(basic_json& j, std::istream& i)
24006 {
24007 return operator>>(i, j);
24008 }
24009
24035 friend std::istream& operator>>(std::istream& i, basic_json& j)
24036 {
24037 parser(detail::input_adapter(i)).parse(false, j);
24038 return i;
24039 }
24040
24042
24044 // convenience functions //
24046
24078
24079 const char* type_name() const noexcept
24080 {
24081 {
24082 switch (m_type)
24083 {
24084 case value_t::null:
24085 return "null";
24086 case value_t::object:
24087 return "object";
24088 case value_t::array:
24089 return "array";
24090 case value_t::string:
24091 return "string";
24092 case value_t::boolean:
24093 return "boolean";
24094 case value_t::binary:
24095 return "binary";
24096 case value_t::discarded:
24097 return "discarded";
24098 default:
24099 return "number";
24100 }
24101 }
24102 }
24103
24104
24105 JSON_PRIVATE_UNLESS_TESTED:
24107 // member variables //
24109
24111 value_t m_type = value_t::null;
24112
24114 json_value m_value = {};
24115
24116 #if JSON_DIAGNOSTICS
24118 basic_json* m_parent = nullptr;
24119 #endif
24120
24122 // binary serialization/deserialization //
24124
24127
24128 public:
24223 static std::vector<uint8_t> to_cbor(const basic_json& j)
24224 {
24225 std::vector<uint8_t> result;
24226 to_cbor(j, result);
24227 return result;
24228 }
24229
24230 static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
24231 {
24232 binary_writer<uint8_t>(o).write_cbor(j);
24233 }
24234
24235 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
24236 {
24237 binary_writer<char>(o).write_cbor(j);
24238 }
24239
24318 static std::vector<uint8_t> to_msgpack(const basic_json& j)
24319 {
24320 std::vector<uint8_t> result;
24321 to_msgpack(j, result);
24322 return result;
24323 }
24324
24325 static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
24326 {
24327 binary_writer<uint8_t>(o).write_msgpack(j);
24328 }
24329
24330 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
24331 {
24332 binary_writer<char>(o).write_msgpack(j);
24333 }
24334
24421 static std::vector<uint8_t> to_ubjson(const basic_json& j,
24422 const bool use_size = false,
24423 const bool use_type = false)
24424 {
24425 std::vector<uint8_t> result;
24426 to_ubjson(j, result, use_size, use_type);
24427 return result;
24428 }
24429
24430 static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
24431 const bool use_size = false, const bool use_type = false)
24432 {
24433 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
24434 }
24435
24436 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
24437 const bool use_size = false, const bool use_type = false)
24438 {
24439 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
24440 }
24441
24442
24499 static std::vector<uint8_t> to_bson(const basic_json& j)
24500 {
24501 std::vector<uint8_t> result;
24502 to_bson(j, result);
24503 return result;
24504 }
24505
24514 static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
24515 {
24516 binary_writer<uint8_t>(o).write_bson(j);
24517 }
24518
24522 static void to_bson(const basic_json& j, detail::output_adapter<char> o)
24523 {
24524 binary_writer<char>(o).write_bson(j);
24525 }
24526
24527
24630 template<typename InputType>
24631
24632 static basic_json from_cbor(InputType&& i,
24633 const bool strict = true,
24634 const bool allow_exceptions = true,
24635 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24636 {
24637 basic_json result;
24638 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24639 auto ia = detail::input_adapter(std::forward<InputType>(i));
24640 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24641 return res ? result : basic_json(value_t::discarded);
24642 }
24643
24647 template<typename IteratorType>
24648
24649 static basic_json from_cbor(IteratorType first, IteratorType last,
24650 const bool strict = true,
24651 const bool allow_exceptions = true,
24652 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24653 {
24654 basic_json result;
24655 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24656 auto ia = detail::input_adapter(std::move(first), std::move(last));
24657 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24658 return res ? result : basic_json(value_t::discarded);
24659 }
24660
24661 template<typename T>
24662
24663 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
24664 static basic_json from_cbor(const T* ptr, std::size_t len,
24665 const bool strict = true,
24666 const bool allow_exceptions = true,
24667 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24668 {
24669 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
24670 }
24671
24672
24673
24674 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
24675 static basic_json from_cbor(detail::span_input_adapter&& i,
24676 const bool strict = true,
24677 const bool allow_exceptions = true,
24678 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24679 {
24680 basic_json result;
24681 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24682 auto ia = i.get();
24683 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24684 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24685 return res ? result : basic_json(value_t::discarded);
24686 }
24687
24774 template<typename InputType>
24775
24776 static basic_json from_msgpack(InputType&& i,
24777 const bool strict = true,
24778 const bool allow_exceptions = true)
24779 {
24780 basic_json result;
24781 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24782 auto ia = detail::input_adapter(std::forward<InputType>(i));
24783 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24784 return res ? result : basic_json(value_t::discarded);
24785 }
24786
24790 template<typename IteratorType>
24791
24792 static basic_json from_msgpack(IteratorType first, IteratorType last,
24793 const bool strict = true,
24794 const bool allow_exceptions = true)
24795 {
24796 basic_json result;
24797 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24798 auto ia = detail::input_adapter(std::move(first), std::move(last));
24799 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24800 return res ? result : basic_json(value_t::discarded);
24801 }
24802
24803
24804 template<typename T>
24805
24806 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
24807 static basic_json from_msgpack(const T* ptr, std::size_t len,
24808 const bool strict = true,
24809 const bool allow_exceptions = true)
24810 {
24811 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
24812 }
24813
24814
24815 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
24816 static basic_json from_msgpack(detail::span_input_adapter&& i,
24817 const bool strict = true,
24818 const bool allow_exceptions = true)
24819 {
24820 basic_json result;
24821 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24822 auto ia = i.get();
24823 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24824 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24825 return res ? result : basic_json(value_t::discarded);
24826 }
24827
24828
24891 template<typename InputType>
24892
24893 static basic_json from_ubjson(InputType&& i,
24894 const bool strict = true,
24895 const bool allow_exceptions = true)
24896 {
24897 basic_json result;
24898 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24899 auto ia = detail::input_adapter(std::forward<InputType>(i));
24900 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24901 return res ? result : basic_json(value_t::discarded);
24902 }
24903
24907 template<typename IteratorType>
24908
24909 static basic_json from_ubjson(IteratorType first, IteratorType last,
24910 const bool strict = true,
24911 const bool allow_exceptions = true)
24912 {
24913 basic_json result;
24914 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24915 auto ia = detail::input_adapter(std::move(first), std::move(last));
24916 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24917 return res ? result : basic_json(value_t::discarded);
24918 }
24919
24920 template<typename T>
24921
24922 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
24923 static basic_json from_ubjson(const T* ptr, std::size_t len,
24924 const bool strict = true,
24925 const bool allow_exceptions = true)
24926 {
24927 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
24928 }
24929
24930
24931 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
24932 static basic_json from_ubjson(detail::span_input_adapter&& i,
24933 const bool strict = true,
24934 const bool allow_exceptions = true)
24935 {
24936 basic_json result;
24937 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24938 auto ia = i.get();
24939 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24940 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24941 return res ? result : basic_json(value_t::discarded);
24942 }
24943
24944
25005 template<typename InputType>
25006
25007 static basic_json from_bson(InputType&& i,
25008 const bool strict = true,
25009 const bool allow_exceptions = true)
25010 {
25011 basic_json result;
25012 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25013 auto ia = detail::input_adapter(std::forward<InputType>(i));
25014 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25015 return res ? result : basic_json(value_t::discarded);
25016 }
25017
25021 template<typename IteratorType>
25022
25023 static basic_json from_bson(IteratorType first, IteratorType last,
25024 const bool strict = true,
25025 const bool allow_exceptions = true)
25026 {
25027 basic_json result;
25028 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25029 auto ia = detail::input_adapter(std::move(first), std::move(last));
25030 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25031 return res ? result : basic_json(value_t::discarded);
25032 }
25033
25034 template<typename T>
25035
25036 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25037 static basic_json from_bson(const T* ptr, std::size_t len,
25038 const bool strict = true,
25039 const bool allow_exceptions = true)
25040 {
25041 return from_bson(ptr, ptr + len, strict, allow_exceptions);
25042 }
25043
25044
25045 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25046 static basic_json from_bson(detail::span_input_adapter&& i,
25047 const bool strict = true,
25048 const bool allow_exceptions = true)
25049 {
25050 basic_json result;
25051 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25052 auto ia = i.get();
25053 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25054 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25055 return res ? result : basic_json(value_t::discarded);
25056 }
25058
25060 // JSON Pointer support //
25062
25065
25099 reference operator[](const json_pointer& ptr)
25100 {
25101 return ptr.get_unchecked(this);
25102 }
25103
25127 const_reference operator[](const json_pointer& ptr) const
25128 {
25129 return ptr.get_unchecked(this);
25130 }
25131
25170 reference at(const json_pointer& ptr)
25171 {
25172 return ptr.get_checked(this);
25173 }
25174
25213 const_reference at(const json_pointer& ptr) const
25214 {
25215 return ptr.get_checked(this);
25216 }
25217
25240 basic_json flatten() const
25241 {
25242 basic_json result(value_t::object);
25243 json_pointer::flatten("", *this, result);
25244 return result;
25245 }
25246
25277 basic_json unflatten() const
25278 {
25279 return json_pointer::unflatten(*this);
25280 }
25281
25283
25285 // JSON Patch functions //
25287
25290
25338 basic_json patch(const basic_json& json_patch) const
25339 {
25340 // make a working copy to apply the patch to
25341 basic_json result = *this;
25342
25343 // the valid JSON Patch operations
25344 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
25345
25346 const auto get_op = [](const std::string & op)
25347 {
25348 if (op == "add")
25349 {
25350 return patch_operations::add;
25351 }
25352 if (op == "remove")
25353 {
25354 return patch_operations::remove;
25355 }
25356 if (op == "replace")
25357 {
25358 return patch_operations::replace;
25359 }
25360 if (op == "move")
25361 {
25362 return patch_operations::move;
25363 }
25364 if (op == "copy")
25365 {
25366 return patch_operations::copy;
25367 }
25368 if (op == "test")
25369 {
25370 return patch_operations::test;
25371 }
25372
25373 return patch_operations::invalid;
25374 };
25375
25376 // wrapper for "add" operation; add value at ptr
25377 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
25378 {
25379 // adding to the root of the target document means replacing it
25380 if (ptr.empty())
25381 {
25382 result = val;
25383 return;
25384 }
25385
25386 // make sure the top element of the pointer exists
25387 json_pointer top_pointer = ptr.top();
25388 if (top_pointer != ptr)
25389 {
25390 result.at(top_pointer);
25391 }
25392
25393 // get reference to parent of JSON pointer ptr
25394 const auto last_path = ptr.back();
25395 ptr.pop_back();
25396 basic_json& parent = result[ptr];
25397
25398 switch (parent.m_type)
25399 {
25400 case value_t::null:
25401 case value_t::object:
25402 {
25403 // use operator[] to add value
25404 parent[last_path] = val;
25405 break;
25406 }
25407
25408 case value_t::array:
25409 {
25410 if (last_path == "-")
25411 {
25412 // special case: append to back
25413 parent.push_back(val);
25414 }
25415 else
25416 {
25417 const auto idx = json_pointer::array_index(last_path);
25418 if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
25419 {
25420 // avoid undefined behavior
25421 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", parent));
25422 }
25423
25424 // default case: insert add offset
25425 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
25426 }
25427 break;
25428 }
25429
25430 // if there exists a parent it cannot be primitive
25431 default: // LCOV_EXCL_LINE
25432 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
25433 }
25434 };
25435
25436 // wrapper for "remove" operation; remove value at ptr
25437 const auto operation_remove = [this, &result](json_pointer & ptr)
25438 {
25439 // get reference to parent of JSON pointer ptr
25440 const auto last_path = ptr.back();
25441 ptr.pop_back();
25442 basic_json& parent = result.at(ptr);
25443
25444 // remove child
25445 if (parent.is_object())
25446 {
25447 // perform range check
25448 auto it = parent.find(last_path);
25449 if (JSON_HEDLEY_LIKELY(it != parent.end()))
25450 {
25451 parent.erase(it);
25452 }
25453 else
25454 {
25455 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found", *this));
25456 }
25457 }
25458 else if (parent.is_array())
25459 {
25460 // note erase performs range check
25461 parent.erase(json_pointer::array_index(last_path));
25462 }
25463 };
25464
25465 // type check: top level value must be an array
25466 if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
25467 {
25468 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", json_patch));
25469 }
25470
25471 // iterate and apply the operations
25472 for (const auto& val : json_patch)
25473 {
25474 // wrapper to get a value for an operation
25475 const auto get_value = [&val](const std::string & op,
25476 const std::string & member,
25477 bool string_type) -> basic_json &
25478 {
25479 // find value
25480 auto it = val.m_value.object->find(member);
25481
25482 // context-sensitive error message
25483 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
25484
25485 // check if desired value is present
25486 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
25487 {
25488 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
25489 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'", val));
25490 }
25491
25492 // check if result is of type string
25493 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
25494 {
25495 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
25496 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'", val));
25497 }
25498
25499 // no error: return value
25500 return it->second;
25501 };
25502
25503 // type check: every element of the array must be an object
25504 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
25505 {
25506 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", val));
25507 }
25508
25509 // collect mandatory members
25510 const auto op = get_value("op", "op", true).template get<std::string>();
25511 const auto path = get_value(op, "path", true).template get<std::string>();
25512 json_pointer ptr(path);
25513
25514 switch (get_op(op))
25515 {
25516 case patch_operations::add:
25517 {
25518 operation_add(ptr, get_value("add", "value", false));
25519 break;
25520 }
25521
25522 case patch_operations::remove:
25523 {
25524 operation_remove(ptr);
25525 break;
25526 }
25527
25528 case patch_operations::replace:
25529 {
25530 // the "path" location must exist - use at()
25531 result.at(ptr) = get_value("replace", "value", false);
25532 break;
25533 }
25534
25535 case patch_operations::move:
25536 {
25537 const auto from_path = get_value("move", "from", true).template get<std::string>();
25538 json_pointer from_ptr(from_path);
25539
25540 // the "from" location must exist - use at()
25541 basic_json v = result.at(from_ptr);
25542
25543 // The move operation is functionally identical to a
25544 // "remove" operation on the "from" location, followed
25545 // immediately by an "add" operation at the target
25546 // location with the value that was just removed.
25547 operation_remove(from_ptr);
25548 operation_add(ptr, v);
25549 break;
25550 }
25551
25552 case patch_operations::copy:
25553 {
25554 const auto from_path = get_value("copy", "from", true).template get<std::string>();
25555 const json_pointer from_ptr(from_path);
25556
25557 // the "from" location must exist - use at()
25558 basic_json v = result.at(from_ptr);
25559
25560 // The copy is functionally identical to an "add"
25561 // operation at the target location using the value
25562 // specified in the "from" member.
25563 operation_add(ptr, v);
25564 break;
25565 }
25566
25567 case patch_operations::test:
25568 {
25569 bool success = false;
25570 JSON_TRY
25571 {
25572 // check if "value" matches the one at "path"
25573 // the "path" location must exist - use at()
25574 success = (result.at(ptr) == get_value("test", "value", false));
25575 }
25576 JSON_INTERNAL_CATCH (out_of_range&)
25577 {
25578 // ignore out of range errors: success remains false
25579 }
25580
25581 // throw an exception if test fails
25582 if (JSON_HEDLEY_UNLIKELY(!success))
25583 {
25584 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump(), val));
25585 }
25586
25587 break;
25588 }
25589
25590 default:
25591 {
25592 // op must be "add", "remove", "replace", "move", "copy", or
25593 // "test"
25594 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid", val));
25595 }
25596 }
25597 }
25598
25599 return result;
25600 }
25601
25635
25636 static basic_json diff(const basic_json& source, const basic_json& target,
25637 const std::string& path = "")
25638 {
25639 // the patch
25640 basic_json result(value_t::array);
25641
25642 // if the values are the same, return empty patch
25643 if (source == target)
25644 {
25645 return result;
25646 }
25647
25648 if (source.type() != target.type())
25649 {
25650 // different types: replace value
25651 result.push_back(
25652 {
25653 {"op", "replace"}, {"path", path}, {"value", target}
25654 });
25655 return result;
25656 }
25657
25658 switch (source.type())
25659 {
25660 case value_t::array:
25661 {
25662 // first pass: traverse common elements
25663 std::size_t i = 0;
25664 while (i < source.size() && i < target.size())
25665 {
25666 // recursive call to compare array values at index i
25667 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
25668 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
25669 ++i;
25670 }
25671
25672 // i now reached the end of at least one array
25673 // in a second pass, traverse the remaining elements
25674
25675 // remove my remaining elements
25676 const auto end_index = static_cast<difference_type>(result.size());
25677 while (i < source.size())
25678 {
25679 // add operations in reverse order to avoid invalid
25680 // indices
25681 result.insert(result.begin() + end_index, object(
25682 {
25683 {"op", "remove"},
25684 {"path", path + "/" + std::to_string(i)}
25685 }));
25686 ++i;
25687 }
25688
25689 // add other remaining elements
25690 while (i < target.size())
25691 {
25692 result.push_back(
25693 {
25694 {"op", "add"},
25695 {"path", path + "/-"},
25696 {"value", target[i]}
25697 });
25698 ++i;
25699 }
25700
25701 break;
25702 }
25703
25704 case value_t::object:
25705 {
25706 // first pass: traverse this object's elements
25707 for (auto it = source.cbegin(); it != source.cend(); ++it)
25708 {
25709 // escape the key name to be used in a JSON patch
25710 const auto path_key = path + "/" + detail::escape(it.key());
25711
25712 if (target.find(it.key()) != target.end())
25713 {
25714 // recursive call to compare object values at key it
25715 auto temp_diff = diff(it.value(), target[it.key()], path_key);
25716 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
25717 }
25718 else
25719 {
25720 // found a key that is not in o -> remove it
25721 result.push_back(object(
25722 {
25723 {"op", "remove"}, {"path", path_key}
25724 }));
25725 }
25726 }
25727
25728 // second pass: traverse other object's elements
25729 for (auto it = target.cbegin(); it != target.cend(); ++it)
25730 {
25731 if (source.find(it.key()) == source.end())
25732 {
25733 // found a key that is not in this -> add it
25734 const auto path_key = path + "/" + detail::escape(it.key());
25735 result.push_back(
25736 {
25737 {"op", "add"}, {"path", path_key},
25738 {"value", it.value()}
25739 });
25740 }
25741 }
25742
25743 break;
25744 }
25745
25746 default:
25747 {
25748 // both primitive type: replace value
25749 result.push_back(
25750 {
25751 {"op", "replace"}, {"path", path}, {"value", target}
25752 });
25753 break;
25754 }
25755 }
25756
25757 return result;
25758 }
25759
25761
25763 // JSON Merge Patch functions //
25765
25768
25811 void merge_patch(const basic_json& apply_patch)
25812 {
25813 if (apply_patch.is_object())
25814 {
25815 if (!is_object())
25816 {
25817 *this = object();
25818 }
25819 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
25820 {
25821 if (it.value().is_null())
25822 {
25823 erase(it.key());
25824 }
25825 else
25826 {
25827 operator[](it.key()).merge_patch(it.value());
25828 }
25829 }
25830 }
25831 else
25832 {
25833 *this = apply_patch;
25834 }
25835 }
25836
25838 };
25839
25849 NLOHMANN_BASIC_JSON_TPL_DECLARATION
25850 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
25851 {
25852 return j.dump();
25853 }
25854 } // namespace nlohmann
25855
25857 // nonmember support //
25859
25860 // specialization of std::swap, and std::hash
25861 namespace std
25862 {
25863
25865 template<>
25866 struct hash<nlohmann::json>
25867 {
25873 std::size_t operator()(const nlohmann::json& j) const
25874 {
25875 return nlohmann::detail::hash(j);
25876 }
25877 };
25878
25882 template<>
25883 struct less<::nlohmann::detail::value_t>
25884 {
25889 bool operator()(nlohmann::detail::value_t lhs,
25890 nlohmann::detail::value_t rhs) const noexcept
25891 {
25892 return nlohmann::detail::operator<(lhs, rhs);
25893 }
25894 };
25895
25896 // C++20 prohibit function specialization in the std namespace.
25897 #ifndef JSON_HAS_CPP_20
25898
25904 template<>
25905 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
25906 is_nothrow_move_constructible<nlohmann::json>::value&& // NOLINT(misc-redundant-expression)
25907 is_nothrow_move_assignable<nlohmann::json>::value
25908 )
25909 {
25910 j1.swap(j2);
25911 }
25912
25913 #endif
25914
25915 } // namespace std
25916
25930 JSON_HEDLEY_NON_NULL(1)
25931 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
25932 {
25933 return nlohmann::json::parse(s, s + n);
25934 }
25935
25949 JSON_HEDLEY_NON_NULL(1)
25950 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
25951 {
25952 return nlohmann::json::json_pointer(std::string(s, n));
25953 }
25954
25955 // #include <nlohmann/detail/macro_unscope.hpp>
25956
25957
25958 // restore GCC/clang diagnostic settings
25959 #if defined(__clang__)
25960 #pragma GCC diagnostic pop
25961 #endif
25962
25963 // clean up
25964 #undef JSON_ASSERT
25965 #undef JSON_INTERNAL_CATCH
25966 #undef JSON_CATCH
25967 #undef JSON_THROW
25968 #undef JSON_TRY
25969 #undef JSON_PRIVATE_UNLESS_TESTED
25970 #undef JSON_HAS_CPP_14
25971 #undef JSON_HAS_CPP_17
25972 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
25973 #undef NLOHMANN_BASIC_JSON_TPL
25974 #undef JSON_EXPLICIT
25975
25976 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
25977
25978
25979 #undef JSON_HEDLEY_ALWAYS_INLINE
25980 #undef JSON_HEDLEY_ARM_VERSION
25981 #undef JSON_HEDLEY_ARM_VERSION_CHECK
25982 #undef JSON_HEDLEY_ARRAY_PARAM
25983 #undef JSON_HEDLEY_ASSUME
25984 #undef JSON_HEDLEY_BEGIN_C_DECLS
25985 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
25986 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
25987 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
25988 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
25989 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
25990 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
25991 #undef JSON_HEDLEY_CLANG_HAS_WARNING
25992 #undef JSON_HEDLEY_COMPCERT_VERSION
25993 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
25994 #undef JSON_HEDLEY_CONCAT
25995 #undef JSON_HEDLEY_CONCAT3
25996 #undef JSON_HEDLEY_CONCAT3_EX
25997 #undef JSON_HEDLEY_CONCAT_EX
25998 #undef JSON_HEDLEY_CONST
25999 #undef JSON_HEDLEY_CONSTEXPR
26000 #undef JSON_HEDLEY_CONST_CAST
26001 #undef JSON_HEDLEY_CPP_CAST
26002 #undef JSON_HEDLEY_CRAY_VERSION
26003 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
26004 #undef JSON_HEDLEY_C_DECL
26005 #undef JSON_HEDLEY_DEPRECATED
26006 #undef JSON_HEDLEY_DEPRECATED_FOR
26007 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
26008 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
26009 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
26010 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
26011 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
26012 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
26013 #undef JSON_HEDLEY_DIAGNOSTIC_POP
26014 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
26015 #undef JSON_HEDLEY_DMC_VERSION
26016 #undef JSON_HEDLEY_DMC_VERSION_CHECK
26017 #undef JSON_HEDLEY_EMPTY_BASES
26018 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
26019 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
26020 #undef JSON_HEDLEY_END_C_DECLS
26021 #undef JSON_HEDLEY_FLAGS
26022 #undef JSON_HEDLEY_FLAGS_CAST
26023 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
26024 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
26025 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
26026 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
26027 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
26028 #undef JSON_HEDLEY_GCC_HAS_FEATURE
26029 #undef JSON_HEDLEY_GCC_HAS_WARNING
26030 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
26031 #undef JSON_HEDLEY_GCC_VERSION
26032 #undef JSON_HEDLEY_GCC_VERSION_CHECK
26033 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
26034 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
26035 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
26036 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
26037 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
26038 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
26039 #undef JSON_HEDLEY_GNUC_HAS_WARNING
26040 #undef JSON_HEDLEY_GNUC_VERSION
26041 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
26042 #undef JSON_HEDLEY_HAS_ATTRIBUTE
26043 #undef JSON_HEDLEY_HAS_BUILTIN
26044 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
26045 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
26046 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
26047 #undef JSON_HEDLEY_HAS_EXTENSION
26048 #undef JSON_HEDLEY_HAS_FEATURE
26049 #undef JSON_HEDLEY_HAS_WARNING
26050 #undef JSON_HEDLEY_IAR_VERSION
26051 #undef JSON_HEDLEY_IAR_VERSION_CHECK
26052 #undef JSON_HEDLEY_IBM_VERSION
26053 #undef JSON_HEDLEY_IBM_VERSION_CHECK
26054 #undef JSON_HEDLEY_IMPORT
26055 #undef JSON_HEDLEY_INLINE
26056 #undef JSON_HEDLEY_INTEL_CL_VERSION
26057 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
26058 #undef JSON_HEDLEY_INTEL_VERSION
26059 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
26060 #undef JSON_HEDLEY_IS_CONSTANT
26061 #undef JSON_HEDLEY_IS_CONSTEXPR_
26062 #undef JSON_HEDLEY_LIKELY
26063 #undef JSON_HEDLEY_MALLOC
26064 #undef JSON_HEDLEY_MCST_LCC_VERSION
26065 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
26066 #undef JSON_HEDLEY_MESSAGE
26067 #undef JSON_HEDLEY_MSVC_VERSION
26068 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
26069 #undef JSON_HEDLEY_NEVER_INLINE
26070 #undef JSON_HEDLEY_NON_NULL
26071 #undef JSON_HEDLEY_NO_ESCAPE
26072 #undef JSON_HEDLEY_NO_RETURN
26073 #undef JSON_HEDLEY_NO_THROW
26074 #undef JSON_HEDLEY_NULL
26075 #undef JSON_HEDLEY_PELLES_VERSION
26076 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
26077 #undef JSON_HEDLEY_PGI_VERSION
26078 #undef JSON_HEDLEY_PGI_VERSION_CHECK
26079 #undef JSON_HEDLEY_PREDICT
26080 #undef JSON_HEDLEY_PRINTF_FORMAT
26081 #undef JSON_HEDLEY_PRIVATE
26082 #undef JSON_HEDLEY_PUBLIC
26083 #undef JSON_HEDLEY_PURE
26084 #undef JSON_HEDLEY_REINTERPRET_CAST
26085 #undef JSON_HEDLEY_REQUIRE
26086 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
26087 #undef JSON_HEDLEY_REQUIRE_MSG
26088 #undef JSON_HEDLEY_RESTRICT
26089 #undef
26090 #undef JSON_HEDLEY_SENTINEL
26091 #undef JSON_HEDLEY_STATIC_ASSERT
26092 #undef JSON_HEDLEY_STATIC_CAST
26093 #undef JSON_HEDLEY_STRINGIFY
26094 #undef JSON_HEDLEY_STRINGIFY_EX
26095 #undef JSON_HEDLEY_SUNPRO_VERSION
26096 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
26097 #undef JSON_HEDLEY_TINYC_VERSION
26098 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
26099 #undef JSON_HEDLEY_TI_ARMCL_VERSION
26100 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
26101 #undef JSON_HEDLEY_TI_CL2000_VERSION
26102 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
26103 #undef JSON_HEDLEY_TI_CL430_VERSION
26104 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
26105 #undef JSON_HEDLEY_TI_CL6X_VERSION
26106 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
26107 #undef JSON_HEDLEY_TI_CL7X_VERSION
26108 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
26109 #undef JSON_HEDLEY_TI_CLPRU_VERSION
26110 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
26111 #undef JSON_HEDLEY_TI_VERSION
26112 #undef JSON_HEDLEY_TI_VERSION_CHECK
26113 #undef JSON_HEDLEY_UNAVAILABLE
26114 #undef JSON_HEDLEY_UNLIKELY
26115 #undef JSON_HEDLEY_UNPREDICTABLE
26116 #undef JSON_HEDLEY_UNREACHABLE
26117 #undef JSON_HEDLEY_UNREACHABLE_RETURN
26118 #undef JSON_HEDLEY_VERSION
26119 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
26120 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
26121 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
26122 #undef JSON_HEDLEY_VERSION_ENCODE
26123 #undef JSON_HEDLEY_WARNING
26124 #undef
26125 #undef _MSG
26126 #undef JSON_HEDLEY_FALL_THROUGH
26127
26128
26129
26130 #endif // INCLUDE_NLOHMANN_JSON_HPP_
nlohmann::basic_json::binary
static basic_json binary(typename binary_t::container_type &&init, std::uint8_t subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:18838
nlohmann::basic_json::parser_callback_t
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:18401
nlohmann::basic_json::contains
bool contains(KeyT &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:21563
nlohmann::basic_json::crbegin
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:21848
nlohmann::basic_json::value
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:20946
nlohmann::basic_json::is_number_float
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:19647
nlohmann::basic_json::number_integer_t
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:17724
nlohmann::basic_json::operator==
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:23285
nlohmann::basic_json::sax_parse
static bool sax_parse(InputType &&i, SAX *sax, input_format_t format=input_format_t::json, const bool strict=true, const bool ignore_comments=false)
generate SAX events
Definition: json.hpp:23966
nlohmann::basic_json::exception
detail::exception exception
general exception of the basic_json class
Definition: json.hpp:17275
nlohmann::basic_json::get_ref
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:20311
nlohmann::basic_json::parse
static basic_json parse(InputType &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a compatible input
Definition: json.hpp:23811
nlohmann::basic_json::emplace_back
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:22571
nlohmann::basic_json::from_cbor
static basic_json from_cbor(const T *ptr, std::size_t len, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition: json.hpp:24674
nlohmann::basic_json::basic_json
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:18442
nlohmann::basic_json::operator=
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:19279
nlohmann::basic_json::max_size
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:22232
nlohmann::basic_json::diff
static basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition: json.hpp:25646
nlohmann::basic_json::input_format_t
detail::input_format_t input_format_t
Definition: json.hpp:17262
nlohmann::basic_json::reference
value_type & reference
the type of an element reference
Definition: json.hpp:17303
nlohmann::basic_json::crend
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:21877
nlohmann::basic_json::out_of_range
detail::out_of_range out_of_range
exception indicating access out of the defined range
Definition: json.hpp:17283
nlohmann::basic_json::iterator_wrapper
static iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition: json.hpp:21941
nlohmann::basic_json::begin
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:21633
nlohmann::basic_json::basic_json
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:19021
nlohmann::basic_json::to_ubjson
static std::vector< uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:24431
nlohmann::basic_json::basic_json
basic_json(const JsonRef &ref)
Definition: json.hpp:19124
nlohmann::basic_json::array
static basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:18884
nlohmann::basic_json::cend
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:21744
nlohmann::basic_json::back
reference back()
access the last element
Definition: json.hpp:21116
nlohmann::basic_json::accept
static bool accept(InputType &&i, const bool ignore_comments=false)
check if the input is valid JSON
Definition: json.hpp:23903
nlohmann::basic_json::string_t
StringType string_t
a type for a string
Definition: json.hpp:17626
nlohmann::basic_json::size
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:22161
nlohmann::basic_json::operator>>
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:23743
nlohmann::basic_json::meta
static basic_json meta()
returns version information on the library
Definition: json.hpp:17367
nlohmann::basic_json::update
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:22929
nlohmann::basic_json::size_type
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:17310
nlohmann::basic_json::difference_type
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:17308
nlohmann::basic_json::binary
static basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition: json.hpp:18781
nlohmann::basic_json::operator+=
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:22406
nlohmann::basic_json::basic_json
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:18576
nlohmann::basic_json::const_pointer
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:17318
nlohmann::basic_json::pointer
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:17316
nlohmann::basic_json::from_cbor
static basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:24642
nlohmann::basic_json::boolean_t
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:17652
nlohmann::basic_json::push_back
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:22523
nlohmann::basic_json::type_name
const char * type_name() const noexcept
return the type as string
Definition: json.hpp:24089
nlohmann::basic_json::dump
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition: json.hpp:19377
nlohmann::basic_json::erase
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:21183
nlohmann::basic_json::from_bson
static basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
Definition: json.hpp:25017
nlohmann::basic_json::is_structured
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:19488
nlohmann::basic_json::at
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:20443
nlohmann::basic_json::front
reference front()
access the first element
Definition: json.hpp:21072
nlohmann::basic_json::is_primitive
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:19461
nlohmann::basic_json::is_number_unsigned
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:19619
nlohmann::basic_json::cbor_tag_handler_t
detail::cbor_tag_handler_t cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:17258
nlohmann::basic_json::parse_error
detail::parse_error parse_error
exception indicating a parse error
Definition: json.hpp:17277
nlohmann::basic_json::is_object
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:19669
nlohmann::basic_json::type
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:19430
nlohmann::basic_json::number_float_t
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:17863
nlohmann::basic_json::reverse_iterator
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:17325
nlohmann::basic_json::operator<=
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:23560
nlohmann::basic_json::empty
bool empty() const noexcept
checks whether the container is empty.
Definition: json.hpp:22088
nlohmann::basic_json::operator<<
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:23719
nlohmann::basic_json::basic_json
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:19151
nlohmann::basic_json::~basic_json
~basic_json() noexcept
destructor
Definition: json.hpp:19313
nlohmann::basic_json::external_constructor
friend struct detail::external_constructor
Definition: json.hpp:17192
nlohmann::basic_json::basic_json
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:19241
nlohmann::basic_json::invalid_iterator
detail::invalid_iterator invalid_iterator
exception indicating errors with iterators
Definition: json.hpp:17279
nlohmann::basic_json::operator!=
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:23393
nlohmann::basic_json::other_error
detail::other_error other_error
exception indicating other library errors
Definition: json.hpp:17285
nlohmann::basic_json::m_value
json_value m_value
the value of the current element
Definition: json.hpp:24124
nlohmann::basic_json::operator>=
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:23652
nlohmann::basic_json::rend
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:21811
nlohmann::basic_json::get_ref
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:20324
nlohmann::basic_json::get
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:20207
nlohmann::basic_json::merge_patch
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:25821
nlohmann::basic_json::get_ptr
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:19965
nlohmann::basic_json::array_t
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:17573
nlohmann::basic_json::get_to
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition: json.hpp:20275
nlohmann::basic_json::operator>
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:23606
nlohmann::basic_json::is_boolean
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:19532
nlohmann::basic_json::items
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:22023
nlohmann::basic_json::end
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:21704
nlohmann::basic_json::swap
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:23031
nlohmann::basic_json::clear
void clear() noexcept
clears the contents
Definition: json.hpp:22303
nlohmann::basic_json::is_binary
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:19735
nlohmann::basic_json::to_msgpack
static std::vector< uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:24328
nlohmann::basic_json::object
static basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:18928
nlohmann::basic_json::operator[]
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:20648
nlohmann::basic_json::get_to
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
Definition: json.hpp:20251
nlohmann::basic_json::iterator
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.hpp:17321
nlohmann::basic_json::to_bson
static std::vector< uint8_t > to_bson(const basic_json &j)
Serializes the given JSON object j to BSON and returns a vector containing the corresponding BSON-rep...
Definition: json.hpp:24509
nlohmann::basic_json::const_reverse_iterator
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:17327
nlohmann::basic_json::from_ubjson
static basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:24903
nlohmann::basic_json::json_pointer
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:17252
nlohmann::basic_json::get_binary
binary_t & get_binary()
Definition: json.hpp:20385
nlohmann::basic_json::operator<
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:23446
nlohmann::basic_json::binary
static basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array (without subtype)
Definition: json.hpp:18828
nlohmann::basic_json::is_string
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:19713
nlohmann::basic_json::is_array
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:19691
nlohmann::basic_json::insert_iterator
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.hpp:22656
nlohmann::basic_json::flatten
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:25250
nlohmann::basic_json::const_reference
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:17305
nlohmann::basic_json::push_back
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:22380
nlohmann::basic_json::count
size_type count(KeyT &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:21530
nlohmann::basic_json::get_binary
const binary_t & get_binary() const
Definition: json.hpp:20396
nlohmann::basic_json::is_number
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:19562
nlohmann::basic_json::object_comparator_t
std::less< StringType > object_comparator_t
Definition: json.hpp:17437
nlohmann::basic_json::emplace
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:22624
nlohmann::basic_json::is_number_integer
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:19591
nlohmann::basic_json::initializer_list_t
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:17260
nlohmann::basic_json::value_t
detail::value_t value_t
Definition: json.hpp:17250
nlohmann::basic_json::get_to
ValueType & get_to(ValueType &v) const
Definition: json.hpp:20264
nlohmann::basic_json::binary
static basic_json binary(const typename binary_t::container_type &init, std::uint8_t subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:18818
nlohmann::basic_json::find
iterator find(KeyT &&key)
find an element in a JSON object
Definition: json.hpp:21479
nlohmann::basic_json::type_error
detail::type_error type_error
exception indicating executing a member function with a wrong type
Definition: json.hpp:17281
nlohmann::basic_json::basic_json
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:18466
nlohmann::basic_json::allocator_type
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:17313
nlohmann::basic_json::binary_t
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:17934
nlohmann::basic_json::json_serializer
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:17254
nlohmann::basic_json::to_cbor
static std::vector< uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:24233
nlohmann::basic_json::from_msgpack
static basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:24786
nlohmann::basic_json::patch
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:25348
nlohmann::basic_json::basic_json
basic_json(CompatibleType &&val) noexcept(noexcept(//NOLINT(bugprone-forwarding-reference-overload, bugprone-exception-escape) JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value
Definition: json.hpp:18538
nlohmann::basic_json::unflatten
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:25287
nlohmann::basic_json::number_unsigned_t
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:17795
nlohmann::basic_json::cbegin
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:21673
nlohmann::basic_json::basic_json
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.hpp:18700
nlohmann::basic_json::insert
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:22694
nlohmann::basic_json::const_iterator
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.hpp:17323
nlohmann::basic_json::is_discarded
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:19762
nlohmann::basic_json::is_null
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:19510
nlohmann::basic_json::object_t
ObjectType< StringType, basic_json, object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > >> object_t
a type for an object
Definition: json.hpp:17527
nlohmann::basic_json::get
auto get() const noexcept(noexcept(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))) -> decltype(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))
get a (pointer) value (explicit)
Definition: json.hpp:20166
nlohmann::basic_json::basic_json
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:18955
nlohmann::basic_json::get_allocator
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:17335
nlohmann::basic_json::get_ptr
constexpr auto get_ptr() const noexcept -> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:19978
nlohmann::basic_json::rbegin
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:21774
nlohmann::basic_json
a class to store JSON values
Definition: json.hpp:17190
nlohmann::byte_container_with_subtype::container_type
BinaryType container_type
the type of the underlying container
Definition: json.hpp:4932
nlohmann::byte_container_with_subtype::set_subtype
void set_subtype(std::uint8_t subtype_) noexcept
sets the binary subtype
Definition: json.hpp:4987
nlohmann::byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition: json.hpp:4938
nlohmann::byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:4942
nlohmann::byte_container_with_subtype::operator!=
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:4964
nlohmann::byte_container_with_subtype::clear_subtype
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:5059
nlohmann::byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:4934
nlohmann::byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype(const container_type &b, std::uint8_t subtype_) noexcept(noexcept(container_type(b)))
Definition: json.hpp:4946
nlohmann::byte_container_with_subtype::has_subtype
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:5035
nlohmann::byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype(container_type &&b, std::uint8_t subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:4952
nlohmann::byte_container_with_subtype::subtype
constexpr std::uint8_t subtype() const noexcept
return the binary subtype
Definition: json.hpp:5014
nlohmann::byte_container_with_subtype::operator==
bool operator==(const byte_container_with_subtype &rhs) const
Definition: json.hpp:4958
nlohmann::byte_container_with_subtype
an internal type for a backed binary type
Definition: json.hpp:4929
nlohmann::json_pointer::back
const std::string & back() const
return last reference token
Definition: json.hpp:12352
nlohmann::json_pointer::to_string
std::string to_string() const
return a string representation of the JSON pointer
Definition: json.hpp:12146
nlohmann::json_pointer::operator==
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for equality
Definition: json.hpp:12989
nlohmann::json_pointer::pop_back
void pop_back()
remove last reference token
Definition: json.hpp:12328
nlohmann::json_pointer::empty
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:12399
nlohmann::json_pointer::operator!=
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for inequality
Definition: json.hpp:13006
nlohmann::json_pointer::push_back
void push_back(const std::string &token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:12374
nlohmann::json_pointer::operator/=
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: json.hpp:12178
nlohmann::json_pointer::operator/=
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition: json.hpp:12224
nlohmann::json_pointer::json_pointer
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.hpp:12128
nlohmann::json_pointer::operator/
friend json_pointer operator/(const json_pointer &lhs, const json_pointer &rhs)
create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
Definition: json.hpp:12244
nlohmann::json_pointer::operator/
friend json_pointer operator/(const json_pointer &ptr, std::string token)
create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
Definition: json.hpp:12265
nlohmann::json_pointer::operator/=
json_pointer & operator/=(std::string token)
append an unescaped reference token at the end of this JSON pointer
Definition: json.hpp:12202
nlohmann::json_pointer::push_back
void push_back(std::string &&token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:12380
nlohmann::json_pointer::operator/
friend json_pointer operator/(const json_pointer &ptr, std::size_t array_idx)
create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
Definition: json.hpp:12285
nlohmann::json_pointer::parent_pointer
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:12303
nlohmann::json_pointer
JSON Pointer.
Definition: json.hpp:12101
nlohmann::anonymous_namespace{json.hpp}::to_json
constexpr const auto & to_json
Definition: json.hpp:4831
nlohmann::anonymous_namespace{json.hpp}::from_json
constexpr const auto & from_json
Definition: json.hpp:4260
nlohmann::json
basic_json<> json
default JSON class
Definition: json.hpp:3385
nlohmann::to_string
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:25860
nlohmann
namespace for Niels Lohmann
Definition: json.hpp:87
nlohmann::adl_serializer::from_json
static auto from_json(BasicJsonType &&j, TargetType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), val), void())
convert a JSON value to any value type
Definition: json.hpp:4858
nlohmann::adl_serializer::from_json
static auto from_json(BasicJsonType &&j) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))
convert a JSON value to any value type
Definition: json.hpp:4878
nlohmann::adl_serializer::to_json
static auto to_json(BasicJsonType &j, TargetType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< TargetType >(val)))) -> decltype(::nlohmann::to_json(j, std::forward< TargetType >(val)), void())
convert any value type to a JSON value
Definition: json.hpp:4895
nlohmann::adl_serializer
default JSONSerializer template argument
Definition: json.hpp:4845
nlohmann::json_sax::start_object
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
nlohmann::json_sax::string
virtual bool string(string_t &val)=0
a string was read
nlohmann::json_sax::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:5727
nlohmann::json_sax::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:5731
nlohmann::json_sax::operator=
json_sax & operator=(const json_sax &)=default
nlohmann::json_sax::end_array
virtual bool end_array()=0
the end of an array was read
nlohmann::json_sax::key
virtual bool key(string_t &val)=0
an object key was read
nlohmann::json_sax::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:5728
nlohmann::json_sax::binary
virtual bool binary(binary_t &val)=0
a binary string was read
nlohmann::json_sax::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:5729
nlohmann::json_sax::start_array
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
nlohmann::json_sax::parse_error
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
nlohmann::json_sax::json_sax
json_sax(json_sax &&) noexcept=default
nlohmann::json_sax::boolean
virtual bool boolean(bool val)=0
a boolean value was read
nlohmann::json_sax::json_sax
json_sax(const json_sax &)=default
nlohmann::json_sax::json_sax
json_sax()=default
nlohmann::json_sax::end_object
virtual bool end_object()=0
the end of an object was read
nlohmann::json_sax::number_unsigned
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
nlohmann::json_sax::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:5730
nlohmann::json_sax::number_float
virtual bool number_float(number_float_t val, const string_t &s)=0
an floating-point number was read
nlohmann::json_sax::number_integer
virtual bool number_integer(number_integer_t val)=0
an integer number was read
nlohmann::json_sax
SAX interface.
Definition: json.hpp:5726
nlohmann::ordered_map::insert
std::pair< iterator, bool > insert(const value_type &value)
Definition: json.hpp:17062
nlohmann::ordered_map::ordered_map
ordered_map(std::initializer_list< T > init, const Allocator &alloc=Allocator())
Definition: json.hpp:16936
nlohmann::ordered_map::Container
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.hpp:16924
nlohmann::ordered_map::mapped_type
T mapped_type
Definition: json.hpp:16923
nlohmann::ordered_map::find
iterator find(const Key &key)
Definition: json.hpp:17033
nlohmann::ordered_map::erase
iterator erase(iterator pos)
Definition: json.hpp:17007
nlohmann::ordered_map::insert
void insert(InputIt first, InputIt last)
Definition: json.hpp:17080
nlohmann::ordered_map::emplace
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition: json.hpp:16939
nlohmann::ordered_map::find
const_iterator find(const Key &key) const
Definition: json.hpp:17045
nlohmann::ordered_map::insert
std::pair< iterator, bool > insert(value_type &&value)
Definition: json.hpp:17057
nlohmann::ordered_map::key_type
Key key_type
Definition: json.hpp:16922
nlohmann::ordered_map::erase
size_type erase(const Key &key)
Definition: json.hpp:16988
nlohmann::ordered_map::operator[]
const T & operator[](const Key &key) const
Definition: json.hpp:16957
nlohmann::ordered_map::ordered_map
ordered_map(const Allocator &alloc=Allocator())
Definition: json.hpp:16932
nlohmann::ordered_map::require_input_iter
typename std::enable_if< std::is_convertible< typename std::iterator_traits< InputIt >::iterator_category, std::input_iterator_tag >::value >::type require_input_iter
Definition: json.hpp:17077
nlohmann::ordered_map::at
const T & at(const Key &key) const
Definition: json.hpp:16975
nlohmann::ordered_map::ordered_map
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition: json.hpp:16934
nlohmann::ordered_map::at
T & at(const Key &key)
Definition: json.hpp:16962
nlohmann::ordered_map::operator[]
T & operator[](const Key &key)
Definition: json.hpp:16952
nlohmann::ordered_map::count
size_type count(const Key &key) const
Definition: json.hpp:17021
nlohmann::ordered_map
Definition: json.hpp:16921