CUDNN Frontend API 8.3.0

json.hpp
Go to the documentation of this file.
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(JSON_HEDLEY_WARN_UNUSED_RESULT)
1263 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1264 #endif
1265 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1266 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_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 JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1287 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1288 #elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1289 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1290 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1291 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1292 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1293 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1294 #elif defined(_Check_return_) /* SAL */
1295 #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1296 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1297 #else
1298 #define JSON_HEDLEY_WARN_UNUSED_RESULT
1299 #define JSON_HEDLEY_WARN_UNUSED_RESULT_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(JSON_HEDLEY_RETURNS_NON_NULL)
1887 #undef JSON_HEDLEY_RETURNS_NON_NULL
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 JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
1894 #elif defined(_Ret_notnull_) /* SAL */
1895 #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
1896 #else
1897 #define JSON_HEDLEY_RETURNS_NON_NULL
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 the user manually specified the used c++ version this is skipped
2234 #if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2235 #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2236 #define JSON_HAS_CPP_20
2237 #define JSON_HAS_CPP_17
2238 #define JSON_HAS_CPP_14
2239 #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2240 #define JSON_HAS_CPP_17
2241 #define JSON_HAS_CPP_14
2242 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2243 #define JSON_HAS_CPP_14
2244 #endif
2245 // the cpp 11 flag is always specified because it is the minimal required version
2246 #define JSON_HAS_CPP_11
2247 #endif
2248
2249 // disable documentation warnings on clang
2250 #if defined(__clang__)
2251 #pragma GCC diagnostic push
2252 #pragma GCC diagnostic ignored "-Wdocumentation"
2253 #endif
2254
2255 // allow to disable exceptions
2256 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2257 #define JSON_THROW(exception) throw exception
2258 #define JSON_TRY try
2259 #define JSON_CATCH(exception) catch(exception)
2260 #define JSON_INTERNAL_CATCH(exception) catch(exception)
2261 #else
2262 #include <cstdlib>
2263 #define JSON_THROW(exception) std::abort()
2264 #define JSON_TRY if(true)
2265 #define JSON_CATCH(exception) if(false)
2266 #define JSON_INTERNAL_CATCH(exception) if(false)
2267 #endif
2268
2269 // override exception macros
2270 #if defined(JSON_THROW_USER)
2271 #undef JSON_THROW
2272 #define JSON_THROW JSON_THROW_USER
2273 #endif
2274 #if defined(JSON_TRY_USER)
2275 #undef JSON_TRY
2276 #define JSON_TRY JSON_TRY_USER
2277 #endif
2278 #if defined(JSON_CATCH_USER)
2279 #undef JSON_CATCH
2280 #define JSON_CATCH JSON_CATCH_USER
2281 #undef JSON_INTERNAL_CATCH
2282 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2283 #endif
2284 #if defined(JSON_INTERNAL_CATCH_USER)
2285 #undef JSON_INTERNAL_CATCH
2286 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2287 #endif
2288
2289 // allow to override assert
2290 #if !defined(JSON_ASSERT)
2291 #include <cassert> // assert
2292 #define JSON_ASSERT(x) assert(x)
2293 #endif
2294
2295 // allow to access some private functions (needed by the test suite)
2296 #if defined(JSON_TESTS_PRIVATE)
2297 #define JSON_PRIVATE_UNLESS_TESTED public
2298 #else
2299 #define JSON_PRIVATE_UNLESS_TESTED private
2300 #endif
2301
2307 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2308 template<typename BasicJsonType> \
2309 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2310 { \
2311 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2312 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2313 auto it = std::find_if(std::begin(m), std::end(m), \
2314 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2315 { \
2316 return ej_pair.first == e; \
2317 }); \
2318 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2319 } \
2320 template<typename BasicJsonType> \
2321 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2322 { \
2323 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2324 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2325 auto it = std::find_if(std::begin(m), std::end(m), \
2326 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2327 { \
2328 return ej_pair.second == j; \
2329 }); \
2330 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2331 }
2332
2333 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2334 // may be removed in the future once the class is split.
2335
2336 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2337 template<template<typename, typename, typename...> class ObjectType, \
2338 template<typename, typename...> class ArrayType, \
2339 class StringType, class BooleanType, class NumberIntegerType, \
2340 class NumberUnsignedType, class NumberFloatType, \
2341 template<typename> class AllocatorType, \
2342 template<typename, typename = void> class JSONSerializer, \
2343 class BinaryType>
2344
2345 #define NLOHMANN_BASIC_JSON_TPL \
2346 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2347 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2348 AllocatorType, JSONSerializer, BinaryType>
2349
2350 // Macros to simplify conversion from/to types
2351
2352 #define NLOHMANN_JSON_EXPAND( x ) x
2353 #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
2354 #define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2355 NLOHMANN_JSON_PASTE64, \
2356 NLOHMANN_JSON_PASTE63, \
2357 NLOHMANN_JSON_PASTE62, \
2358 NLOHMANN_JSON_PASTE61, \
2359 NLOHMANN_JSON_PASTE60, \
2360 NLOHMANN_JSON_PASTE59, \
2361 NLOHMANN_JSON_PASTE58, \
2362 NLOHMANN_JSON_PASTE57, \
2363 NLOHMANN_JSON_PASTE56, \
2364 NLOHMANN_JSON_PASTE55, \
2365 NLOHMANN_JSON_PASTE54, \
2366 NLOHMANN_JSON_PASTE53, \
2367 NLOHMANN_JSON_PASTE52, \
2368 NLOHMANN_JSON_PASTE51, \
2369 NLOHMANN_JSON_PASTE50, \
2370 NLOHMANN_JSON_PASTE49, \
2371 NLOHMANN_JSON_PASTE48, \
2372 NLOHMANN_JSON_PASTE47, \
2373 NLOHMANN_JSON_PASTE46, \
2374 NLOHMANN_JSON_PASTE45, \
2375 NLOHMANN_JSON_PASTE44, \
2376 NLOHMANN_JSON_PASTE43, \
2377 NLOHMANN_JSON_PASTE42, \
2378 NLOHMANN_JSON_PASTE41, \
2379 NLOHMANN_JSON_PASTE40, \
2380 NLOHMANN_JSON_PASTE39, \
2381 NLOHMANN_JSON_PASTE38, \
2382 NLOHMANN_JSON_PASTE37, \
2383 NLOHMANN_JSON_PASTE36, \
2384 NLOHMANN_JSON_PASTE35, \
2385 NLOHMANN_JSON_PASTE34, \
2386 NLOHMANN_JSON_PASTE33, \
2387 NLOHMANN_JSON_PASTE32, \
2388 NLOHMANN_JSON_PASTE31, \
2389 NLOHMANN_JSON_PASTE30, \
2390 NLOHMANN_JSON_PASTE29, \
2391 NLOHMANN_JSON_PASTE28, \
2392 NLOHMANN_JSON_PASTE27, \
2393 NLOHMANN_JSON_PASTE26, \
2394 NLOHMANN_JSON_PASTE25, \
2395 NLOHMANN_JSON_PASTE24, \
2396 NLOHMANN_JSON_PASTE23, \
2397 NLOHMANN_JSON_PASTE22, \
2398 NLOHMANN_JSON_PASTE21, \
2399 NLOHMANN_JSON_PASTE20, \
2400 NLOHMANN_JSON_PASTE19, \
2401 NLOHMANN_JSON_PASTE18, \
2402 NLOHMANN_JSON_PASTE17, \
2403 NLOHMANN_JSON_PASTE16, \
2404 NLOHMANN_JSON_PASTE15, \
2405 NLOHMANN_JSON_PASTE14, \
2406 NLOHMANN_JSON_PASTE13, \
2407 NLOHMANN_JSON_PASTE12, \
2408 NLOHMANN_JSON_PASTE11, \
2409 NLOHMANN_JSON_PASTE10, \
2410 NLOHMANN_JSON_PASTE9, \
2411 NLOHMANN_JSON_PASTE8, \
2412 NLOHMANN_JSON_PASTE7, \
2413 NLOHMANN_JSON_PASTE6, \
2414 NLOHMANN_JSON_PASTE5, \
2415 NLOHMANN_JSON_PASTE4, \
2416 NLOHMANN_JSON_PASTE3, \
2417 NLOHMANN_JSON_PASTE2, \
2418 NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2419 #define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2420 #define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2421 #define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2422 #define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2423 #define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2424 #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)
2425 #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)
2426 #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)
2427 #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)
2428 #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)
2429 #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)
2430 #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)
2431 #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)
2432 #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)
2433 #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)
2434 #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)
2435 #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)
2436 #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)
2437 #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)
2438 #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)
2439 #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)
2440 #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)
2441 #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)
2442 #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)
2443 #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)
2444 #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)
2445 #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)
2446 #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)
2447 #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)
2448 #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)
2449 #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)
2450 #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)
2451 #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)
2452 #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)
2453 #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)
2454 #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)
2455 #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)
2456 #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)
2457 #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)
2458 #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)
2459 #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)
2460 #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)
2461 #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)
2462 #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)
2463 #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)
2464 #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)
2465 #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)
2466 #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)
2467 #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)
2468 #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)
2469 #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)
2470 #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)
2471 #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)
2472 #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)
2473 #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)
2474 #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)
2475 #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)
2476 #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)
2477 #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)
2478 #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)
2479 #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)
2480 #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)
2481 #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)
2482
2483 #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2484 #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2485
2491 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2492 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__)) } \
2493 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__)) }
2494
2500 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2501 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__)) } \
2502 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__)) }
2503
2504 #ifndef JSON_USE_IMPLICIT_CONVERSIONS
2505 #define JSON_USE_IMPLICIT_CONVERSIONS 1
2506 #endif
2507
2508 #if JSON_USE_IMPLICIT_CONVERSIONS
2509 #define JSON_EXPLICIT
2510 #else
2511 #define JSON_EXPLICIT explicit
2512 #endif
2513
2514
2515 namespace nlohmann
2516 {
2517 namespace detail
2518 {
2519
2533 inline void replace_substring(std::string& s, const std::string& f,
2534 const std::string& t)
2535 {
2536 JSON_ASSERT(!f.empty());
2537 for (auto pos = s.find(f); // find first occurrence of f
2538 pos != std::string::npos; // make sure f was found
2539 s.replace(pos, f.size(), t), // replace with t, and
2540 pos = s.find(f, pos + t.size())) // find next occurrence of f
2541 {}
2542 }
2543
2551 inline std::string escape(std::string s)
2552 {
2553 replace_substring(s, "~", "~0");
2554 replace_substring(s, "/", "~1");
2555 return s;
2556 }
2557
2565 static void unescape(std::string& s)
2566 {
2567 replace_substring(s, "~1", "/");
2568 replace_substring(s, "~0", "~");
2569 }
2570
2571 } // namespace detail
2572 } // namespace nlohmann
2573
2574 // #include <nlohmann/detail/input/position_t.hpp>
2575
2576
2577 #include <cstddef> // size_t
2578
2579 namespace nlohmann
2580 {
2581 namespace detail
2582 {
2584 struct position_t
2585 {
2587 std::size_t chars_read_total = 0;
2589 std::size_t chars_read_current_line = 0;
2591 std::size_t lines_read = 0;
2592
2594 constexpr operator size_t() const
2595 {
2596 return chars_read_total;
2597 }
2598 };
2599
2600 } // namespace detail
2601 } // namespace nlohmann
2602
2603 // #include <nlohmann/detail/macro_scope.hpp>
2604
2605
2606 namespace nlohmann
2607 {
2608 namespace detail
2609 {
2611 // exceptions //
2613
2642 class exception : public std::exception
2643 {
2644 public:
2646 const char* what() const noexcept override
2647 {
2648 return m.what();
2649 }
2650
2652 const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
2653
2654 protected:
2655 JSON_HEDLEY_NON_NULL(3)
2656 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
2657
2658 static std::string name(const std::string& ename, int id_)
2659 {
2660 return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2661 }
2662
2663 template<typename BasicJsonType>
2664 static std::string diagnostics(const BasicJsonType& leaf_element)
2665 {
2666 #if JSON_DIAGNOSTICS
2667 std::vector<std::string> tokens;
2668 for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent)
2669 {
2670 switch (current->m_parent->type())
2671 {
2672 case value_t::array:
2673 {
2674 for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
2675 {
2676 if (&current->m_parent->m_value.array->operator[](i) == current)
2677 {
2678 tokens.emplace_back(std::to_string(i));
2679 break;
2680 }
2681 }
2682 break;
2683 }
2684
2685 case value_t::object:
2686 {
2687 for (const auto& element : *current->m_parent->m_value.object)
2688 {
2689 if (&element.second == current)
2690 {
2691 tokens.emplace_back(element.first.c_str());
2692 break;
2693 }
2694 }
2695 break;
2696 }
2697
2698 default: // LCOV_EXCL_LINE
2699 break; // LCOV_EXCL_LINE
2700 }
2701 }
2702
2703 if (tokens.empty())
2704 {
2705 return "";
2706 }
2707
2708 return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
2709 [](const std::string & a, const std::string & b)
2710 {
2711 return a + "/" + detail::escape(b);
2712 }) + ") ";
2713 #else
2714 static_cast<void>(leaf_element);
2715 return "";
2716 #endif
2717 }
2718
2719 private:
2721 std::runtime_error m;
2722 };
2723
2769 class parse_error : public exception
2770 {
2771 public:
2781 template<typename BasicJsonType>
2782 static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context)
2783 {
2784 std::string w = exception::name("parse_error", id_) + "parse error" +
2785 position_string(pos) + ": " + exception::diagnostics(context) + what_arg;
2786 return parse_error(id_, pos.chars_read_total, w.c_str());
2787 }
2788
2789 template<typename BasicJsonType>
2790 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context)
2791 {
2792 std::string w = exception::name("parse_error", id_) + "parse error" +
2793 (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2794 ": " + exception::diagnostics(context) + what_arg;
2795 return parse_error(id_, byte_, w.c_str());
2796 }
2797
2807 const std::size_t byte;
2808
2809 private:
2810 parse_error(int id_, std::size_t byte_, const char* what_arg)
2811 : exception(id_, what_arg), byte(byte_) {}
2812
2813 static std::string position_string(const position_t& pos)
2814 {
2815 return " at line " + std::to_string(pos.lines_read + 1) +
2816 ", column " + std::to_string(pos.chars_read_current_line);
2817 }
2818 };
2819
2857 class invalid_iterator : public exception
2858 {
2859 public:
2860 template<typename BasicJsonType>
2861 static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context)
2862 {
2863 std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg;
2864 return invalid_iterator(id_, w.c_str());
2865 }
2866
2867 private:
2868 JSON_HEDLEY_NON_NULL(3)
2869 invalid_iterator(int id_, const char* what_arg)
2870 : exception(id_, what_arg) {}
2871 };
2872
2912 class type_error : public exception
2913 {
2914 public:
2915 template<typename BasicJsonType>
2916 static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
2917 {
2918 std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg;
2919 return type_error(id_, w.c_str());
2920 }
2921
2922 private:
2923 JSON_HEDLEY_NON_NULL(3)
2924 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2925 };
2926
2960 class out_of_range : public exception
2961 {
2962 public:
2963 template<typename BasicJsonType>
2964 static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context)
2965 {
2966 std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg;
2967 return out_of_range(id_, w.c_str());
2968 }
2969
2970 private:
2971 JSON_HEDLEY_NON_NULL(3)
2972 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
2973 };
2974
2999 class other_error : public exception
3000 {
3001 public:
3002 template<typename BasicJsonType>
3003 static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
3004 {
3005 std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg;
3006 return other_error(id_, w.c_str());
3007 }
3008
3009 private:
3010 JSON_HEDLEY_NON_NULL(3)
3011 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
3012 };
3013 } // namespace detail
3014 } // namespace nlohmann
3015
3016 // #include <nlohmann/detail/macro_scope.hpp>
3017
3018 // #include <nlohmann/detail/meta/cpp_future.hpp>
3019
3020
3021 #include <cstddef> // size_t
3022 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3023 #include <utility> // index_sequence, make_index_sequence, index_sequence_for
3024
3025 // #include <nlohmann/detail/macro_scope.hpp>
3026
3027
3028 namespace nlohmann
3029 {
3030 namespace detail
3031 {
3032
3033 template<typename T>
3034 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3035
3036 #ifdef JSON_HAS_CPP_14
3037
3038 // the following utilities are natively available in C++14
3039 using std::enable_if_t;
3040 using std::index_sequence;
3041 using std::make_index_sequence;
3042 using std::index_sequence_for;
3043
3044 #else
3045
3046 // alias templates to reduce boilerplate
3047 template<bool B, typename T = void>
3048 using enable_if_t = typename std::enable_if<B, T>::type;
3049
3050 // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3051 // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3052
3054
3055 // integer_sequence
3056 //
3057 // Class template representing a compile-time integer sequence. An instantiation
3058 // of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3059 // type through its template arguments (which is a common need when
3060 // working with C++11 variadic templates). `absl::integer_sequence` is designed
3061 // to be a drop-in replacement for C++14's `std::integer_sequence`.
3062 //
3063 // Example:
3064 //
3065 // template< class T, T... Ints >
3066 // void user_function(integer_sequence<T, Ints...>);
3067 //
3068 // int main()
3069 // {
3070 // // user_function's `T` will be deduced to `int` and `Ints...`
3071 // // will be deduced to `0, 1, 2, 3, 4`.
3072 // user_function(make_integer_sequence<int, 5>());
3073 // }
3074 template <typename T, T... Ints>
3075 struct integer_sequence
3076 {
3077 using value_type = T;
3078 static constexpr std::size_t size() noexcept
3079 {
3080 return sizeof...(Ints);
3081 }
3082 };
3083
3084 // index_sequence
3085 //
3086 // A helper template for an `integer_sequence` of `size_t`,
3087 // `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3088 // `std::index_sequence`.
3089 template <size_t... Ints>
3090 using index_sequence = integer_sequence<size_t, Ints...>;
3091
3092 namespace utility_internal
3093 {
3094
3095 template <typename Seq, size_t SeqSize, size_t Rem>
3096 struct Extend;
3097
3098 // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3099 template <typename T, T... Ints, size_t SeqSize>
3100 struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3101 {
3102 using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3103 };
3104
3105 template <typename T, T... Ints, size_t SeqSize>
3106 struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3107 {
3108 using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3109 };
3110
3111 // Recursion helper for 'make_integer_sequence<T, N>'.
3112 // 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3113 template <typename T, size_t N>
3114 struct Gen
3115 {
3116 using type =
3117 typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3118 };
3119
3120 template <typename T>
3121 struct Gen<T, 0>
3122 {
3123 using type = integer_sequence<T>;
3124 };
3125
3126 } // namespace utility_internal
3127
3128 // Compile-time sequences of integers
3129
3130 // make_integer_sequence
3131 //
3132 // This template alias is equivalent to
3133 // `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3134 // replacement for C++14's `std::make_integer_sequence`.
3135 template <typename T, T N>
3136 using make_integer_sequence = typename utility_internal::Gen<T, N>::type;
3137
3138 // make_index_sequence
3139 //
3140 // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3141 // and is designed to be a drop-in replacement for C++14's
3142 // `std::make_index_sequence`.
3143 template <size_t N>
3144 using make_index_sequence = make_integer_sequence<size_t, N>;
3145
3146 // index_sequence_for
3147 //
3148 // Converts a typename pack into an index sequence of the same length, and
3149 // is designed to be a drop-in replacement for C++14's
3150 // `std::index_sequence_for()`
3151 template <typename... Ts>
3152 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
3153
3155
3156 #endif
3157
3158 // dispatch utility (taken from ranges-v3)
3159 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3160 template<> struct priority_tag<0> {};
3161
3162 // taken from ranges-v3
3163 template<typename T>
3164 struct static_const
3165 {
3166 static constexpr T value{};
3167 };
3168
3169 template<typename T>
3170 constexpr T static_const<T>::value;
3171
3172 } // namespace detail
3173 } // namespace nlohmann
3174
3175 // #include <nlohmann/detail/meta/identity_tag.hpp>
3176
3177
3178 namespace nlohmann
3179 {
3180 namespace detail
3181 {
3182 // dispatching helper struct
3183 template <class T> struct identity_tag {};
3184 } // namespace detail
3185 } // namespace nlohmann
3186
3187 // #include <nlohmann/detail/meta/type_traits.hpp>
3188
3189
3190 #include <limits> // numeric_limits
3191 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3192 #include <utility> // declval
3193 #include <tuple> // tuple
3194
3195 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
3196
3197
3198 #include <iterator> // random_access_iterator_tag
3199
3200 // #include <nlohmann/detail/meta/void_t.hpp>
3201
3202
3203 namespace nlohmann
3204 {
3205 namespace detail
3206 {
3207 template<typename ...Ts> struct make_void
3208 {
3209 using type = void;
3210 };
3211 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
3212 } // namespace detail
3213 } // namespace nlohmann
3214
3215 // #include <nlohmann/detail/meta/cpp_future.hpp>
3216
3217
3218 namespace nlohmann
3219 {
3220 namespace detail
3221 {
3222 template<typename It, typename = void>
3223 struct iterator_types {};
3224
3225 template<typename It>
3226 struct iterator_types <
3227 It,
3228 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3229 typename It::reference, typename It::iterator_category >>
3230 {
3231 using difference_type = typename It::difference_type;
3232 using value_type = typename It::value_type;
3233 using pointer = typename It::pointer;
3234 using reference = typename It::reference;
3235 using iterator_category = typename It::iterator_category;
3236 };
3237
3238 // This is required as some compilers implement std::iterator_traits in a way that
3239 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3240 template<typename T, typename = void>
3241 struct iterator_traits
3242 {
3243 };
3244
3245 template<typename T>
3246 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3247 : iterator_types<T>
3248 {
3249 };
3250
3251 template<typename T>
3252 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
3253 {
3254 using iterator_category = std::random_access_iterator_tag;
3255 using value_type = T;
3256 using difference_type = ptrdiff_t;
3257 using pointer = T*;
3258 using reference = T&;
3259 };
3260 } // namespace detail
3261 } // namespace nlohmann
3262
3263 // #include <nlohmann/detail/macro_scope.hpp>
3264
3265 // #include <nlohmann/detail/meta/cpp_future.hpp>
3266
3267 // #include <nlohmann/detail/meta/detected.hpp>
3268
3269
3270 #include <type_traits>
3271
3272 // #include <nlohmann/detail/meta/void_t.hpp>
3273
3274
3275 // https://en.cppreference.com/w/cpp/experimental/is_detected
3276 namespace nlohmann
3277 {
3278 namespace detail
3279 {
3280 struct nonesuch
3281 {
3282 nonesuch() = delete;
3283 ~nonesuch() = delete;
3284 nonesuch(nonesuch const&) = delete;
3285 nonesuch(nonesuch const&&) = delete;
3286 void operator=(nonesuch const&) = delete;
3287 void operator=(nonesuch&&) = delete;
3288 };
3289
3290 template<class Default,
3291 class AlwaysVoid,
3292 template<class...> class Op,
3293 class... Args>
3294 struct detector
3295 {
3296 using value_t = std::false_type;
3297 using type = Default;
3298 };
3299
3300 template<class Default, template<class...> class Op, class... Args>
3301 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
3302 {
3303 using value_t = std::true_type;
3304 using type = Op<Args...>;
3305 };
3306
3307 template<template<class...> class Op, class... Args>
3308 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
3309
3310 template<template<class...> class Op, class... Args>
3311 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
3312
3313 template<class Default, template<class...> class Op, class... Args>
3314 using detected_or = detector<Default, void, Op, Args...>;
3315
3316 template<class Default, template<class...> class Op, class... Args>
3317 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
3318
3319 template<class Expected, template<class...> class Op, class... Args>
3320 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
3321
3322 template<class To, template<class...> class Op, class... Args>
3323 using is_detected_convertible =
3324 std::is_convertible<detected_t<Op, Args...>, To>;
3325 } // namespace detail
3326 } // namespace nlohmann
3327
3328 // #include <nlohmann/json_fwd.hpp>
3329 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3330 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3331
3332 #include <cstdint> // int64_t, uint64_t
3333 #include <map> // map
3334 #include <memory> // allocator
3335 #include <string> // string
3336 #include <vector> // vector
3337
3343 namespace nlohmann
3344 {
3352 template<typename T = void, typename SFINAE = void>
3353 struct adl_serializer;
3354
3355 template<template<typename U, typename V, typename... Args> class ObjectType =
3356 std::map,
3357 template<typename U, typename... Args> class ArrayType = std::vector,
3358 class StringType = std::string, class BooleanType = bool,
3359 class NumberIntegerType = std::int64_t,
3360 class NumberUnsignedType = std::uint64_t,
3361 class NumberFloatType = double,
3362 template<typename U> class AllocatorType = std::allocator,
3363 template<typename T, typename SFINAE = void> class JSONSerializer =
3364 adl_serializer,
3365 class BinaryType = std::vector<std::uint8_t>>
3366 class basic_json;
3367
3379 template<typename BasicJsonType>
3380 class json_pointer;
3381
3390 using json = basic_json<>;
3391
3392 template<class Key, class T, class IgnoredLess, class Allocator>
3393 struct ordered_map;
3394
3402 using ordered_json = basic_json<nlohmann::ordered_map>;
3403
3404 } // namespace nlohmann
3405
3406 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3407
3408
3409 namespace nlohmann
3410 {
3419 namespace detail
3420 {
3422 // helpers //
3424
3425 // Note to maintainers:
3426 //
3427 // Every trait in this file expects a non CV-qualified type.
3428 // The only exceptions are in the 'aliases for detected' section
3429 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3430 //
3431 // In this case, T has to be properly CV-qualified to constraint the function arguments
3432 // (e.g. to_json(BasicJsonType&, const T&))
3433
3434 template<typename> struct is_basic_json : std::false_type {};
3435
3436 NLOHMANN_BASIC_JSON_TPL_DECLARATION
3437 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3438
3440 // json_ref helpers //
3442
3443 template<typename>
3444 class json_ref;
3445
3446 template<typename>
3447 struct is_json_ref : std::false_type {};
3448
3449 template<typename T>
3450 struct is_json_ref<json_ref<T>> : std::true_type {};
3451
3453 // aliases for detected //
3455
3456 template<typename T>
3457 using mapped_type_t = typename T::mapped_type;
3458
3459 template<typename T>
3460 using key_type_t = typename T::key_type;
3461
3462 template<typename T>
3463 using value_type_t = typename T::value_type;
3464
3465 template<typename T>
3466 using difference_type_t = typename T::difference_type;
3467
3468 template<typename T>
3469 using pointer_t = typename T::pointer;
3470
3471 template<typename T>
3472 using reference_t = typename T::reference;
3473
3474 template<typename T>
3475 using iterator_category_t = typename T::iterator_category;
3476
3477 template<typename T>
3478 using iterator_t = typename T::iterator;
3479
3480 template<typename T, typename... Args>
3481 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3482
3483 template<typename T, typename... Args>
3484 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3485
3486 template<typename T, typename U>
3487 using get_template_function = decltype(std::declval<T>().template get<U>());
3488
3489 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3490 template<typename BasicJsonType, typename T, typename = void>
3491 struct has_from_json : std::false_type {};
3492
3493 // trait checking if j.get<T> is valid
3494 // use this trait instead of std::is_constructible or std::is_convertible,
3495 // both rely on, or make use of implicit conversions, and thus fail when T
3496 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3497 template <typename BasicJsonType, typename T>
3498 struct is_getable
3499 {
3500 static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
3501 };
3502
3503 template<typename BasicJsonType, typename T>
3504 struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3505 {
3506 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3507
3508 static constexpr bool value =
3509 is_detected_exact<void, from_json_function, serializer,
3510 const BasicJsonType&, T&>::value;
3511 };
3512
3513 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3514 // this overload is used for non-default-constructible user-defined-types
3515 template<typename BasicJsonType, typename T, typename = void>
3516 struct has_non_default_from_json : std::false_type {};
3517
3518 template<typename BasicJsonType, typename T>
3519 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3520 {
3521 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3522
3523 static constexpr bool value =
3524 is_detected_exact<T, from_json_function, serializer,
3525 const BasicJsonType&>::value;
3526 };
3527
3528 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3529 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3530 template<typename BasicJsonType, typename T, typename = void>
3531 struct has_to_json : std::false_type {};
3532
3533 template<typename BasicJsonType, typename T>
3534 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3535 {
3536 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3537
3538 static constexpr bool value =
3539 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3540 T>::value;
3541 };
3542
3543
3545 // is_ functions //
3547
3548 // https://en.cppreference.com/w/cpp/types/conjunction
3549 template<class...> struct conjunction : std::true_type { };
3550 template<class B1> struct conjunction<B1> : B1 { };
3551 template<class B1, class... Bn>
3552 struct conjunction<B1, Bn...>
3553 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3554
3555 // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3556 // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3557 // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3558 template <typename T>
3559 struct is_default_constructible : std::is_default_constructible<T> {};
3560
3561 template <typename T1, typename T2>
3562 struct is_default_constructible<std::pair<T1, T2>>
3563 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3564
3565 template <typename T1, typename T2>
3566 struct is_default_constructible<const std::pair<T1, T2>>
3567 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3568
3569 template <typename... Ts>
3570 struct is_default_constructible<std::tuple<Ts...>>
3571 : conjunction<is_default_constructible<Ts>...> {};
3572
3573 template <typename... Ts>
3574 struct is_default_constructible<const std::tuple<Ts...>>
3575 : conjunction<is_default_constructible<Ts>...> {};
3576
3577
3578 template <typename T, typename... Args>
3579 struct is_constructible : std::is_constructible<T, Args...> {};
3580
3581 template <typename T1, typename T2>
3582 struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3583
3584 template <typename T1, typename T2>
3585 struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3586
3587 template <typename... Ts>
3588 struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3589
3590 template <typename... Ts>
3591 struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3592
3593
3594 template<typename T, typename = void>
3595 struct is_iterator_traits : std::false_type {};
3596
3597 template<typename T>
3598 struct is_iterator_traits<iterator_traits<T>>
3599 {
3600 private:
3601 using traits = iterator_traits<T>;
3602
3603 public:
3604 static constexpr auto value =
3605 is_detected<value_type_t, traits>::value &&
3606 is_detected<difference_type_t, traits>::value &&
3607 is_detected<pointer_t, traits>::value &&
3608 is_detected<iterator_category_t, traits>::value &&
3609 is_detected<reference_t, traits>::value;
3610 };
3611
3612 // The following implementation of is_complete_type is taken from
3613 // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3614 // and is written by Xiang Fan who agreed to using it in this library.
3615
3616 template<typename T, typename = void>
3617 struct is_complete_type : std::false_type {};
3618
3619 template<typename T>
3620 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3621
3622 template<typename BasicJsonType, typename CompatibleObjectType,
3623 typename = void>
3624 struct is_compatible_object_type_impl : std::false_type {};
3625
3626 template<typename BasicJsonType, typename CompatibleObjectType>
3627 struct is_compatible_object_type_impl <
3628 BasicJsonType, CompatibleObjectType,
3629 enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3630 is_detected<key_type_t, CompatibleObjectType>::value >>
3631 {
3632 using object_t = typename BasicJsonType::object_t;
3633
3634 // macOS's is_constructible does not play well with nonesuch...
3635 static constexpr bool value =
3636 is_constructible<typename object_t::key_type,
3637 typename CompatibleObjectType::key_type>::value &&
3638 is_constructible<typename object_t::mapped_type,
3639 typename CompatibleObjectType::mapped_type>::value;
3640 };
3641
3642 template<typename BasicJsonType, typename CompatibleObjectType>
3643 struct is_compatible_object_type
3644 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3645
3646 template<typename BasicJsonType, typename ConstructibleObjectType,
3647 typename = void>
3648 struct is_constructible_object_type_impl : std::false_type {};
3649
3650 template<typename BasicJsonType, typename ConstructibleObjectType>
3651 struct is_constructible_object_type_impl <
3652 BasicJsonType, ConstructibleObjectType,
3653 enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3654 is_detected<key_type_t, ConstructibleObjectType>::value >>
3655 {
3656 using object_t = typename BasicJsonType::object_t;
3657
3658 static constexpr bool value =
3659 (is_default_constructible<ConstructibleObjectType>::value &&
3660 (std::is_move_assignable<ConstructibleObjectType>::value ||
3661 std::is_copy_assignable<ConstructibleObjectType>::value) &&
3662 (is_constructible<typename ConstructibleObjectType::key_type,
3663 typename object_t::key_type>::value &&
3664 std::is_same <
3665 typename object_t::mapped_type,
3666 typename ConstructibleObjectType::mapped_type >::value)) ||
3667 (has_from_json<BasicJsonType,
3668 typename ConstructibleObjectType::mapped_type>::value ||
3669 has_non_default_from_json <
3670 BasicJsonType,
3671 typename ConstructibleObjectType::mapped_type >::value);
3672 };
3673
3674 template<typename BasicJsonType, typename ConstructibleObjectType>
3675 struct is_constructible_object_type
3676 : is_constructible_object_type_impl<BasicJsonType,
3677 ConstructibleObjectType> {};
3678
3679 template<typename BasicJsonType, typename CompatibleStringType,
3680 typename = void>
3681 struct is_compatible_string_type_impl : std::false_type {};
3682
3683 template<typename BasicJsonType, typename CompatibleStringType>
3684 struct is_compatible_string_type_impl <
3685 BasicJsonType, CompatibleStringType,
3686 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3687 value_type_t, CompatibleStringType>::value >>
3688 {
3689 static constexpr auto value =
3690 is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
3691 };
3692
3693 template<typename BasicJsonType, typename ConstructibleStringType>
3694 struct is_compatible_string_type
3695 : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3696
3697 template<typename BasicJsonType, typename ConstructibleStringType,
3698 typename = void>
3699 struct is_constructible_string_type_impl : std::false_type {};
3700
3701 template<typename BasicJsonType, typename ConstructibleStringType>
3702 struct is_constructible_string_type_impl <
3703 BasicJsonType, ConstructibleStringType,
3704 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3705 value_type_t, ConstructibleStringType>::value >>
3706 {
3707 static constexpr auto value =
3708 is_constructible<ConstructibleStringType,
3709 typename BasicJsonType::string_t>::value;
3710 };
3711
3712 template<typename BasicJsonType, typename ConstructibleStringType>
3713 struct is_constructible_string_type
3714 : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3715
3716 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3717 struct is_compatible_array_type_impl : std::false_type {};
3718
3719 template<typename BasicJsonType, typename CompatibleArrayType>
3720 struct is_compatible_array_type_impl <
3721 BasicJsonType, CompatibleArrayType,
3722 enable_if_t < is_detected<value_type_t, CompatibleArrayType>::value&&
3723 is_detected<iterator_t, CompatibleArrayType>::value&&
3724 // This is needed because json_reverse_iterator has a ::iterator type...
3725 // Therefore it is detected as a CompatibleArrayType.
3726 // The real fix would be to have an Iterable concept.
3727 !is_iterator_traits <
3728 iterator_traits<CompatibleArrayType >>::value >>
3729 {
3730 static constexpr bool value =
3731 is_constructible<BasicJsonType,
3732 typename CompatibleArrayType::value_type>::value;
3733 };
3734
3735 template<typename BasicJsonType, typename CompatibleArrayType>
3736 struct is_compatible_array_type
3737 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3738
3739 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3740 struct is_constructible_array_type_impl : std::false_type {};
3741
3742 template<typename BasicJsonType, typename ConstructibleArrayType>
3743 struct is_constructible_array_type_impl <
3744 BasicJsonType, ConstructibleArrayType,
3745 enable_if_t<std::is_same<ConstructibleArrayType,
3746 typename BasicJsonType::value_type>::value >>
3747 : std::true_type {};
3748
3749 template<typename BasicJsonType, typename ConstructibleArrayType>
3750 struct is_constructible_array_type_impl <
3751 BasicJsonType, ConstructibleArrayType,
3752 enable_if_t < !std::is_same<ConstructibleArrayType,
3753 typename BasicJsonType::value_type>::value&&
3754 is_default_constructible<ConstructibleArrayType>::value&&
3755 (std::is_move_assignable<ConstructibleArrayType>::value ||
3756 std::is_copy_assignable<ConstructibleArrayType>::value)&&
3757 is_detected<value_type_t, ConstructibleArrayType>::value&&
3758 is_detected<iterator_t, ConstructibleArrayType>::value&&
3759 is_complete_type <
3760 detected_t<value_type_t, ConstructibleArrayType >>::value >>
3761 {
3762 static constexpr bool value =
3763 // This is needed because json_reverse_iterator has a ::iterator type,
3764 // furthermore, std::back_insert_iterator (and other iterators) have a
3765 // base class `iterator`... Therefore it is detected as a
3766 // ConstructibleArrayType. The real fix would be to have an Iterable
3767 // concept.
3768 !is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value &&
3769
3770 (std::is_same<typename ConstructibleArrayType::value_type,
3771 typename BasicJsonType::array_t::value_type>::value ||
3772 has_from_json<BasicJsonType,
3773 typename ConstructibleArrayType::value_type>::value ||
3774 has_non_default_from_json <
3775 BasicJsonType, typename ConstructibleArrayType::value_type >::value);
3776 };
3777
3778 template<typename BasicJsonType, typename ConstructibleArrayType>
3779 struct is_constructible_array_type
3780 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3781
3782 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3783 typename = void>
3784 struct is_compatible_integer_type_impl : std::false_type {};
3785
3786 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3787 struct is_compatible_integer_type_impl <
3788 RealIntegerType, CompatibleNumberIntegerType,
3789 enable_if_t < std::is_integral<RealIntegerType>::value&&
3790 std::is_integral<CompatibleNumberIntegerType>::value&&
3791 !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3792 {
3793 // is there an assert somewhere on overflows?
3794 using RealLimits = std::numeric_limits<RealIntegerType>;
3795 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3796
3797 static constexpr auto value =
3798 is_constructible<RealIntegerType,
3799 CompatibleNumberIntegerType>::value &&
3800 CompatibleLimits::is_integer &&
3801 RealLimits::is_signed == CompatibleLimits::is_signed;
3802 };
3803
3804 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3805 struct is_compatible_integer_type
3806 : is_compatible_integer_type_impl<RealIntegerType,
3807 CompatibleNumberIntegerType> {};
3808
3809 template<typename BasicJsonType, typename CompatibleType, typename = void>
3810 struct is_compatible_type_impl: std::false_type {};
3811
3812 template<typename BasicJsonType, typename CompatibleType>
3813 struct is_compatible_type_impl <
3814 BasicJsonType, CompatibleType,
3815 enable_if_t<is_complete_type<CompatibleType>::value >>
3816 {
3817 static constexpr bool value =
3818 has_to_json<BasicJsonType, CompatibleType>::value;
3819 };
3820
3821 template<typename BasicJsonType, typename CompatibleType>
3822 struct is_compatible_type
3823 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3824
3825 template<typename T1, typename T2>
3826 struct is_constructible_tuple : std::false_type {};
3827
3828 template<typename T1, typename... Args>
3829 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3830 } // namespace detail
3831 } // namespace nlohmann
3832
3833 // #include <nlohmann/detail/value_t.hpp>
3834
3835
3836 namespace nlohmann
3837 {
3838 namespace detail
3839 {
3840 template<typename BasicJsonType>
3841 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3842 {
3843 if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
3844 {
3845 JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()), j));
3846 }
3847 n = nullptr;
3848 }
3849
3850 // overloads for basic_json template parameters
3851 template < typename BasicJsonType, typename ArithmeticType,
3852 enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
3853 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3854 int > = 0 >
3855 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3856 {
3857 switch (static_cast<value_t>(j))
3858 {
3859 case value_t::number_unsigned:
3860 {
3861 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3862 break;
3863 }
3864 case value_t::number_integer:
3865 {
3866 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3867 break;
3868 }
3869 case value_t::number_float:
3870 {
3871 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3872 break;
3873 }
3874
3875 default:
3876 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
3877 }
3878 }
3879
3880 template<typename BasicJsonType>
3881 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
3882 {
3883 if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
3884 {
3885 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()), j));
3886 }
3887 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
3888 }
3889
3890 template<typename BasicJsonType>
3891 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
3892 {
3893 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3894 {
3895 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
3896 }
3897 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3898 }
3899
3900 template <
3901 typename BasicJsonType, typename ConstructibleStringType,
3902 enable_if_t <
3903 is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&
3904 !std::is_same<typename BasicJsonType::string_t,
3905 ConstructibleStringType>::value,
3906 int > = 0 >
3907 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
3908 {
3909 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3910 {
3911 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
3912 }
3913
3914 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3915 }
3916
3917 template<typename BasicJsonType>
3918 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
3919 {
3920 get_arithmetic_value(j, val);
3921 }
3922
3923 template<typename BasicJsonType>
3924 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
3925 {
3926 get_arithmetic_value(j, val);
3927 }
3928
3929 template<typename BasicJsonType>
3930 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
3931 {
3932 get_arithmetic_value(j, val);
3933 }
3934
3935 template<typename BasicJsonType, typename EnumType,
3936 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
3937 void from_json(const BasicJsonType& j, EnumType& e)
3938 {
3939 typename std::underlying_type<EnumType>::type val;
3940 get_arithmetic_value(j, val);
3941 e = static_cast<EnumType>(val);
3942 }
3943
3944 // forward_list doesn't have an insert method
3945 template<typename BasicJsonType, typename T, typename Allocator,
3946 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
3947 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
3948 {
3949 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3950 {
3951 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
3952 }
3953 l.clear();
3954 std::transform(j.rbegin(), j.rend(),
3955 std::front_inserter(l), [](const BasicJsonType & i)
3956 {
3957 return i.template get<T>();
3958 });
3959 }
3960
3961 // valarray doesn't have an insert method
3962 template<typename BasicJsonType, typename T,
3963 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
3964 void from_json(const BasicJsonType& j, std::valarray<T>& l)
3965 {
3966 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3967 {
3968 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
3969 }
3970 l.resize(j.size());
3971 std::transform(j.begin(), j.end(), std::begin(l),
3972 [](const BasicJsonType & elem)
3973 {
3974 return elem.template get<T>();
3975 });
3976 }
3977
3978 template<typename BasicJsonType, typename T, std::size_t N>
3979 auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3980 -> decltype(j.template get<T>(), void())
3981 {
3982 for (std::size_t i = 0; i < N; ++i)
3983 {
3984 arr[i] = j.at(i).template get<T>();
3985 }
3986 }
3987
3988 template<typename BasicJsonType>
3989 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
3990 {
3991 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
3992 }
3993
3994 template<typename BasicJsonType, typename T, std::size_t N>
3995 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
3996 priority_tag<2> /*unused*/)
3997 -> decltype(j.template get<T>(), void())
3998 {
3999 for (std::size_t i = 0; i < N; ++i)
4000 {
4001 arr[i] = j.at(i).template get<T>();
4002 }
4003 }
4004
4005 template<typename BasicJsonType, typename ConstructibleArrayType,
4006 enable_if_t<
4007 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4008 int> = 0>
4009 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4010 -> decltype(
4011 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4012 j.template get<typename ConstructibleArrayType::value_type>(),
4013 void())
4014 {
4015 using std::end;
4016
4017 ConstructibleArrayType ret;
4018 ret.reserve(j.size());
4019 std::transform(j.begin(), j.end(),
4020 std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4021 {
4022 // get<BasicJsonType>() returns *this, this won't call a from_json
4023 // method when value_type is BasicJsonType
4024 return i.template get<typename ConstructibleArrayType::value_type>();
4025 });
4026 arr = std::move(ret);
4027 }
4028
4029 template<typename BasicJsonType, typename ConstructibleArrayType,
4030 enable_if_t<
4031 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4032 int> = 0>
4033 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4034 priority_tag<0> /*unused*/)
4035 {
4036 using std::end;
4037
4038 ConstructibleArrayType ret;
4039 std::transform(
4040 j.begin(), j.end(), std::inserter(ret, end(ret)),
4041 [](const BasicJsonType & i)
4042 {
4043 // get<BasicJsonType>() returns *this, this won't call a from_json
4044 // method when value_type is BasicJsonType
4045 return i.template get<typename ConstructibleArrayType::value_type>();
4046 });
4047 arr = std::move(ret);
4048 }
4049
4050 template < typename BasicJsonType, typename ConstructibleArrayType,
4051 enable_if_t <
4052 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
4053 !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
4054 !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
4055 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
4056 !is_basic_json<ConstructibleArrayType>::value,
4057 int > = 0 >
4058 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4059 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4060 j.template get<typename ConstructibleArrayType::value_type>(),
4061 void())
4062 {
4063 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4064 {
4065 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4066 }
4067
4068 from_json_array_impl(j, arr, priority_tag<3> {});
4069 }
4070
4071 template < typename BasicJsonType, typename T, std::size_t... Idx >
4072 std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4073 identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4074 {
4075 return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4076 }
4077
4078 template < typename BasicJsonType, typename T, std::size_t N >
4079 auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4080 -> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4081 {
4082 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4083 {
4084 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4085 }
4086
4087 return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4088 }
4089
4090 template<typename BasicJsonType>
4091 void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4092 {
4093 if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4094 {
4095 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()), j));
4096 }
4097
4098 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4099 }
4100
4101 template<typename BasicJsonType, typename ConstructibleObjectType,
4102 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4103 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4104 {
4105 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4106 {
4107 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()), j));
4108 }
4109
4110 ConstructibleObjectType ret;
4111 const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4112 using value_type = typename ConstructibleObjectType::value_type;
4113 std::transform(
4114 inner_object->begin(), inner_object->end(),
4115 std::inserter(ret, ret.begin()),
4116 [](typename BasicJsonType::object_t::value_type const & p)
4117 {
4118 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4119 });
4120 obj = std::move(ret);
4121 }
4122
4123 // overload for arithmetic types, not chosen for basic_json template arguments
4124 // (BooleanType, etc..); note: Is it really necessary to provide explicit
4125 // overloads for boolean_t etc. in case of a custom BooleanType which is not
4126 // an arithmetic type?
4127 template < typename BasicJsonType, typename ArithmeticType,
4128 enable_if_t <
4129 std::is_arithmetic<ArithmeticType>::value&&
4130 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
4131 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
4132 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
4133 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4134 int > = 0 >
4135 void from_json(const BasicJsonType& j, ArithmeticType& val)
4136 {
4137 switch (static_cast<value_t>(j))
4138 {
4139 case value_t::number_unsigned:
4140 {
4141 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4142 break;
4143 }
4144 case value_t::number_integer:
4145 {
4146 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4147 break;
4148 }
4149 case value_t::number_float:
4150 {
4151 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4152 break;
4153 }
4154 case value_t::boolean:
4155 {
4156 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4157 break;
4158 }
4159
4160 default:
4161 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4162 }
4163 }
4164
4165 template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4166 std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4167 {
4168 return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4169 }
4170
4171 template < typename BasicJsonType, class A1, class A2 >
4172 std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4173 {
4174 return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4175 std::forward<BasicJsonType>(j).at(1).template get<A2>()};
4176 }
4177
4178 template<typename BasicJsonType, typename A1, typename A2>
4179 void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4180 {
4181 p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4182 }
4183
4184 template<typename BasicJsonType, typename... Args>
4185 std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4186 {
4187 return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4188 }
4189
4190 template<typename BasicJsonType, typename... Args>
4191 void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4192 {
4193 t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4194 }
4195
4196 template<typename BasicJsonType, typename TupleRelated>
4197 auto from_json(BasicJsonType&& j, TupleRelated&& t)
4198 -> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4199 {
4200 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4201 {
4202 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4203 }
4204
4205 return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4206 }
4207
4208 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4209 typename = enable_if_t < !std::is_constructible <
4210 typename BasicJsonType::string_t, Key >::value >>
4211 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4212 {
4213 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4214 {
4215 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4216 }
4217 m.clear();
4218 for (const auto& p : j)
4219 {
4220 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4221 {
4222 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4223 }
4224 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4225 }
4226 }
4227
4228 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4229 typename = enable_if_t < !std::is_constructible <
4230 typename BasicJsonType::string_t, Key >::value >>
4231 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
4232 {
4233 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4234 {
4235 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4236 }
4237 m.clear();
4238 for (const auto& p : j)
4239 {
4240 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4241 {
4242 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4243 }
4244 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4245 }
4246 }
4247
4248 struct from_json_fn
4249 {
4250 template<typename BasicJsonType, typename T>
4251 auto operator()(const BasicJsonType& j, T&& val) const
4252 noexcept(noexcept(from_json(j, std::forward<T>(val))))
4253 -> decltype(from_json(j, std::forward<T>(val)))
4254 {
4255 return from_json(j, std::forward<T>(val));
4256 }
4257 };
4258 } // namespace detail
4259
4263 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4264 {
4265 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4266 } // namespace
4267 } // namespace nlohmann
4268
4269 // #include <nlohmann/detail/conversions/to_json.hpp>
4270
4271
4272 #include <algorithm> // copy
4273 #include <iterator> // begin, end
4274 #include <string> // string
4275 #include <tuple> // tuple, get
4276 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
4277 #include <utility> // move, forward, declval, pair
4278 #include <valarray> // valarray
4279 #include <vector> // vector
4280
4281 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4282
4283
4284 #include <cstddef> // size_t
4285 #include <iterator> // input_iterator_tag
4286 #include <string> // string, to_string
4287 #include <tuple> // tuple_size, get, tuple_element
4288 #include <utility> // move
4289
4290 // #include <nlohmann/detail/meta/type_traits.hpp>
4291
4292 // #include <nlohmann/detail/value_t.hpp>
4293
4294
4295 namespace nlohmann
4296 {
4297 namespace detail
4298 {
4299 template<typename string_type>
4300 void int_to_string( string_type& target, std::size_t value )
4301 {
4302 // For ADL
4303 using std::to_string;
4304 target = to_string(value);
4305 }
4306 template<typename IteratorType> class iteration_proxy_value
4307 {
4308 public:
4309 using difference_type = std::ptrdiff_t;
4310 using value_type = iteration_proxy_value;
4311 using pointer = value_type * ;
4312 using reference = value_type & ;
4313 using iterator_category = std::input_iterator_tag;
4314 using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
4315
4316 private:
4318 IteratorType anchor;
4320 std::size_t array_index = 0;
4322 mutable std::size_t array_index_last = 0;
4324 mutable string_type array_index_str = "0";
4326 const string_type empty_str{};
4327
4328 public:
4329 explicit iteration_proxy_value(IteratorType it) noexcept
4330 : anchor(std::move(it))
4331 {}
4332
4334 iteration_proxy_value& operator*()
4335 {
4336 return *this;
4337 }
4338
4340 iteration_proxy_value& operator++()
4341 {
4342 ++anchor;
4343 ++array_index;
4344
4345 return *this;
4346 }
4347
4349 bool operator==(const iteration_proxy_value& o) const
4350 {
4351 return anchor == o.anchor;
4352 }
4353
4355 bool operator!=(const iteration_proxy_value& o) const
4356 {
4357 return anchor != o.anchor;
4358 }
4359
4361 const string_type& key() const
4362 {
4363 JSON_ASSERT(anchor.m_object != nullptr);
4364
4365 switch (anchor.m_object->type())
4366 {
4367 // use integer array index as key
4368 case value_t::array:
4369 {
4370 if (array_index != array_index_last)
4371 {
4372 int_to_string( array_index_str, array_index );
4373 array_index_last = array_index;
4374 }
4375 return array_index_str;
4376 }
4377
4378 // use key from the object
4379 case value_t::object:
4380 return anchor.key();
4381
4382 // use an empty key for all primitive types
4383 default:
4384 return empty_str;
4385 }
4386 }
4387
4389 typename IteratorType::reference value() const
4390 {
4391 return anchor.value();
4392 }
4393 };
4394
4396 template<typename IteratorType> class iteration_proxy
4397 {
4398 private:
4400 typename IteratorType::reference container;
4401
4402 public:
4404 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4405 : container(cont) {}
4406
4408 iteration_proxy_value<IteratorType> begin() noexcept
4409 {
4410 return iteration_proxy_value<IteratorType>(container.begin());
4411 }
4412
4414 iteration_proxy_value<IteratorType> end() noexcept
4415 {
4416 return iteration_proxy_value<IteratorType>(container.end());
4417 }
4418 };
4419 // Structured Bindings Support
4420 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4421 // And see https://github.com/nlohmann/json/pull/1391
4422 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
4423 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
4424 {
4425 return i.key();
4426 }
4427 // Structured Bindings Support
4428 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4429 // And see https://github.com/nlohmann/json/pull/1391
4430 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
4431 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
4432 {
4433 return i.value();
4434 }
4435 } // namespace detail
4436 } // namespace nlohmann
4437
4438 // The Addition to the STD Namespace is required to add
4439 // Structured Bindings Support to the iteration_proxy_value class
4440 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4441 // And see https://github.com/nlohmann/json/pull/1391
4442 namespace std
4443 {
4444 #if defined(__clang__)
4445 // Fix: https://github.com/nlohmann/json/issues/1401
4446 #pragma clang diagnostic push
4447 #pragma clang diagnostic ignored "-Wmismatched-tags"
4448 #endif
4449 template<typename IteratorType>
4450 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4451 : public std::integral_constant<std::size_t, 2> {};
4452
4453 template<std::size_t N, typename IteratorType>
4454 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4455 {
4456 public:
4457 using type = decltype(
4458 get<N>(std::declval <
4459 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
4460 };
4461 #if defined(__clang__)
4462 #pragma clang diagnostic pop
4463 #endif
4464 } // namespace std
4465
4466 // #include <nlohmann/detail/meta/cpp_future.hpp>
4467
4468 // #include <nlohmann/detail/meta/type_traits.hpp>
4469
4470 // #include <nlohmann/detail/value_t.hpp>
4471
4472
4473 namespace nlohmann
4474 {
4475 namespace detail
4476 {
4478 // constructors //
4480
4481 template<value_t> struct external_constructor;
4482
4483 template<>
4484 struct external_constructor<value_t::boolean>
4485 {
4486 template<typename BasicJsonType>
4487 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4488 {
4489 j.m_type = value_t::boolean;
4490 j.m_value = b;
4491 j.assert_invariant();
4492 }
4493 };
4494
4495 template<>
4496 struct external_constructor<value_t::string>
4497 {
4498 template<typename BasicJsonType>
4499 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4500 {
4501 j.m_type = value_t::string;
4502 j.m_value = s;
4503 j.assert_invariant();
4504 }
4505
4506 template<typename BasicJsonType>
4507 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4508 {
4509 j.m_type = value_t::string;
4510 j.m_value = std::move(s);
4511 j.assert_invariant();
4512 }
4513
4514 template < typename BasicJsonType, typename CompatibleStringType,
4515 enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
4516 int > = 0 >
4517 static void construct(BasicJsonType& j, const CompatibleStringType& str)
4518 {
4519 j.m_type = value_t::string;
4520 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4521 j.assert_invariant();
4522 }
4523 };
4524
4525 template<>
4526 struct external_constructor<value_t::binary>
4527 {
4528 template<typename BasicJsonType>
4529 static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4530 {
4531 j.m_type = value_t::binary;
4532 j.m_value = typename BasicJsonType::binary_t(b);
4533 j.assert_invariant();
4534 }
4535
4536 template<typename BasicJsonType>
4537 static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4538 {
4539 j.m_type = value_t::binary;
4540 j.m_value = typename BasicJsonType::binary_t(std::move(b));;
4541 j.assert_invariant();
4542 }
4543 };
4544
4545 template<>
4546 struct external_constructor<value_t::number_float>
4547 {
4548 template<typename BasicJsonType>
4549 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4550 {
4551 j.m_type = value_t::number_float;
4552 j.m_value = val;
4553 j.assert_invariant();
4554 }
4555 };
4556
4557 template<>
4558 struct external_constructor<value_t::number_unsigned>
4559 {
4560 template<typename BasicJsonType>
4561 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4562 {
4563 j.m_type = value_t::number_unsigned;
4564 j.m_value = val;
4565 j.assert_invariant();
4566 }
4567 };
4568
4569 template<>
4570 struct external_constructor<value_t::number_integer>
4571 {
4572 template<typename BasicJsonType>
4573 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4574 {
4575 j.m_type = value_t::number_integer;
4576 j.m_value = val;
4577 j.assert_invariant();
4578 }
4579 };
4580
4581 template<>
4582 struct external_constructor<value_t::array>
4583 {
4584 template<typename BasicJsonType>
4585 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4586 {
4587 j.m_type = value_t::array;
4588 j.m_value = arr;
4589 j.set_parents();
4590 j.assert_invariant();
4591 }
4592
4593 template<typename BasicJsonType>
4594 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4595 {
4596 j.m_type = value_t::array;
4597 j.m_value = std::move(arr);
4598 j.set_parents();
4599 j.assert_invariant();
4600 }
4601
4602 template < typename BasicJsonType, typename CompatibleArrayType,
4603 enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
4604 int > = 0 >
4605 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4606 {
4607 using std::begin;
4608 using std::end;
4609 j.m_type = value_t::array;
4610 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4611 j.set_parents();
4612 j.assert_invariant();
4613 }
4614
4615 template<typename BasicJsonType>
4616 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4617 {
4618 j.m_type = value_t::array;
4619 j.m_value = value_t::array;
4620 j.m_value.array->reserve(arr.size());
4621 for (const bool x : arr)
4622 {
4623 j.m_value.array->push_back(x);
4624 j.set_parent(j.m_value.array->back());
4625 }
4626 j.assert_invariant();
4627 }
4628
4629 template<typename BasicJsonType, typename T,
4630 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4631 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4632 {
4633 j.m_type = value_t::array;
4634 j.m_value = value_t::array;
4635 j.m_value.array->resize(arr.size());
4636 if (arr.size() > 0)
4637 {
4638 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4639 }
4640 j.set_parents();
4641 j.assert_invariant();
4642 }
4643 };
4644
4645 template<>
4646 struct external_constructor<value_t::object>
4647 {
4648 template<typename BasicJsonType>
4649 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
4650 {
4651 j.m_type = value_t::object;
4652 j.m_value = obj;
4653 j.set_parents();
4654 j.assert_invariant();
4655 }
4656
4657 template<typename BasicJsonType>
4658 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4659 {
4660 j.m_type = value_t::object;
4661 j.m_value = std::move(obj);
4662 j.set_parents();
4663 j.assert_invariant();
4664 }
4665
4666 template < typename BasicJsonType, typename CompatibleObjectType,
4667 enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
4668 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4669 {
4670 using std::begin;
4671 using std::end;
4672
4673 j.m_type = value_t::object;
4674 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4675 j.set_parents();
4676 j.assert_invariant();
4677 }
4678 };
4679
4681 // to_json //
4683
4684 template<typename BasicJsonType, typename T,
4685 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
4686 void to_json(BasicJsonType& j, T b) noexcept
4687 {
4688 external_constructor<value_t::boolean>::construct(j, b);
4689 }
4690
4691 template<typename BasicJsonType, typename CompatibleString,
4692 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
4693 void to_json(BasicJsonType& j, const CompatibleString& s)
4694 {
4695 external_constructor<value_t::string>::construct(j, s);
4696 }
4697
4698 template<typename BasicJsonType>
4699 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4700 {
4701 external_constructor<value_t::string>::construct(j, std::move(s));
4702 }
4703
4704 template<typename BasicJsonType, typename FloatType,
4705 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
4706 void to_json(BasicJsonType& j, FloatType val) noexcept
4707 {
4708 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4709 }
4710
4711 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4712 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
4713 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4714 {
4715 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4716 }
4717
4718 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4719 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
4720 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4721 {
4722 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4723 }
4724
4725 template<typename BasicJsonType, typename EnumType,
4726 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4727 void to_json(BasicJsonType& j, EnumType e) noexcept
4728 {
4729 using underlying_type = typename std::underlying_type<EnumType>::type;
4730 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4731 }
4732
4733 template<typename BasicJsonType>
4734 void to_json(BasicJsonType& j, const std::vector<bool>& e)
4735 {
4736 external_constructor<value_t::array>::construct(j, e);
4737 }
4738
4739 template < typename BasicJsonType, typename CompatibleArrayType,
4740 enable_if_t < is_compatible_array_type<BasicJsonType,
4741 CompatibleArrayType>::value&&
4742 !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
4743 !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
4744 !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
4745 !is_basic_json<CompatibleArrayType>::value,
4746 int > = 0 >
4747 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4748 {
4749 external_constructor<value_t::array>::construct(j, arr);
4750 }
4751
4752 template<typename BasicJsonType>
4753 void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4754 {
4755 external_constructor<value_t::binary>::construct(j, bin);
4756 }
4757
4758 template<typename BasicJsonType, typename T,
4759 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4760 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4761 {
4762 external_constructor<value_t::array>::construct(j, std::move(arr));
4763 }
4764
4765 template<typename BasicJsonType>
4766 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4767 {
4768 external_constructor<value_t::array>::construct(j, std::move(arr));
4769 }
4770
4771 template < typename BasicJsonType, typename CompatibleObjectType,
4772 enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
4773 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4774 {
4775 external_constructor<value_t::object>::construct(j, obj);
4776 }
4777
4778 template<typename BasicJsonType>
4779 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4780 {
4781 external_constructor<value_t::object>::construct(j, std::move(obj));
4782 }
4783
4784 template <
4785 typename BasicJsonType, typename T, std::size_t N,
4786 enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4787 const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4788 int > = 0 >
4789 void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4790 {
4791 external_constructor<value_t::array>::construct(j, arr);
4792 }
4793
4794 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
4795 void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4796 {
4797 j = { p.first, p.second };
4798 }
4799
4800 // for https://github.com/nlohmann/json/pull/1134
4801 template<typename BasicJsonType, typename T,
4802 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
4803 void to_json(BasicJsonType& j, const T& b)
4804 {
4805 j = { {b.key(), b.value()} };
4806 }
4807
4808 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
4809 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4810 {
4811 j = { std::get<Idx>(t)... };
4812 }
4813
4814 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
4815 void to_json(BasicJsonType& j, const T& t)
4816 {
4817 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
4818 }
4819
4820 struct to_json_fn
4821 {
4822 template<typename BasicJsonType, typename T>
4823 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
4824 -> decltype(to_json(j, std::forward<T>(val)), void())
4825 {
4826 return to_json(j, std::forward<T>(val));
4827 }
4828 };
4829 } // namespace detail
4830
4834 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4835 {
4836 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4837 } // namespace
4838 } // namespace nlohmann
4839
4840 // #include <nlohmann/detail/meta/identity_tag.hpp>
4841
4842 // #include <nlohmann/detail/meta/type_traits.hpp>
4843
4844
4845 namespace nlohmann
4846 {
4847
4848 template<typename ValueType, typename>
4849 struct adl_serializer
4850 {
4862 template<typename BasicJsonType, typename TargetType = ValueType>
4863 static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
4864 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
4865 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
4866 {
4867 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
4868 }
4869
4882 template<typename BasicJsonType, typename TargetType = ValueType>
4883 static auto from_json(BasicJsonType && j) noexcept(
4884 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
4885 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
4886 {
4887 return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
4888 }
4889
4899 template<typename BasicJsonType, typename TargetType = ValueType>
4900 static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
4901 noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
4902 -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
4903 {
4904 ::nlohmann::to_json(j, std::forward<TargetType>(val));
4905 }
4906 };
4907 } // namespace nlohmann
4908
4909 // #include <nlohmann/byte_container_with_subtype.hpp>
4910
4911
4912 #include <cstdint> // uint8_t
4913 #include <tuple> // tie
4914 #include <utility> // move
4915
4916 namespace nlohmann
4917 {
4918
4932 template<typename BinaryType>
4933 class byte_container_with_subtype : public BinaryType
4934 {
4935 public:
4937 using container_type = BinaryType;
4938
4939 byte_container_with_subtype() noexcept(noexcept(container_type()))
4940 : container_type()
4941 {}
4942
4943 byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))
4944 : container_type(b)
4945 {}
4946
4947 byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
4948 : container_type(std::move(b))
4949 {}
4950
4951 byte_container_with_subtype(const container_type& b, std::uint8_t subtype_) noexcept(noexcept(container_type(b)))
4952 : container_type(b)
4953 , m_subtype(subtype_)
4954 , m_has_subtype(true)
4955 {}
4956
4957 byte_container_with_subtype(container_type&& b, std::uint8_t subtype_) noexcept(noexcept(container_type(std::move(b))))
4958 : container_type(std::move(b))
4959 , m_subtype(subtype_)
4960 , m_has_subtype(true)
4961 {}
4962
4963 bool operator==(const byte_container_with_subtype& rhs) const
4964 {
4965 return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
4966 std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
4967 }
4968
4969 bool operator!=(const byte_container_with_subtype& rhs) const
4970 {
4971 return !(rhs == *this);
4972 }
4973
4992 void set_subtype(std::uint8_t subtype_) noexcept
4993 {
4994 m_subtype = subtype_;
4995 m_has_subtype = true;
4996 }
4997
5019 constexpr std::uint8_t subtype() const noexcept
5020 {
5021 return m_subtype;
5022 }
5023
5040 constexpr bool has_subtype() const noexcept
5041 {
5042 return m_has_subtype;
5043 }
5044
5064 void clear_subtype() noexcept
5065 {
5066 m_subtype = 0;
5067 m_has_subtype = false;
5068 }
5069
5070 private:
5071 std::uint8_t m_subtype = 0;
5072 bool m_has_subtype = false;
5073 };
5074
5075 } // namespace nlohmann
5076
5077 // #include <nlohmann/detail/conversions/from_json.hpp>
5078
5079 // #include <nlohmann/detail/conversions/to_json.hpp>
5080
5081 // #include <nlohmann/detail/exceptions.hpp>
5082
5083 // #include <nlohmann/detail/hash.hpp>
5084
5085
5086 #include <cstdint> // uint8_t
5087 #include <cstddef> // size_t
5088 #include <functional> // hash
5089
5090 // #include <nlohmann/detail/macro_scope.hpp>
5091
5092
5093 namespace nlohmann
5094 {
5095 namespace detail
5096 {
5097
5098 // boost::hash_combine
5099 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5100 {
5101 seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5102 return seed;
5103 }
5104
5116 template<typename BasicJsonType>
5117 std::size_t hash(const BasicJsonType& j)
5118 {
5119 using string_t = typename BasicJsonType::string_t;
5120 using number_integer_t = typename BasicJsonType::number_integer_t;
5121 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5122 using number_float_t = typename BasicJsonType::number_float_t;
5123
5124 const auto type = static_cast<std::size_t>(j.type());
5125 switch (j.type())
5126 {
5127 case BasicJsonType::value_t::null:
5128 case BasicJsonType::value_t::discarded:
5129 {
5130 return combine(type, 0);
5131 }
5132
5133 case BasicJsonType::value_t::object:
5134 {
5135 auto seed = combine(type, j.size());
5136 for (const auto& element : j.items())
5137 {
5138 const auto h = std::hash<string_t> {}(element.key());
5139 seed = combine(seed, h);
5140 seed = combine(seed, hash(element.value()));
5141 }
5142 return seed;
5143 }
5144
5145 case BasicJsonType::value_t::array:
5146 {
5147 auto seed = combine(type, j.size());
5148 for (const auto& element : j)
5149 {
5150 seed = combine(seed, hash(element));
5151 }
5152 return seed;
5153 }
5154
5155 case BasicJsonType::value_t::string:
5156 {
5157 const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
5158 return combine(type, h);
5159 }
5160
5161 case BasicJsonType::value_t::boolean:
5162 {
5163 const auto h = std::hash<bool> {}(j.template get<bool>());
5164 return combine(type, h);
5165 }
5166
5167 case BasicJsonType::value_t::number_integer:
5168 {
5169 const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
5170 return combine(type, h);
5171 }
5172
5173 case BasicJsonType::value_t::number_unsigned:
5174 {
5175 const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
5176 return combine(type, h);
5177 }
5178
5179 case BasicJsonType::value_t::number_float:
5180 {
5181 const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
5182 return combine(type, h);
5183 }
5184
5185 case BasicJsonType::value_t::binary:
5186 {
5187 auto seed = combine(type, j.get_binary().size());
5188 const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
5189 seed = combine(seed, h);
5190 seed = combine(seed, j.get_binary().subtype());
5191 for (const auto byte : j.get_binary())
5192 {
5193 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
5194 }
5195 return seed;
5196 }
5197
5198 default: // LCOV_EXCL_LINE
5199 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
5200 return 0; // LCOV_EXCL_LINE
5201 }
5202 }
5203
5204 } // namespace detail
5205 } // namespace nlohmann
5206
5207 // #include <nlohmann/detail/input/binary_reader.hpp>
5208
5209
5210 #include <algorithm> // generate_n
5211 #include <array> // array
5212 #include <cmath> // ldexp
5213 #include <cstddef> // size_t
5214 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5215 #include <cstdio> // snprintf
5216 #include <cstring> // memcpy
5217 #include <iterator> // back_inserter
5218 #include <limits> // numeric_limits
5219 #include <string> // char_traits, string
5220 #include <utility> // make_pair, move
5221 #include <vector> // vector
5222
5223 // #include <nlohmann/detail/exceptions.hpp>
5224
5225 // #include <nlohmann/detail/input/input_adapters.hpp>
5226
5227
5228 #include <array> // array
5229 #include <cstddef> // size_t
5230 #include <cstdio> //FILE *
5231 #include <cstring> // strlen
5232 #include <istream> // istream
5233 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
5234 #include <memory> // shared_ptr, make_shared, addressof
5235 #include <numeric> // accumulate
5236 #include <string> // string, char_traits
5237 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
5238 #include <utility> // pair, declval
5239
5240 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
5241
5242 // #include <nlohmann/detail/macro_scope.hpp>
5243
5244
5245 namespace nlohmann
5246 {
5247 namespace detail
5248 {
5250 enum class input_format_t { json, cbor, msgpack, ubjson, bson };
5251
5253 // input adapters //
5255
5260 class file_input_adapter
5261 {
5262 public:
5263 using char_type = char;
5264
5265 JSON_HEDLEY_NON_NULL(2)
5266 explicit file_input_adapter(std::FILE* f) noexcept
5267 : m_file(f)
5268 {}
5269
5270 // make class move-only
5271 file_input_adapter(const file_input_adapter&) = delete;
5272 file_input_adapter(file_input_adapter&&) noexcept = default;
5273 file_input_adapter& operator=(const file_input_adapter&) = delete;
5274 file_input_adapter& operator=(file_input_adapter&&) = delete;
5275 ~file_input_adapter() = default;
5276
5277 std::char_traits<char>::int_type get_character() noexcept
5278 {
5279 return std::fgetc(m_file);
5280 }
5281
5282 private:
5284 std::FILE* m_file;
5285 };
5286
5287
5297 class input_stream_adapter
5298 {
5299 public:
5300 using char_type = char;
5301
5302 ~input_stream_adapter()
5303 {
5304 // clear stream flags; we use underlying streambuf I/O, do not
5305 // maintain ifstream flags, except eof
5306 if (is != nullptr)
5307 {
5308 is->clear(is->rdstate() & std::ios::eofbit);
5309 }
5310 }
5311
5312 explicit input_stream_adapter(std::istream& i)
5313 : is(&i), sb(i.rdbuf())
5314 {}
5315
5316 // delete because of pointer members
5317 input_stream_adapter(const input_stream_adapter&) = delete;
5318 input_stream_adapter& operator=(input_stream_adapter&) = delete;
5319 input_stream_adapter& operator=(input_stream_adapter&&) = delete;
5320
5321 input_stream_adapter(input_stream_adapter&& rhs) noexcept
5322 : is(rhs.is), sb(rhs.sb)
5323 {
5324 rhs.is = nullptr;
5325 rhs.sb = nullptr;
5326 }
5327
5328 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
5329 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
5330 // end up as the same value, eg. 0xFFFFFFFF.
5331 std::char_traits<char>::int_type get_character()
5332 {
5333 auto res = sb->sbumpc();
5334 // set eof manually, as we don't use the istream interface.
5335 if (JSON_HEDLEY_UNLIKELY(res == EOF))
5336 {
5337 is->clear(is->rdstate() | std::ios::eofbit);
5338 }
5339 return res;
5340 }
5341
5342 private:
5344 std::istream* is = nullptr;
5345 std::streambuf* sb = nullptr;
5346 };
5347
5348 // General-purpose iterator-based adapter. It might not be as fast as
5349 // theoretically possible for some containers, but it is extremely versatile.
5350 template<typename IteratorType>
5351 class iterator_input_adapter
5352 {
5353 public:
5354 using char_type = typename std::iterator_traits<IteratorType>::value_type;
5355
5356 iterator_input_adapter(IteratorType first, IteratorType last)
5357 : current(std::move(first)), end(std::move(last))
5358 {}
5359
5360 typename std::char_traits<char_type>::int_type get_character()
5361 {
5362 if (JSON_HEDLEY_LIKELY(current != end))
5363 {
5364 auto result = std::char_traits<char_type>::to_int_type(*current);
5365 std::advance(current, 1);
5366 return result;
5367 }
5368
5369 return std::char_traits<char_type>::eof();
5370 }
5371
5372 private:
5373 IteratorType current;
5374 IteratorType end;
5375
5376 template<typename BaseInputAdapter, size_t T>
5377 friend struct wide_string_input_helper;
5378
5379 bool empty() const
5380 {
5381 return current == end;
5382 }
5383 };
5384
5385
5386 template<typename BaseInputAdapter, size_t T>
5387 struct wide_string_input_helper;
5388
5389 template<typename BaseInputAdapter>
5390 struct wide_string_input_helper<BaseInputAdapter, 4>
5391 {
5392 // UTF-32
5393 static void fill_buffer(BaseInputAdapter& input,
5394 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5395 size_t& utf8_bytes_index,
5396 size_t& utf8_bytes_filled)
5397 {
5398 utf8_bytes_index = 0;
5399
5400 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5401 {
5402 utf8_bytes[0] = std::char_traits<char>::eof();
5403 utf8_bytes_filled = 1;
5404 }
5405 else
5406 {
5407 // get the current character
5408 const auto wc = input.get_character();
5409
5410 // UTF-32 to UTF-8 encoding
5411 if (wc < 0x80)
5412 {
5413 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5414 utf8_bytes_filled = 1;
5415 }
5416 else if (wc <= 0x7FF)
5417 {
5418 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
5419 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5420 utf8_bytes_filled = 2;
5421 }
5422 else if (wc <= 0xFFFF)
5423 {
5424 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
5425 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5426 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5427 utf8_bytes_filled = 3;
5428 }
5429 else if (wc <= 0x10FFFF)
5430 {
5431 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
5432 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
5433 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5434 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5435 utf8_bytes_filled = 4;
5436 }
5437 else
5438 {
5439 // unknown character
5440 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5441 utf8_bytes_filled = 1;
5442 }
5443 }
5444 }
5445 };
5446
5447 template<typename BaseInputAdapter>
5448 struct wide_string_input_helper<BaseInputAdapter, 2>
5449 {
5450 // UTF-16
5451 static void fill_buffer(BaseInputAdapter& input,
5452 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5453 size_t& utf8_bytes_index,
5454 size_t& utf8_bytes_filled)
5455 {
5456 utf8_bytes_index = 0;
5457
5458 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5459 {
5460 utf8_bytes[0] = std::char_traits<char>::eof();
5461 utf8_bytes_filled = 1;
5462 }
5463 else
5464 {
5465 // get the current character
5466 const auto wc = input.get_character();
5467
5468 // UTF-16 to UTF-8 encoding
5469 if (wc < 0x80)
5470 {
5471 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5472 utf8_bytes_filled = 1;
5473 }
5474 else if (wc <= 0x7FF)
5475 {
5476 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5477 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5478 utf8_bytes_filled = 2;
5479 }
5480 else if (0xD800 > wc || wc >= 0xE000)
5481 {
5482 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5483 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5484 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5485 utf8_bytes_filled = 3;
5486 }
5487 else
5488 {
5489 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
5490 {
5491 const auto wc2 = static_cast<unsigned int>(input.get_character());
5492 const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
5493 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
5494 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
5495 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
5496 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
5497 utf8_bytes_filled = 4;
5498 }
5499 else
5500 {
5501 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5502 utf8_bytes_filled = 1;
5503 }
5504 }
5505 }
5506 }
5507 };
5508
5509 // Wraps another input apdater to convert wide character types into individual bytes.
5510 template<typename BaseInputAdapter, typename WideCharType>
5511 class wide_string_input_adapter
5512 {
5513 public:
5514 using char_type = char;
5515
5516 wide_string_input_adapter(BaseInputAdapter base)
5517 : base_adapter(base) {}
5518
5519 typename std::char_traits<char>::int_type get_character() noexcept
5520 {
5521 // check if buffer needs to be filled
5522 if (utf8_bytes_index == utf8_bytes_filled)
5523 {
5524 fill_buffer<sizeof(WideCharType)>();
5525
5526 JSON_ASSERT(utf8_bytes_filled > 0);
5527 JSON_ASSERT(utf8_bytes_index == 0);
5528 }
5529
5530 // use buffer
5531 JSON_ASSERT(utf8_bytes_filled > 0);
5532 JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
5533 return utf8_bytes[utf8_bytes_index++];
5534 }
5535
5536 private:
5537 BaseInputAdapter base_adapter;
5538
5539 template<size_t T>
5540 void fill_buffer()
5541 {
5542 wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
5543 }
5544
5546 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5547
5549 std::size_t utf8_bytes_index = 0;
5551 std::size_t utf8_bytes_filled = 0;
5552 };
5553
5554
5555 template<typename IteratorType, typename Enable = void>
5556 struct iterator_input_adapter_factory
5557 {
5558 using iterator_type = IteratorType;
5559 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5560 using adapter_type = iterator_input_adapter<iterator_type>;
5561
5562 static adapter_type create(IteratorType first, IteratorType last)
5563 {
5564 return adapter_type(std::move(first), std::move(last));
5565 }
5566 };
5567
5568 template<typename T>
5569 struct is_iterator_of_multibyte
5570 {
5571 using value_type = typename std::iterator_traits<T>::value_type;
5572 enum
5573 {
5574 value = sizeof(value_type) > 1
5575 };
5576 };
5577
5578 template<typename IteratorType>
5579 struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
5580 {
5581 using iterator_type = IteratorType;
5582 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5583 using base_adapter_type = iterator_input_adapter<iterator_type>;
5584 using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
5585
5586 static adapter_type create(IteratorType first, IteratorType last)
5587 {
5588 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5589 }
5590 };
5591
5592 // General purpose iterator-based input
5593 template<typename IteratorType>
5594 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
5595 {
5596 using factory_type = iterator_input_adapter_factory<IteratorType>;
5597 return factory_type::create(first, last);
5598 }
5599
5600 // Convenience shorthand from container to iterator
5601 // Enables ADL on begin(container) and end(container)
5602 // Encloses the using declarations in namespace for not to leak them to outside scope
5603
5604 namespace container_input_adapter_factory_impl
5605 {
5606
5607 using std::begin;
5608 using std::end;
5609
5610 template<typename ContainerType, typename Enable = void>
5611 struct container_input_adapter_factory {};
5612
5613 template<typename ContainerType>
5614 struct container_input_adapter_factory< ContainerType,
5615 void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
5616 {
5617 using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
5618
5619 static adapter_type create(const ContainerType& container)
5620 {
5621 return input_adapter(begin(container), end(container));
5622 }
5623 };
5624
5625 } // namespace container_input_adapter_factory_impl
5626
5627 template<typename ContainerType>
5628 typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)
5629 {
5630 return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);
5631 }
5632
5633 // Special cases with fast paths
5634 inline file_input_adapter input_adapter(std::FILE* file)
5635 {
5636 return file_input_adapter(file);
5637 }
5638
5639 inline input_stream_adapter input_adapter(std::istream& stream)
5640 {
5641 return input_stream_adapter(stream);
5642 }
5643
5644 inline input_stream_adapter input_adapter(std::istream&& stream)
5645 {
5646 return input_stream_adapter(stream);
5647 }
5648
5649 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5650
5651 // Null-delimited strings, and the like.
5652 template < typename CharT,
5653 typename std::enable_if <
5654 std::is_pointer<CharT>::value&&
5655 !std::is_array<CharT>::value&&
5656 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5657 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5658 int >::type = 0 >
5659 contiguous_bytes_input_adapter input_adapter(CharT b)
5660 {
5661 auto length = std::strlen(reinterpret_cast<const char*>(b));
5662 const auto* ptr = reinterpret_cast<const char*>(b);
5663 return input_adapter(ptr, ptr + length);
5664 }
5665
5666 template<typename T, std::size_t N>
5667 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)
5668 {
5669 return input_adapter(array, array + N);
5670 }
5671
5672 // This class only handles inputs of input_buffer_adapter type.
5673 // It's required so that expressions like {ptr, len} can be implicitely casted
5674 // to the correct adapter.
5675 class span_input_adapter
5676 {
5677 public:
5678 template < typename CharT,
5679 typename std::enable_if <
5680 std::is_pointer<CharT>::value&&
5681 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5682 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5683 int >::type = 0 >
5684 span_input_adapter(CharT b, std::size_t l)
5685 : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5686
5687 template<class IteratorType,
5688 typename std::enable_if<
5689 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5690 int>::type = 0>
5691 span_input_adapter(IteratorType first, IteratorType last)
5692 : ia(input_adapter(first, last)) {}
5693
5694 contiguous_bytes_input_adapter&& get()
5695 {
5696 return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
5697 }
5698
5699 private:
5700 contiguous_bytes_input_adapter ia;
5701 };
5702 } // namespace detail
5703 } // namespace nlohmann
5704
5705 // #include <nlohmann/detail/input/json_sax.hpp>
5706
5707
5708 #include <cstddef>
5709 #include <string> // string
5710 #include <utility> // move
5711 #include <vector> // vector
5712
5713 // #include <nlohmann/detail/exceptions.hpp>
5714
5715 // #include <nlohmann/detail/macro_scope.hpp>
5716
5717
5718 namespace nlohmann
5719 {
5720
5729 template<typename BasicJsonType>
5730 struct json_sax
5731 {
5732 using number_integer_t = typename BasicJsonType::number_integer_t;
5733 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5734 using number_float_t = typename BasicJsonType::number_float_t;
5735 using string_t = typename BasicJsonType::string_t;
5736 using binary_t = typename BasicJsonType::binary_t;
5737
5742 virtual bool null() = 0;
5743
5749 virtual bool boolean(bool val) = 0;
5750
5756 virtual bool number_integer(number_integer_t val) = 0;
5757
5763 virtual bool number_unsigned(number_unsigned_t val) = 0;
5764
5771 virtual bool number_float(number_float_t val, const string_t& s) = 0;
5772
5779 virtual bool string(string_t& val) = 0;
5780
5787 virtual bool binary(binary_t& val) = 0;
5788
5795 virtual bool start_object(std::size_t elements) = 0;
5796
5803 virtual bool key(string_t& val) = 0;
5804
5809 virtual bool end_object() = 0;
5810
5817 virtual bool start_array(std::size_t elements) = 0;
5818
5823 virtual bool end_array() = 0;
5824
5832 virtual bool parse_error(std::size_t position,
5833 const std::string& last_token,
5834 const detail::exception& ex) = 0;
5835
5836 json_sax() = default;
5837 json_sax(const json_sax&) = default;
5838 json_sax(json_sax&&) noexcept = default;
5839 json_sax& operator=(const json_sax&) = default;
5840 json_sax& operator=(json_sax&&) noexcept = default;
5841 virtual ~json_sax() = default;
5842 };
5843
5844
5845 namespace detail
5846 {
5860 template<typename BasicJsonType>
5861 class json_sax_dom_parser
5862 {
5863 public:
5864 using number_integer_t = typename BasicJsonType::number_integer_t;
5865 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5866 using number_float_t = typename BasicJsonType::number_float_t;
5867 using string_t = typename BasicJsonType::string_t;
5868 using binary_t = typename BasicJsonType::binary_t;
5869
5875 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
5876 : root(r), allow_exceptions(allow_exceptions_)
5877 {}
5878
5879 // make class move-only
5880 json_sax_dom_parser(const json_sax_dom_parser&) = delete;
5881 json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
5882 json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
5883 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
5884 ~json_sax_dom_parser() = default;
5885
5886 bool null()
5887 {
5888 handle_value(nullptr);
5889 return true;
5890 }
5891
5892 bool boolean(bool val)
5893 {
5894 handle_value(val);
5895 return true;
5896 }
5897
5898 bool number_integer(number_integer_t val)
5899 {
5900 handle_value(val);
5901 return true;
5902 }
5903
5904 bool number_unsigned(number_unsigned_t val)
5905 {
5906 handle_value(val);
5907 return true;
5908 }
5909
5910 bool number_float(number_float_t val, const string_t& /*unused*/)
5911 {
5912 handle_value(val);
5913 return true;
5914 }
5915
5916 bool string(string_t& val)
5917 {
5918 handle_value(val);
5919 return true;
5920 }
5921
5922 bool binary(binary_t& val)
5923 {
5924 handle_value(std::move(val));
5925 return true;
5926 }
5927
5928 bool start_object(std::size_t len)
5929 {
5930 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
5931
5932 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5933 {
5934 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
5935 }
5936
5937 return true;
5938 }
5939
5940 bool key(string_t& val)
5941 {
5942 // add null at given key and store the reference for later
5943 object_element = &(ref_stack.back()->m_value.object->operator[](val));
5944 return true;
5945 }
5946
5947 bool end_object()
5948 {
5949 ref_stack.back()->set_parents();
5950 ref_stack.pop_back();
5951 return true;
5952 }
5953
5954 bool start_array(std::size_t len)
5955 {
5956 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
5957
5958 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5959 {
5960 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
5961 }
5962
5963 return true;
5964 }
5965
5966 bool end_array()
5967 {
5968 ref_stack.back()->set_parents();
5969 ref_stack.pop_back();
5970 return true;
5971 }
5972
5973 template<class Exception>
5974 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5975 const Exception& ex)
5976 {
5977 errored = true;
5978 static_cast<void>(ex);
5979 if (allow_exceptions)
5980 {
5981 JSON_THROW(ex);
5982 }
5983 return false;
5984 }
5985
5986 constexpr bool is_errored() const
5987 {
5988 return errored;
5989 }
5990
5991 private:
5998 template<typename Value>
5999 JSON_HEDLEY_RETURNS_NON_NULL
6000 BasicJsonType* handle_value(Value&& v)
6001 {
6002 if (ref_stack.empty())
6003 {
6004 root = BasicJsonType(std::forward<Value>(v));
6005 return &root;
6006 }
6007
6008 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6009
6010 if (ref_stack.back()->is_array())
6011 {
6012 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6013 return &(ref_stack.back()->m_value.array->back());
6014 }
6015
6016 JSON_ASSERT(ref_stack.back()->is_object());
6017 JSON_ASSERT(object_element);
6018 *object_element = BasicJsonType(std::forward<Value>(v));
6019 return object_element;
6020 }
6021
6023 BasicJsonType& root;
6025 std::vector<BasicJsonType*> ref_stack {};
6027 BasicJsonType* object_element = nullptr;
6029 bool errored = false;
6031 const bool allow_exceptions = true;
6032 };
6033
6034 template<typename BasicJsonType>
6035 class json_sax_dom_callback_parser
6036 {
6037 public:
6038 using number_integer_t = typename BasicJsonType::number_integer_t;
6039 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6040 using number_float_t = typename BasicJsonType::number_float_t;
6041 using string_t = typename BasicJsonType::string_t;
6042 using binary_t = typename BasicJsonType::binary_t;
6043 using parser_callback_t = typename BasicJsonType::parser_callback_t;
6044 using parse_event_t = typename BasicJsonType::parse_event_t;
6045
6046 json_sax_dom_callback_parser(BasicJsonType& r,
6047 const parser_callback_t cb,
6048 const bool allow_exceptions_ = true)
6049 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6050 {
6051 keep_stack.push_back(true);
6052 }
6053
6054 // make class move-only
6055 json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
6056 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6057 json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
6058 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6059 ~json_sax_dom_callback_parser() = default;
6060
6061 bool null()
6062 {
6063 handle_value(nullptr);
6064 return true;
6065 }
6066
6067 bool boolean(bool val)
6068 {
6069 handle_value(val);
6070 return true;
6071 }
6072
6073 bool number_integer(number_integer_t val)
6074 {
6075 handle_value(val);
6076 return true;
6077 }
6078
6079 bool number_unsigned(number_unsigned_t val)
6080 {
6081 handle_value(val);
6082 return true;
6083 }
6084
6085 bool number_float(number_float_t val, const string_t& /*unused*/)
6086 {
6087 handle_value(val);
6088 return true;
6089 }
6090
6091 bool string(string_t& val)
6092 {
6093 handle_value(val);
6094 return true;
6095 }
6096
6097 bool binary(binary_t& val)
6098 {
6099 handle_value(std::move(val));
6100 return true;
6101 }
6102
6103 bool start_object(std::size_t len)
6104 {
6105 // check callback for object start
6106 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6107 keep_stack.push_back(keep);
6108
6109 auto val = handle_value(BasicJsonType::value_t::object, true);
6110 ref_stack.push_back(val.second);
6111
6112 // check object limit
6113 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6114 {
6115 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6116 }
6117
6118 return true;
6119 }
6120
6121 bool key(string_t& val)
6122 {
6123 BasicJsonType k = BasicJsonType(val);
6124
6125 // check callback for key
6126 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
6127 key_keep_stack.push_back(keep);
6128
6129 // add discarded value at given key and store the reference for later
6130 if (keep && ref_stack.back())
6131 {
6132 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
6133 }
6134
6135 return true;
6136 }
6137
6138 bool end_object()
6139 {
6140 if (ref_stack.back())
6141 {
6142 if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
6143 {
6144 // discard object
6145 *ref_stack.back() = discarded;
6146 }
6147 else
6148 {
6149 ref_stack.back()->set_parents();
6150 }
6151 }
6152
6153 JSON_ASSERT(!ref_stack.empty());
6154 JSON_ASSERT(!keep_stack.empty());
6155 ref_stack.pop_back();
6156 keep_stack.pop_back();
6157
6158 if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
6159 {
6160 // remove discarded value
6161 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
6162 {
6163 if (it->is_discarded())
6164 {
6165 ref_stack.back()->erase(it);
6166 break;
6167 }
6168 }
6169 }
6170
6171 return true;
6172 }
6173
6174 bool start_array(std::size_t len)
6175 {
6176 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
6177 keep_stack.push_back(keep);
6178
6179 auto val = handle_value(BasicJsonType::value_t::array, true);
6180 ref_stack.push_back(val.second);
6181
6182 // check array limit
6183 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6184 {
6185 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6186 }
6187
6188 return true;
6189 }
6190
6191 bool end_array()
6192 {
6193 bool keep = true;
6194
6195 if (ref_stack.back())
6196 {
6197 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
6198 if (keep)
6199 {
6200 ref_stack.back()->set_parents();
6201 }
6202 else
6203 {
6204 // discard array
6205 *ref_stack.back() = discarded;
6206 }
6207 }
6208
6209 JSON_ASSERT(!ref_stack.empty());
6210 JSON_ASSERT(!keep_stack.empty());
6211 ref_stack.pop_back();
6212 keep_stack.pop_back();
6213
6214 // remove discarded value
6215 if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
6216 {
6217 ref_stack.back()->m_value.array->pop_back();
6218 }
6219
6220 return true;
6221 }
6222
6223 template<class Exception>
6224 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6225 const Exception& ex)
6226 {
6227 errored = true;
6228 static_cast<void>(ex);
6229 if (allow_exceptions)
6230 {
6231 JSON_THROW(ex);
6232 }
6233 return false;
6234 }
6235
6236 constexpr bool is_errored() const
6237 {
6238 return errored;
6239 }
6240
6241 private:
6257 template<typename Value>
6258 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
6259 {
6260 JSON_ASSERT(!keep_stack.empty());
6261
6262 // do not handle this value if we know it would be added to a discarded
6263 // container
6264 if (!keep_stack.back())
6265 {
6266 return {false, nullptr};
6267 }
6268
6269 // create value
6270 auto value = BasicJsonType(std::forward<Value>(v));
6271
6272 // check callback
6273 const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
6274
6275 // do not handle this value if we just learnt it shall be discarded
6276 if (!keep)
6277 {
6278 return {false, nullptr};
6279 }
6280
6281 if (ref_stack.empty())
6282 {
6283 root = std::move(value);
6284 return {true, &root};
6285 }
6286
6287 // skip this value if we already decided to skip the parent
6288 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
6289 if (!ref_stack.back())
6290 {
6291 return {false, nullptr};
6292 }
6293
6294 // we now only expect arrays and objects
6295 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6296
6297 // array
6298 if (ref_stack.back()->is_array())
6299 {
6300 ref_stack.back()->m_value.array->emplace_back(std::move(value));
6301 return {true, &(ref_stack.back()->m_value.array->back())};
6302 }
6303
6304 // object
6305 JSON_ASSERT(ref_stack.back()->is_object());
6306 // check if we should store an element for the current key
6307 JSON_ASSERT(!key_keep_stack.empty());
6308 const bool store_element = key_keep_stack.back();
6309 key_keep_stack.pop_back();
6310
6311 if (!store_element)
6312 {
6313 return {false, nullptr};
6314 }
6315
6316 JSON_ASSERT(object_element);
6317 *object_element = std::move(value);
6318 return {true, object_element};
6319 }
6320
6322 BasicJsonType& root;
6324 std::vector<BasicJsonType*> ref_stack {};
6326 std::vector<bool> keep_stack {};
6328 std::vector<bool> key_keep_stack {};
6330 BasicJsonType* object_element = nullptr;
6332 bool errored = false;
6334 const parser_callback_t callback = nullptr;
6336 const bool allow_exceptions = true;
6338 BasicJsonType discarded = BasicJsonType::value_t::discarded;
6339 };
6340
6341 template<typename BasicJsonType>
6342 class json_sax_acceptor
6343 {
6344 public:
6345 using number_integer_t = typename BasicJsonType::number_integer_t;
6346 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6347 using number_float_t = typename BasicJsonType::number_float_t;
6348 using string_t = typename BasicJsonType::string_t;
6349 using binary_t = typename BasicJsonType::binary_t;
6350
6351 bool null()
6352 {
6353 return true;
6354 }
6355
6356 bool boolean(bool /*unused*/)
6357 {
6358 return true;
6359 }
6360
6361 bool number_integer(number_integer_t /*unused*/)
6362 {
6363 return true;
6364 }
6365
6366 bool number_unsigned(number_unsigned_t /*unused*/)
6367 {
6368 return true;
6369 }
6370
6371 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
6372 {
6373 return true;
6374 }
6375
6376 bool string(string_t& /*unused*/)
6377 {
6378 return true;
6379 }
6380
6381 bool binary(binary_t& /*unused*/)
6382 {
6383 return true;
6384 }
6385
6386 bool start_object(std::size_t /*unused*/ = std::size_t(-1))
6387 {
6388 return true;
6389 }
6390
6391 bool key(string_t& /*unused*/)
6392 {
6393 return true;
6394 }
6395
6396 bool end_object()
6397 {
6398 return true;
6399 }
6400
6401 bool start_array(std::size_t /*unused*/ = std::size_t(-1))
6402 {
6403 return true;
6404 }
6405
6406 bool end_array()
6407 {
6408 return true;
6409 }
6410
6411 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
6412 {
6413 return false;
6414 }
6415 };
6416 } // namespace detail
6417
6418 } // namespace nlohmann
6419
6420 // #include <nlohmann/detail/input/lexer.hpp>
6421
6422
6423 #include <array> // array
6424 #include <clocale> // localeconv
6425 #include <cstddef> // size_t
6426 #include <cstdio> // snprintf
6427 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
6428 #include <initializer_list> // initializer_list
6429 #include <string> // char_traits, string
6430 #include <utility> // move
6431 #include <vector> // vector
6432
6433 // #include <nlohmann/detail/input/input_adapters.hpp>
6434
6435 // #include <nlohmann/detail/input/position_t.hpp>
6436
6437 // #include <nlohmann/detail/macro_scope.hpp>
6438
6439
6440 namespace nlohmann
6441 {
6442 namespace detail
6443 {
6445 // lexer //
6447
6448 template<typename BasicJsonType>
6449 class lexer_base
6450 {
6451 public:
6453 enum class token_type
6454 {
6455 uninitialized,
6456 literal_true,
6457 literal_false,
6458 literal_null,
6459 value_string,
6460 value_unsigned,
6461 value_integer,
6462 value_float,
6463 begin_array,
6464 begin_object,
6465 end_array,
6466 end_object,
6467 name_separator,
6468 value_separator,
6469 parse_error,
6470 end_of_input,
6471 literal_or_value
6472 };
6473
6475 JSON_HEDLEY_RETURNS_NON_NULL
6476 JSON_HEDLEY_CONST
6477 static const char* token_type_name(const token_type t) noexcept
6478 {
6479 switch (t)
6480 {
6481 case token_type::uninitialized:
6482 return "<uninitialized>";
6483 case token_type::literal_true:
6484 return "true literal";
6485 case token_type::literal_false:
6486 return "false literal";
6487 case token_type::literal_null:
6488 return "null literal";
6489 case token_type::value_string:
6490 return "string literal";
6491 case token_type::value_unsigned:
6492 case token_type::value_integer:
6493 case token_type::value_float:
6494 return "number literal";
6495 case token_type::begin_array:
6496 return "'['";
6497 case token_type::begin_object:
6498 return "'{'";
6499 case token_type::end_array:
6500 return "']'";
6501 case token_type::end_object:
6502 return "'}'";
6503 case token_type::name_separator:
6504 return "':'";
6505 case token_type::value_separator:
6506 return "','";
6507 case token_type::parse_error:
6508 return "<parse error>";
6509 case token_type::end_of_input:
6510 return "end of input";
6511 case token_type::literal_or_value:
6512 return "'[', '{', or a literal";
6513 // LCOV_EXCL_START
6514 default: // catch non-enum values
6515 return "unknown token";
6516 // LCOV_EXCL_STOP
6517 }
6518 }
6519 };
6525 template<typename BasicJsonType, typename InputAdapterType>
6526 class lexer : public lexer_base<BasicJsonType>
6527 {
6528 using number_integer_t = typename BasicJsonType::number_integer_t;
6529 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6530 using number_float_t = typename BasicJsonType::number_float_t;
6531 using string_t = typename BasicJsonType::string_t;
6532 using char_type = typename InputAdapterType::char_type;
6533 using char_int_type = typename std::char_traits<char_type>::int_type;
6534
6535 public:
6536 using token_type = typename lexer_base<BasicJsonType>::token_type;
6537
6538 explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
6539 : ia(std::move(adapter))
6540 , ignore_comments(ignore_comments_)
6541 , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
6542 {}
6543
6544 // delete because of pointer members
6545 lexer(const lexer&) = delete;
6546 lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6547 lexer& operator=(lexer&) = delete;
6548 lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6549 ~lexer() = default;
6550
6551 private:
6553 // locales
6555
6557 JSON_HEDLEY_PURE
6558 static char get_decimal_point() noexcept
6559 {
6560 const auto* loc = localeconv();
6561 JSON_ASSERT(loc != nullptr);
6562 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6563 }
6564
6566 // scan functions
6568
6584 int get_codepoint()
6585 {
6586 // this function only makes sense after reading `\u`
6587 JSON_ASSERT(current == 'u');
6588 int codepoint = 0;
6589
6590 const auto factors = { 12u, 8u, 4u, 0u };
6591 for (const auto factor : factors)
6592 {
6593 get();
6594
6595 if (current >= '0' && current <= '9')
6596 {
6597 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6598 }
6599 else if (current >= 'A' && current <= 'F')
6600 {
6601 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6602 }
6603 else if (current >= 'a' && current <= 'f')
6604 {
6605 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6606 }
6607 else
6608 {
6609 return -1;
6610 }
6611 }
6612
6613 JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6614 return codepoint;
6615 }
6616
6632 bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6633 {
6634 JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6635 add(current);
6636
6637 for (auto range = ranges.begin(); range != ranges.end(); ++range)
6638 {
6639 get();
6640 if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6641 {
6642 add(current);
6643 }
6644 else
6645 {
6646 error_message = "invalid string: ill-formed UTF-8 byte";
6647 return false;
6648 }
6649 }
6650
6651 return true;
6652 }
6653
6669 token_type scan_string()
6670 {
6671 // reset token_buffer (ignore opening quote)
6672 reset();
6673
6674 // we entered the function by reading an open quote
6675 JSON_ASSERT(current == '\"');
6676
6677 while (true)
6678 {
6679 // get next character
6680 switch (get())
6681 {
6682 // end of file while parsing string
6683 case std::char_traits<char_type>::eof():
6684 {
6685 error_message = "invalid string: missing closing quote";
6686 return token_type::parse_error;
6687 }
6688
6689 // closing quote
6690 case '\"':
6691 {
6692 return token_type::value_string;
6693 }
6694
6695 // escapes
6696 case '\\':
6697 {
6698 switch (get())
6699 {
6700 // quotation mark
6701 case '\"':
6702 add('\"');
6703 break;
6704 // reverse solidus
6705 case '\\':
6706 add('\\');
6707 break;
6708 // solidus
6709 case '/':
6710 add('/');
6711 break;
6712 // backspace
6713 case 'b':
6714 add('\b');
6715 break;
6716 // form feed
6717 case 'f':
6718 add('\f');
6719 break;
6720 // line feed
6721 case 'n':
6722 add('\n');
6723 break;
6724 // carriage return
6725 case 'r':
6726 add('\r');
6727 break;
6728 // tab
6729 case 't':
6730 add('\t');
6731 break;
6732
6733 // unicode escapes
6734 case 'u':
6735 {
6736 const int codepoint1 = get_codepoint();
6737 int codepoint = codepoint1; // start with codepoint1
6738
6739 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
6740 {
6741 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6742 return token_type::parse_error;
6743 }
6744
6745 // check if code point is a high surrogate
6746 if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6747 {
6748 // expect next \uxxxx entry
6749 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6750 {
6751 const int codepoint2 = get_codepoint();
6752
6753 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
6754 {
6755 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6756 return token_type::parse_error;
6757 }
6758
6759 // check if codepoint2 is a low surrogate
6760 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6761 {
6762 // overwrite codepoint
6763 codepoint = static_cast<int>(
6764 // high surrogate occupies the most significant 22 bits
6765 (static_cast<unsigned int>(codepoint1) << 10u)
6766 // low surrogate occupies the least significant 15 bits
6767 + static_cast<unsigned int>(codepoint2)
6768 // there is still the 0xD800, 0xDC00 and 0x10000 noise
6769 // in the result so we have to subtract with:
6770 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6771 - 0x35FDC00u);
6772 }
6773 else
6774 {
6775 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6776 return token_type::parse_error;
6777 }
6778 }
6779 else
6780 {
6781 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6782 return token_type::parse_error;
6783 }
6784 }
6785 else
6786 {
6787 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6788 {
6789 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6790 return token_type::parse_error;
6791 }
6792 }
6793
6794 // result of the above calculation yields a proper codepoint
6795 JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
6796
6797 // translate codepoint into bytes
6798 if (codepoint < 0x80)
6799 {
6800 // 1-byte characters: 0xxxxxxx (ASCII)
6801 add(static_cast<char_int_type>(codepoint));
6802 }
6803 else if (codepoint <= 0x7FF)
6804 {
6805 // 2-byte characters: 110xxxxx 10xxxxxx
6806 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
6807 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6808 }
6809 else if (codepoint <= 0xFFFF)
6810 {
6811 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
6812 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
6813 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6814 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6815 }
6816 else
6817 {
6818 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
6819 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
6820 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
6821 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6822 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6823 }
6824
6825 break;
6826 }
6827
6828 // other characters after escape
6829 default:
6830 error_message = "invalid string: forbidden character after backslash";
6831 return token_type::parse_error;
6832 }
6833
6834 break;
6835 }
6836
6837 // invalid control characters
6838 case 0x00:
6839 {
6840 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
6841 return token_type::parse_error;
6842 }
6843
6844 case 0x01:
6845 {
6846 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
6847 return token_type::parse_error;
6848 }
6849
6850 case 0x02:
6851 {
6852 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
6853 return token_type::parse_error;
6854 }
6855
6856 case 0x03:
6857 {
6858 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
6859 return token_type::parse_error;
6860 }
6861
6862 case 0x04:
6863 {
6864 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
6865 return token_type::parse_error;
6866 }
6867
6868 case 0x05:
6869 {
6870 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
6871 return token_type::parse_error;
6872 }
6873
6874 case 0x06:
6875 {
6876 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
6877 return token_type::parse_error;
6878 }
6879
6880 case 0x07:
6881 {
6882 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
6883 return token_type::parse_error;
6884 }
6885
6886 case 0x08:
6887 {
6888 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
6889 return token_type::parse_error;
6890 }
6891
6892 case 0x09:
6893 {
6894 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
6895 return token_type::parse_error;
6896 }
6897
6898 case 0x0A:
6899 {
6900 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
6901 return token_type::parse_error;
6902 }
6903
6904 case 0x0B:
6905 {
6906 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
6907 return token_type::parse_error;
6908 }
6909
6910 case 0x0C:
6911 {
6912 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
6913 return token_type::parse_error;
6914 }
6915
6916 case 0x0D:
6917 {
6918 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
6919 return token_type::parse_error;
6920 }
6921
6922 case 0x0E:
6923 {
6924 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
6925 return token_type::parse_error;
6926 }
6927
6928 case 0x0F:
6929 {
6930 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
6931 return token_type::parse_error;
6932 }
6933
6934 case 0x10:
6935 {
6936 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
6937 return token_type::parse_error;
6938 }
6939
6940 case 0x11:
6941 {
6942 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
6943 return token_type::parse_error;
6944 }
6945
6946 case 0x12:
6947 {
6948 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
6949 return token_type::parse_error;
6950 }
6951
6952 case 0x13:
6953 {
6954 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
6955 return token_type::parse_error;
6956 }
6957
6958 case 0x14:
6959 {
6960 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
6961 return token_type::parse_error;
6962 }
6963
6964 case 0x15:
6965 {
6966 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
6967 return token_type::parse_error;
6968 }
6969
6970 case 0x16:
6971 {
6972 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
6973 return token_type::parse_error;
6974 }
6975
6976 case 0x17:
6977 {
6978 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
6979 return token_type::parse_error;
6980 }
6981
6982 case 0x18:
6983 {
6984 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
6985 return token_type::parse_error;
6986 }
6987
6988 case 0x19:
6989 {
6990 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
6991 return token_type::parse_error;
6992 }
6993
6994 case 0x1A:
6995 {
6996 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
6997 return token_type::parse_error;
6998 }
6999
7000 case 0x1B:
7001 {
7002 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7003 return token_type::parse_error;
7004 }
7005
7006 case 0x1C:
7007 {
7008 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7009 return token_type::parse_error;
7010 }
7011
7012 case 0x1D:
7013 {
7014 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7015 return token_type::parse_error;
7016 }
7017
7018 case 0x1E:
7019 {
7020 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7021 return token_type::parse_error;
7022 }
7023
7024 case 0x1F:
7025 {
7026 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7027 return token_type::parse_error;
7028 }
7029
7030 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7031 case 0x20:
7032 case 0x21:
7033 case 0x23:
7034 case 0x24:
7035 case 0x25:
7036 case 0x26:
7037 case 0x27:
7038 case 0x28:
7039 case 0x29:
7040 case 0x2A:
7041 case 0x2B:
7042 case 0x2C:
7043 case 0x2D:
7044 case 0x2E:
7045 case 0x2F:
7046 case 0x30:
7047 case 0x31:
7048 case 0x32:
7049 case 0x33:
7050 case 0x34:
7051 case 0x35:
7052 case 0x36:
7053 case 0x37:
7054 case 0x38:
7055 case 0x39:
7056 case 0x3A:
7057 case 0x3B:
7058 case 0x3C:
7059 case 0x3D:
7060 case 0x3E:
7061 case 0x3F:
7062 case 0x40:
7063 case 0x41:
7064 case 0x42:
7065 case 0x43:
7066 case 0x44:
7067 case 0x45:
7068 case 0x46:
7069 case 0x47:
7070 case 0x48:
7071 case 0x49:
7072 case 0x4A:
7073 case 0x4B:
7074 case 0x4C:
7075 case 0x4D:
7076 case 0x4E:
7077 case 0x4F:
7078 case 0x50:
7079 case 0x51:
7080 case 0x52:
7081 case 0x53:
7082 case 0x54:
7083 case 0x55:
7084 case 0x56:
7085 case 0x57:
7086 case 0x58:
7087 case 0x59:
7088 case 0x5A:
7089 case 0x5B:
7090 case 0x5D:
7091 case 0x5E:
7092 case 0x5F:
7093 case 0x60:
7094 case 0x61:
7095 case 0x62:
7096 case 0x63:
7097 case 0x64:
7098 case 0x65:
7099 case 0x66:
7100 case 0x67:
7101 case 0x68:
7102 case 0x69:
7103 case 0x6A:
7104 case 0x6B:
7105 case 0x6C:
7106 case 0x6D:
7107 case 0x6E:
7108 case 0x6F:
7109 case 0x70:
7110 case 0x71:
7111 case 0x72:
7112 case 0x73:
7113 case 0x74:
7114 case 0x75:
7115 case 0x76:
7116 case 0x77:
7117 case 0x78:
7118 case 0x79:
7119 case 0x7A:
7120 case 0x7B:
7121 case 0x7C:
7122 case 0x7D:
7123 case 0x7E:
7124 case 0x7F:
7125 {
7126 add(current);
7127 break;
7128 }
7129
7130 // U+0080..U+07FF: bytes C2..DF 80..BF
7131 case 0xC2:
7132 case 0xC3:
7133 case 0xC4:
7134 case 0xC5:
7135 case 0xC6:
7136 case 0xC7:
7137 case 0xC8:
7138 case 0xC9:
7139 case 0xCA:
7140 case 0xCB:
7141 case 0xCC:
7142 case 0xCD:
7143 case 0xCE:
7144 case 0xCF:
7145 case 0xD0:
7146 case 0xD1:
7147 case 0xD2:
7148 case 0xD3:
7149 case 0xD4:
7150 case 0xD5:
7151 case 0xD6:
7152 case 0xD7:
7153 case 0xD8:
7154 case 0xD9:
7155 case 0xDA:
7156 case 0xDB:
7157 case 0xDC:
7158 case 0xDD:
7159 case 0xDE:
7160 case 0xDF:
7161 {
7162 if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
7163 {
7164 return token_type::parse_error;
7165 }
7166 break;
7167 }
7168
7169 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7170 case 0xE0:
7171 {
7172 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7173 {
7174 return token_type::parse_error;
7175 }
7176 break;
7177 }
7178
7179 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7180 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7181 case 0xE1:
7182 case 0xE2:
7183 case 0xE3:
7184 case 0xE4:
7185 case 0xE5:
7186 case 0xE6:
7187 case 0xE7:
7188 case 0xE8:
7189 case 0xE9:
7190 case 0xEA:
7191 case 0xEB:
7192 case 0xEC:
7193 case 0xEE:
7194 case 0xEF:
7195 {
7196 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
7197 {
7198 return token_type::parse_error;
7199 }
7200 break;
7201 }
7202
7203 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7204 case 0xED:
7205 {
7206 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
7207 {
7208 return token_type::parse_error;
7209 }
7210 break;
7211 }
7212
7213 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7214 case 0xF0:
7215 {
7216 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7217 {
7218 return token_type::parse_error;
7219 }
7220 break;
7221 }
7222
7223 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7224 case 0xF1:
7225 case 0xF2:
7226 case 0xF3:
7227 {
7228 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7229 {
7230 return token_type::parse_error;
7231 }
7232 break;
7233 }
7234
7235 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7236 case 0xF4:
7237 {
7238 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
7239 {
7240 return token_type::parse_error;
7241 }
7242 break;
7243 }
7244
7245 // remaining bytes (80..C1 and F5..FF) are ill-formed
7246 default:
7247 {
7248 error_message = "invalid string: ill-formed UTF-8 byte";
7249 return token_type::parse_error;
7250 }
7251 }
7252 }
7253 }
7254
7259 bool scan_comment()
7260 {
7261 switch (get())
7262 {
7263 // single-line comments skip input until a newline or EOF is read
7264 case '/':
7265 {
7266 while (true)
7267 {
7268 switch (get())
7269 {
7270 case '\n':
7271 case '\r':
7272 case std::char_traits<char_type>::eof():
7273 case '\0':
7274 return true;
7275
7276 default:
7277 break;
7278 }
7279 }
7280 }
7281
7282 // multi-line comments skip input until */ is read
7283 case '*':
7284 {
7285 while (true)
7286 {
7287 switch (get())
7288 {
7289 case std::char_traits<char_type>::eof():
7290 case '\0':
7291 {
7292 error_message = "invalid comment; missing closing '*/'";
7293 return false;
7294 }
7295
7296 case '*':
7297 {
7298 switch (get())
7299 {
7300 case '/':
7301 return true;
7302
7303 default:
7304 {
7305 unget();
7306 continue;
7307 }
7308 }
7309 }
7310
7311 default:
7312 continue;
7313 }
7314 }
7315 }
7316
7317 // unexpected character after reading '/'
7318 default:
7319 {
7320 error_message = "invalid comment; expecting '/' or '*' after '/'";
7321 return false;
7322 }
7323 }
7324 }
7325
7326 JSON_HEDLEY_NON_NULL(2)
7327 static void strtof(float& f, const char* str, char** endptr) noexcept
7328 {
7329 f = std::strtof(str, endptr);
7330 }
7331
7332 JSON_HEDLEY_NON_NULL(2)
7333 static void strtof(double& f, const char* str, char** endptr) noexcept
7334 {
7335 f = std::strtod(str, endptr);
7336 }
7337
7338 JSON_HEDLEY_NON_NULL(2)
7339 static void strtof(long double& f, const char* str, char** endptr) noexcept
7340 {
7341 f = std::strtold(str, endptr);
7342 }
7343
7384 token_type scan_number() // lgtm [cpp/use-of-goto]
7385 {
7386 // reset token_buffer to store the number's bytes
7387 reset();
7388
7389 // the type of the parsed number; initially set to unsigned; will be
7390 // changed if minus sign, decimal point or exponent is read
7391 token_type number_type = token_type::value_unsigned;
7392
7393 // state (init): we just found out we need to scan a number
7394 switch (current)
7395 {
7396 case '-':
7397 {
7398 add(current);
7399 goto scan_number_minus;
7400 }
7401
7402 case '0':
7403 {
7404 add(current);
7405 goto scan_number_zero;
7406 }
7407
7408 case '1':
7409 case '2':
7410 case '3':
7411 case '4':
7412 case '5':
7413 case '6':
7414 case '7':
7415 case '8':
7416 case '9':
7417 {
7418 add(current);
7419 goto scan_number_any1;
7420 }
7421
7422 // all other characters are rejected outside scan_number()
7423 default: // LCOV_EXCL_LINE
7424 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
7425 }
7426
7427 scan_number_minus:
7428 // state: we just parsed a leading minus sign
7429 number_type = token_type::value_integer;
7430 switch (get())
7431 {
7432 case '0':
7433 {
7434 add(current);
7435 goto scan_number_zero;
7436 }
7437
7438 case '1':
7439 case '2':
7440 case '3':
7441 case '4':
7442 case '5':
7443 case '6':
7444 case '7':
7445 case '8':
7446 case '9':
7447 {
7448 add(current);
7449 goto scan_number_any1;
7450 }
7451
7452 default:
7453 {
7454 error_message = "invalid number; expected digit after '-'";
7455 return token_type::parse_error;
7456 }
7457 }
7458
7459 scan_number_zero:
7460 // state: we just parse a zero (maybe with a leading minus sign)
7461 switch (get())
7462 {
7463 case '.':
7464 {
7465 add(decimal_point_char);
7466 goto scan_number_decimal1;
7467 }
7468
7469 case 'e':
7470 case 'E':
7471 {
7472 add(current);
7473 goto scan_number_exponent;
7474 }
7475
7476 default:
7477 goto scan_number_done;
7478 }
7479
7480 scan_number_any1:
7481 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7482 switch (get())
7483 {
7484 case '0':
7485 case '1':
7486 case '2':
7487 case '3':
7488 case '4':
7489 case '5':
7490 case '6':
7491 case '7':
7492 case '8':
7493 case '9':
7494 {
7495 add(current);
7496 goto scan_number_any1;
7497 }
7498
7499 case '.':
7500 {
7501 add(decimal_point_char);
7502 goto scan_number_decimal1;
7503 }
7504
7505 case 'e':
7506 case 'E':
7507 {
7508 add(current);
7509 goto scan_number_exponent;
7510 }
7511
7512 default:
7513 goto scan_number_done;
7514 }
7515
7516 scan_number_decimal1:
7517 // state: we just parsed a decimal point
7518 number_type = token_type::value_float;
7519 switch (get())
7520 {
7521 case '0':
7522 case '1':
7523 case '2':
7524 case '3':
7525 case '4':
7526 case '5':
7527 case '6':
7528 case '7':
7529 case '8':
7530 case '9':
7531 {
7532 add(current);
7533 goto scan_number_decimal2;
7534 }
7535
7536 default:
7537 {
7538 error_message = "invalid number; expected digit after '.'";
7539 return token_type::parse_error;
7540 }
7541 }
7542
7543 scan_number_decimal2:
7544 // we just parsed at least one number after a decimal point
7545 switch (get())
7546 {
7547 case '0':
7548 case '1':
7549 case '2':
7550 case '3':
7551 case '4':
7552 case '5':
7553 case '6':
7554 case '7':
7555 case '8':
7556 case '9':
7557 {
7558 add(current);
7559 goto scan_number_decimal2;
7560 }
7561
7562 case 'e':
7563 case 'E':
7564 {
7565 add(current);
7566 goto scan_number_exponent;
7567 }
7568
7569 default:
7570 goto scan_number_done;
7571 }
7572
7573 scan_number_exponent:
7574 // we just parsed an exponent
7575 number_type = token_type::value_float;
7576 switch (get())
7577 {
7578 case '+':
7579 case '-':
7580 {
7581 add(current);
7582 goto scan_number_sign;
7583 }
7584
7585 case '0':
7586 case '1':
7587 case '2':
7588 case '3':
7589 case '4':
7590 case '5':
7591 case '6':
7592 case '7':
7593 case '8':
7594 case '9':
7595 {
7596 add(current);
7597 goto scan_number_any2;
7598 }
7599
7600 default:
7601 {
7602 error_message =
7603 "invalid number; expected '+', '-', or digit after exponent";
7604 return token_type::parse_error;
7605 }
7606 }
7607
7608 scan_number_sign:
7609 // we just parsed an exponent sign
7610 switch (get())
7611 {
7612 case '0':
7613 case '1':
7614 case '2':
7615 case '3':
7616 case '4':
7617 case '5':
7618 case '6':
7619 case '7':
7620 case '8':
7621 case '9':
7622 {
7623 add(current);
7624 goto scan_number_any2;
7625 }
7626
7627 default:
7628 {
7629 error_message = "invalid number; expected digit after exponent sign";
7630 return token_type::parse_error;
7631 }
7632 }
7633
7634 scan_number_any2:
7635 // we just parsed a number after the exponent or exponent sign
7636 switch (get())
7637 {
7638 case '0':
7639 case '1':
7640 case '2':
7641 case '3':
7642 case '4':
7643 case '5':
7644 case '6':
7645 case '7':
7646 case '8':
7647 case '9':
7648 {
7649 add(current);
7650 goto scan_number_any2;
7651 }
7652
7653 default:
7654 goto scan_number_done;
7655 }
7656
7657 scan_number_done:
7658 // unget the character after the number (we only read it to know that
7659 // we are done scanning a number)
7660 unget();
7661
7662 char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7663 errno = 0;
7664
7665 // try to parse integers first and fall back to floats
7666 if (number_type == token_type::value_unsigned)
7667 {
7668 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7669
7670 // we checked the number format before
7671 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7672
7673 if (errno == 0)
7674 {
7675 value_unsigned = static_cast<number_unsigned_t>(x);
7676 if (value_unsigned == x)
7677 {
7678 return token_type::value_unsigned;
7679 }
7680 }
7681 }
7682 else if (number_type == token_type::value_integer)
7683 {
7684 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7685
7686 // we checked the number format before
7687 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7688
7689 if (errno == 0)
7690 {
7691 value_integer = static_cast<number_integer_t>(x);
7692 if (value_integer == x)
7693 {
7694 return token_type::value_integer;
7695 }
7696 }
7697 }
7698
7699 // this code is reached if we parse a floating-point number or if an
7700 // integer conversion above failed
7701 strtof(value_float, token_buffer.data(), &endptr);
7702
7703 // we checked the number format before
7704 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7705
7706 return token_type::value_float;
7707 }
7708
7714 JSON_HEDLEY_NON_NULL(2)
7715 token_type scan_literal(const char_type* literal_text, const std::size_t length,
7716 token_type return_type)
7717 {
7718 JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
7719 for (std::size_t i = 1; i < length; ++i)
7720 {
7721 if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
7722 {
7723 error_message = "invalid literal";
7724 return token_type::parse_error;
7725 }
7726 }
7727 return return_type;
7728 }
7729
7731 // input management
7733
7735 void reset() noexcept
7736 {
7737 token_buffer.clear();
7738 token_string.clear();
7739 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7740 }
7741
7742 /*
7743 @brief get next character from the input
7744
7745 This function provides the interface to the used input adapter. It does
7746 not throw in case the input reached EOF, but returns a
7747 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
7748 for use in error messages.
7749
7750 @return character read from the input
7751 */
7752 char_int_type get()
7753 {
7754 ++position.chars_read_total;
7755 ++position.chars_read_current_line;
7756
7757 if (next_unget)
7758 {
7759 // just reset the next_unget variable and work with current
7760 next_unget = false;
7761 }
7762 else
7763 {
7764 current = ia.get_character();
7765 }
7766
7767 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7768 {
7769 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7770 }
7771
7772 if (current == '\n')
7773 {
7774 ++position.lines_read;
7775 position.chars_read_current_line = 0;
7776 }
7777
7778 return current;
7779 }
7780
7789 void unget()
7790 {
7791 next_unget = true;
7792
7793 --position.chars_read_total;
7794
7795 // in case we "unget" a newline, we have to also decrement the lines_read
7796 if (position.chars_read_current_line == 0)
7797 {
7798 if (position.lines_read > 0)
7799 {
7800 --position.lines_read;
7801 }
7802 }
7803 else
7804 {
7805 --position.chars_read_current_line;
7806 }
7807
7808 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7809 {
7810 JSON_ASSERT(!token_string.empty());
7811 token_string.pop_back();
7812 }
7813 }
7814
7816 void add(char_int_type c)
7817 {
7818 token_buffer.push_back(static_cast<typename string_t::value_type>(c));
7819 }
7820
7821 public:
7823 // value getters
7825
7827 constexpr number_integer_t get_number_integer() const noexcept
7828 {
7829 return value_integer;
7830 }
7831
7833 constexpr number_unsigned_t get_number_unsigned() const noexcept
7834 {
7835 return value_unsigned;
7836 }
7837
7839 constexpr number_float_t get_number_float() const noexcept
7840 {
7841 return value_float;
7842 }
7843
7845 string_t& get_string()
7846 {
7847 return token_buffer;
7848 }
7849
7851 // diagnostics
7853
7855 constexpr position_t get_position() const noexcept
7856 {
7857 return position;
7858 }
7859
7863 std::string get_token_string() const
7864 {
7865 // escape control characters
7866 std::string result;
7867 for (const auto c : token_string)
7868 {
7869 if (static_cast<unsigned char>(c) <= '\x1F')
7870 {
7871 // escape control characters
7872 std::array<char, 9> cs{{}};
7873 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7874 result += cs.data();
7875 }
7876 else
7877 {
7878 // add character as is
7879 result.push_back(static_cast<std::string::value_type>(c));
7880 }
7881 }
7882
7883 return result;
7884 }
7885
7887 JSON_HEDLEY_RETURNS_NON_NULL
7888 constexpr const char* get_error_message() const noexcept
7889 {
7890 return error_message;
7891 }
7892
7894 // actual scanner
7896
7901 bool skip_bom()
7902 {
7903 if (get() == 0xEF)
7904 {
7905 // check if we completely parse the BOM
7906 return get() == 0xBB && get() == 0xBF;
7907 }
7908
7909 // the first character is not the beginning of the BOM; unget it to
7910 // process is later
7911 unget();
7912 return true;
7913 }
7914
7915 void skip_whitespace()
7916 {
7917 do
7918 {
7919 get();
7920 }
7921 while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
7922 }
7923
7924 token_type scan()
7925 {
7926 // initially, skip the BOM
7927 if (position.chars_read_total == 0 && !skip_bom())
7928 {
7929 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
7930 return token_type::parse_error;
7931 }
7932
7933 // read next character and ignore whitespace
7934 skip_whitespace();
7935
7936 // ignore comments
7937 while (ignore_comments && current == '/')
7938 {
7939 if (!scan_comment())
7940 {
7941 return token_type::parse_error;
7942 }
7943
7944 // skip following whitespace
7945 skip_whitespace();
7946 }
7947
7948 switch (current)
7949 {
7950 // structural characters
7951 case '[':
7952 return token_type::begin_array;
7953 case ']':
7954 return token_type::end_array;
7955 case '{':
7956 return token_type::begin_object;
7957 case '}':
7958 return token_type::end_object;
7959 case ':':
7960 return token_type::name_separator;
7961 case ',':
7962 return token_type::value_separator;
7963
7964 // literals
7965 case 't':
7966 {
7967 std::array<char_type, 4> true_literal = {{char_type('t'), char_type('r'), char_type('u'), char_type('e')}};
7968 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
7969 }
7970 case 'f':
7971 {
7972 std::array<char_type, 5> false_literal = {{char_type('f'), char_type('a'), char_type('l'), char_type('s'), char_type('e')}};
7973 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
7974 }
7975 case 'n':
7976 {
7977 std::array<char_type, 4> null_literal = {{char_type('n'), char_type('u'), char_type('l'), char_type('l')}};
7978 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
7979 }
7980
7981 // string
7982 case '\"':
7983 return scan_string();
7984
7985 // number
7986 case '-':
7987 case '0':
7988 case '1':
7989 case '2':
7990 case '3':
7991 case '4':
7992 case '5':
7993 case '6':
7994 case '7':
7995 case '8':
7996 case '9':
7997 return scan_number();
7998
7999 // end of input (the null byte is needed when parsing from
8000 // string literals)
8001 case '\0':
8002 case std::char_traits<char_type>::eof():
8003 return token_type::end_of_input;
8004
8005 // error
8006 default:
8007 error_message = "invalid literal";
8008 return token_type::parse_error;
8009 }
8010 }
8011
8012 private:
8014 InputAdapterType ia;
8015
8017 const bool ignore_comments = false;
8018
8020 char_int_type current = std::char_traits<char_type>::eof();
8021
8023 bool next_unget = false;
8024
8026 position_t position {};
8027
8029 std::vector<char_type> token_string {};
8030
8032 string_t token_buffer {};
8033
8035 const char* error_message = "";
8036
8037 // number values
8038 number_integer_t value_integer = 0;
8039 number_unsigned_t value_unsigned = 0;
8040 number_float_t value_float = 0;
8041
8043 const char_int_type decimal_point_char = '.';
8044 };
8045 } // namespace detail
8046 } // namespace nlohmann
8047
8048 // #include <nlohmann/detail/macro_scope.hpp>
8049
8050 // #include <nlohmann/detail/meta/is_sax.hpp>
8051
8052
8053 #include <cstdint> // size_t
8054 #include <utility> // declval
8055 #include <string> // string
8056
8057 // #include <nlohmann/detail/meta/detected.hpp>
8058
8059 // #include <nlohmann/detail/meta/type_traits.hpp>
8060
8061
8062 namespace nlohmann
8063 {
8064 namespace detail
8065 {
8066 template<typename T>
8067 using null_function_t = decltype(std::declval<T&>().null());
8068
8069 template<typename T>
8070 using boolean_function_t =
8071 decltype(std::declval<T&>().boolean(std::declval<bool>()));
8072
8073 template<typename T, typename Integer>
8074 using number_integer_function_t =
8075 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8076
8077 template<typename T, typename Unsigned>
8078 using number_unsigned_function_t =
8079 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8080
8081 template<typename T, typename Float, typename String>
8082 using number_float_function_t = decltype(std::declval<T&>().number_float(
8083 std::declval<Float>(), std::declval<const String&>()));
8084
8085 template<typename T, typename String>
8086 using string_function_t =
8087 decltype(std::declval<T&>().string(std::declval<String&>()));
8088
8089 template<typename T, typename Binary>
8090 using binary_function_t =
8091 decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8092
8093 template<typename T>
8094 using start_object_function_t =
8095 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8096
8097 template<typename T, typename String>
8098 using key_function_t =
8099 decltype(std::declval<T&>().key(std::declval<String&>()));
8100
8101 template<typename T>
8102 using end_object_function_t = decltype(std::declval<T&>().end_object());
8103
8104 template<typename T>
8105 using start_array_function_t =
8106 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
8107
8108 template<typename T>
8109 using end_array_function_t = decltype(std::declval<T&>().end_array());
8110
8111 template<typename T, typename Exception>
8112 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
8113 std::declval<std::size_t>(), std::declval<const std::string&>(),
8114 std::declval<const Exception&>()));
8115
8116 template<typename SAX, typename BasicJsonType>
8117 struct is_sax
8118 {
8119 private:
8120 static_assert(is_basic_json<BasicJsonType>::value,
8121 "BasicJsonType must be of type basic_json<...>");
8122
8123 using number_integer_t = typename BasicJsonType::number_integer_t;
8124 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8125 using number_float_t = typename BasicJsonType::number_float_t;
8126 using string_t = typename BasicJsonType::string_t;
8127 using binary_t = typename BasicJsonType::binary_t;
8128 using exception_t = typename BasicJsonType::exception;
8129
8130 public:
8131 static constexpr bool value =
8132 is_detected_exact<bool, null_function_t, SAX>::value &&
8133 is_detected_exact<bool, boolean_function_t, SAX>::value &&
8134 is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
8135 is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
8136 is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
8137 is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
8138 is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
8139 is_detected_exact<bool, start_object_function_t, SAX>::value &&
8140 is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
8141 is_detected_exact<bool, end_object_function_t, SAX>::value &&
8142 is_detected_exact<bool, start_array_function_t, SAX>::value &&
8143 is_detected_exact<bool, end_array_function_t, SAX>::value &&
8144 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
8145 };
8146
8147 template<typename SAX, typename BasicJsonType>
8148 struct is_sax_static_asserts
8149 {
8150 private:
8151 static_assert(is_basic_json<BasicJsonType>::value,
8152 "BasicJsonType must be of type basic_json<...>");
8153
8154 using number_integer_t = typename BasicJsonType::number_integer_t;
8155 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8156 using number_float_t = typename BasicJsonType::number_float_t;
8157 using string_t = typename BasicJsonType::string_t;
8158 using binary_t = typename BasicJsonType::binary_t;
8159 using exception_t = typename BasicJsonType::exception;
8160
8161 public:
8162 static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
8163 "Missing/invalid function: bool null()");
8164 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
8165 "Missing/invalid function: bool boolean(bool)");
8166 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
8167 "Missing/invalid function: bool boolean(bool)");
8168 static_assert(
8169 is_detected_exact<bool, number_integer_function_t, SAX,
8170 number_integer_t>::value,
8171 "Missing/invalid function: bool number_integer(number_integer_t)");
8172 static_assert(
8173 is_detected_exact<bool, number_unsigned_function_t, SAX,
8174 number_unsigned_t>::value,
8175 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
8176 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
8177 number_float_t, string_t>::value,
8178 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
8179 static_assert(
8180 is_detected_exact<bool, string_function_t, SAX, string_t>::value,
8181 "Missing/invalid function: bool string(string_t&)");
8182 static_assert(
8183 is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,
8184 "Missing/invalid function: bool binary(binary_t&)");
8185 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
8186 "Missing/invalid function: bool start_object(std::size_t)");
8187 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
8188 "Missing/invalid function: bool key(string_t&)");
8189 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
8190 "Missing/invalid function: bool end_object()");
8191 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
8192 "Missing/invalid function: bool start_array(std::size_t)");
8193 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
8194 "Missing/invalid function: bool end_array()");
8195 static_assert(
8196 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
8197 "Missing/invalid function: bool parse_error(std::size_t, const "
8198 "std::string&, const exception&)");
8199 };
8200 } // namespace detail
8201 } // namespace nlohmann
8202
8203 // #include <nlohmann/detail/value_t.hpp>
8204
8205
8206 namespace nlohmann
8207 {
8208 namespace detail
8209 {
8210
8212 enum class cbor_tag_handler_t
8213 {
8214 error,
8215 ignore
8216 };
8217
8225 static inline bool little_endianess(int num = 1) noexcept
8226 {
8227 return *reinterpret_cast<char*>(&num) == 1;
8228 }
8229
8230
8232 // binary reader //
8234
8238 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
8239 class binary_reader
8240 {
8241 using number_integer_t = typename BasicJsonType::number_integer_t;
8242 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8243 using number_float_t = typename BasicJsonType::number_float_t;
8244 using string_t = typename BasicJsonType::string_t;
8245 using binary_t = typename BasicJsonType::binary_t;
8246 using json_sax_t = SAX;
8247 using char_type = typename InputAdapterType::char_type;
8248 using char_int_type = typename std::char_traits<char_type>::int_type;
8249
8250 public:
8256 explicit binary_reader(InputAdapterType&& adapter) noexcept : ia(std::move(adapter))
8257 {
8258 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
8259 }
8260
8261 // make class move-only
8262 binary_reader(const binary_reader&) = delete;
8263 binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8264 binary_reader& operator=(const binary_reader&) = delete;
8265 binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8266 ~binary_reader() = default;
8267
8276 JSON_HEDLEY_NON_NULL(3)
8277 bool sax_parse(const input_format_t format,
8278 json_sax_t* sax_,
8279 const bool strict = true,
8280 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
8281 {
8282 sax = sax_;
8283 bool result = false;
8284
8285 switch (format)
8286 {
8287 case input_format_t::bson:
8288 result = parse_bson_internal();
8289 break;
8290
8291 case input_format_t::cbor:
8292 result = parse_cbor_internal(true, tag_handler);
8293 break;
8294
8295 case input_format_t::msgpack:
8296 result = parse_msgpack_internal();
8297 break;
8298
8299 case input_format_t::ubjson:
8300 result = parse_ubjson_internal();
8301 break;
8302
8303 default: // LCOV_EXCL_LINE
8304 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8305 }
8306
8307 // strict mode: next byte must be EOF
8308 if (result && strict)
8309 {
8310 if (format == input_format_t::ubjson)
8311 {
8312 get_ignore_noop();
8313 }
8314 else
8315 {
8316 get();
8317 }
8318
8319 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
8320 {
8321 return sax->parse_error(chars_read, get_token_string(),
8322 parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value"), BasicJsonType()));
8323 }
8324 }
8325
8326 return result;
8327 }
8328
8329 private:
8331 // BSON //
8333
8338 bool parse_bson_internal()
8339 {
8340 std::int32_t document_size{};
8341 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8342
8343 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
8344 {
8345 return false;
8346 }
8347
8348 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
8349 {
8350 return false;
8351 }
8352
8353 return sax->end_object();
8354 }
8355
8363 bool get_bson_cstr(string_t& result)
8364 {
8365 auto out = std::back_inserter(result);
8366 while (true)
8367 {
8368 get();
8369 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
8370 {
8371 return false;
8372 }
8373 if (current == 0x00)
8374 {
8375 return true;
8376 }
8377 *out++ = static_cast<typename string_t::value_type>(current);
8378 }
8379 }
8380
8392 template<typename NumberType>
8393 bool get_bson_string(const NumberType len, string_t& result)
8394 {
8395 if (JSON_HEDLEY_UNLIKELY(len < 1))
8396 {
8397 auto last_token = get_token_string();
8398 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()));
8399 }
8400
8401 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
8402 }
8403
8413 template<typename NumberType>
8414 bool get_bson_binary(const NumberType len, binary_t& result)
8415 {
8416 if (JSON_HEDLEY_UNLIKELY(len < 0))
8417 {
8418 auto last_token = get_token_string();
8419 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()));
8420 }
8421
8422 // All BSON binary values have a subtype
8423 std::uint8_t subtype{};
8424 get_number<std::uint8_t>(input_format_t::bson, subtype);
8425 result.set_subtype(subtype);
8426
8427 return get_binary(input_format_t::bson, len, result);
8428 }
8429
8440 bool parse_bson_element_internal(const char_int_type element_type,
8441 const std::size_t element_type_parse_position)
8442 {
8443 switch (element_type)
8444 {
8445 case 0x01: // double
8446 {
8447 double number{};
8448 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
8449 }
8450
8451 case 0x02: // string
8452 {
8453 std::int32_t len{};
8454 string_t value;
8455 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
8456 }
8457
8458 case 0x03: // object
8459 {
8460 return parse_bson_internal();
8461 }
8462
8463 case 0x04: // array
8464 {
8465 return parse_bson_array();
8466 }
8467
8468 case 0x05: // binary
8469 {
8470 std::int32_t len{};
8471 binary_t value;
8472 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
8473 }
8474
8475 case 0x08: // boolean
8476 {
8477 return sax->boolean(get() != 0);
8478 }
8479
8480 case 0x0A: // null
8481 {
8482 return sax->null();
8483 }
8484
8485 case 0x10: // int32
8486 {
8487 std::int32_t value{};
8488 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8489 }
8490
8491 case 0x12: // int64
8492 {
8493 std::int64_t value{};
8494 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8495 }
8496
8497 default: // anything else not supported (yet)
8498 {
8499 std::array<char, 3> cr{{}};
8500 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8501 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()));
8502 }
8503 }
8504 }
8505
8518 bool parse_bson_element_list(const bool is_array)
8519 {
8520 string_t key;
8521
8522 while (auto element_type = get())
8523 {
8524 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
8525 {
8526 return false;
8527 }
8528
8529 const std::size_t element_type_parse_position = chars_read;
8530 if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
8531 {
8532 return false;
8533 }
8534
8535 if (!is_array && !sax->key(key))
8536 {
8537 return false;
8538 }
8539
8540 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
8541 {
8542 return false;
8543 }
8544
8545 // get_bson_cstr only appends
8546 key.clear();
8547 }
8548
8549 return true;
8550 }
8551
8556 bool parse_bson_array()
8557 {
8558 std::int32_t document_size{};
8559 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8560
8561 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
8562 {
8563 return false;
8564 }
8565
8566 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8567 {
8568 return false;
8569 }
8570
8571 return sax->end_array();
8572 }
8573
8575 // CBOR //
8577
8586 bool parse_cbor_internal(const bool get_char,
8587 const cbor_tag_handler_t tag_handler)
8588 {
8589 switch (get_char ? get() : current)
8590 {
8591 // EOF
8592 case std::char_traits<char_type>::eof():
8593 return unexpect_eof(input_format_t::cbor, "value");
8594
8595 // Integer 0x00..0x17 (0..23)
8596 case 0x00:
8597 case 0x01:
8598 case 0x02:
8599 case 0x03:
8600 case 0x04:
8601 case 0x05:
8602 case 0x06:
8603 case 0x07:
8604 case 0x08:
8605 case 0x09:
8606 case 0x0A:
8607 case 0x0B:
8608 case 0x0C:
8609 case 0x0D:
8610 case 0x0E:
8611 case 0x0F:
8612 case 0x10:
8613 case 0x11:
8614 case 0x12:
8615 case 0x13:
8616 case 0x14:
8617 case 0x15:
8618 case 0x16:
8619 case 0x17:
8620 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8621
8622 case 0x18: // Unsigned integer (one-byte uint8_t follows)
8623 {
8624 std::uint8_t number{};
8625 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8626 }
8627
8628 case 0x19: // Unsigned integer (two-byte uint16_t follows)
8629 {
8630 std::uint16_t number{};
8631 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8632 }
8633
8634 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8635 {
8636 std::uint32_t number{};
8637 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8638 }
8639
8640 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8641 {
8642 std::uint64_t number{};
8643 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8644 }
8645
8646 // Negative integer -1-0x00..-1-0x17 (-1..-24)
8647 case 0x20:
8648 case 0x21:
8649 case 0x22:
8650 case 0x23:
8651 case 0x24:
8652 case 0x25:
8653 case 0x26:
8654 case 0x27:
8655 case 0x28:
8656 case 0x29:
8657 case 0x2A:
8658 case 0x2B:
8659 case 0x2C:
8660 case 0x2D:
8661 case 0x2E:
8662 case 0x2F:
8663 case 0x30:
8664 case 0x31:
8665 case 0x32:
8666 case 0x33:
8667 case 0x34:
8668 case 0x35:
8669 case 0x36:
8670 case 0x37:
8671 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8672
8673 case 0x38: // Negative integer (one-byte uint8_t follows)
8674 {
8675 std::uint8_t number{};
8676 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8677 }
8678
8679 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8680 {
8681 std::uint16_t number{};
8682 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8683 }
8684
8685 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8686 {
8687 std::uint32_t number{};
8688 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8689 }
8690
8691 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8692 {
8693 std::uint64_t number{};
8694 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8695 - static_cast<number_integer_t>(number));
8696 }
8697
8698 // Binary data (0x00..0x17 bytes follow)
8699 case 0x40:
8700 case 0x41:
8701 case 0x42:
8702 case 0x43:
8703 case 0x44:
8704 case 0x45:
8705 case 0x46:
8706 case 0x47:
8707 case 0x48:
8708 case 0x49:
8709 case 0x4A:
8710 case 0x4B:
8711 case 0x4C:
8712 case 0x4D:
8713 case 0x4E:
8714 case 0x4F:
8715 case 0x50:
8716 case 0x51:
8717 case 0x52:
8718 case 0x53:
8719 case 0x54:
8720 case 0x55:
8721 case 0x56:
8722 case 0x57:
8723 case 0x58: // Binary data (one-byte uint8_t for n follows)
8724 case 0x59: // Binary data (two-byte uint16_t for n follow)
8725 case 0x5A: // Binary data (four-byte uint32_t for n follow)
8726 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8727 case 0x5F: // Binary data (indefinite length)
8728 {
8729 binary_t b;
8730 return get_cbor_binary(b) && sax->binary(b);
8731 }
8732
8733 // UTF-8 string (0x00..0x17 bytes follow)
8734 case 0x60:
8735 case 0x61:
8736 case 0x62:
8737 case 0x63:
8738 case 0x64:
8739 case 0x65:
8740 case 0x66:
8741 case 0x67:
8742 case 0x68:
8743 case 0x69:
8744 case 0x6A:
8745 case 0x6B:
8746 case 0x6C:
8747 case 0x6D:
8748 case 0x6E:
8749 case 0x6F:
8750 case 0x70:
8751 case 0x71:
8752 case 0x72:
8753 case 0x73:
8754 case 0x74:
8755 case 0x75:
8756 case 0x76:
8757 case 0x77:
8758 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8759 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8760 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8761 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8762 case 0x7F: // UTF-8 string (indefinite length)
8763 {
8764 string_t s;
8765 return get_cbor_string(s) && sax->string(s);
8766 }
8767
8768 // array (0x00..0x17 data items follow)
8769 case 0x80:
8770 case 0x81:
8771 case 0x82:
8772 case 0x83:
8773 case 0x84:
8774 case 0x85:
8775 case 0x86:
8776 case 0x87:
8777 case 0x88:
8778 case 0x89:
8779 case 0x8A:
8780 case 0x8B:
8781 case 0x8C:
8782 case 0x8D:
8783 case 0x8E:
8784 case 0x8F:
8785 case 0x90:
8786 case 0x91:
8787 case 0x92:
8788 case 0x93:
8789 case 0x94:
8790 case 0x95:
8791 case 0x96:
8792 case 0x97:
8793 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8794
8795 case 0x98: // array (one-byte uint8_t for n follows)
8796 {
8797 std::uint8_t len{};
8798 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8799 }
8800
8801 case 0x99: // array (two-byte uint16_t for n follow)
8802 {
8803 std::uint16_t len{};
8804 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8805 }
8806
8807 case 0x9A: // array (four-byte uint32_t for n follow)
8808 {
8809 std::uint32_t len{};
8810 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8811 }
8812
8813 case 0x9B: // array (eight-byte uint64_t for n follow)
8814 {
8815 std::uint64_t len{};
8816 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8817 }
8818
8819 case 0x9F: // array (indefinite length)
8820 return get_cbor_array(std::size_t(-1), tag_handler);
8821
8822 // map (0x00..0x17 pairs of data items follow)
8823 case 0xA0:
8824 case 0xA1:
8825 case 0xA2:
8826 case 0xA3:
8827 case 0xA4:
8828 case 0xA5:
8829 case 0xA6:
8830 case 0xA7:
8831 case 0xA8:
8832 case 0xA9:
8833 case 0xAA:
8834 case 0xAB:
8835 case 0xAC:
8836 case 0xAD:
8837 case 0xAE:
8838 case 0xAF:
8839 case 0xB0:
8840 case 0xB1:
8841 case 0xB2:
8842 case 0xB3:
8843 case 0xB4:
8844 case 0xB5:
8845 case 0xB6:
8846 case 0xB7:
8847 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8848
8849 case 0xB8: // map (one-byte uint8_t for n follows)
8850 {
8851 std::uint8_t len{};
8852 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8853 }
8854
8855 case 0xB9: // map (two-byte uint16_t for n follow)
8856 {
8857 std::uint16_t len{};
8858 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8859 }
8860
8861 case 0xBA: // map (four-byte uint32_t for n follow)
8862 {
8863 std::uint32_t len{};
8864 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8865 }
8866
8867 case 0xBB: // map (eight-byte uint64_t for n follow)
8868 {
8869 std::uint64_t len{};
8870 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8871 }
8872
8873 case 0xBF: // map (indefinite length)
8874 return get_cbor_object(std::size_t(-1), tag_handler);
8875
8876 case 0xC6: // tagged item
8877 case 0xC7:
8878 case 0xC8:
8879 case 0xC9:
8880 case 0xCA:
8881 case 0xCB:
8882 case 0xCC:
8883 case 0xCD:
8884 case 0xCE:
8885 case 0xCF:
8886 case 0xD0:
8887 case 0xD1:
8888 case 0xD2:
8889 case 0xD3:
8890 case 0xD4:
8891 case 0xD8: // tagged item (1 bytes follow)
8892 case 0xD9: // tagged item (2 bytes follow)
8893 case 0xDA: // tagged item (4 bytes follow)
8894 case 0xDB: // tagged item (8 bytes follow)
8895 {
8896 switch (tag_handler)
8897 {
8898 case cbor_tag_handler_t::error:
8899 {
8900 auto last_token = get_token_string();
8901 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()));
8902 }
8903
8904 case cbor_tag_handler_t::ignore:
8905 {
8906 switch (current)
8907 {
8908 case 0xD8:
8909 {
8910 std::uint8_t len{};
8911 get_number(input_format_t::cbor, len);
8912 break;
8913 }
8914 case 0xD9:
8915 {
8916 std::uint16_t len{};
8917 get_number(input_format_t::cbor, len);
8918 break;
8919 }
8920 case 0xDA:
8921 {
8922 std::uint32_t len{};
8923 get_number(input_format_t::cbor, len);
8924 break;
8925 }
8926 case 0xDB:
8927 {
8928 std::uint64_t len{};
8929 get_number(input_format_t::cbor, len);
8930 break;
8931 }
8932 default:
8933 break;
8934 }
8935 return parse_cbor_internal(true, tag_handler);
8936 }
8937
8938 default: // LCOV_EXCL_LINE
8939 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8940 return false; // LCOV_EXCL_LINE
8941 }
8942 }
8943
8944 case 0xF4: // false
8945 return sax->boolean(false);
8946
8947 case 0xF5: // true
8948 return sax->boolean(true);
8949
8950 case 0xF6: // null
8951 return sax->null();
8952
8953 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
8954 {
8955 const auto byte1_raw = get();
8956 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
8957 {
8958 return false;
8959 }
8960 const auto byte2_raw = get();
8961 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
8962 {
8963 return false;
8964 }
8965
8966 const auto byte1 = static_cast<unsigned char>(byte1_raw);
8967 const auto byte2 = static_cast<unsigned char>(byte2_raw);
8968
8969 // code from RFC 7049, Appendix D, Figure 3:
8970 // As half-precision floating-point numbers were only added
8971 // to IEEE 754 in 2008, today's programming platforms often
8972 // still only have limited support for them. It is very
8973 // easy to include at least decoding support for them even
8974 // without such support. An example of a small decoder for
8975 // half-precision floating-point numbers in the C language
8976 // is shown in Fig. 3.
8977 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
8978 const double val = [&half]
8979 {
8980 const int exp = (half >> 10u) & 0x1Fu;
8981 const unsigned int mant = half & 0x3FFu;
8982 JSON_ASSERT(0 <= exp&& exp <= 32);
8983 JSON_ASSERT(mant <= 1024);
8984 switch (exp)
8985 {
8986 case 0:
8987 return std::ldexp(mant, -24);
8988 case 31:
8989 return (mant == 0)
8990 ? std::numeric_limits<double>::infinity()
8991 : std::numeric_limits<double>::quiet_NaN();
8992 default:
8993 return std::ldexp(mant + 1024, exp - 25);
8994 }
8995 }();
8996 return sax->number_float((half & 0x8000u) != 0
8997 ? static_cast<number_float_t>(-val)
8998 : static_cast<number_float_t>(val), "");
8999 }
9000
9001 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9002 {
9003 float number{};
9004 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9005 }
9006
9007 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9008 {
9009 double number{};
9010 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9011 }
9012
9013 default: // anything else (0xFF is handled inside the other types)
9014 {
9015 auto last_token = get_token_string();
9016 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
9017 }
9018 }
9019 }
9020
9032 bool get_cbor_string(string_t& result)
9033 {
9034 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
9035 {
9036 return false;
9037 }
9038
9039 switch (current)
9040 {
9041 // UTF-8 string (0x00..0x17 bytes follow)
9042 case 0x60:
9043 case 0x61:
9044 case 0x62:
9045 case 0x63:
9046 case 0x64:
9047 case 0x65:
9048 case 0x66:
9049 case 0x67:
9050 case 0x68:
9051 case 0x69:
9052 case 0x6A:
9053 case 0x6B:
9054 case 0x6C:
9055 case 0x6D:
9056 case 0x6E:
9057 case 0x6F:
9058 case 0x70:
9059 case 0x71:
9060 case 0x72:
9061 case 0x73:
9062 case 0x74:
9063 case 0x75:
9064 case 0x76:
9065 case 0x77:
9066 {
9067 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9068 }
9069
9070 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9071 {
9072 std::uint8_t len{};
9073 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9074 }
9075
9076 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9077 {
9078 std::uint16_t len{};
9079 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9080 }
9081
9082 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9083 {
9084 std::uint32_t len{};
9085 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9086 }
9087
9088 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9089 {
9090 std::uint64_t len{};
9091 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9092 }
9093
9094 case 0x7F: // UTF-8 string (indefinite length)
9095 {
9096 while (get() != 0xFF)
9097 {
9098 string_t chunk;
9099 if (!get_cbor_string(chunk))
9100 {
9101 return false;
9102 }
9103 result.append(chunk);
9104 }
9105 return true;
9106 }
9107
9108 default:
9109 {
9110 auto last_token = get_token_string();
9111 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()));
9112 }
9113 }
9114 }
9115
9127 bool get_cbor_binary(binary_t& result)
9128 {
9129 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
9130 {
9131 return false;
9132 }
9133
9134 switch (current)
9135 {
9136 // Binary data (0x00..0x17 bytes follow)
9137 case 0x40:
9138 case 0x41:
9139 case 0x42:
9140 case 0x43:
9141 case 0x44:
9142 case 0x45:
9143 case 0x46:
9144 case 0x47:
9145 case 0x48:
9146 case 0x49:
9147 case 0x4A:
9148 case 0x4B:
9149 case 0x4C:
9150 case 0x4D:
9151 case 0x4E:
9152 case 0x4F:
9153 case 0x50:
9154 case 0x51:
9155 case 0x52:
9156 case 0x53:
9157 case 0x54:
9158 case 0x55:
9159 case 0x56:
9160 case 0x57:
9161 {
9162 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9163 }
9164
9165 case 0x58: // Binary data (one-byte uint8_t for n follows)
9166 {
9167 std::uint8_t len{};
9168 return get_number(input_format_t::cbor, len) &&
9169 get_binary(input_format_t::cbor, len, result);
9170 }
9171
9172 case 0x59: // Binary data (two-byte uint16_t for n follow)
9173 {
9174 std::uint16_t len{};
9175 return get_number(input_format_t::cbor, len) &&
9176 get_binary(input_format_t::cbor, len, result);
9177 }
9178
9179 case 0x5A: // Binary data (four-byte uint32_t for n follow)
9180 {
9181 std::uint32_t len{};
9182 return get_number(input_format_t::cbor, len) &&
9183 get_binary(input_format_t::cbor, len, result);
9184 }
9185
9186 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9187 {
9188 std::uint64_t len{};
9189 return get_number(input_format_t::cbor, len) &&
9190 get_binary(input_format_t::cbor, len, result);
9191 }
9192
9193 case 0x5F: // Binary data (indefinite length)
9194 {
9195 while (get() != 0xFF)
9196 {
9197 binary_t chunk;
9198 if (!get_cbor_binary(chunk))
9199 {
9200 return false;
9201 }
9202 result.insert(result.end(), chunk.begin(), chunk.end());
9203 }
9204 return true;
9205 }
9206
9207 default:
9208 {
9209 auto last_token = get_token_string();
9210 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()));
9211 }
9212 }
9213 }
9214
9221 bool get_cbor_array(const std::size_t len,
9222 const cbor_tag_handler_t tag_handler)
9223 {
9224 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9225 {
9226 return false;
9227 }
9228
9229 if (len != std::size_t(-1))
9230 {
9231 for (std::size_t i = 0; i < len; ++i)
9232 {
9233 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9234 {
9235 return false;
9236 }
9237 }
9238 }
9239 else
9240 {
9241 while (get() != 0xFF)
9242 {
9243 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
9244 {
9245 return false;
9246 }
9247 }
9248 }
9249
9250 return sax->end_array();
9251 }
9252
9259 bool get_cbor_object(const std::size_t len,
9260 const cbor_tag_handler_t tag_handler)
9261 {
9262 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9263 {
9264 return false;
9265 }
9266
9267 string_t key;
9268 if (len != std::size_t(-1))
9269 {
9270 for (std::size_t i = 0; i < len; ++i)
9271 {
9272 get();
9273 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9274 {
9275 return false;
9276 }
9277
9278 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9279 {
9280 return false;
9281 }
9282 key.clear();
9283 }
9284 }
9285 else
9286 {
9287 while (get() != 0xFF)
9288 {
9289 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9290 {
9291 return false;
9292 }
9293
9294 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9295 {
9296 return false;
9297 }
9298 key.clear();
9299 }
9300 }
9301
9302 return sax->end_object();
9303 }
9304
9306 // MsgPack //
9308
9312 bool parse_msgpack_internal()
9313 {
9314 switch (get())
9315 {
9316 // EOF
9317 case std::char_traits<char_type>::eof():
9318 return unexpect_eof(input_format_t::msgpack, "value");
9319
9320 // positive fixint
9321 case 0x00:
9322 case 0x01:
9323 case 0x02:
9324 case 0x03:
9325 case 0x04:
9326 case 0x05:
9327 case 0x06:
9328 case 0x07:
9329 case 0x08:
9330 case 0x09:
9331 case 0x0A:
9332 case 0x0B:
9333 case 0x0C:
9334 case 0x0D:
9335 case 0x0E:
9336 case 0x0F:
9337 case 0x10:
9338 case 0x11:
9339 case 0x12:
9340 case 0x13:
9341 case 0x14:
9342 case 0x15:
9343 case 0x16:
9344 case 0x17:
9345 case 0x18:
9346 case 0x19:
9347 case 0x1A:
9348 case 0x1B:
9349 case 0x1C:
9350 case 0x1D:
9351 case 0x1E:
9352 case 0x1F:
9353 case 0x20:
9354 case 0x21:
9355 case 0x22:
9356 case 0x23:
9357 case 0x24:
9358 case 0x25:
9359 case 0x26:
9360 case 0x27:
9361 case 0x28:
9362 case 0x29:
9363 case 0x2A:
9364 case 0x2B:
9365 case 0x2C:
9366 case 0x2D:
9367 case 0x2E:
9368 case 0x2F:
9369 case 0x30:
9370 case 0x31:
9371 case 0x32:
9372 case 0x33:
9373 case 0x34:
9374 case 0x35:
9375 case 0x36:
9376 case 0x37:
9377 case 0x38:
9378 case 0x39:
9379 case 0x3A:
9380 case 0x3B:
9381 case 0x3C:
9382 case 0x3D:
9383 case 0x3E:
9384 case 0x3F:
9385 case 0x40:
9386 case 0x41:
9387 case 0x42:
9388 case 0x43:
9389 case 0x44:
9390 case 0x45:
9391 case 0x46:
9392 case 0x47:
9393 case 0x48:
9394 case 0x49:
9395 case 0x4A:
9396 case 0x4B:
9397 case 0x4C:
9398 case 0x4D:
9399 case 0x4E:
9400 case 0x4F:
9401 case 0x50:
9402 case 0x51:
9403 case 0x52:
9404 case 0x53:
9405 case 0x54:
9406 case 0x55:
9407 case 0x56:
9408 case 0x57:
9409 case 0x58:
9410 case 0x59:
9411 case 0x5A:
9412 case 0x5B:
9413 case 0x5C:
9414 case 0x5D:
9415 case 0x5E:
9416 case 0x5F:
9417 case 0x60:
9418 case 0x61:
9419 case 0x62:
9420 case 0x63:
9421 case 0x64:
9422 case 0x65:
9423 case 0x66:
9424 case 0x67:
9425 case 0x68:
9426 case 0x69:
9427 case 0x6A:
9428 case 0x6B:
9429 case 0x6C:
9430 case 0x6D:
9431 case 0x6E:
9432 case 0x6F:
9433 case 0x70:
9434 case 0x71:
9435 case 0x72:
9436 case 0x73:
9437 case 0x74:
9438 case 0x75:
9439 case 0x76:
9440 case 0x77:
9441 case 0x78:
9442 case 0x79:
9443 case 0x7A:
9444 case 0x7B:
9445 case 0x7C:
9446 case 0x7D:
9447 case 0x7E:
9448 case 0x7F:
9449 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9450
9451 // fixmap
9452 case 0x80:
9453 case 0x81:
9454 case 0x82:
9455 case 0x83:
9456 case 0x84:
9457 case 0x85:
9458 case 0x86:
9459 case 0x87:
9460 case 0x88:
9461 case 0x89:
9462 case 0x8A:
9463 case 0x8B:
9464 case 0x8C:
9465 case 0x8D:
9466 case 0x8E:
9467 case 0x8F:
9468 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9469
9470 // fixarray
9471 case 0x90:
9472 case 0x91:
9473 case 0x92:
9474 case 0x93:
9475 case 0x94:
9476 case 0x95:
9477 case 0x96:
9478 case 0x97:
9479 case 0x98:
9480 case 0x99:
9481 case 0x9A:
9482 case 0x9B:
9483 case 0x9C:
9484 case 0x9D:
9485 case 0x9E:
9486 case 0x9F:
9487 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9488
9489 // fixstr
9490 case 0xA0:
9491 case 0xA1:
9492 case 0xA2:
9493 case 0xA3:
9494 case 0xA4:
9495 case 0xA5:
9496 case 0xA6:
9497 case 0xA7:
9498 case 0xA8:
9499 case 0xA9:
9500 case 0xAA:
9501 case 0xAB:
9502 case 0xAC:
9503 case 0xAD:
9504 case 0xAE:
9505 case 0xAF:
9506 case 0xB0:
9507 case 0xB1:
9508 case 0xB2:
9509 case 0xB3:
9510 case 0xB4:
9511 case 0xB5:
9512 case 0xB6:
9513 case 0xB7:
9514 case 0xB8:
9515 case 0xB9:
9516 case 0xBA:
9517 case 0xBB:
9518 case 0xBC:
9519 case 0xBD:
9520 case 0xBE:
9521 case 0xBF:
9522 case 0xD9: // str 8
9523 case 0xDA: // str 16
9524 case 0xDB: // str 32
9525 {
9526 string_t s;
9527 return get_msgpack_string(s) && sax->string(s);
9528 }
9529
9530 case 0xC0: // nil
9531 return sax->null();
9532
9533 case 0xC2: // false
9534 return sax->boolean(false);
9535
9536 case 0xC3: // true
9537 return sax->boolean(true);
9538
9539 case 0xC4: // bin 8
9540 case 0xC5: // bin 16
9541 case 0xC6: // bin 32
9542 case 0xC7: // ext 8
9543 case 0xC8: // ext 16
9544 case 0xC9: // ext 32
9545 case 0xD4: // fixext 1
9546 case 0xD5: // fixext 2
9547 case 0xD6: // fixext 4
9548 case 0xD7: // fixext 8
9549 case 0xD8: // fixext 16
9550 {
9551 binary_t b;
9552 return get_msgpack_binary(b) && sax->binary(b);
9553 }
9554
9555 case 0xCA: // float 32
9556 {
9557 float number{};
9558 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9559 }
9560
9561 case 0xCB: // float 64
9562 {
9563 double number{};
9564 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9565 }
9566
9567 case 0xCC: // uint 8
9568 {
9569 std::uint8_t number{};
9570 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9571 }
9572
9573 case 0xCD: // uint 16
9574 {
9575 std::uint16_t number{};
9576 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9577 }
9578
9579 case 0xCE: // uint 32
9580 {
9581 std::uint32_t number{};
9582 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9583 }
9584
9585 case 0xCF: // uint 64
9586 {
9587 std::uint64_t number{};
9588 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9589 }
9590
9591 case 0xD0: // int 8
9592 {
9593 std::int8_t number{};
9594 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9595 }
9596
9597 case 0xD1: // int 16
9598 {
9599 std::int16_t number{};
9600 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9601 }
9602
9603 case 0xD2: // int 32
9604 {
9605 std::int32_t number{};
9606 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9607 }
9608
9609 case 0xD3: // int 64
9610 {
9611 std::int64_t number{};
9612 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9613 }
9614
9615 case 0xDC: // array 16
9616 {
9617 std::uint16_t len{};
9618 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9619 }
9620
9621 case 0xDD: // array 32
9622 {
9623 std::uint32_t len{};
9624 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9625 }
9626
9627 case 0xDE: // map 16
9628 {
9629 std::uint16_t len{};
9630 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9631 }
9632
9633 case 0xDF: // map 32
9634 {
9635 std::uint32_t len{};
9636 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9637 }
9638
9639 // negative fixint
9640 case 0xE0:
9641 case 0xE1:
9642 case 0xE2:
9643 case 0xE3:
9644 case 0xE4:
9645 case 0xE5:
9646 case 0xE6:
9647 case 0xE7:
9648 case 0xE8:
9649 case 0xE9:
9650 case 0xEA:
9651 case 0xEB:
9652 case 0xEC:
9653 case 0xED:
9654 case 0xEE:
9655 case 0xEF:
9656 case 0xF0:
9657 case 0xF1:
9658 case 0xF2:
9659 case 0xF3:
9660 case 0xF4:
9661 case 0xF5:
9662 case 0xF6:
9663 case 0xF7:
9664 case 0xF8:
9665 case 0xF9:
9666 case 0xFA:
9667 case 0xFB:
9668 case 0xFC:
9669 case 0xFD:
9670 case 0xFE:
9671 case 0xFF:
9672 return sax->number_integer(static_cast<std::int8_t>(current));
9673
9674 default: // anything else
9675 {
9676 auto last_token = get_token_string();
9677 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()));
9678 }
9679 }
9680 }
9681
9692 bool get_msgpack_string(string_t& result)
9693 {
9694 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
9695 {
9696 return false;
9697 }
9698
9699 switch (current)
9700 {
9701 // fixstr
9702 case 0xA0:
9703 case 0xA1:
9704 case 0xA2:
9705 case 0xA3:
9706 case 0xA4:
9707 case 0xA5:
9708 case 0xA6:
9709 case 0xA7:
9710 case 0xA8:
9711 case 0xA9:
9712 case 0xAA:
9713 case 0xAB:
9714 case 0xAC:
9715 case 0xAD:
9716 case 0xAE:
9717 case 0xAF:
9718 case 0xB0:
9719 case 0xB1:
9720 case 0xB2:
9721 case 0xB3:
9722 case 0xB4:
9723 case 0xB5:
9724 case 0xB6:
9725 case 0xB7:
9726 case 0xB8:
9727 case 0xB9:
9728 case 0xBA:
9729 case 0xBB:
9730 case 0xBC:
9731 case 0xBD:
9732 case 0xBE:
9733 case 0xBF:
9734 {
9735 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
9736 }
9737
9738 case 0xD9: // str 8
9739 {
9740 std::uint8_t len{};
9741 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9742 }
9743
9744 case 0xDA: // str 16
9745 {
9746 std::uint16_t len{};
9747 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9748 }
9749
9750 case 0xDB: // str 32
9751 {
9752 std::uint32_t len{};
9753 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9754 }
9755
9756 default:
9757 {
9758 auto last_token = get_token_string();
9759 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()));
9760 }
9761 }
9762 }
9763
9774 bool get_msgpack_binary(binary_t& result)
9775 {
9776 // helper function to set the subtype
9777 auto assign_and_return_true = [&result](std::int8_t subtype)
9778 {
9779 result.set_subtype(static_cast<std::uint8_t>(subtype));
9780 return true;
9781 };
9782
9783 switch (current)
9784 {
9785 case 0xC4: // bin 8
9786 {
9787 std::uint8_t len{};
9788 return get_number(input_format_t::msgpack, len) &&
9789 get_binary(input_format_t::msgpack, len, result);
9790 }
9791
9792 case 0xC5: // bin 16
9793 {
9794 std::uint16_t len{};
9795 return get_number(input_format_t::msgpack, len) &&
9796 get_binary(input_format_t::msgpack, len, result);
9797 }
9798
9799 case 0xC6: // bin 32
9800 {
9801 std::uint32_t len{};
9802 return get_number(input_format_t::msgpack, len) &&
9803 get_binary(input_format_t::msgpack, len, result);
9804 }
9805
9806 case 0xC7: // ext 8
9807 {
9808 std::uint8_t len{};
9809 std::int8_t subtype{};
9810 return get_number(input_format_t::msgpack, len) &&
9811 get_number(input_format_t::msgpack, subtype) &&
9812 get_binary(input_format_t::msgpack, len, result) &&
9813 assign_and_return_true(subtype);
9814 }
9815
9816 case 0xC8: // ext 16
9817 {
9818 std::uint16_t len{};
9819 std::int8_t subtype{};
9820 return get_number(input_format_t::msgpack, len) &&
9821 get_number(input_format_t::msgpack, subtype) &&
9822 get_binary(input_format_t::msgpack, len, result) &&
9823 assign_and_return_true(subtype);
9824 }
9825
9826 case 0xC9: // ext 32
9827 {
9828 std::uint32_t len{};
9829 std::int8_t subtype{};
9830 return get_number(input_format_t::msgpack, len) &&
9831 get_number(input_format_t::msgpack, subtype) &&
9832 get_binary(input_format_t::msgpack, len, result) &&
9833 assign_and_return_true(subtype);
9834 }
9835
9836 case 0xD4: // fixext 1
9837 {
9838 std::int8_t subtype{};
9839 return get_number(input_format_t::msgpack, subtype) &&
9840 get_binary(input_format_t::msgpack, 1, result) &&
9841 assign_and_return_true(subtype);
9842 }
9843
9844 case 0xD5: // fixext 2
9845 {
9846 std::int8_t subtype{};
9847 return get_number(input_format_t::msgpack, subtype) &&
9848 get_binary(input_format_t::msgpack, 2, result) &&
9849 assign_and_return_true(subtype);
9850 }
9851
9852 case 0xD6: // fixext 4
9853 {
9854 std::int8_t subtype{};
9855 return get_number(input_format_t::msgpack, subtype) &&
9856 get_binary(input_format_t::msgpack, 4, result) &&
9857 assign_and_return_true(subtype);
9858 }
9859
9860 case 0xD7: // fixext 8
9861 {
9862 std::int8_t subtype{};
9863 return get_number(input_format_t::msgpack, subtype) &&
9864 get_binary(input_format_t::msgpack, 8, result) &&
9865 assign_and_return_true(subtype);
9866 }
9867
9868 case 0xD8: // fixext 16
9869 {
9870 std::int8_t subtype{};
9871 return get_number(input_format_t::msgpack, subtype) &&
9872 get_binary(input_format_t::msgpack, 16, result) &&
9873 assign_and_return_true(subtype);
9874 }
9875
9876 default: // LCOV_EXCL_LINE
9877 return false; // LCOV_EXCL_LINE
9878 }
9879 }
9880
9885 bool get_msgpack_array(const std::size_t len)
9886 {
9887 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9888 {
9889 return false;
9890 }
9891
9892 for (std::size_t i = 0; i < len; ++i)
9893 {
9894 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
9895 {
9896 return false;
9897 }
9898 }
9899
9900 return sax->end_array();
9901 }
9902
9907 bool get_msgpack_object(const std::size_t len)
9908 {
9909 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9910 {
9911 return false;
9912 }
9913
9914 string_t key;
9915 for (std::size_t i = 0; i < len; ++i)
9916 {
9917 get();
9918 if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
9919 {
9920 return false;
9921 }
9922
9923 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
9924 {
9925 return false;
9926 }
9927 key.clear();
9928 }
9929
9930 return sax->end_object();
9931 }
9932
9934 // UBJSON //
9936
9944 bool parse_ubjson_internal(const bool get_char = true)
9945 {
9946 return get_ubjson_value(get_char ? get_ignore_noop() : current);
9947 }
9948
9963 bool get_ubjson_string(string_t& result, const bool get_char = true)
9964 {
9965 if (get_char)
9966 {
9967 get(); // TODO(niels): may we ignore N here?
9968 }
9969
9970 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
9971 {
9972 return false;
9973 }
9974
9975 switch (current)
9976 {
9977 case 'U':
9978 {
9979 std::uint8_t len{};
9980 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9981 }
9982
9983 case 'i':
9984 {
9985 std::int8_t len{};
9986 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9987 }
9988
9989 case 'I':
9990 {
9991 std::int16_t len{};
9992 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9993 }
9994
9995 case 'l':
9996 {
9997 std::int32_t len{};
9998 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9999 }
10000
10001 case 'L':
10002 {
10003 std::int64_t len{};
10004 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10005 }
10006
10007 default:
10008 auto last_token = get_token_string();
10009 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()));
10010 }
10011 }
10012
10017 bool get_ubjson_size_value(std::size_t& result)
10018 {
10019 switch (get_ignore_noop())
10020 {
10021 case 'U':
10022 {
10023 std::uint8_t number{};
10024 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10025 {
10026 return false;
10027 }
10028 result = static_cast<std::size_t>(number);
10029 return true;
10030 }
10031
10032 case 'i':
10033 {
10034 std::int8_t number{};
10035 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10036 {
10037 return false;
10038 }
10039 result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
10040 return true;
10041 }
10042
10043 case 'I':
10044 {
10045 std::int16_t number{};
10046 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10047 {
10048 return false;
10049 }
10050 result = static_cast<std::size_t>(number);
10051 return true;
10052 }
10053
10054 case 'l':
10055 {
10056 std::int32_t number{};
10057 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10058 {
10059 return false;
10060 }
10061 result = static_cast<std::size_t>(number);
10062 return true;
10063 }
10064
10065 case 'L':
10066 {
10067 std::int64_t number{};
10068 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10069 {
10070 return false;
10071 }
10072 result = static_cast<std::size_t>(number);
10073 return true;
10074 }
10075
10076 default:
10077 {
10078 auto last_token = get_token_string();
10079 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()));
10080 }
10081 }
10082 }
10083
10094 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
10095 {
10096 result.first = string_t::npos; // size
10097 result.second = 0; // type
10098
10099 get_ignore_noop();
10100
10101 if (current == '$')
10102 {
10103 result.second = get(); // must not ignore 'N', because 'N' maybe the type
10104 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type")))
10105 {
10106 return false;
10107 }
10108
10109 get_ignore_noop();
10110 if (JSON_HEDLEY_UNLIKELY(current != '#'))
10111 {
10112 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
10113 {
10114 return false;
10115 }
10116 auto last_token = get_token_string();
10117 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()));
10118 }
10119
10120 return get_ubjson_size_value(result.first);
10121 }
10122
10123 if (current == '#')
10124 {
10125 return get_ubjson_size_value(result.first);
10126 }
10127
10128 return true;
10129 }
10130
10135 bool get_ubjson_value(const char_int_type prefix)
10136 {
10137 switch (prefix)
10138 {
10139 case std::char_traits<char_type>::eof(): // EOF
10140 return unexpect_eof(input_format_t::ubjson, "value");
10141
10142 case 'T': // true
10143 return sax->boolean(true);
10144 case 'F': // false
10145 return sax->boolean(false);
10146
10147 case 'Z': // null
10148 return sax->null();
10149
10150 case 'U':
10151 {
10152 std::uint8_t number{};
10153 return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
10154 }
10155
10156 case 'i':
10157 {
10158 std::int8_t number{};
10159 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10160 }
10161
10162 case 'I':
10163 {
10164 std::int16_t number{};
10165 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10166 }
10167
10168 case 'l':
10169 {
10170 std::int32_t number{};
10171 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10172 }
10173
10174 case 'L':
10175 {
10176 std::int64_t number{};
10177 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10178 }
10179
10180 case 'd':
10181 {
10182 float number{};
10183 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10184 }
10185
10186 case 'D':
10187 {
10188 double number{};
10189 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10190 }
10191
10192 case 'H':
10193 {
10194 return get_ubjson_high_precision_number();
10195 }
10196
10197 case 'C': // char
10198 {
10199 get();
10200 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char")))
10201 {
10202 return false;
10203 }
10204 if (JSON_HEDLEY_UNLIKELY(current > 127))
10205 {
10206 auto last_token = get_token_string();
10207 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()));
10208 }
10209 string_t s(1, static_cast<typename string_t::value_type>(current));
10210 return sax->string(s);
10211 }
10212
10213 case 'S': // string
10214 {
10215 string_t s;
10216 return get_ubjson_string(s) && sax->string(s);
10217 }
10218
10219 case '[': // array
10220 return get_ubjson_array();
10221
10222 case '{': // object
10223 return get_ubjson_object();
10224
10225 default: // anything else
10226 {
10227 auto last_token = get_token_string();
10228 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()));
10229 }
10230 }
10231 }
10232
10236 bool get_ubjson_array()
10237 {
10238 std::pair<std::size_t, char_int_type> size_and_type;
10239 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10240 {
10241 return false;
10242 }
10243
10244 if (size_and_type.first != string_t::npos)
10245 {
10246 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
10247 {
10248 return false;
10249 }
10250
10251 if (size_and_type.second != 0)
10252 {
10253 if (size_and_type.second != 'N')
10254 {
10255 for (std::size_t i = 0; i < size_and_type.first; ++i)
10256 {
10257 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10258 {
10259 return false;
10260 }
10261 }
10262 }
10263 }
10264 else
10265 {
10266 for (std::size_t i = 0; i < size_and_type.first; ++i)
10267 {
10268 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10269 {
10270 return false;
10271 }
10272 }
10273 }
10274 }
10275 else
10276 {
10277 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10278 {
10279 return false;
10280 }
10281
10282 while (current != ']')
10283 {
10284 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
10285 {
10286 return false;
10287 }
10288 get_ignore_noop();
10289 }
10290 }
10291
10292 return sax->end_array();
10293 }
10294
10298 bool get_ubjson_object()
10299 {
10300 std::pair<std::size_t, char_int_type> size_and_type;
10301 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10302 {
10303 return false;
10304 }
10305
10306 string_t key;
10307 if (size_and_type.first != string_t::npos)
10308 {
10309 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
10310 {
10311 return false;
10312 }
10313
10314 if (size_and_type.second != 0)
10315 {
10316 for (std::size_t i = 0; i < size_and_type.first; ++i)
10317 {
10318 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10319 {
10320 return false;
10321 }
10322 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10323 {
10324 return false;
10325 }
10326 key.clear();
10327 }
10328 }
10329 else
10330 {
10331 for (std::size_t i = 0; i < size_and_type.first; ++i)
10332 {
10333 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10334 {
10335 return false;
10336 }
10337 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10338 {
10339 return false;
10340 }
10341 key.clear();
10342 }
10343 }
10344 }
10345 else
10346 {
10347 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10348 {
10349 return false;
10350 }
10351
10352 while (current != '}')
10353 {
10354 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
10355 {
10356 return false;
10357 }
10358 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10359 {
10360 return false;
10361 }
10362 get_ignore_noop();
10363 key.clear();
10364 }
10365 }
10366
10367 return sax->end_object();
10368 }
10369
10370 // Note, no reader for UBJSON binary types is implemented because they do
10371 // not exist
10372
10373 bool get_ubjson_high_precision_number()
10374 {
10375 // get size of following number string
10376 std::size_t size{};
10377 auto res = get_ubjson_size_value(size);
10378 if (JSON_HEDLEY_UNLIKELY(!res))
10379 {
10380 return res;
10381 }
10382
10383 // get number string
10384 std::vector<char> number_vector;
10385 for (std::size_t i = 0; i < size; ++i)
10386 {
10387 get();
10388 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number")))
10389 {
10390 return false;
10391 }
10392 number_vector.push_back(static_cast<char>(current));
10393 }
10394
10395 // parse number string
10396 using ia_type = decltype(detail::input_adapter(number_vector));
10397 auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
10398 const auto result_number = number_lexer.scan();
10399 const auto number_string = number_lexer.get_token_string();
10400 const auto result_remainder = number_lexer.scan();
10401
10402 using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
10403
10404 if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
10405 {
10406 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()));
10407 }
10408
10409 switch (result_number)
10410 {
10411 case token_type::value_integer:
10412 return sax->number_integer(number_lexer.get_number_integer());
10413 case token_type::value_unsigned:
10414 return sax->number_unsigned(number_lexer.get_number_unsigned());
10415 case token_type::value_float:
10416 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
10417 default:
10418 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()));
10419 }
10420 }
10421
10423 // Utility functions //
10425
10435 char_int_type get()
10436 {
10437 ++chars_read;
10438 return current = ia.get_character();
10439 }
10440
10444 char_int_type get_ignore_noop()
10445 {
10446 do
10447 {
10448 get();
10449 }
10450 while (current == 'N');
10451
10452 return current;
10453 }
10454
10455 /*
10456 @brief read a number from the input
10457
10458 @tparam NumberType the type of the number
10459 @param[in] format the current format (for diagnostics)
10460 @param[out] result number of type @a NumberType
10461
10462 @return whether conversion completed
10463
10464 @note This function needs to respect the system's endianess, because
10465 bytes in CBOR, MessagePack, and UBJSON are stored in network order
10466 (big endian) and therefore need reordering on little endian systems.
10467 */
10468 template<typename NumberType, bool InputIsLittleEndian = false>
10469 bool get_number(const input_format_t format, NumberType& result)
10470 {
10471 // step 1: read input into array with system's byte order
10472 std::array<std::uint8_t, sizeof(NumberType)> vec{};
10473 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
10474 {
10475 get();
10476 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
10477 {
10478 return false;
10479 }
10480
10481 // reverse byte order prior to conversion if necessary
10482 if (is_little_endian != InputIsLittleEndian)
10483 {
10484 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
10485 }
10486 else
10487 {
10488 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
10489 }
10490 }
10491
10492 // step 2: convert array into number of type T and return
10493 std::memcpy(&result, vec.data(), sizeof(NumberType));
10494 return true;
10495 }
10496
10511 template<typename NumberType>
10512 bool get_string(const input_format_t format,
10513 const NumberType len,
10514 string_t& result)
10515 {
10516 bool success = true;
10517 for (NumberType i = 0; i < len; i++)
10518 {
10519 get();
10520 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
10521 {
10522 success = false;
10523 break;
10524 }
10525 result.push_back(static_cast<typename string_t::value_type>(current));
10526 }
10527 return success;
10528 }
10529
10544 template<typename NumberType>
10545 bool get_binary(const input_format_t format,
10546 const NumberType len,
10547 binary_t& result)
10548 {
10549 bool success = true;
10550 for (NumberType i = 0; i < len; i++)
10551 {
10552 get();
10553 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10554 {
10555 success = false;
10556 break;
10557 }
10558 result.push_back(static_cast<std::uint8_t>(current));
10559 }
10560 return success;
10561 }
10562
10568 JSON_HEDLEY_NON_NULL(3)
10569 bool unexpect_eof(const input_format_t format, const char* context) const
10570 {
10571 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
10572 {
10573 return sax->parse_error(chars_read, "<end of file>",
10574 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), BasicJsonType()));
10575 }
10576 return true;
10577 }
10578
10582 std::string get_token_string() const
10583 {
10584 std::array<char, 3> cr{{}};
10585 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
10586 return std::string{cr.data()};
10587 }
10588
10595 std::string exception_message(const input_format_t format,
10596 const std::string& detail,
10597 const std::string& context) const
10598 {
10599 std::string error_msg = "syntax error while parsing ";
10600
10601 switch (format)
10602 {
10603 case input_format_t::cbor:
10604 error_msg += "CBOR";
10605 break;
10606
10607 case input_format_t::msgpack:
10608 error_msg += "MessagePack";
10609 break;
10610
10611 case input_format_t::ubjson:
10612 error_msg += "UBJSON";
10613 break;
10614
10615 case input_format_t::bson:
10616 error_msg += "BSON";
10617 break;
10618
10619 default: // LCOV_EXCL_LINE
10620 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
10621 }
10622
10623 return error_msg + " " + context + ": " + detail;
10624 }
10625
10626 private:
10628 InputAdapterType ia;
10629
10631 char_int_type current = std::char_traits<char_type>::eof();
10632
10634 std::size_t chars_read = 0;
10635
10637 const bool is_little_endian = little_endianess();
10638
10640 json_sax_t* sax = nullptr;
10641 };
10642 } // namespace detail
10643 } // namespace nlohmann
10644
10645 // #include <nlohmann/detail/input/input_adapters.hpp>
10646
10647 // #include <nlohmann/detail/input/lexer.hpp>
10648
10649 // #include <nlohmann/detail/input/parser.hpp>
10650
10651
10652 #include <cmath> // isfinite
10653 #include <cstdint> // uint8_t
10654 #include <functional> // function
10655 #include <string> // string
10656 #include <utility> // move
10657 #include <vector> // vector
10658
10659 // #include <nlohmann/detail/exceptions.hpp>
10660
10661 // #include <nlohmann/detail/input/input_adapters.hpp>
10662
10663 // #include <nlohmann/detail/input/json_sax.hpp>
10664
10665 // #include <nlohmann/detail/input/lexer.hpp>
10666
10667 // #include <nlohmann/detail/macro_scope.hpp>
10668
10669 // #include <nlohmann/detail/meta/is_sax.hpp>
10670
10671 // #include <nlohmann/detail/value_t.hpp>
10672
10673
10674 namespace nlohmann
10675 {
10676 namespace detail
10677 {
10679 // parser //
10681
10682 enum class parse_event_t : uint8_t
10683 {
10685 object_start,
10687 object_end,
10689 array_start,
10691 array_end,
10693 key,
10695 value
10696 };
10697
10698 template<typename BasicJsonType>
10699 using parser_callback_t =
10700 std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
10701
10707 template<typename BasicJsonType, typename InputAdapterType>
10708 class parser
10709 {
10710 using number_integer_t = typename BasicJsonType::number_integer_t;
10711 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10712 using number_float_t = typename BasicJsonType::number_float_t;
10713 using string_t = typename BasicJsonType::string_t;
10714 using lexer_t = lexer<BasicJsonType, InputAdapterType>;
10715 using token_type = typename lexer_t::token_type;
10716
10717 public:
10719 explicit parser(InputAdapterType&& adapter,
10720 const parser_callback_t<BasicJsonType> cb = nullptr,
10721 const bool allow_exceptions_ = true,
10722 const bool skip_comments = false)
10723 : callback(cb)
10724 , m_lexer(std::move(adapter), skip_comments)
10725 , allow_exceptions(allow_exceptions_)
10726 {
10727 // read first token
10728 get_token();
10729 }
10730
10741 void parse(const bool strict, BasicJsonType& result)
10742 {
10743 if (callback)
10744 {
10745 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
10746 sax_parse_internal(&sdp);
10747
10748 // in strict mode, input must be completely read
10749 if (strict && (get_token() != token_type::end_of_input))
10750 {
10751 sdp.parse_error(m_lexer.get_position(),
10752 m_lexer.get_token_string(),
10753 parse_error::create(101, m_lexer.get_position(),
10754 exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10755 }
10756
10757 // in case of an error, return discarded value
10758 if (sdp.is_errored())
10759 {
10760 result = value_t::discarded;
10761 return;
10762 }
10763
10764 // set top-level value to null if it was discarded by the callback
10765 // function
10766 if (result.is_discarded())
10767 {
10768 result = nullptr;
10769 }
10770 }
10771 else
10772 {
10773 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
10774 sax_parse_internal(&sdp);
10775
10776 // in strict mode, input must be completely read
10777 if (strict && (get_token() != token_type::end_of_input))
10778 {
10779 sdp.parse_error(m_lexer.get_position(),
10780 m_lexer.get_token_string(),
10781 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10782 }
10783
10784 // in case of an error, return discarded value
10785 if (sdp.is_errored())
10786 {
10787 result = value_t::discarded;
10788 return;
10789 }
10790 }
10791
10792 result.assert_invariant();
10793 }
10794
10801 bool accept(const bool strict = true)
10802 {
10803 json_sax_acceptor<BasicJsonType> sax_acceptor;
10804 return sax_parse(&sax_acceptor, strict);
10805 }
10806
10807 template<typename SAX>
10808 JSON_HEDLEY_NON_NULL(2)
10809 bool sax_parse(SAX* sax, const bool strict = true)
10810 {
10811 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
10812 const bool result = sax_parse_internal(sax);
10813
10814 // strict mode: next byte must be EOF
10815 if (result && strict && (get_token() != token_type::end_of_input))
10816 {
10817 return sax->parse_error(m_lexer.get_position(),
10818 m_lexer.get_token_string(),
10819 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10820 }
10821
10822 return result;
10823 }
10824
10825 private:
10826 template<typename SAX>
10827 JSON_HEDLEY_NON_NULL(2)
10828 bool sax_parse_internal(SAX* sax)
10829 {
10830 // stack to remember the hierarchy of structured values we are parsing
10831 // true = array; false = object
10832 std::vector<bool> states;
10833 // value to avoid a goto (see comment where set to true)
10834 bool skip_to_state_evaluation = false;
10835
10836 while (true)
10837 {
10838 if (!skip_to_state_evaluation)
10839 {
10840 // invariant: get_token() was called before each iteration
10841 switch (last_token)
10842 {
10843 case token_type::begin_object:
10844 {
10845 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10846 {
10847 return false;
10848 }
10849
10850 // closing } -> we are done
10851 if (get_token() == token_type::end_object)
10852 {
10853 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
10854 {
10855 return false;
10856 }
10857 break;
10858 }
10859
10860 // parse key
10861 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
10862 {
10863 return sax->parse_error(m_lexer.get_position(),
10864 m_lexer.get_token_string(),
10865 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
10866 }
10867 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
10868 {
10869 return false;
10870 }
10871
10872 // parse separator (:)
10873 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10874 {
10875 return sax->parse_error(m_lexer.get_position(),
10876 m_lexer.get_token_string(),
10877 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
10878 }
10879
10880 // remember we are now inside an object
10881 states.push_back(false);
10882
10883 // parse values
10884 get_token();
10885 continue;
10886 }
10887
10888 case token_type::begin_array:
10889 {
10890 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10891 {
10892 return false;
10893 }
10894
10895 // closing ] -> we are done
10896 if (get_token() == token_type::end_array)
10897 {
10898 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
10899 {
10900 return false;
10901 }
10902 break;
10903 }
10904
10905 // remember we are now inside an array
10906 states.push_back(true);
10907
10908 // parse values (no need to call get_token)
10909 continue;
10910 }
10911
10912 case token_type::value_float:
10913 {
10914 const auto res = m_lexer.get_number_float();
10915
10916 if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
10917 {
10918 return sax->parse_error(m_lexer.get_position(),
10919 m_lexer.get_token_string(),
10920 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType()));
10921 }
10922
10923 if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
10924 {
10925 return false;
10926 }
10927
10928 break;
10929 }
10930
10931 case token_type::literal_false:
10932 {
10933 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
10934 {
10935 return false;
10936 }
10937 break;
10938 }
10939
10940 case token_type::literal_null:
10941 {
10942 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
10943 {
10944 return false;
10945 }
10946 break;
10947 }
10948
10949 case token_type::literal_true:
10950 {
10951 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
10952 {
10953 return false;
10954 }
10955 break;
10956 }
10957
10958 case token_type::value_integer:
10959 {
10960 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
10961 {
10962 return false;
10963 }
10964 break;
10965 }
10966
10967 case token_type::value_string:
10968 {
10969 if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
10970 {
10971 return false;
10972 }
10973 break;
10974 }
10975
10976 case token_type::value_unsigned:
10977 {
10978 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
10979 {
10980 return false;
10981 }
10982 break;
10983 }
10984
10985 case token_type::parse_error:
10986 {
10987 // using "uninitialized" to avoid "expected" message
10988 return sax->parse_error(m_lexer.get_position(),
10989 m_lexer.get_token_string(),
10990 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType()));
10991 }
10992
10993 default: // the last token was unexpected
10994 {
10995 return sax->parse_error(m_lexer.get_position(),
10996 m_lexer.get_token_string(),
10997 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), BasicJsonType()));
10998 }
10999 }
11000 }
11001 else
11002 {
11003 skip_to_state_evaluation = false;
11004 }
11005
11006 // we reached this line after we successfully parsed a value
11007 if (states.empty())
11008 {
11009 // empty stack: we reached the end of the hierarchy: done
11010 return true;
11011 }
11012
11013 if (states.back()) // array
11014 {
11015 // comma -> next value
11016 if (get_token() == token_type::value_separator)
11017 {
11018 // parse a new value
11019 get_token();
11020 continue;
11021 }
11022
11023 // closing ]
11024 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
11025 {
11026 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11027 {
11028 return false;
11029 }
11030
11031 // We are done with this array. Before we can parse a
11032 // new value, we need to evaluate the new state first.
11033 // By setting skip_to_state_evaluation to false, we
11034 // are effectively jumping to the beginning of this if.
11035 JSON_ASSERT(!states.empty());
11036 states.pop_back();
11037 skip_to_state_evaluation = true;
11038 continue;
11039 }
11040
11041 return sax->parse_error(m_lexer.get_position(),
11042 m_lexer.get_token_string(),
11043 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), BasicJsonType()));
11044 }
11045
11046 // states.back() is false -> object
11047
11048 // comma -> next value
11049 if (get_token() == token_type::value_separator)
11050 {
11051 // parse key
11052 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
11053 {
11054 return sax->parse_error(m_lexer.get_position(),
11055 m_lexer.get_token_string(),
11056 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11057 }
11058
11059 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11060 {
11061 return false;
11062 }
11063
11064 // parse separator (:)
11065 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11066 {
11067 return sax->parse_error(m_lexer.get_position(),
11068 m_lexer.get_token_string(),
11069 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11070 }
11071
11072 // parse values
11073 get_token();
11074 continue;
11075 }
11076
11077 // closing }
11078 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
11079 {
11080 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11081 {
11082 return false;
11083 }
11084
11085 // We are done with this object. Before we can parse a
11086 // new value, we need to evaluate the new state first.
11087 // By setting skip_to_state_evaluation to false, we
11088 // are effectively jumping to the beginning of this if.
11089 JSON_ASSERT(!states.empty());
11090 states.pop_back();
11091 skip_to_state_evaluation = true;
11092 continue;
11093 }
11094
11095 return sax->parse_error(m_lexer.get_position(),
11096 m_lexer.get_token_string(),
11097 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), BasicJsonType()));
11098 }
11099 }
11100
11102 token_type get_token()
11103 {
11104 return last_token = m_lexer.scan();
11105 }
11106
11107 std::string exception_message(const token_type expected, const std::string& context)
11108 {
11109 std::string error_msg = "syntax error ";
11110
11111 if (!context.empty())
11112 {
11113 error_msg += "while parsing " + context + " ";
11114 }
11115
11116 error_msg += "- ";
11117
11118 if (last_token == token_type::parse_error)
11119 {
11120 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
11121 m_lexer.get_token_string() + "'";
11122 }
11123 else
11124 {
11125 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
11126 }
11127
11128 if (expected != token_type::uninitialized)
11129 {
11130 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
11131 }
11132
11133 return error_msg;
11134 }
11135
11136 private:
11138 const parser_callback_t<BasicJsonType> callback = nullptr;
11140 token_type last_token = token_type::uninitialized;
11142 lexer_t m_lexer;
11144 const bool allow_exceptions = true;
11145 };
11146
11147 } // namespace detail
11148 } // namespace nlohmann
11149
11150 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
11151
11152
11153 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11154
11155
11156 #include <cstddef> // ptrdiff_t
11157 #include <limits> // numeric_limits
11158
11159 // #include <nlohmann/detail/macro_scope.hpp>
11160
11161
11162 namespace nlohmann
11163 {
11164 namespace detail
11165 {
11166 /*
11167 @brief an iterator for primitive JSON types
11168
11169 This class models an iterator for primitive JSON types (boolean, number,
11170 string). It's only purpose is to allow the iterator/const_iterator classes
11171 to "iterate" over primitive values. Internally, the iterator is modeled by
11172 a `difference_type` variable. Value begin_value (`0`) models the begin,
11173 end_value (`1`) models past the end.
11174 */
11175 class primitive_iterator_t
11176 {
11177 private:
11178 using difference_type = std::ptrdiff_t;
11179 static constexpr difference_type begin_value = 0;
11180 static constexpr difference_type end_value = begin_value + 1;
11181
11182 JSON_PRIVATE_UNLESS_TESTED:
11184 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
11185
11186 public:
11187 constexpr difference_type get_value() const noexcept
11188 {
11189 return m_it;
11190 }
11191
11193 void set_begin() noexcept
11194 {
11195 m_it = begin_value;
11196 }
11197
11199 void set_end() noexcept
11200 {
11201 m_it = end_value;
11202 }
11203
11205 constexpr bool is_begin() const noexcept
11206 {
11207 return m_it == begin_value;
11208 }
11209
11211 constexpr bool is_end() const noexcept
11212 {
11213 return m_it == end_value;
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 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11222 {
11223 return lhs.m_it < rhs.m_it;
11224 }
11225
11226 primitive_iterator_t operator+(difference_type n) noexcept
11227 {
11228 auto result = *this;
11229 result += n;
11230 return result;
11231 }
11232
11233 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11234 {
11235 return lhs.m_it - rhs.m_it;
11236 }
11237
11238 primitive_iterator_t& operator++() noexcept
11239 {
11240 ++m_it;
11241 return *this;
11242 }
11243
11244 primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)
11245 {
11246 auto result = *this;
11247 ++m_it;
11248 return result;
11249 }
11250
11251 primitive_iterator_t& operator--() noexcept
11252 {
11253 --m_it;
11254 return *this;
11255 }
11256
11257 primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)
11258 {
11259 auto result = *this;
11260 --m_it;
11261 return result;
11262 }
11263
11264 primitive_iterator_t& operator+=(difference_type n) noexcept
11265 {
11266 m_it += n;
11267 return *this;
11268 }
11269
11270 primitive_iterator_t& operator-=(difference_type n) noexcept
11271 {
11272 m_it -= n;
11273 return *this;
11274 }
11275 };
11276 } // namespace detail
11277 } // namespace nlohmann
11278
11279
11280 namespace nlohmann
11281 {
11282 namespace detail
11283 {
11290 template<typename BasicJsonType> struct internal_iterator
11291 {
11293 typename BasicJsonType::object_t::iterator object_iterator {};
11295 typename BasicJsonType::array_t::iterator array_iterator {};
11297 primitive_iterator_t primitive_iterator {};
11298 };
11299 } // namespace detail
11300 } // namespace nlohmann
11301
11302 // #include <nlohmann/detail/iterators/iter_impl.hpp>
11303
11304
11305 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
11306 #include <type_traits> // conditional, is_const, remove_const
11307
11308 // #include <nlohmann/detail/exceptions.hpp>
11309
11310 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
11311
11312 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11313
11314 // #include <nlohmann/detail/macro_scope.hpp>
11315
11316 // #include <nlohmann/detail/meta/cpp_future.hpp>
11317
11318 // #include <nlohmann/detail/meta/type_traits.hpp>
11319
11320 // #include <nlohmann/detail/value_t.hpp>
11321
11322
11323 namespace nlohmann
11324 {
11325 namespace detail
11326 {
11327 // forward declare, to be able to friend it later on
11328 template<typename IteratorType> class iteration_proxy;
11329 template<typename IteratorType> class iteration_proxy_value;
11330
11347 template<typename BasicJsonType>
11348 class iter_impl
11349 {
11351 using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
11353 friend other_iter_impl;
11354 friend BasicJsonType;
11355 friend iteration_proxy<iter_impl>;
11356 friend iteration_proxy_value<iter_impl>;
11357
11358 using object_t = typename BasicJsonType::object_t;
11359 using array_t = typename BasicJsonType::array_t;
11360 // make sure BasicJsonType is basic_json or const basic_json
11361 static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
11362 "iter_impl only accepts (const) basic_json");
11363
11364 public:
11365
11371 using iterator_category = std::bidirectional_iterator_tag;
11372
11374 using value_type = typename BasicJsonType::value_type;
11376 using difference_type = typename BasicJsonType::difference_type;
11378 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
11379 typename BasicJsonType::const_pointer,
11380 typename BasicJsonType::pointer>::type;
11382 using reference =
11383 typename std::conditional<std::is_const<BasicJsonType>::value,
11384 typename BasicJsonType::const_reference,
11385 typename BasicJsonType::reference>::type;
11386
11387 iter_impl() = default;
11388 ~iter_impl() = default;
11389 iter_impl(iter_impl&&) noexcept = default;
11390 iter_impl& operator=(iter_impl&&) noexcept = default;
11391
11398 explicit iter_impl(pointer object) noexcept : m_object(object)
11399 {
11400 JSON_ASSERT(m_object != nullptr);
11401
11402 switch (m_object->m_type)
11403 {
11404 case value_t::object:
11405 {
11406 m_it.object_iterator = typename object_t::iterator();
11407 break;
11408 }
11409
11410 case value_t::array:
11411 {
11412 m_it.array_iterator = typename array_t::iterator();
11413 break;
11414 }
11415
11416 default:
11417 {
11418 m_it.primitive_iterator = primitive_iterator_t();
11419 break;
11420 }
11421 }
11422 }
11423
11440 iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
11441 : m_object(other.m_object), m_it(other.m_it)
11442 {}
11443
11450 iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
11451 {
11452 if (&other != this)
11453 {
11454 m_object = other.m_object;
11455 m_it = other.m_it;
11456 }
11457 return *this;
11458 }
11459
11465 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
11466 : m_object(other.m_object), m_it(other.m_it)
11467 {}
11468
11475 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
11476 {
11477 m_object = other.m_object;
11478 m_it = other.m_it;
11479 return *this;
11480 }
11481
11482 JSON_PRIVATE_UNLESS_TESTED:
11487 void set_begin() noexcept
11488 {
11489 JSON_ASSERT(m_object != nullptr);
11490
11491 switch (m_object->m_type)
11492 {
11493 case value_t::object:
11494 {
11495 m_it.object_iterator = m_object->m_value.object->begin();
11496 break;
11497 }
11498
11499 case value_t::array:
11500 {
11501 m_it.array_iterator = m_object->m_value.array->begin();
11502 break;
11503 }
11504
11505 case value_t::null:
11506 {
11507 // set to end so begin()==end() is true: null is empty
11508 m_it.primitive_iterator.set_end();
11509 break;
11510 }
11511
11512 default:
11513 {
11514 m_it.primitive_iterator.set_begin();
11515 break;
11516 }
11517 }
11518 }
11519
11524 void set_end() noexcept
11525 {
11526 JSON_ASSERT(m_object != nullptr);
11527
11528 switch (m_object->m_type)
11529 {
11530 case value_t::object:
11531 {
11532 m_it.object_iterator = m_object->m_value.object->end();
11533 break;
11534 }
11535
11536 case value_t::array:
11537 {
11538 m_it.array_iterator = m_object->m_value.array->end();
11539 break;
11540 }
11541
11542 default:
11543 {
11544 m_it.primitive_iterator.set_end();
11545 break;
11546 }
11547 }
11548 }
11549
11550 public:
11555 reference operator*() const
11556 {
11557 JSON_ASSERT(m_object != nullptr);
11558
11559 switch (m_object->m_type)
11560 {
11561 case value_t::object:
11562 {
11563 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11564 return m_it.object_iterator->second;
11565 }
11566
11567 case value_t::array:
11568 {
11569 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11570 return *m_it.array_iterator;
11571 }
11572
11573 case value_t::null:
11574 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11575
11576 default:
11577 {
11578 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11579 {
11580 return *m_object;
11581 }
11582
11583 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11584 }
11585 }
11586 }
11587
11592 pointer operator->() const
11593 {
11594 JSON_ASSERT(m_object != nullptr);
11595
11596 switch (m_object->m_type)
11597 {
11598 case value_t::object:
11599 {
11600 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11601 return &(m_it.object_iterator->second);
11602 }
11603
11604 case value_t::array:
11605 {
11606 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11607 return &*m_it.array_iterator;
11608 }
11609
11610 default:
11611 {
11612 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11613 {
11614 return m_object;
11615 }
11616
11617 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11618 }
11619 }
11620 }
11621
11626 iter_impl const operator++(int) // NOLINT(readability-const-return-type)
11627 {
11628 auto result = *this;
11629 ++(*this);
11630 return result;
11631 }
11632
11637 iter_impl& operator++()
11638 {
11639 JSON_ASSERT(m_object != nullptr);
11640
11641 switch (m_object->m_type)
11642 {
11643 case value_t::object:
11644 {
11645 std::advance(m_it.object_iterator, 1);
11646 break;
11647 }
11648
11649 case value_t::array:
11650 {
11651 std::advance(m_it.array_iterator, 1);
11652 break;
11653 }
11654
11655 default:
11656 {
11657 ++m_it.primitive_iterator;
11658 break;
11659 }
11660 }
11661
11662 return *this;
11663 }
11664
11669 iter_impl const operator--(int) // NOLINT(readability-const-return-type)
11670 {
11671 auto result = *this;
11672 --(*this);
11673 return result;
11674 }
11675
11680 iter_impl& operator--()
11681 {
11682 JSON_ASSERT(m_object != nullptr);
11683
11684 switch (m_object->m_type)
11685 {
11686 case value_t::object:
11687 {
11688 std::advance(m_it.object_iterator, -1);
11689 break;
11690 }
11691
11692 case value_t::array:
11693 {
11694 std::advance(m_it.array_iterator, -1);
11695 break;
11696 }
11697
11698 default:
11699 {
11700 --m_it.primitive_iterator;
11701 break;
11702 }
11703 }
11704
11705 return *this;
11706 }
11707
11712 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 >
11713 bool operator==(const IterImpl& other) const
11714 {
11715 // if objects are not the same, the comparison is undefined
11716 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11717 {
11718 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
11719 }
11720
11721 JSON_ASSERT(m_object != nullptr);
11722
11723 switch (m_object->m_type)
11724 {
11725 case value_t::object:
11726 return (m_it.object_iterator == other.m_it.object_iterator);
11727
11728 case value_t::array:
11729 return (m_it.array_iterator == other.m_it.array_iterator);
11730
11731 default:
11732 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
11733 }
11734 }
11735
11740 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 >
11741 bool operator!=(const IterImpl& other) const
11742 {
11743 return !operator==(other);
11744 }
11745
11750 bool operator<(const iter_impl& other) const
11751 {
11752 // if objects are not the same, the comparison is undefined
11753 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11754 {
11755 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
11756 }
11757
11758 JSON_ASSERT(m_object != nullptr);
11759
11760 switch (m_object->m_type)
11761 {
11762 case value_t::object:
11763 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", *m_object));
11764
11765 case value_t::array:
11766 return (m_it.array_iterator < other.m_it.array_iterator);
11767
11768 default:
11769 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
11770 }
11771 }
11772
11777 bool operator<=(const iter_impl& other) const
11778 {
11779 return !other.operator < (*this);
11780 }
11781
11786 bool operator>(const iter_impl& other) const
11787 {
11788 return !operator<=(other);
11789 }
11790
11795 bool operator>=(const iter_impl& other) const
11796 {
11797 return !operator<(other);
11798 }
11799
11804 iter_impl& operator+=(difference_type i)
11805 {
11806 JSON_ASSERT(m_object != nullptr);
11807
11808 switch (m_object->m_type)
11809 {
11810 case value_t::object:
11811 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
11812
11813 case value_t::array:
11814 {
11815 std::advance(m_it.array_iterator, i);
11816 break;
11817 }
11818
11819 default:
11820 {
11821 m_it.primitive_iterator += i;
11822 break;
11823 }
11824 }
11825
11826 return *this;
11827 }
11828
11833 iter_impl& operator-=(difference_type i)
11834 {
11835 return operator+=(-i);
11836 }
11837
11842 iter_impl operator+(difference_type i) const
11843 {
11844 auto result = *this;
11845 result += i;
11846 return result;
11847 }
11848
11853 friend iter_impl operator+(difference_type i, const iter_impl& it)
11854 {
11855 auto result = it;
11856 result += i;
11857 return result;
11858 }
11859
11864 iter_impl operator-(difference_type i) const
11865 {
11866 auto result = *this;
11867 result -= i;
11868 return result;
11869 }
11870
11875 difference_type operator-(const iter_impl& other) const
11876 {
11877 JSON_ASSERT(m_object != nullptr);
11878
11879 switch (m_object->m_type)
11880 {
11881 case value_t::object:
11882 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
11883
11884 case value_t::array:
11885 return m_it.array_iterator - other.m_it.array_iterator;
11886
11887 default:
11888 return m_it.primitive_iterator - other.m_it.primitive_iterator;
11889 }
11890 }
11891
11896 reference operator[](difference_type n) const
11897 {
11898 JSON_ASSERT(m_object != nullptr);
11899
11900 switch (m_object->m_type)
11901 {
11902 case value_t::object:
11903 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", *m_object));
11904
11905 case value_t::array:
11906 return *std::next(m_it.array_iterator, n);
11907
11908 case value_t::null:
11909 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11910
11911 default:
11912 {
11913 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
11914 {
11915 return *m_object;
11916 }
11917
11918 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11919 }
11920 }
11921 }
11922
11927 const typename object_t::key_type& key() const
11928 {
11929 JSON_ASSERT(m_object != nullptr);
11930
11931 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
11932 {
11933 return m_it.object_iterator->first;
11934 }
11935
11936 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", *m_object));
11937 }
11938
11943 reference value() const
11944 {
11945 return operator*();
11946 }
11947
11948 JSON_PRIVATE_UNLESS_TESTED:
11950 pointer m_object = nullptr;
11952 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
11953 };
11954 } // namespace detail
11955 } // namespace nlohmann
11956
11957 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
11958
11959 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
11960
11961
11962 #include <cstddef> // ptrdiff_t
11963 #include <iterator> // reverse_iterator
11964 #include <utility> // declval
11965
11966 namespace nlohmann
11967 {
11968 namespace detail
11969 {
11971 // reverse_iterator //
11973
11992 template<typename Base>
11993 class json_reverse_iterator : public std::reverse_iterator<Base>
11994 {
11995 public:
11996 using difference_type = std::ptrdiff_t;
11998 using base_iterator = std::reverse_iterator<Base>;
12000 using reference = typename Base::reference;
12001
12003 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
12004 : base_iterator(it) {}
12005
12007 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
12008
12010 json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)
12011 {
12012 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
12013 }
12014
12016 json_reverse_iterator& operator++()
12017 {
12018 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
12019 }
12020
12022 json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)
12023 {
12024 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
12025 }
12026
12028 json_reverse_iterator& operator--()
12029 {
12030 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
12031 }
12032
12034 json_reverse_iterator& operator+=(difference_type i)
12035 {
12036 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
12037 }
12038
12040 json_reverse_iterator operator+(difference_type i) const
12041 {
12042 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
12043 }
12044
12046 json_reverse_iterator operator-(difference_type i) const
12047 {
12048 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
12049 }
12050
12052 difference_type operator-(const json_reverse_iterator& other) const
12053 {
12054 return base_iterator(*this) - base_iterator(other);
12055 }
12056
12058 reference operator[](difference_type n) const
12059 {
12060 return *(this->operator+(n));
12061 }
12062
12064 auto key() const -> decltype(std::declval<Base>().key())
12065 {
12066 auto it = --this->base();
12067 return it.key();
12068 }
12069
12071 reference value() const
12072 {
12073 auto it = --this->base();
12074 return it.operator * ();
12075 }
12076 };
12077 } // namespace detail
12078 } // namespace nlohmann
12079
12080 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12081
12082 // #include <nlohmann/detail/json_pointer.hpp>
12083
12084
12085 #include <algorithm> // all_of
12086 #include <cctype> // isdigit
12087 #include <limits> // max
12088 #include <numeric> // accumulate
12089 #include <string> // string
12090 #include <utility> // move
12091 #include <vector> // vector
12092
12093 // #include <nlohmann/detail/exceptions.hpp>
12094
12095 // #include <nlohmann/detail/macro_scope.hpp>
12096
12097 // #include <nlohmann/detail/string_escape.hpp>
12098
12099 // #include <nlohmann/detail/value_t.hpp>
12100
12101
12102 namespace nlohmann
12103 {
12104 template<typename BasicJsonType>
12105 class json_pointer
12106 {
12107 // allow basic_json to access private members
12108 NLOHMANN_BASIC_JSON_TPL_DECLARATION
12109 friend class basic_json;
12110
12111 public:
12133 explicit json_pointer(const std::string& s = "")
12134 : reference_tokens(split(s))
12135 {}
12136
12151 std::string to_string() const
12152 {
12153 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
12154 std::string{},
12155 [](const std::string & a, const std::string & b)
12156 {
12157 return a + "/" + detail::escape(b);
12158 });
12159 }
12160
12162 operator std::string() const
12163 {
12164 return to_string();
12165 }
12166
12183 json_pointer& operator/=(const json_pointer& ptr)
12184 {
12185 reference_tokens.insert(reference_tokens.end(),
12186 ptr.reference_tokens.begin(),
12187 ptr.reference_tokens.end());
12188 return *this;
12189 }
12190
12207 json_pointer& operator/=(std::string token)
12208 {
12209 push_back(std::move(token));
12210 return *this;
12211 }
12212
12229 json_pointer& operator/=(std::size_t array_idx)
12230 {
12231 return *this /= std::to_string(array_idx);
12232 }
12233
12249 friend json_pointer operator/(const json_pointer& lhs,
12250 const json_pointer& rhs)
12251 {
12252 return json_pointer(lhs) /= rhs;
12253 }
12254
12270 friend json_pointer operator/(const json_pointer& ptr, std::string token) // NOLINT(performance-unnecessary-value-param)
12271 {
12272 return json_pointer(ptr) /= std::move(token);
12273 }
12274
12290 friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
12291 {
12292 return json_pointer(ptr) /= array_idx;
12293 }
12294
12308 json_pointer parent_pointer() const
12309 {
12310 if (empty())
12311 {
12312 return *this;
12313 }
12314
12315 json_pointer res = *this;
12316 res.pop_back();
12317 return res;
12318 }
12319
12333 void pop_back()
12334 {
12335 if (JSON_HEDLEY_UNLIKELY(empty()))
12336 {
12337 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12338 }
12339
12340 reference_tokens.pop_back();
12341 }
12342
12357 const std::string& back() const
12358 {
12359 if (JSON_HEDLEY_UNLIKELY(empty()))
12360 {
12361 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12362 }
12363
12364 return reference_tokens.back();
12365 }
12366
12379 void push_back(const std::string& token)
12380 {
12381 reference_tokens.push_back(token);
12382 }
12383
12385 void push_back(std::string&& token)
12386 {
12387 reference_tokens.push_back(std::move(token));
12388 }
12389
12404 bool empty() const noexcept
12405 {
12406 return reference_tokens.empty();
12407 }
12408
12409 private:
12420 static typename BasicJsonType::size_type array_index(const std::string& s)
12421 {
12422 using size_type = typename BasicJsonType::size_type;
12423
12424 // error condition (cf. RFC 6901, Sect. 4)
12425 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
12426 {
12427 JSON_THROW(detail::parse_error::create(106, 0, "array index '" + s + "' must not begin with '0'", BasicJsonType()));
12428 }
12429
12430 // error condition (cf. RFC 6901, Sect. 4)
12431 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
12432 {
12433 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number", BasicJsonType()));
12434 }
12435
12436 std::size_t processed_chars = 0;
12437 unsigned long long res = 0; // NOLINT(runtime/int)
12438 JSON_TRY
12439 {
12440 res = std::stoull(s, &processed_chars);
12441 }
12442 JSON_CATCH(std::out_of_range&)
12443 {
12444 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12445 }
12446
12447 // check if the string was completely read
12448 if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
12449 {
12450 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12451 }
12452
12453 // only triggered on special platforms (like 32bit), see also
12454 // https://github.com/nlohmann/json/pull/2203
12455 if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
12456 {
12457 JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type", BasicJsonType())); // LCOV_EXCL_LINE
12458 }
12459
12460 return static_cast<size_type>(res);
12461 }
12462
12463 JSON_PRIVATE_UNLESS_TESTED:
12464 json_pointer top() const
12465 {
12466 if (JSON_HEDLEY_UNLIKELY(empty()))
12467 {
12468 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12469 }
12470
12471 json_pointer result = *this;
12472 result.reference_tokens = {reference_tokens[0]};
12473 return result;
12474 }
12475
12476 private:
12485 BasicJsonType& get_and_create(BasicJsonType& j) const
12486 {
12487 auto* result = &j;
12488
12489 // in case no reference tokens exist, return a reference to the JSON value
12490 // j which will be overwritten by a primitive value
12491 for (const auto& reference_token : reference_tokens)
12492 {
12493 switch (result->type())
12494 {
12495 case detail::value_t::null:
12496 {
12497 if (reference_token == "0")
12498 {
12499 // start a new array if reference token is 0
12500 result = &result->operator[](0);
12501 }
12502 else
12503 {
12504 // start a new object otherwise
12505 result = &result->operator[](reference_token);
12506 }
12507 break;
12508 }
12509
12510 case detail::value_t::object:
12511 {
12512 // create an entry in the object
12513 result = &result->operator[](reference_token);
12514 break;
12515 }
12516
12517 case detail::value_t::array:
12518 {
12519 // create an entry in the array
12520 result = &result->operator[](array_index(reference_token));
12521 break;
12522 }
12523
12524 /*
12525 The following code is only reached if there exists a reference
12526 token _and_ the current value is primitive. In this case, we have
12527 an error situation, because primitive values may only occur as
12528 single value; that is, with an empty list of reference tokens.
12529 */
12530 default:
12531 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j));
12532 }
12533 }
12534
12535 return *result;
12536 }
12537
12557 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
12558 {
12559 for (const auto& reference_token : reference_tokens)
12560 {
12561 // convert null values to arrays or objects before continuing
12562 if (ptr->is_null())
12563 {
12564 // check if reference token is a number
12565 const bool nums =
12566 std::all_of(reference_token.begin(), reference_token.end(),
12567 [](const unsigned char x)
12568 {
12569 return std::isdigit(x);
12570 });
12571
12572 // change value to array for numbers or "-" or to object otherwise
12573 *ptr = (nums || reference_token == "-")
12574 ? detail::value_t::array
12575 : detail::value_t::object;
12576 }
12577
12578 switch (ptr->type())
12579 {
12580 case detail::value_t::object:
12581 {
12582 // use unchecked object access
12583 ptr = &ptr->operator[](reference_token);
12584 break;
12585 }
12586
12587 case detail::value_t::array:
12588 {
12589 if (reference_token == "-")
12590 {
12591 // explicitly treat "-" as index beyond the end
12592 ptr = &ptr->operator[](ptr->m_value.array->size());
12593 }
12594 else
12595 {
12596 // convert array index to number; unchecked access
12597 ptr = &ptr->operator[](array_index(reference_token));
12598 }
12599 break;
12600 }
12601
12602 default:
12603 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12604 }
12605 }
12606
12607 return *ptr;
12608 }
12609
12616 BasicJsonType& get_checked(BasicJsonType* ptr) const
12617 {
12618 for (const auto& reference_token : reference_tokens)
12619 {
12620 switch (ptr->type())
12621 {
12622 case detail::value_t::object:
12623 {
12624 // note: at performs range check
12625 ptr = &ptr->at(reference_token);
12626 break;
12627 }
12628
12629 case detail::value_t::array:
12630 {
12631 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12632 {
12633 // "-" always fails the range check
12634 JSON_THROW(detail::out_of_range::create(402,
12635 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12636 ") is out of range", *ptr));
12637 }
12638
12639 // note: at performs range check
12640 ptr = &ptr->at(array_index(reference_token));
12641 break;
12642 }
12643
12644 default:
12645 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12646 }
12647 }
12648
12649 return *ptr;
12650 }
12651
12665 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
12666 {
12667 for (const auto& reference_token : reference_tokens)
12668 {
12669 switch (ptr->type())
12670 {
12671 case detail::value_t::object:
12672 {
12673 // use unchecked object access
12674 ptr = &ptr->operator[](reference_token);
12675 break;
12676 }
12677
12678 case detail::value_t::array:
12679 {
12680 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12681 {
12682 // "-" cannot be used for const access
12683 JSON_THROW(detail::out_of_range::create(402, "array index '-' (" + std::to_string(ptr->m_value.array->size()) + ") is out of range", *ptr));
12684 }
12685
12686 // use unchecked array access
12687 ptr = &ptr->operator[](array_index(reference_token));
12688 break;
12689 }
12690
12691 default:
12692 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12693 }
12694 }
12695
12696 return *ptr;
12697 }
12698
12705 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
12706 {
12707 for (const auto& reference_token : reference_tokens)
12708 {
12709 switch (ptr->type())
12710 {
12711 case detail::value_t::object:
12712 {
12713 // note: at performs range check
12714 ptr = &ptr->at(reference_token);
12715 break;
12716 }
12717
12718 case detail::value_t::array:
12719 {
12720 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12721 {
12722 // "-" always fails the range check
12723 JSON_THROW(detail::out_of_range::create(402,
12724 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12725 ") is out of range", *ptr));
12726 }
12727
12728 // note: at performs range check
12729 ptr = &ptr->at(array_index(reference_token));
12730 break;
12731 }
12732
12733 default:
12734 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12735 }
12736 }
12737
12738 return *ptr;
12739 }
12740
12745 bool contains(const BasicJsonType* ptr) const
12746 {
12747 for (const auto& reference_token : reference_tokens)
12748 {
12749 switch (ptr->type())
12750 {
12751 case detail::value_t::object:
12752 {
12753 if (!ptr->contains(reference_token))
12754 {
12755 // we did not find the key in the object
12756 return false;
12757 }
12758
12759 ptr = &ptr->operator[](reference_token);
12760 break;
12761 }
12762
12763 case detail::value_t::array:
12764 {
12765 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12766 {
12767 // "-" always fails the range check
12768 return false;
12769 }
12770 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
12771 {
12772 // invalid char
12773 return false;
12774 }
12775 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
12776 {
12777 if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
12778 {
12779 // first char should be between '1' and '9'
12780 return false;
12781 }
12782 for (std::size_t i = 1; i < reference_token.size(); i++)
12783 {
12784 if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
12785 {
12786 // other char should be between '0' and '9'
12787 return false;
12788 }
12789 }
12790 }
12791
12792 const auto idx = array_index(reference_token);
12793 if (idx >= ptr->size())
12794 {
12795 // index out of range
12796 return false;
12797 }
12798
12799 ptr = &ptr->operator[](idx);
12800 break;
12801 }
12802
12803 default:
12804 {
12805 // we do not expect primitive values if there is still a
12806 // reference token to process
12807 return false;
12808 }
12809 }
12810 }
12811
12812 // no reference token left means we found a primitive value
12813 return true;
12814 }
12815
12825 static std::vector<std::string> split(const std::string& reference_string)
12826 {
12827 std::vector<std::string> result;
12828
12829 // special case: empty reference string -> no reference tokens
12830 if (reference_string.empty())
12831 {
12832 return result;
12833 }
12834
12835 // check if nonempty reference string begins with slash
12836 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
12837 {
12838 JSON_THROW(detail::parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'", BasicJsonType()));
12839 }
12840
12841 // extract the reference tokens:
12842 // - slash: position of the last read slash (or end of string)
12843 // - start: position after the previous slash
12844 for (
12845 // search for the first slash after the first character
12846 std::size_t slash = reference_string.find_first_of('/', 1),
12847 // set the beginning of the first reference token
12848 start = 1;
12849 // we can stop if start == 0 (if slash == std::string::npos)
12850 start != 0;
12851 // set the beginning of the next reference token
12852 // (will eventually be 0 if slash == std::string::npos)
12853 start = (slash == std::string::npos) ? 0 : slash + 1,
12854 // find next slash
12855 slash = reference_string.find_first_of('/', start))
12856 {
12857 // use the text between the beginning of the reference token
12858 // (start) and the last slash (slash).
12859 auto reference_token = reference_string.substr(start, slash - start);
12860
12861 // check reference tokens are properly escaped
12862 for (std::size_t pos = reference_token.find_first_of('~');
12863 pos != std::string::npos;
12864 pos = reference_token.find_first_of('~', pos + 1))
12865 {
12866 JSON_ASSERT(reference_token[pos] == '~');
12867
12868 // ~ must be followed by 0 or 1
12869 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
12870 (reference_token[pos + 1] != '0' &&
12871 reference_token[pos + 1] != '1')))
12872 {
12873 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", BasicJsonType()));
12874 }
12875 }
12876
12877 // finally, store the reference token
12878 detail::unescape(reference_token);
12879 result.push_back(reference_token);
12880 }
12881
12882 return result;
12883 }
12884
12885 private:
12893 static void flatten(const std::string& reference_string,
12894 const BasicJsonType& value,
12895 BasicJsonType& result)
12896 {
12897 switch (value.type())
12898 {
12899 case detail::value_t::array:
12900 {
12901 if (value.m_value.array->empty())
12902 {
12903 // flatten empty array as null
12904 result[reference_string] = nullptr;
12905 }
12906 else
12907 {
12908 // iterate array and use index as reference string
12909 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
12910 {
12911 flatten(reference_string + "/" + std::to_string(i),
12912 value.m_value.array->operator[](i), result);
12913 }
12914 }
12915 break;
12916 }
12917
12918 case detail::value_t::object:
12919 {
12920 if (value.m_value.object->empty())
12921 {
12922 // flatten empty object as null
12923 result[reference_string] = nullptr;
12924 }
12925 else
12926 {
12927 // iterate object and use keys as reference string
12928 for (const auto& element : *value.m_value.object)
12929 {
12930 flatten(reference_string + "/" + detail::escape(element.first), element.second, result);
12931 }
12932 }
12933 break;
12934 }
12935
12936 default:
12937 {
12938 // add primitive value with its reference string
12939 result[reference_string] = value;
12940 break;
12941 }
12942 }
12943 }
12944
12955 static BasicJsonType
12956 unflatten(const BasicJsonType& value)
12957 {
12958 if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
12959 {
12960 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", value));
12961 }
12962
12963 BasicJsonType result;
12964
12965 // iterate the JSON object values
12966 for (const auto& element : *value.m_value.object)
12967 {
12968 if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
12969 {
12970 JSON_THROW(detail::type_error::create(315, "values in object must be primitive", element.second));
12971 }
12972
12973 // assign value to reference pointed to by JSON pointer; Note that if
12974 // the JSON pointer is "" (i.e., points to the whole value), function
12975 // get_and_create returns a reference to result itself. An assignment
12976 // will then create a primitive value.
12977 json_pointer(element.first).get_and_create(result) = element.second;
12978 }
12979
12980 return result;
12981 }
12982
12994 friend bool operator==(json_pointer const& lhs,
12995 json_pointer const& rhs) noexcept
12996 {
12997 return lhs.reference_tokens == rhs.reference_tokens;
12998 }
12999
13011 friend bool operator!=(json_pointer const& lhs,
13012 json_pointer const& rhs) noexcept
13013 {
13014 return !(lhs == rhs);
13015 }
13016
13018 std::vector<std::string> reference_tokens;
13019 };
13020 } // namespace nlohmann
13021
13022 // #include <nlohmann/detail/json_ref.hpp>
13023
13024
13025 #include <initializer_list>
13026 #include <utility>
13027
13028 // #include <nlohmann/detail/meta/type_traits.hpp>
13029
13030
13031 namespace nlohmann
13032 {
13033 namespace detail
13034 {
13035 template<typename BasicJsonType>
13036 class json_ref
13037 {
13038 public:
13039 using value_type = BasicJsonType;
13040
13041 json_ref(value_type&& value)
13042 : owned_value(std::move(value))
13043 {}
13044
13045 json_ref(const value_type& value)
13046 : value_ref(&value)
13047 {}
13048
13049 json_ref(std::initializer_list<json_ref> init)
13050 : owned_value(init)
13051 {}
13052
13053 template <
13054 class... Args,
13055 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
13056 json_ref(Args && ... args)
13057 : owned_value(std::forward<Args>(args)...)
13058 {}
13059
13060 // class should be movable only
13061 json_ref(json_ref&&) noexcept = default;
13062 json_ref(const json_ref&) = delete;
13063 json_ref& operator=(const json_ref&) = delete;
13064 json_ref& operator=(json_ref&&) = delete;
13065 ~json_ref() = default;
13066
13067 value_type moved_or_copied() const
13068 {
13069 if (value_ref == nullptr)
13070 {
13071 return std::move(owned_value);
13072 }
13073 return *value_ref;
13074 }
13075
13076 value_type const& operator*() const
13077 {
13078 return value_ref ? *value_ref : owned_value;
13079 }
13080
13081 value_type const* operator->() const
13082 {
13083 return &** this;
13084 }
13085
13086 private:
13087 mutable value_type owned_value = nullptr;
13088 value_type const* value_ref = nullptr;
13089 };
13090 } // namespace detail
13091 } // namespace nlohmann
13092
13093 // #include <nlohmann/detail/macro_scope.hpp>
13094
13095 // #include <nlohmann/detail/string_escape.hpp>
13096
13097 // #include <nlohmann/detail/meta/cpp_future.hpp>
13098
13099 // #include <nlohmann/detail/meta/type_traits.hpp>
13100
13101 // #include <nlohmann/detail/output/binary_writer.hpp>
13102
13103
13104 #include <algorithm> // reverse
13105 #include <array> // array
13106 #include <cmath> // isnan, isinf
13107 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
13108 #include <cstring> // memcpy
13109 #include <limits> // numeric_limits
13110 #include <string> // string
13111 #include <utility> // move
13112
13113 // #include <nlohmann/detail/input/binary_reader.hpp>
13114
13115 // #include <nlohmann/detail/macro_scope.hpp>
13116
13117 // #include <nlohmann/detail/output/output_adapters.hpp>
13118
13119
13120 #include <algorithm> // copy
13121 #include <cstddef> // size_t
13122 #include <ios> // streamsize
13123 #include <iterator> // back_inserter
13124 #include <memory> // shared_ptr, make_shared
13125 #include <ostream> // basic_ostream
13126 #include <string> // basic_string
13127 #include <vector> // vector
13128 // #include <nlohmann/detail/macro_scope.hpp>
13129
13130
13131 namespace nlohmann
13132 {
13133 namespace detail
13134 {
13136 template<typename CharType> struct output_adapter_protocol
13137 {
13138 virtual void write_character(CharType c) = 0;
13139 virtual void write_characters(const CharType* s, std::size_t length) = 0;
13140 virtual ~output_adapter_protocol() = default;
13141
13142 output_adapter_protocol() = default;
13143 output_adapter_protocol(const output_adapter_protocol&) = default;
13144 output_adapter_protocol(output_adapter_protocol&&) noexcept = default;
13145 output_adapter_protocol& operator=(const output_adapter_protocol&) = default;
13146 output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
13147 };
13148
13150 template<typename CharType>
13151 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
13152
13154 template<typename CharType>
13155 class output_vector_adapter : public output_adapter_protocol<CharType>
13156 {
13157 public:
13158 explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
13159 : v(vec)
13160 {}
13161
13162 void write_character(CharType c) override
13163 {
13164 v.push_back(c);
13165 }
13166
13167 JSON_HEDLEY_NON_NULL(2)
13168 void write_characters(const CharType* s, std::size_t length) override
13169 {
13170 std::copy(s, s + length, std::back_inserter(v));
13171 }
13172
13173 private:
13174 std::vector<CharType>& v;
13175 };
13176
13178 template<typename CharType>
13179 class output_stream_adapter : public output_adapter_protocol<CharType>
13180 {
13181 public:
13182 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
13183 : stream(s)
13184 {}
13185
13186 void write_character(CharType c) override
13187 {
13188 stream.put(c);
13189 }
13190
13191 JSON_HEDLEY_NON_NULL(2)
13192 void write_characters(const CharType* s, std::size_t length) override
13193 {
13194 stream.write(s, static_cast<std::streamsize>(length));
13195 }
13196
13197 private:
13198 std::basic_ostream<CharType>& stream;
13199 };
13200
13202 template<typename CharType, typename StringType = std::basic_string<CharType>>
13203 class output_string_adapter : public output_adapter_protocol<CharType>
13204 {
13205 public:
13206 explicit output_string_adapter(StringType& s) noexcept
13207 : str(s)
13208 {}
13209
13210 void write_character(CharType c) override
13211 {
13212 str.push_back(c);
13213 }
13214
13215 JSON_HEDLEY_NON_NULL(2)
13216 void write_characters(const CharType* s, std::size_t length) override
13217 {
13218 str.append(s, length);
13219 }
13220
13221 private:
13222 StringType& str;
13223 };
13224
13225 template<typename CharType, typename StringType = std::basic_string<CharType>>
13226 class output_adapter
13227 {
13228 public:
13229 output_adapter(std::vector<CharType>& vec)
13230 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
13231
13232 output_adapter(std::basic_ostream<CharType>& s)
13233 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
13234
13235 output_adapter(StringType& s)
13236 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
13237
13238 operator output_adapter_t<CharType>()
13239 {
13240 return oa;
13241 }
13242
13243 private:
13244 output_adapter_t<CharType> oa = nullptr;
13245 };
13246 } // namespace detail
13247 } // namespace nlohmann
13248
13249
13250 namespace nlohmann
13251 {
13252 namespace detail
13253 {
13255 // binary writer //
13257
13261 template<typename BasicJsonType, typename CharType>
13262 class binary_writer
13263 {
13264 using string_t = typename BasicJsonType::string_t;
13265 using binary_t = typename BasicJsonType::binary_t;
13266 using number_float_t = typename BasicJsonType::number_float_t;
13267
13268 public:
13274 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
13275 {
13276 JSON_ASSERT(oa);
13277 }
13278
13283 void write_bson(const BasicJsonType& j)
13284 {
13285 switch (j.type())
13286 {
13287 case value_t::object:
13288 {
13289 write_bson_object(*j.m_value.object);
13290 break;
13291 }
13292
13293 default:
13294 {
13295 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));;
13296 }
13297 }
13298 }
13299
13303 void write_cbor(const BasicJsonType& j)
13304 {
13305 switch (j.type())
13306 {
13307 case value_t::null:
13308 {
13309 oa->write_character(to_char_type(0xF6));
13310 break;
13311 }
13312
13313 case value_t::boolean:
13314 {
13315 oa->write_character(j.m_value.boolean
13316 ? to_char_type(0xF5)
13317 : to_char_type(0xF4));
13318 break;
13319 }
13320
13321 case value_t::number_integer:
13322 {
13323 if (j.m_value.number_integer >= 0)
13324 {
13325 // CBOR does not differentiate between positive signed
13326 // integers and unsigned integers. Therefore, we used the
13327 // code from the value_t::number_unsigned case here.
13328 if (j.m_value.number_integer <= 0x17)
13329 {
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::uint8_t>::max)())
13333 {
13334 oa->write_character(to_char_type(0x18));
13335 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13336 }
13337 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
13338 {
13339 oa->write_character(to_char_type(0x19));
13340 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13341 }
13342 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
13343 {
13344 oa->write_character(to_char_type(0x1A));
13345 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13346 }
13347 else
13348 {
13349 oa->write_character(to_char_type(0x1B));
13350 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13351 }
13352 }
13353 else
13354 {
13355 // The conversions below encode the sign in the first
13356 // byte, and the value is converted to a positive number.
13357 const auto positive_number = -1 - j.m_value.number_integer;
13358 if (j.m_value.number_integer >= -24)
13359 {
13360 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
13361 }
13362 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
13363 {
13364 oa->write_character(to_char_type(0x38));
13365 write_number(static_cast<std::uint8_t>(positive_number));
13366 }
13367 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
13368 {
13369 oa->write_character(to_char_type(0x39));
13370 write_number(static_cast<std::uint16_t>(positive_number));
13371 }
13372 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
13373 {
13374 oa->write_character(to_char_type(0x3A));
13375 write_number(static_cast<std::uint32_t>(positive_number));
13376 }
13377 else
13378 {
13379 oa->write_character(to_char_type(0x3B));
13380 write_number(static_cast<std::uint64_t>(positive_number));
13381 }
13382 }
13383 break;
13384 }
13385
13386 case value_t::number_unsigned:
13387 {
13388 if (j.m_value.number_unsigned <= 0x17)
13389 {
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::uint8_t>::max)())
13393 {
13394 oa->write_character(to_char_type(0x18));
13395 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13396 }
13397 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13398 {
13399 oa->write_character(to_char_type(0x19));
13400 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
13401 }
13402 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13403 {
13404 oa->write_character(to_char_type(0x1A));
13405 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
13406 }
13407 else
13408 {
13409 oa->write_character(to_char_type(0x1B));
13410 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
13411 }
13412 break;
13413 }
13414
13415 case value_t::number_float:
13416 {
13417 if (std::isnan(j.m_value.number_float))
13418 {
13419 // NaN is 0xf97e00 in CBOR
13420 oa->write_character(to_char_type(0xF9));
13421 oa->write_character(to_char_type(0x7E));
13422 oa->write_character(to_char_type(0x00));
13423 }
13424 else if (std::isinf(j.m_value.number_float))
13425 {
13426 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
13427 oa->write_character(to_char_type(0xf9));
13428 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
13429 oa->write_character(to_char_type(0x00));
13430 }
13431 else
13432 {
13433 write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
13434 }
13435 break;
13436 }
13437
13438 case value_t::string:
13439 {
13440 // step 1: write control byte and the string length
13441 const auto N = j.m_value.string->size();
13442 if (N <= 0x17)
13443 {
13444 write_number(static_cast<std::uint8_t>(0x60 + N));
13445 }
13446 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13447 {
13448 oa->write_character(to_char_type(0x78));
13449 write_number(static_cast<std::uint8_t>(N));
13450 }
13451 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13452 {
13453 oa->write_character(to_char_type(0x79));
13454 write_number(static_cast<std::uint16_t>(N));
13455 }
13456 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13457 {
13458 oa->write_character(to_char_type(0x7A));
13459 write_number(static_cast<std::uint32_t>(N));
13460 }
13461 // LCOV_EXCL_START
13462 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13463 {
13464 oa->write_character(to_char_type(0x7B));
13465 write_number(static_cast<std::uint64_t>(N));
13466 }
13467 // LCOV_EXCL_STOP
13468
13469 // step 2: write the string
13470 oa->write_characters(
13471 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13472 j.m_value.string->size());
13473 break;
13474 }
13475
13476 case value_t::array:
13477 {
13478 // step 1: write control byte and the array size
13479 const auto N = j.m_value.array->size();
13480 if (N <= 0x17)
13481 {
13482 write_number(static_cast<std::uint8_t>(0x80 + N));
13483 }
13484 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13485 {
13486 oa->write_character(to_char_type(0x98));
13487 write_number(static_cast<std::uint8_t>(N));
13488 }
13489 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13490 {
13491 oa->write_character(to_char_type(0x99));
13492 write_number(static_cast<std::uint16_t>(N));
13493 }
13494 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13495 {
13496 oa->write_character(to_char_type(0x9A));
13497 write_number(static_cast<std::uint32_t>(N));
13498 }
13499 // LCOV_EXCL_START
13500 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13501 {
13502 oa->write_character(to_char_type(0x9B));
13503 write_number(static_cast<std::uint64_t>(N));
13504 }
13505 // LCOV_EXCL_STOP
13506
13507 // step 2: write each element
13508 for (const auto& el : *j.m_value.array)
13509 {
13510 write_cbor(el);
13511 }
13512 break;
13513 }
13514
13515 case value_t::binary:
13516 {
13517 if (j.m_value.binary->has_subtype())
13518 {
13519 write_number(static_cast<std::uint8_t>(0xd8));
13520 write_number(j.m_value.binary->subtype());
13521 }
13522
13523 // step 1: write control byte and the binary array size
13524 const auto N = j.m_value.binary->size();
13525 if (N <= 0x17)
13526 {
13527 write_number(static_cast<std::uint8_t>(0x40 + N));
13528 }
13529 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13530 {
13531 oa->write_character(to_char_type(0x58));
13532 write_number(static_cast<std::uint8_t>(N));
13533 }
13534 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13535 {
13536 oa->write_character(to_char_type(0x59));
13537 write_number(static_cast<std::uint16_t>(N));
13538 }
13539 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13540 {
13541 oa->write_character(to_char_type(0x5A));
13542 write_number(static_cast<std::uint32_t>(N));
13543 }
13544 // LCOV_EXCL_START
13545 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13546 {
13547 oa->write_character(to_char_type(0x5B));
13548 write_number(static_cast<std::uint64_t>(N));
13549 }
13550 // LCOV_EXCL_STOP
13551
13552 // step 2: write each element
13553 oa->write_characters(
13554 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13555 N);
13556
13557 break;
13558 }
13559
13560 case value_t::object:
13561 {
13562 // step 1: write control byte and the object size
13563 const auto N = j.m_value.object->size();
13564 if (N <= 0x17)
13565 {
13566 write_number(static_cast<std::uint8_t>(0xA0 + N));
13567 }
13568 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13569 {
13570 oa->write_character(to_char_type(0xB8));
13571 write_number(static_cast<std::uint8_t>(N));
13572 }
13573 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13574 {
13575 oa->write_character(to_char_type(0xB9));
13576 write_number(static_cast<std::uint16_t>(N));
13577 }
13578 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13579 {
13580 oa->write_character(to_char_type(0xBA));
13581 write_number(static_cast<std::uint32_t>(N));
13582 }
13583 // LCOV_EXCL_START
13584 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13585 {
13586 oa->write_character(to_char_type(0xBB));
13587 write_number(static_cast<std::uint64_t>(N));
13588 }
13589 // LCOV_EXCL_STOP
13590
13591 // step 2: write each element
13592 for (const auto& el : *j.m_value.object)
13593 {
13594 write_cbor(el.first);
13595 write_cbor(el.second);
13596 }
13597 break;
13598 }
13599
13600 default:
13601 break;
13602 }
13603 }
13604
13608 void write_msgpack(const BasicJsonType& j)
13609 {
13610 switch (j.type())
13611 {
13612 case value_t::null: // nil
13613 {
13614 oa->write_character(to_char_type(0xC0));
13615 break;
13616 }
13617
13618 case value_t::boolean: // true and false
13619 {
13620 oa->write_character(j.m_value.boolean
13621 ? to_char_type(0xC3)
13622 : to_char_type(0xC2));
13623 break;
13624 }
13625
13626 case value_t::number_integer:
13627 {
13628 if (j.m_value.number_integer >= 0)
13629 {
13630 // MessagePack does not differentiate between positive
13631 // signed integers and unsigned integers. Therefore, we used
13632 // the code from the value_t::number_unsigned case here.
13633 if (j.m_value.number_unsigned < 128)
13634 {
13635 // positive fixnum
13636 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13637 }
13638 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13639 {
13640 // uint 8
13641 oa->write_character(to_char_type(0xCC));
13642 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13643 }
13644 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13645 {
13646 // uint 16
13647 oa->write_character(to_char_type(0xCD));
13648 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13649 }
13650 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13651 {
13652 // uint 32
13653 oa->write_character(to_char_type(0xCE));
13654 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13655 }
13656 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
13657 {
13658 // uint 64
13659 oa->write_character(to_char_type(0xCF));
13660 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13661 }
13662 }
13663 else
13664 {
13665 if (j.m_value.number_integer >= -32)
13666 {
13667 // negative fixnum
13668 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
13669 }
13670 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
13671 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
13672 {
13673 // int 8
13674 oa->write_character(to_char_type(0xD0));
13675 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
13676 }
13677 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
13678 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
13679 {
13680 // int 16
13681 oa->write_character(to_char_type(0xD1));
13682 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
13683 }
13684 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
13685 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
13686 {
13687 // int 32
13688 oa->write_character(to_char_type(0xD2));
13689 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
13690 }
13691 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
13692 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
13693 {
13694 // int 64
13695 oa->write_character(to_char_type(0xD3));
13696 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
13697 }
13698 }
13699 break;
13700 }
13701
13702 case value_t::number_unsigned:
13703 {
13704 if (j.m_value.number_unsigned < 128)
13705 {
13706 // positive fixnum
13707 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13708 }
13709 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13710 {
13711 // uint 8
13712 oa->write_character(to_char_type(0xCC));
13713 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13714 }
13715 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13716 {
13717 // uint 16
13718 oa->write_character(to_char_type(0xCD));
13719 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13720 }
13721 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13722 {
13723 // uint 32
13724 oa->write_character(to_char_type(0xCE));
13725 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13726 }
13727 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
13728 {
13729 // uint 64
13730 oa->write_character(to_char_type(0xCF));
13731 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13732 }
13733 break;
13734 }
13735
13736 case value_t::number_float:
13737 {
13738 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
13739 break;
13740 }
13741
13742 case value_t::string:
13743 {
13744 // step 1: write control byte and the string length
13745 const auto N = j.m_value.string->size();
13746 if (N <= 31)
13747 {
13748 // fixstr
13749 write_number(static_cast<std::uint8_t>(0xA0 | N));
13750 }
13751 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13752 {
13753 // str 8
13754 oa->write_character(to_char_type(0xD9));
13755 write_number(static_cast<std::uint8_t>(N));
13756 }
13757 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13758 {
13759 // str 16
13760 oa->write_character(to_char_type(0xDA));
13761 write_number(static_cast<std::uint16_t>(N));
13762 }
13763 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13764 {
13765 // str 32
13766 oa->write_character(to_char_type(0xDB));
13767 write_number(static_cast<std::uint32_t>(N));
13768 }
13769
13770 // step 2: write the string
13771 oa->write_characters(
13772 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13773 j.m_value.string->size());
13774 break;
13775 }
13776
13777 case value_t::array:
13778 {
13779 // step 1: write control byte and the array size
13780 const auto N = j.m_value.array->size();
13781 if (N <= 15)
13782 {
13783 // fixarray
13784 write_number(static_cast<std::uint8_t>(0x90 | N));
13785 }
13786 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13787 {
13788 // array 16
13789 oa->write_character(to_char_type(0xDC));
13790 write_number(static_cast<std::uint16_t>(N));
13791 }
13792 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13793 {
13794 // array 32
13795 oa->write_character(to_char_type(0xDD));
13796 write_number(static_cast<std::uint32_t>(N));
13797 }
13798
13799 // step 2: write each element
13800 for (const auto& el : *j.m_value.array)
13801 {
13802 write_msgpack(el);
13803 }
13804 break;
13805 }
13806
13807 case value_t::binary:
13808 {
13809 // step 0: determine if the binary type has a set subtype to
13810 // determine whether or not to use the ext or fixext types
13811 const bool use_ext = j.m_value.binary->has_subtype();
13812
13813 // step 1: write control byte and the byte string length
13814 const auto N = j.m_value.binary->size();
13815 if (N <= (std::numeric_limits<std::uint8_t>::max)())
13816 {
13817 std::uint8_t output_type{};
13818 bool fixed = true;
13819 if (use_ext)
13820 {
13821 switch (N)
13822 {
13823 case 1:
13824 output_type = 0xD4; // fixext 1
13825 break;
13826 case 2:
13827 output_type = 0xD5; // fixext 2
13828 break;
13829 case 4:
13830 output_type = 0xD6; // fixext 4
13831 break;
13832 case 8:
13833 output_type = 0xD7; // fixext 8
13834 break;
13835 case 16:
13836 output_type = 0xD8; // fixext 16
13837 break;
13838 default:
13839 output_type = 0xC7; // ext 8
13840 fixed = false;
13841 break;
13842 }
13843
13844 }
13845 else
13846 {
13847 output_type = 0xC4; // bin 8
13848 fixed = false;
13849 }
13850
13851 oa->write_character(to_char_type(output_type));
13852 if (!fixed)
13853 {
13854 write_number(static_cast<std::uint8_t>(N));
13855 }
13856 }
13857 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13858 {
13859 std::uint8_t output_type = use_ext
13860 ? 0xC8 // ext 16
13861 : 0xC5; // bin 16
13862
13863 oa->write_character(to_char_type(output_type));
13864 write_number(static_cast<std::uint16_t>(N));
13865 }
13866 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13867 {
13868 std::uint8_t output_type = use_ext
13869 ? 0xC9 // ext 32
13870 : 0xC6; // bin 32
13871
13872 oa->write_character(to_char_type(output_type));
13873 write_number(static_cast<std::uint32_t>(N));
13874 }
13875
13876 // step 1.5: if this is an ext type, write the subtype
13877 if (use_ext)
13878 {
13879 write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
13880 }
13881
13882 // step 2: write the byte string
13883 oa->write_characters(
13884 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13885 N);
13886
13887 break;
13888 }
13889
13890 case value_t::object:
13891 {
13892 // step 1: write control byte and the object size
13893 const auto N = j.m_value.object->size();
13894 if (N <= 15)
13895 {
13896 // fixmap
13897 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
13898 }
13899 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13900 {
13901 // map 16
13902 oa->write_character(to_char_type(0xDE));
13903 write_number(static_cast<std::uint16_t>(N));
13904 }
13905 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13906 {
13907 // map 32
13908 oa->write_character(to_char_type(0xDF));
13909 write_number(static_cast<std::uint32_t>(N));
13910 }
13911
13912 // step 2: write each element
13913 for (const auto& el : *j.m_value.object)
13914 {
13915 write_msgpack(el.first);
13916 write_msgpack(el.second);
13917 }
13918 break;
13919 }
13920
13921 default:
13922 break;
13923 }
13924 }
13925
13932 void write_ubjson(const BasicJsonType& j, const bool use_count,
13933 const bool use_type, const bool add_prefix = true)
13934 {
13935 switch (j.type())
13936 {
13937 case value_t::null:
13938 {
13939 if (add_prefix)
13940 {
13941 oa->write_character(to_char_type('Z'));
13942 }
13943 break;
13944 }
13945
13946 case value_t::boolean:
13947 {
13948 if (add_prefix)
13949 {
13950 oa->write_character(j.m_value.boolean
13951 ? to_char_type('T')
13952 : to_char_type('F'));
13953 }
13954 break;
13955 }
13956
13957 case value_t::number_integer:
13958 {
13959 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
13960 break;
13961 }
13962
13963 case value_t::number_unsigned:
13964 {
13965 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
13966 break;
13967 }
13968
13969 case value_t::number_float:
13970 {
13971 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
13972 break;
13973 }
13974
13975 case value_t::string:
13976 {
13977 if (add_prefix)
13978 {
13979 oa->write_character(to_char_type('S'));
13980 }
13981 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
13982 oa->write_characters(
13983 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13984 j.m_value.string->size());
13985 break;
13986 }
13987
13988 case value_t::array:
13989 {
13990 if (add_prefix)
13991 {
13992 oa->write_character(to_char_type('['));
13993 }
13994
13995 bool prefix_required = true;
13996 if (use_type && !j.m_value.array->empty())
13997 {
13998 JSON_ASSERT(use_count);
13999 const CharType first_prefix = ubjson_prefix(j.front());
14000 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
14001 [this, first_prefix](const BasicJsonType & v)
14002 {
14003 return ubjson_prefix(v) == first_prefix;
14004 });
14005
14006 if (same_prefix)
14007 {
14008 prefix_required = false;
14009 oa->write_character(to_char_type('$'));
14010 oa->write_character(first_prefix);
14011 }
14012 }
14013
14014 if (use_count)
14015 {
14016 oa->write_character(to_char_type('#'));
14017 write_number_with_ubjson_prefix(j.m_value.array->size(), true);
14018 }
14019
14020 for (const auto& el : *j.m_value.array)
14021 {
14022 write_ubjson(el, use_count, use_type, prefix_required);
14023 }
14024
14025 if (!use_count)
14026 {
14027 oa->write_character(to_char_type(']'));
14028 }
14029
14030 break;
14031 }
14032
14033 case value_t::binary:
14034 {
14035 if (add_prefix)
14036 {
14037 oa->write_character(to_char_type('['));
14038 }
14039
14040 if (use_type && !j.m_value.binary->empty())
14041 {
14042 JSON_ASSERT(use_count);
14043 oa->write_character(to_char_type('$'));
14044 oa->write_character('U');
14045 }
14046
14047 if (use_count)
14048 {
14049 oa->write_character(to_char_type('#'));
14050 write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
14051 }
14052
14053 if (use_type)
14054 {
14055 oa->write_characters(
14056 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14057 j.m_value.binary->size());
14058 }
14059 else
14060 {
14061 for (size_t i = 0; i < j.m_value.binary->size(); ++i)
14062 {
14063 oa->write_character(to_char_type('U'));
14064 oa->write_character(j.m_value.binary->data()[i]);
14065 }
14066 }
14067
14068 if (!use_count)
14069 {
14070 oa->write_character(to_char_type(']'));
14071 }
14072
14073 break;
14074 }
14075
14076 case value_t::object:
14077 {
14078 if (add_prefix)
14079 {
14080 oa->write_character(to_char_type('{'));
14081 }
14082
14083 bool prefix_required = true;
14084 if (use_type && !j.m_value.object->empty())
14085 {
14086 JSON_ASSERT(use_count);
14087 const CharType first_prefix = ubjson_prefix(j.front());
14088 const bool same_prefix = std::all_of(j.begin(), j.end(),
14089 [this, first_prefix](const BasicJsonType & v)
14090 {
14091 return ubjson_prefix(v) == first_prefix;
14092 });
14093
14094 if (same_prefix)
14095 {
14096 prefix_required = false;
14097 oa->write_character(to_char_type('$'));
14098 oa->write_character(first_prefix);
14099 }
14100 }
14101
14102 if (use_count)
14103 {
14104 oa->write_character(to_char_type('#'));
14105 write_number_with_ubjson_prefix(j.m_value.object->size(), true);
14106 }
14107
14108 for (const auto& el : *j.m_value.object)
14109 {
14110 write_number_with_ubjson_prefix(el.first.size(), true);
14111 oa->write_characters(
14112 reinterpret_cast<const CharType*>(el.first.c_str()),
14113 el.first.size());
14114 write_ubjson(el.second, use_count, use_type, prefix_required);
14115 }
14116
14117 if (!use_count)
14118 {
14119 oa->write_character(to_char_type('}'));
14120 }
14121
14122 break;
14123 }
14124
14125 default:
14126 break;
14127 }
14128 }
14129
14130 private:
14132 // BSON //
14134
14139 static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
14140 {
14141 const auto it = name.find(static_cast<typename string_t::value_type>(0));
14142 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
14143 {
14144 JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j));
14145 }
14146
14147 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
14148 }
14149
14153 void write_bson_entry_header(const string_t& name,
14154 const std::uint8_t element_type)
14155 {
14156 oa->write_character(to_char_type(element_type)); // boolean
14157 oa->write_characters(
14158 reinterpret_cast<const CharType*>(name.c_str()),
14159 name.size() + 1u);
14160 }
14161
14165 void write_bson_boolean(const string_t& name,
14166 const bool value)
14167 {
14168 write_bson_entry_header(name, 0x08);
14169 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
14170 }
14171
14175 void write_bson_double(const string_t& name,
14176 const double value)
14177 {
14178 write_bson_entry_header(name, 0x01);
14179 write_number<double, true>(value);
14180 }
14181
14185 static std::size_t calc_bson_string_size(const string_t& value)
14186 {
14187 return sizeof(std::int32_t) + value.size() + 1ul;
14188 }
14189
14193 void write_bson_string(const string_t& name,
14194 const string_t& value)
14195 {
14196 write_bson_entry_header(name, 0x02);
14197
14198 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
14199 oa->write_characters(
14200 reinterpret_cast<const CharType*>(value.c_str()),
14201 value.size() + 1);
14202 }
14203
14207 void write_bson_null(const string_t& name)
14208 {
14209 write_bson_entry_header(name, 0x0A);
14210 }
14211
14215 static std::size_t calc_bson_integer_size(const std::int64_t value)
14216 {
14217 return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
14218 ? sizeof(std::int32_t)
14219 : sizeof(std::int64_t);
14220 }
14221
14225 void write_bson_integer(const string_t& name,
14226 const std::int64_t value)
14227 {
14228 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
14229 {
14230 write_bson_entry_header(name, 0x10); // int32
14231 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
14232 }
14233 else
14234 {
14235 write_bson_entry_header(name, 0x12); // int64
14236 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
14237 }
14238 }
14239
14243 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
14244 {
14245 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14246 ? sizeof(std::int32_t)
14247 : sizeof(std::int64_t);
14248 }
14249
14253 void write_bson_unsigned(const string_t& name,
14254 const BasicJsonType& j)
14255 {
14256 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14257 {
14258 write_bson_entry_header(name, 0x10 /* int32 */);
14259 write_number<std::int32_t, true>(static_cast<std::int32_t>(j.m_value.number_unsigned));
14260 }
14261 else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14262 {
14263 write_bson_entry_header(name, 0x12 /* int64 */);
14264 write_number<std::int64_t, true>(static_cast<std::int64_t>(j.m_value.number_unsigned));
14265 }
14266 else
14267 {
14268 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));
14269 }
14270 }
14271
14275 void write_bson_object_entry(const string_t& name,
14276 const typename BasicJsonType::object_t& value)
14277 {
14278 write_bson_entry_header(name, 0x03); // object
14279 write_bson_object(value);
14280 }
14281
14285 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
14286 {
14287 std::size_t array_index = 0ul;
14288
14289 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)
14290 {
14291 return result + calc_bson_element_size(std::to_string(array_index++), el);
14292 });
14293
14294 return sizeof(std::int32_t) + embedded_document_size + 1ul;
14295 }
14296
14300 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
14301 {
14302 return sizeof(std::int32_t) + value.size() + 1ul;
14303 }
14304
14308 void write_bson_array(const string_t& name,
14309 const typename BasicJsonType::array_t& value)
14310 {
14311 write_bson_entry_header(name, 0x04); // array
14312 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
14313
14314 std::size_t array_index = 0ul;
14315
14316 for (const auto& el : value)
14317 {
14318 write_bson_element(std::to_string(array_index++), el);
14319 }
14320
14321 oa->write_character(to_char_type(0x00));
14322 }
14323
14327 void write_bson_binary(const string_t& name,
14328 const binary_t& value)
14329 {
14330 write_bson_entry_header(name, 0x05);
14331
14332 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
14333 write_number(value.has_subtype() ? value.subtype() : std::uint8_t(0x00));
14334
14335 oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
14336 }
14337
14342 static std::size_t calc_bson_element_size(const string_t& name,
14343 const BasicJsonType& j)
14344 {
14345 const auto header_size = calc_bson_entry_header_size(name, j);
14346 switch (j.type())
14347 {
14348 case value_t::object:
14349 return header_size + calc_bson_object_size(*j.m_value.object);
14350
14351 case value_t::array:
14352 return header_size + calc_bson_array_size(*j.m_value.array);
14353
14354 case value_t::binary:
14355 return header_size + calc_bson_binary_size(*j.m_value.binary);
14356
14357 case value_t::boolean:
14358 return header_size + 1ul;
14359
14360 case value_t::number_float:
14361 return header_size + 8ul;
14362
14363 case value_t::number_integer:
14364 return header_size + calc_bson_integer_size(j.m_value.number_integer);
14365
14366 case value_t::number_unsigned:
14367 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
14368
14369 case value_t::string:
14370 return header_size + calc_bson_string_size(*j.m_value.string);
14371
14372 case value_t::null:
14373 return header_size + 0ul;
14374
14375 // LCOV_EXCL_START
14376 default:
14377 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14378 return 0ul;
14379 // LCOV_EXCL_STOP
14380 }
14381 }
14382
14389 void write_bson_element(const string_t& name,
14390 const BasicJsonType& j)
14391 {
14392 switch (j.type())
14393 {
14394 case value_t::object:
14395 return write_bson_object_entry(name, *j.m_value.object);
14396
14397 case value_t::array:
14398 return write_bson_array(name, *j.m_value.array);
14399
14400 case value_t::binary:
14401 return write_bson_binary(name, *j.m_value.binary);
14402
14403 case value_t::boolean:
14404 return write_bson_boolean(name, j.m_value.boolean);
14405
14406 case value_t::number_float:
14407 return write_bson_double(name, j.m_value.number_float);
14408
14409 case value_t::number_integer:
14410 return write_bson_integer(name, j.m_value.number_integer);
14411
14412 case value_t::number_unsigned:
14413 return write_bson_unsigned(name, j);
14414
14415 case value_t::string:
14416 return write_bson_string(name, *j.m_value.string);
14417
14418 case value_t::null:
14419 return write_bson_null(name);
14420
14421 // LCOV_EXCL_START
14422 default:
14423 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14424 return;
14425 // LCOV_EXCL_STOP
14426 }
14427 }
14428
14435 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
14436 {
14437 std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
14438 [](size_t result, const typename BasicJsonType::object_t::value_type & el)
14439 {
14440 return result += calc_bson_element_size(el.first, el.second);
14441 });
14442
14443 return sizeof(std::int32_t) + document_size + 1ul;
14444 }
14445
14450 void write_bson_object(const typename BasicJsonType::object_t& value)
14451 {
14452 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
14453
14454 for (const auto& el : value)
14455 {
14456 write_bson_element(el.first, el.second);
14457 }
14458
14459 oa->write_character(to_char_type(0x00));
14460 }
14461
14463 // CBOR //
14465
14466 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
14467 {
14468 return to_char_type(0xFA); // Single-Precision Float
14469 }
14470
14471 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
14472 {
14473 return to_char_type(0xFB); // Double-Precision Float
14474 }
14475
14477 // MsgPack //
14479
14480 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
14481 {
14482 return to_char_type(0xCA); // float 32
14483 }
14484
14485 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
14486 {
14487 return to_char_type(0xCB); // float 64
14488 }
14489
14491 // UBJSON //
14493
14494 // UBJSON: write number (floating point)
14495 template<typename NumberType, typename std::enable_if<
14496 std::is_floating_point<NumberType>::value, int>::type = 0>
14497 void write_number_with_ubjson_prefix(const NumberType n,
14498 const bool add_prefix)
14499 {
14500 if (add_prefix)
14501 {
14502 oa->write_character(get_ubjson_float_prefix(n));
14503 }
14504 write_number(n);
14505 }
14506
14507 // UBJSON: write number (unsigned integer)
14508 template<typename NumberType, typename std::enable_if<
14509 std::is_unsigned<NumberType>::value, int>::type = 0>
14510 void write_number_with_ubjson_prefix(const NumberType n,
14511 const bool add_prefix)
14512 {
14513 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14514 {
14515 if (add_prefix)
14516 {
14517 oa->write_character(to_char_type('i')); // int8
14518 }
14519 write_number(static_cast<std::uint8_t>(n));
14520 }
14521 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
14522 {
14523 if (add_prefix)
14524 {
14525 oa->write_character(to_char_type('U')); // uint8
14526 }
14527 write_number(static_cast<std::uint8_t>(n));
14528 }
14529 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14530 {
14531 if (add_prefix)
14532 {
14533 oa->write_character(to_char_type('I')); // int16
14534 }
14535 write_number(static_cast<std::int16_t>(n));
14536 }
14537 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14538 {
14539 if (add_prefix)
14540 {
14541 oa->write_character(to_char_type('l')); // int32
14542 }
14543 write_number(static_cast<std::int32_t>(n));
14544 }
14545 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14546 {
14547 if (add_prefix)
14548 {
14549 oa->write_character(to_char_type('L')); // int64
14550 }
14551 write_number(static_cast<std::int64_t>(n));
14552 }
14553 else
14554 {
14555 if (add_prefix)
14556 {
14557 oa->write_character(to_char_type('H')); // high-precision number
14558 }
14559
14560 const auto number = BasicJsonType(n).dump();
14561 write_number_with_ubjson_prefix(number.size(), true);
14562 for (std::size_t i = 0; i < number.size(); ++i)
14563 {
14564 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14565 }
14566 }
14567 }
14568
14569 // UBJSON: write number (signed integer)
14570 template < typename NumberType, typename std::enable_if <
14571 std::is_signed<NumberType>::value&&
14572 !std::is_floating_point<NumberType>::value, int >::type = 0 >
14573 void write_number_with_ubjson_prefix(const NumberType n,
14574 const bool add_prefix)
14575 {
14576 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
14577 {
14578 if (add_prefix)
14579 {
14580 oa->write_character(to_char_type('i')); // int8
14581 }
14582 write_number(static_cast<std::int8_t>(n));
14583 }
14584 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)()))
14585 {
14586 if (add_prefix)
14587 {
14588 oa->write_character(to_char_type('U')); // uint8
14589 }
14590 write_number(static_cast<std::uint8_t>(n));
14591 }
14592 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
14593 {
14594 if (add_prefix)
14595 {
14596 oa->write_character(to_char_type('I')); // int16
14597 }
14598 write_number(static_cast<std::int16_t>(n));
14599 }
14600 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
14601 {
14602 if (add_prefix)
14603 {
14604 oa->write_character(to_char_type('l')); // int32
14605 }
14606 write_number(static_cast<std::int32_t>(n));
14607 }
14608 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
14609 {
14610 if (add_prefix)
14611 {
14612 oa->write_character(to_char_type('L')); // int64
14613 }
14614 write_number(static_cast<std::int64_t>(n));
14615 }
14616 // LCOV_EXCL_START
14617 else
14618 {
14619 if (add_prefix)
14620 {
14621 oa->write_character(to_char_type('H')); // high-precision number
14622 }
14623
14624 const auto number = BasicJsonType(n).dump();
14625 write_number_with_ubjson_prefix(number.size(), true);
14626 for (std::size_t i = 0; i < number.size(); ++i)
14627 {
14628 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14629 }
14630 }
14631 // LCOV_EXCL_STOP
14632 }
14633
14637 CharType ubjson_prefix(const BasicJsonType& j) const noexcept
14638 {
14639 switch (j.type())
14640 {
14641 case value_t::null:
14642 return 'Z';
14643
14644 case value_t::boolean:
14645 return j.m_value.boolean ? 'T' : 'F';
14646
14647 case value_t::number_integer:
14648 {
14649 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)())
14650 {
14651 return 'i';
14652 }
14653 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)())
14654 {
14655 return 'U';
14656 }
14657 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)())
14658 {
14659 return 'I';
14660 }
14661 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)())
14662 {
14663 return 'l';
14664 }
14665 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)())
14666 {
14667 return 'L';
14668 }
14669 // anything else is treated as high-precision number
14670 return 'H'; // LCOV_EXCL_LINE
14671 }
14672
14673 case value_t::number_unsigned:
14674 {
14675 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14676 {
14677 return 'i';
14678 }
14679 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
14680 {
14681 return 'U';
14682 }
14683 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14684 {
14685 return 'I';
14686 }
14687 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14688 {
14689 return 'l';
14690 }
14691 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14692 {
14693 return 'L';
14694 }
14695 // anything else is treated as high-precision number
14696 return 'H'; // LCOV_EXCL_LINE
14697 }
14698
14699 case value_t::number_float:
14700 return get_ubjson_float_prefix(j.m_value.number_float);
14701
14702 case value_t::string:
14703 return 'S';
14704
14705 case value_t::array: // fallthrough
14706 case value_t::binary:
14707 return '[';
14708
14709 case value_t::object:
14710 return '{';
14711
14712 default: // discarded values
14713 return 'N';
14714 }
14715 }
14716
14717 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
14718 {
14719 return 'd'; // float 32
14720 }
14721
14722 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
14723 {
14724 return 'D'; // float 64
14725 }
14726
14728 // Utility functions //
14730
14731 /*
14732 @brief write a number to output input
14733 @param[in] n number of type @a NumberType
14734 @tparam NumberType the type of the number
14735 @tparam OutputIsLittleEndian Set to true if output data is
14736 required to be little endian
14737
14738 @note This function needs to respect the system's endianess, because bytes
14739 in CBOR, MessagePack, and UBJSON are stored in network order (big
14740 endian) and therefore need reordering on little endian systems.
14741 */
14742 template<typename NumberType, bool OutputIsLittleEndian = false>
14743 void write_number(const NumberType n)
14744 {
14745 // step 1: write number to array of length NumberType
14746 std::array<CharType, sizeof(NumberType)> vec{};
14747 std::memcpy(vec.data(), &n, sizeof(NumberType));
14748
14749 // step 2: write array to output (with possible reordering)
14750 if (is_little_endian != OutputIsLittleEndian)
14751 {
14752 // reverse byte order prior to conversion if necessary
14753 std::reverse(vec.begin(), vec.end());
14754 }
14755
14756 oa->write_characters(vec.data(), sizeof(NumberType));
14757 }
14758
14759 void write_compact_float(const number_float_t n, detail::input_format_t format)
14760 {
14761 if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
14762 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
14763 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
14764 {
14765 oa->write_character(format == detail::input_format_t::cbor
14766 ? get_cbor_float_prefix(static_cast<float>(n))
14767 : get_msgpack_float_prefix(static_cast<float>(n)));
14768 write_number(static_cast<float>(n));
14769 }
14770 else
14771 {
14772 oa->write_character(format == detail::input_format_t::cbor
14773 ? get_cbor_float_prefix(n)
14774 : get_msgpack_float_prefix(n));
14775 write_number(n);
14776 }
14777 }
14778
14779 public:
14780 // The following to_char_type functions are implement the conversion
14781 // between uint8_t and CharType. In case CharType is not unsigned,
14782 // such a conversion is required to allow values greater than 128.
14783 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
14784 template < typename C = CharType,
14785 enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
14786 static constexpr CharType to_char_type(std::uint8_t x) noexcept
14787 {
14788 return *reinterpret_cast<char*>(&x);
14789 }
14790
14791 template < typename C = CharType,
14792 enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
14793 static CharType to_char_type(std::uint8_t x) noexcept
14794 {
14795 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
14796 static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
14797 CharType result;
14798 std::memcpy(&result, &x, sizeof(x));
14799 return result;
14800 }
14801
14802 template<typename C = CharType,
14803 enable_if_t<std::is_unsigned<C>::value>* = nullptr>
14804 static constexpr CharType to_char_type(std::uint8_t x) noexcept
14805 {
14806 return x;
14807 }
14808
14809 template < typename InputCharType, typename C = CharType,
14810 enable_if_t <
14811 std::is_signed<C>::value &&
14812 std::is_signed<char>::value &&
14813 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
14814 > * = nullptr >
14815 static constexpr CharType to_char_type(InputCharType x) noexcept
14816 {
14817 return x;
14818 }
14819
14820 private:
14822 const bool is_little_endian = little_endianess();
14823
14825 output_adapter_t<CharType> oa = nullptr;
14826 };
14827 } // namespace detail
14828 } // namespace nlohmann
14829
14830 // #include <nlohmann/detail/output/output_adapters.hpp>
14831
14832 // #include <nlohmann/detail/output/serializer.hpp>
14833
14834
14835 #include <algorithm> // reverse, remove, fill, find, none_of
14836 #include <array> // array
14837 #include <clocale> // localeconv, lconv
14838 #include <cmath> // labs, isfinite, isnan, signbit
14839 #include <cstddef> // size_t, ptrdiff_t
14840 #include <cstdint> // uint8_t
14841 #include <cstdio> // snprintf
14842 #include <limits> // numeric_limits
14843 #include <string> // string, char_traits
14844 #include <type_traits> // is_same
14845 #include <utility> // move
14846
14847 // #include <nlohmann/detail/conversions/to_chars.hpp>
14848
14849
14850 #include <array> // array
14851 #include <cmath> // signbit, isfinite
14852 #include <cstdint> // intN_t, uintN_t
14853 #include <cstring> // memcpy, memmove
14854 #include <limits> // numeric_limits
14855 #include <type_traits> // conditional
14856
14857 // #include <nlohmann/detail/macro_scope.hpp>
14858
14859
14860 namespace nlohmann
14861 {
14862 namespace detail
14863 {
14864
14884 namespace dtoa_impl
14885 {
14886
14887 template<typename Target, typename Source>
14888 Target reinterpret_bits(const Source source)
14889 {
14890 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
14891
14892 Target target;
14893 std::memcpy(&target, &source, sizeof(Source));
14894 return target;
14895 }
14896
14897 struct diyfp // f * 2^e
14898 {
14899 static constexpr int kPrecision = 64; // = q
14900
14901 std::uint64_t f = 0;
14902 int e = 0;
14903
14904 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
14905
14910 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
14911 {
14912 JSON_ASSERT(x.e == y.e);
14913 JSON_ASSERT(x.f >= y.f);
14914
14915 return {x.f - y.f, x.e};
14916 }
14917
14922 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
14923 {
14924 static_assert(kPrecision == 64, "internal error");
14925
14926 // Computes:
14927 // f = round((x.f * y.f) / 2^q)
14928 // e = x.e + y.e + q
14929
14930 // Emulate the 64-bit * 64-bit multiplication:
14931 //
14932 // p = u * v
14933 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
14934 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
14935 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
14936 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
14937 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
14938 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
14939 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
14940 //
14941 // (Since Q might be larger than 2^32 - 1)
14942 //
14943 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
14944 //
14945 // (Q_hi + H does not overflow a 64-bit int)
14946 //
14947 // = p_lo + 2^64 p_hi
14948
14949 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
14950 const std::uint64_t u_hi = x.f >> 32u;
14951 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
14952 const std::uint64_t v_hi = y.f >> 32u;
14953
14954 const std::uint64_t p0 = u_lo * v_lo;
14955 const std::uint64_t p1 = u_lo * v_hi;
14956 const std::uint64_t p2 = u_hi * v_lo;
14957 const std::uint64_t p3 = u_hi * v_hi;
14958
14959 const std::uint64_t p0_hi = p0 >> 32u;
14960 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
14961 const std::uint64_t p1_hi = p1 >> 32u;
14962 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
14963 const std::uint64_t p2_hi = p2 >> 32u;
14964
14965 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
14966
14967 // The full product might now be computed as
14968 //
14969 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
14970 // p_lo = p0_lo + (Q << 32)
14971 //
14972 // But in this particular case here, the full p_lo is not required.
14973 // Effectively we only need to add the highest bit in p_lo to p_hi (and
14974 // Q_hi + 1 does not overflow).
14975
14976 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
14977
14978 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
14979
14980 return {h, x.e + y.e + 64};
14981 }
14982
14987 static diyfp normalize(diyfp x) noexcept
14988 {
14989 JSON_ASSERT(x.f != 0);
14990
14991 while ((x.f >> 63u) == 0)
14992 {
14993 x.f <<= 1u;
14994 x.e--;
14995 }
14996
14997 return x;
14998 }
14999
15004 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
15005 {
15006 const int delta = x.e - target_exponent;
15007
15008 JSON_ASSERT(delta >= 0);
15009 JSON_ASSERT(((x.f << delta) >> delta) == x.f);
15010
15011 return {x.f << delta, target_exponent};
15012 }
15013 };
15014
15015 struct boundaries
15016 {
15017 diyfp w;
15018 diyfp minus;
15019 diyfp plus;
15020 };
15021
15028 template<typename FloatType>
15029 boundaries compute_boundaries(FloatType value)
15030 {
15031 JSON_ASSERT(std::isfinite(value));
15032 JSON_ASSERT(value > 0);
15033
15034 // Convert the IEEE representation into a diyfp.
15035 //
15036 // If v is denormal:
15037 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
15038 // If v is normalized:
15039 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
15040
15041 static_assert(std::numeric_limits<FloatType>::is_iec559,
15042 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
15043
15044 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
15045 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
15046 constexpr int kMinExp = 1 - kBias;
15047 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
15048
15049 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
15050
15051 const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
15052 const std::uint64_t E = bits >> (kPrecision - 1);
15053 const std::uint64_t F = bits & (kHiddenBit - 1);
15054
15055 const bool is_denormal = E == 0;
15056 const diyfp v = is_denormal
15057 ? diyfp(F, kMinExp)
15058 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
15059
15060 // Compute the boundaries m- and m+ of the floating-point value
15061 // v = f * 2^e.
15062 //
15063 // Determine v- and v+, the floating-point predecessor and successor if v,
15064 // respectively.
15065 //
15066 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
15067 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
15068 //
15069 // v+ = v + 2^e
15070 //
15071 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
15072 // between m- and m+ round to v, regardless of how the input rounding
15073 // algorithm breaks ties.
15074 //
15075 // ---+-------------+-------------+-------------+-------------+--- (A)
15076 // v- m- v m+ v+
15077 //
15078 // -----------------+------+------+-------------+-------------+--- (B)
15079 // v- m- v m+ v+
15080
15081 const bool lower_boundary_is_closer = F == 0 && E > 1;
15082 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
15083 const diyfp m_minus = lower_boundary_is_closer
15084 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
15085 : diyfp(2 * v.f - 1, v.e - 1); // (A)
15086
15087 // Determine the normalized w+ = m+.
15088 const diyfp w_plus = diyfp::normalize(m_plus);
15089
15090 // Determine w- = m- such that e_(w-) = e_(w+).
15091 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
15092
15093 return {diyfp::normalize(v), w_minus, w_plus};
15094 }
15095
15096 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
15097 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
15098 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
15099 //
15100 // alpha <= e = e_c + e_w + q <= gamma
15101 //
15102 // or
15103 //
15104 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
15105 // <= f_c * f_w * 2^gamma
15106 //
15107 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
15108 //
15109 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
15110 //
15111 // or
15112 //
15113 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
15114 //
15115 // The choice of (alpha,gamma) determines the size of the table and the form of
15116 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
15117 // in practice:
15118 //
15119 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
15120 // processed independently: An integral part p1, and a fractional part p2:
15121 //
15122 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
15123 // = (f div 2^-e) + (f mod 2^-e) * 2^e
15124 // = p1 + p2 * 2^e
15125 //
15126 // The conversion of p1 into decimal form requires a series of divisions and
15127 // modulos by (a power of) 10. These operations are faster for 32-bit than for
15128 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
15129 // achieved by choosing
15130 //
15131 // -e >= 32 or e <= -32 := gamma
15132 //
15133 // In order to convert the fractional part
15134 //
15135 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
15136 //
15137 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
15138 // d[-i] are extracted in order:
15139 //
15140 // (10 * p2) div 2^-e = d[-1]
15141 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
15142 //
15143 // The multiplication by 10 must not overflow. It is sufficient to choose
15144 //
15145 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
15146 //
15147 // Since p2 = f mod 2^-e < 2^-e,
15148 //
15149 // -e <= 60 or e >= -60 := alpha
15150
15151 constexpr int kAlpha = -60;
15152 constexpr int kGamma = -32;
15153
15154 struct cached_power // c = f * 2^e ~= 10^k
15155 {
15156 std::uint64_t f;
15157 int e;
15158 int k;
15159 };
15160
15168 inline cached_power get_cached_power_for_binary_exponent(int e)
15169 {
15170 // Now
15171 //
15172 // alpha <= e_c + e + q <= gamma (1)
15173 // ==> f_c * 2^alpha <= c * 2^e * 2^q
15174 //
15175 // and since the c's are normalized, 2^(q-1) <= f_c,
15176 //
15177 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
15178 // ==> 2^(alpha - e - 1) <= c
15179 //
15180 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
15181 //
15182 // k = ceil( log_10( 2^(alpha - e - 1) ) )
15183 // = ceil( (alpha - e - 1) * log_10(2) )
15184 //
15185 // From the paper:
15186 // "In theory the result of the procedure could be wrong since c is rounded,
15187 // and the computation itself is approximated [...]. In practice, however,
15188 // this simple function is sufficient."
15189 //
15190 // For IEEE double precision floating-point numbers converted into
15191 // normalized diyfp's w = f * 2^e, with q = 64,
15192 //
15193 // e >= -1022 (min IEEE exponent)
15194 // -52 (p - 1)
15195 // -52 (p - 1, possibly normalize denormal IEEE numbers)
15196 // -11 (normalize the diyfp)
15197 // = -1137
15198 //
15199 // and
15200 //
15201 // e <= +1023 (max IEEE exponent)
15202 // -52 (p - 1)
15203 // -11 (normalize the diyfp)
15204 // = 960
15205 //
15206 // This binary exponent range [-1137,960] results in a decimal exponent
15207 // range [-307,324]. One does not need to store a cached power for each
15208 // k in this range. For each such k it suffices to find a cached power
15209 // such that the exponent of the product lies in [alpha,gamma].
15210 // This implies that the difference of the decimal exponents of adjacent
15211 // table entries must be less than or equal to
15212 //
15213 // floor( (gamma - alpha) * log_10(2) ) = 8.
15214 //
15215 // (A smaller distance gamma-alpha would require a larger table.)
15216
15217 // NB:
15218 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
15219
15220 constexpr int kCachedPowersMinDecExp = -300;
15221 constexpr int kCachedPowersDecStep = 8;
15222
15223 static constexpr std::array<cached_power, 79> kCachedPowers =
15224 {
15225 {
15226 { 0xAB70FE17C79AC6CA, -1060, -300 },
15227 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
15228 { 0xBE5691EF416BD60C, -1007, -284 },
15229 { 0x8DD01FAD907FFC3C, -980, -276 },
15230 { 0xD3515C2831559A83, -954, -268 },
15231 { 0x9D71AC8FADA6C9B5, -927, -260 },
15232 { 0xEA9C227723EE8BCB, -901, -252 },
15233 { 0xAECC49914078536D, -874, -244 },
15234 { 0x823C12795DB6CE57, -847, -236 },
15235 { 0xC21094364DFB5637, -821, -228 },
15236 { 0x9096EA6F3848984F, -794, -220 },
15237 { 0xD77485CB25823AC7, -768, -212 },
15238 { 0xA086CFCD97BF97F4, -741, -204 },
15239 { 0xEF340A98172AACE5, -715, -196 },
15240 { 0xB23867FB2A35B28E, -688, -188 },
15241 { 0x84C8D4DFD2C63F3B, -661, -180 },
15242 { 0xC5DD44271AD3CDBA, -635, -172 },
15243 { 0x936B9FCEBB25C996, -608, -164 },
15244 { 0xDBAC6C247D62A584, -582, -156 },
15245 { 0xA3AB66580D5FDAF6, -555, -148 },
15246 { 0xF3E2F893DEC3F126, -529, -140 },
15247 { 0xB5B5ADA8AAFF80B8, -502, -132 },
15248 { 0x87625F056C7C4A8B, -475, -124 },
15249 { 0xC9BCFF6034C13053, -449, -116 },
15250 { 0x964E858C91BA2655, -422, -108 },
15251 { 0xDFF9772470297EBD, -396, -100 },
15252 { 0xA6DFBD9FB8E5B88F, -369, -92 },
15253 { 0xF8A95FCF88747D94, -343, -84 },
15254 { 0xB94470938FA89BCF, -316, -76 },
15255 { 0x8A08F0F8BF0F156B, -289, -68 },
15256 { 0xCDB02555653131B6, -263, -60 },
15257 { 0x993FE2C6D07B7FAC, -236, -52 },
15258 { 0xE45C10C42A2B3B06, -210, -44 },
15259 { 0xAA242499697392D3, -183, -36 },
15260 { 0xFD87B5F28300CA0E, -157, -28 },
15261 { 0xBCE5086492111AEB, -130, -20 },
15262 { 0x8CBCCC096F5088CC, -103, -12 },
15263 { 0xD1B71758E219652C, -77, -4 },
15264 { 0x9C40000000000000, -50, 4 },
15265 { 0xE8D4A51000000000, -24, 12 },
15266 { 0xAD78EBC5AC620000, 3, 20 },
15267 { 0x813F3978F8940984, 30, 28 },
15268 { 0xC097CE7BC90715B3, 56, 36 },
15269 { 0x8F7E32CE7BEA5C70, 83, 44 },
15270 { 0xD5D238A4ABE98068, 109, 52 },
15271 { 0x9F4F2726179A2245, 136, 60 },
15272 { 0xED63A231D4C4FB27, 162, 68 },
15273 { 0xB0DE65388CC8ADA8, 189, 76 },
15274 { 0x83C7088E1AAB65DB, 216, 84 },
15275 { 0xC45D1DF942711D9A, 242, 92 },
15276 { 0x924D692CA61BE758, 269, 100 },
15277 { 0xDA01EE641A708DEA, 295, 108 },
15278 { 0xA26DA3999AEF774A, 322, 116 },
15279 { 0xF209787BB47D6B85, 348, 124 },
15280 { 0xB454E4A179DD1877, 375, 132 },
15281 { 0x865B86925B9BC5C2, 402, 140 },
15282 { 0xC83553C5C8965D3D, 428, 148 },
15283 { 0x952AB45CFA97A0B3, 455, 156 },
15284 { 0xDE469FBD99A05FE3, 481, 164 },
15285 { 0xA59BC234DB398C25, 508, 172 },
15286 { 0xF6C69A72A3989F5C, 534, 180 },
15287 { 0xB7DCBF5354E9BECE, 561, 188 },
15288 { 0x88FCF317F22241E2, 588, 196 },
15289 { 0xCC20CE9BD35C78A5, 614, 204 },
15290 { 0x98165AF37B2153DF, 641, 212 },
15291 { 0xE2A0B5DC971F303A, 667, 220 },
15292 { 0xA8D9D1535CE3B396, 694, 228 },
15293 { 0xFB9B7CD9A4A7443C, 720, 236 },
15294 { 0xBB764C4CA7A44410, 747, 244 },
15295 { 0x8BAB8EEFB6409C1A, 774, 252 },
15296 { 0xD01FEF10A657842C, 800, 260 },
15297 { 0x9B10A4E5E9913129, 827, 268 },
15298 { 0xE7109BFBA19C0C9D, 853, 276 },
15299 { 0xAC2820D9623BF429, 880, 284 },
15300 { 0x80444B5E7AA7CF85, 907, 292 },
15301 { 0xBF21E44003ACDD2D, 933, 300 },
15302 { 0x8E679C2F5E44FF8F, 960, 308 },
15303 { 0xD433179D9C8CB841, 986, 316 },
15304 { 0x9E19DB92B4E31BA9, 1013, 324 },
15305 }
15306 };
15307
15308 // This computation gives exactly the same results for k as
15309 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
15310 // for |e| <= 1500, but doesn't require floating-point operations.
15311 // NB: log_10(2) ~= 78913 / 2^18
15312 JSON_ASSERT(e >= -1500);
15313 JSON_ASSERT(e <= 1500);
15314 const int f = kAlpha - e - 1;
15315 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
15316
15317 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
15318 JSON_ASSERT(index >= 0);
15319 JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
15320
15321 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
15322 JSON_ASSERT(kAlpha <= cached.e + e + 64);
15323 JSON_ASSERT(kGamma >= cached.e + e + 64);
15324
15325 return cached;
15326 }
15327
15332 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
15333 {
15334 // LCOV_EXCL_START
15335 if (n >= 1000000000)
15336 {
15337 pow10 = 1000000000;
15338 return 10;
15339 }
15340 // LCOV_EXCL_STOP
15341 if (n >= 100000000)
15342 {
15343 pow10 = 100000000;
15344 return 9;
15345 }
15346 if (n >= 10000000)
15347 {
15348 pow10 = 10000000;
15349 return 8;
15350 }
15351 if (n >= 1000000)
15352 {
15353 pow10 = 1000000;
15354 return 7;
15355 }
15356 if (n >= 100000)
15357 {
15358 pow10 = 100000;
15359 return 6;
15360 }
15361 if (n >= 10000)
15362 {
15363 pow10 = 10000;
15364 return 5;
15365 }
15366 if (n >= 1000)
15367 {
15368 pow10 = 1000;
15369 return 4;
15370 }
15371 if (n >= 100)
15372 {
15373 pow10 = 100;
15374 return 3;
15375 }
15376 if (n >= 10)
15377 {
15378 pow10 = 10;
15379 return 2;
15380 }
15381
15382 pow10 = 1;
15383 return 1;
15384 }
15385
15386 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
15387 std::uint64_t rest, std::uint64_t ten_k)
15388 {
15389 JSON_ASSERT(len >= 1);
15390 JSON_ASSERT(dist <= delta);
15391 JSON_ASSERT(rest <= delta);
15392 JSON_ASSERT(ten_k > 0);
15393
15394 // <--------------------------- delta ---->
15395 // <---- dist --------->
15396 // --------------[------------------+-------------------]--------------
15397 // M- w M+
15398 //
15399 // ten_k
15400 // <------>
15401 // <---- rest ---->
15402 // --------------[------------------+----+--------------]--------------
15403 // w V
15404 // = buf * 10^k
15405 //
15406 // ten_k represents a unit-in-the-last-place in the decimal representation
15407 // stored in buf.
15408 // Decrement buf by ten_k while this takes buf closer to w.
15409
15410 // The tests are written in this order to avoid overflow in unsigned
15411 // integer arithmetic.
15412
15413 while (rest < dist
15414 && delta - rest >= ten_k
15415 && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
15416 {
15417 JSON_ASSERT(buf[len - 1] != '0');
15418 buf[len - 1]--;
15419 rest += ten_k;
15420 }
15421 }
15422
15427 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
15428 diyfp M_minus, diyfp w, diyfp M_plus)
15429 {
15430 static_assert(kAlpha >= -60, "internal error");
15431 static_assert(kGamma <= -32, "internal error");
15432
15433 // Generates the digits (and the exponent) of a decimal floating-point
15434 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
15435 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
15436 //
15437 // <--------------------------- delta ---->
15438 // <---- dist --------->
15439 // --------------[------------------+-------------------]--------------
15440 // M- w M+
15441 //
15442 // Grisu2 generates the digits of M+ from left to right and stops as soon as
15443 // V is in [M-,M+].
15444
15445 JSON_ASSERT(M_plus.e >= kAlpha);
15446 JSON_ASSERT(M_plus.e <= kGamma);
15447
15448 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
15449 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
15450
15451 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
15452 //
15453 // M+ = f * 2^e
15454 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
15455 // = ((p1 ) * 2^-e + (p2 )) * 2^e
15456 // = p1 + p2 * 2^e
15457
15458 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
15459
15460 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.)
15461 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
15462
15463 // 1)
15464 //
15465 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
15466
15467 JSON_ASSERT(p1 > 0);
15468
15469 std::uint32_t pow10{};
15470 const int k = find_largest_pow10(p1, pow10);
15471
15472 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
15473 //
15474 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
15475 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
15476 //
15477 // M+ = p1 + p2 * 2^e
15478 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
15479 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
15480 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
15481 //
15482 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
15483 //
15484 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
15485 //
15486 // but stop as soon as
15487 //
15488 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
15489
15490 int n = k;
15491 while (n > 0)
15492 {
15493 // Invariants:
15494 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
15495 // pow10 = 10^(n-1) <= p1 < 10^n
15496 //
15497 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
15498 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
15499 //
15500 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
15501 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
15502 //
15503 JSON_ASSERT(d <= 9);
15504 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15505 //
15506 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
15507 //
15508 p1 = r;
15509 n--;
15510 //
15511 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
15512 // pow10 = 10^n
15513 //
15514
15515 // Now check if enough digits have been generated.
15516 // Compute
15517 //
15518 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
15519 //
15520 // Note:
15521 // Since rest and delta share the same exponent e, it suffices to
15522 // compare the significands.
15523 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
15524 if (rest <= delta)
15525 {
15526 // V = buffer * 10^n, with M- <= V <= M+.
15527
15528 decimal_exponent += n;
15529
15530 // We may now just stop. But instead look if the buffer could be
15531 // decremented to bring V closer to w.
15532 //
15533 // pow10 = 10^n is now 1 ulp in the decimal representation V.
15534 // The rounding procedure works with diyfp's with an implicit
15535 // exponent of e.
15536 //
15537 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
15538 //
15539 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
15540 grisu2_round(buffer, length, dist, delta, rest, ten_n);
15541
15542 return;
15543 }
15544
15545 pow10 /= 10;
15546 //
15547 // pow10 = 10^(n-1) <= p1 < 10^n
15548 // Invariants restored.
15549 }
15550
15551 // 2)
15552 //
15553 // The digits of the integral part have been generated:
15554 //
15555 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
15556 // = buffer + p2 * 2^e
15557 //
15558 // Now generate the digits of the fractional part p2 * 2^e.
15559 //
15560 // Note:
15561 // No decimal point is generated: the exponent is adjusted instead.
15562 //
15563 // p2 actually represents the fraction
15564 //
15565 // p2 * 2^e
15566 // = p2 / 2^-e
15567 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
15568 //
15569 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
15570 //
15571 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
15572 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
15573 //
15574 // using
15575 //
15576 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
15577 // = ( d) * 2^-e + ( r)
15578 //
15579 // or
15580 // 10^m * p2 * 2^e = d + r * 2^e
15581 //
15582 // i.e.
15583 //
15584 // M+ = buffer + p2 * 2^e
15585 // = buffer + 10^-m * (d + r * 2^e)
15586 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
15587 //
15588 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
15589
15590 JSON_ASSERT(p2 > delta);
15591
15592 int m = 0;
15593 for (;;)
15594 {
15595 // Invariant:
15596 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
15597 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
15598 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
15599 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
15600 //
15601 JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
15602 p2 *= 10;
15603 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
15604 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
15605 //
15606 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
15607 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
15608 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
15609 //
15610 JSON_ASSERT(d <= 9);
15611 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15612 //
15613 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
15614 //
15615 p2 = r;
15616 m++;
15617 //
15618 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
15619 // Invariant restored.
15620
15621 // Check if enough digits have been generated.
15622 //
15623 // 10^-m * p2 * 2^e <= delta * 2^e
15624 // p2 * 2^e <= 10^m * delta * 2^e
15625 // p2 <= 10^m * delta
15626 delta *= 10;
15627 dist *= 10;
15628 if (p2 <= delta)
15629 {
15630 break;
15631 }
15632 }
15633
15634 // V = buffer * 10^-m, with M- <= V <= M+.
15635
15636 decimal_exponent -= m;
15637
15638 // 1 ulp in the decimal representation is now 10^-m.
15639 // Since delta and dist are now scaled by 10^m, we need to do the
15640 // same with ulp in order to keep the units in sync.
15641 //
15642 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
15643 //
15644 const std::uint64_t ten_m = one.f;
15645 grisu2_round(buffer, length, dist, delta, p2, ten_m);
15646
15647 // By construction this algorithm generates the shortest possible decimal
15648 // number (Loitsch, Theorem 6.2) which rounds back to w.
15649 // For an input number of precision p, at least
15650 //
15651 // N = 1 + ceil(p * log_10(2))
15652 //
15653 // decimal digits are sufficient to identify all binary floating-point
15654 // numbers (Matula, "In-and-Out conversions").
15655 // This implies that the algorithm does not produce more than N decimal
15656 // digits.
15657 //
15658 // N = 17 for p = 53 (IEEE double precision)
15659 // N = 9 for p = 24 (IEEE single precision)
15660 }
15661
15667 JSON_HEDLEY_NON_NULL(1)
15668 inline void grisu2(char* buf, int& len, int& decimal_exponent,
15669 diyfp m_minus, diyfp v, diyfp m_plus)
15670 {
15671 JSON_ASSERT(m_plus.e == m_minus.e);
15672 JSON_ASSERT(m_plus.e == v.e);
15673
15674 // --------(-----------------------+-----------------------)-------- (A)
15675 // m- v m+
15676 //
15677 // --------------------(-----------+-----------------------)-------- (B)
15678 // m- v m+
15679 //
15680 // First scale v (and m- and m+) such that the exponent is in the range
15681 // [alpha, gamma].
15682
15683 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
15684
15685 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
15686
15687 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
15688 const diyfp w = diyfp::mul(v, c_minus_k);
15689 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
15690 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
15691
15692 // ----(---+---)---------------(---+---)---------------(---+---)----
15693 // w- w w+
15694 // = c*m- = c*v = c*m+
15695 //
15696 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
15697 // w+ are now off by a small amount.
15698 // In fact:
15699 //
15700 // w - v * 10^k < 1 ulp
15701 //
15702 // To account for this inaccuracy, add resp. subtract 1 ulp.
15703 //
15704 // --------+---[---------------(---+---)---------------]---+--------
15705 // w- M- w M+ w+
15706 //
15707 // Now any number in [M-, M+] (bounds included) will round to w when input,
15708 // regardless of how the input rounding algorithm breaks ties.
15709 //
15710 // And digit_gen generates the shortest possible such number in [M-, M+].
15711 // Note that this does not mean that Grisu2 always generates the shortest
15712 // possible number in the interval (m-, m+).
15713 const diyfp M_minus(w_minus.f + 1, w_minus.e);
15714 const diyfp M_plus (w_plus.f - 1, w_plus.e );
15715
15716 decimal_exponent = -cached.k; // = -(-k) = k
15717
15718 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
15719 }
15720
15726 template<typename FloatType>
15727 JSON_HEDLEY_NON_NULL(1)
15728 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
15729 {
15730 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
15731 "internal error: not enough precision");
15732
15733 JSON_ASSERT(std::isfinite(value));
15734 JSON_ASSERT(value > 0);
15735
15736 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
15737 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
15738 // decimal representations are not exactly "short".
15739 //
15740 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
15741 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
15742 // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
15743 // does.
15744 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
15745 // representation using the corresponding std::from_chars function recovers value exactly". That
15746 // indicates that single precision floating-point numbers should be recovered using
15747 // 'std::strtof'.
15748 //
15749 // NB: If the neighbors are computed for single-precision numbers, there is a single float
15750 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
15751 // value is off by 1 ulp.
15752 #if 0
15753 const boundaries w = compute_boundaries(static_cast<double>(value));
15754 #else
15755 const boundaries w = compute_boundaries(value);
15756 #endif
15757
15758 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
15759 }
15760
15766 JSON_HEDLEY_NON_NULL(1)
15767 JSON_HEDLEY_RETURNS_NON_NULL
15768 inline char* append_exponent(char* buf, int e)
15769 {
15770 JSON_ASSERT(e > -1000);
15771 JSON_ASSERT(e < 1000);
15772
15773 if (e < 0)
15774 {
15775 e = -e;
15776 *buf++ = '-';
15777 }
15778 else
15779 {
15780 *buf++ = '+';
15781 }
15782
15783 auto k = static_cast<std::uint32_t>(e);
15784 if (k < 10)
15785 {
15786 // Always print at least two digits in the exponent.
15787 // This is for compatibility with printf("%g").
15788 *buf++ = '0';
15789 *buf++ = static_cast<char>('0' + k);
15790 }
15791 else if (k < 100)
15792 {
15793 *buf++ = static_cast<char>('0' + k / 10);
15794 k %= 10;
15795 *buf++ = static_cast<char>('0' + k);
15796 }
15797 else
15798 {
15799 *buf++ = static_cast<char>('0' + k / 100);
15800 k %= 100;
15801 *buf++ = static_cast<char>('0' + k / 10);
15802 k %= 10;
15803 *buf++ = static_cast<char>('0' + k);
15804 }
15805
15806 return buf;
15807 }
15808
15818 JSON_HEDLEY_NON_NULL(1)
15819 JSON_HEDLEY_RETURNS_NON_NULL
15820 inline char* format_buffer(char* buf, int len, int decimal_exponent,
15821 int min_exp, int max_exp)
15822 {
15823 JSON_ASSERT(min_exp < 0);
15824 JSON_ASSERT(max_exp > 0);
15825
15826 const int k = len;
15827 const int n = len + decimal_exponent;
15828
15829 // v = buf * 10^(n-k)
15830 // k is the length of the buffer (number of decimal digits)
15831 // n is the position of the decimal point relative to the start of the buffer.
15832
15833 if (k <= n && n <= max_exp)
15834 {
15835 // digits[000]
15836 // len <= max_exp + 2
15837
15838 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
15839 // Make it look like a floating-point number (#362, #378)
15840 buf[n + 0] = '.';
15841 buf[n + 1] = '0';
15842 return buf + (static_cast<size_t>(n) + 2);
15843 }
15844
15845 if (0 < n && n <= max_exp)
15846 {
15847 // dig.its
15848 // len <= max_digits10 + 1
15849
15850 JSON_ASSERT(k > n);
15851
15852 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
15853 buf[n] = '.';
15854 return buf + (static_cast<size_t>(k) + 1U);
15855 }
15856
15857 if (min_exp < n && n <= 0)
15858 {
15859 // 0.[000]digits
15860 // len <= 2 + (-min_exp - 1) + max_digits10
15861
15862 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
15863 buf[0] = '0';
15864 buf[1] = '.';
15865 std::memset(buf + 2, '0', static_cast<size_t>(-n));
15866 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
15867 }
15868
15869 if (k == 1)
15870 {
15871 // dE+123
15872 // len <= 1 + 5
15873
15874 buf += 1;
15875 }
15876 else
15877 {
15878 // d.igitsE+123
15879 // len <= max_digits10 + 1 + 5
15880
15881 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
15882 buf[1] = '.';
15883 buf += 1 + static_cast<size_t>(k);
15884 }
15885
15886 *buf++ = 'e';
15887 return append_exponent(buf, n - 1);
15888 }
15889
15890 } // namespace dtoa_impl
15891
15902 template<typename FloatType>
15903 JSON_HEDLEY_NON_NULL(1, 2)
15904 JSON_HEDLEY_RETURNS_NON_NULL
15905 char* to_chars(char* first, const char* last, FloatType value)
15906 {
15907 static_cast<void>(last); // maybe unused - fix warning
15908 JSON_ASSERT(std::isfinite(value));
15909
15910 // Use signbit(value) instead of (value < 0) since signbit works for -0.
15911 if (std::signbit(value))
15912 {
15913 value = -value;
15914 *first++ = '-';
15915 }
15916
15917 if (value == 0) // +-0
15918 {
15919 *first++ = '0';
15920 // Make it look like a floating-point number (#362, #378)
15921 *first++ = '.';
15922 *first++ = '0';
15923 return first;
15924 }
15925
15926 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
15927
15928 // Compute v = buffer * 10^decimal_exponent.
15929 // The decimal digits are stored in the buffer, which needs to be interpreted
15930 // as an unsigned decimal integer.
15931 // len is the length of the buffer, i.e. the number of decimal digits.
15932 int len = 0;
15933 int decimal_exponent = 0;
15934 dtoa_impl::grisu2(first, len, decimal_exponent, value);
15935
15936 JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
15937
15938 // Format the buffer like printf("%.*g", prec, value)
15939 constexpr int kMinExp = -4;
15940 // Use digits10 here to increase compatibility with version 2.
15941 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
15942
15943 JSON_ASSERT(last - first >= kMaxExp + 2);
15944 JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
15945 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
15946
15947 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
15948 }
15949
15950 } // namespace detail
15951 } // namespace nlohmann
15952
15953 // #include <nlohmann/detail/exceptions.hpp>
15954
15955 // #include <nlohmann/detail/macro_scope.hpp>
15956
15957 // #include <nlohmann/detail/meta/cpp_future.hpp>
15958
15959 // #include <nlohmann/detail/output/binary_writer.hpp>
15960
15961 // #include <nlohmann/detail/output/output_adapters.hpp>
15962
15963 // #include <nlohmann/detail/value_t.hpp>
15964
15965
15966 namespace nlohmann
15967 {
15968 namespace detail
15969 {
15971 // serialization //
15973
15975 enum class error_handler_t
15976 {
15977 strict,
15978 replace,
15979 ignore
15980 };
15981
15982 template<typename BasicJsonType>
15983 class serializer
15984 {
15985 using string_t = typename BasicJsonType::string_t;
15986 using number_float_t = typename BasicJsonType::number_float_t;
15987 using number_integer_t = typename BasicJsonType::number_integer_t;
15988 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
15989 using binary_char_t = typename BasicJsonType::binary_t::value_type;
15990 static constexpr std::uint8_t UTF8_ACCEPT = 0;
15991 static constexpr std::uint8_t UTF8_REJECT = 1;
15992
15993 public:
15999 serializer(output_adapter_t<char> s, const char ichar,
16000 error_handler_t error_handler_ = error_handler_t::strict)
16001 : o(std::move(s))
16002 , loc(std::localeconv())
16003 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
16004 , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
16005 , indent_char(ichar)
16006 , indent_string(512, indent_char)
16007 , error_handler(error_handler_)
16008 {}
16009
16010 // delete because of pointer members
16011 serializer(const serializer&) = delete;
16012 serializer& operator=(const serializer&) = delete;
16013 serializer(serializer&&) = delete;
16014 serializer& operator=(serializer&&) = delete;
16015 ~serializer() = default;
16016
16039 void dump(const BasicJsonType& val,
16040 const bool pretty_print,
16041 const bool ensure_ascii,
16042 const unsigned int indent_step,
16043 const unsigned int current_indent = 0)
16044 {
16045 switch (val.m_type)
16046 {
16047 case value_t::object:
16048 {
16049 if (val.m_value.object->empty())
16050 {
16051 o->write_characters("{}", 2);
16052 return;
16053 }
16054
16055 if (pretty_print)
16056 {
16057 o->write_characters("{\n", 2);
16058
16059 // variable to hold indentation for recursive calls
16060 const auto new_indent = current_indent + indent_step;
16061 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16062 {
16063 indent_string.resize(indent_string.size() * 2, ' ');
16064 }
16065
16066 // first n-1 elements
16067 auto i = val.m_value.object->cbegin();
16068 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16069 {
16070 o->write_characters(indent_string.c_str(), new_indent);
16071 o->write_character('\"');
16072 dump_escaped(i->first, ensure_ascii);
16073 o->write_characters("\": ", 3);
16074 dump(i->second, true, ensure_ascii, indent_step, new_indent);
16075 o->write_characters(",\n", 2);
16076 }
16077
16078 // last element
16079 JSON_ASSERT(i != val.m_value.object->cend());
16080 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16081 o->write_characters(indent_string.c_str(), new_indent);
16082 o->write_character('\"');
16083 dump_escaped(i->first, ensure_ascii);
16084 o->write_characters("\": ", 3);
16085 dump(i->second, true, ensure_ascii, indent_step, new_indent);
16086
16087 o->write_character('\n');
16088 o->write_characters(indent_string.c_str(), current_indent);
16089 o->write_character('}');
16090 }
16091 else
16092 {
16093 o->write_character('{');
16094
16095 // first n-1 elements
16096 auto i = val.m_value.object->cbegin();
16097 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16098 {
16099 o->write_character('\"');
16100 dump_escaped(i->first, ensure_ascii);
16101 o->write_characters("\":", 2);
16102 dump(i->second, false, ensure_ascii, indent_step, current_indent);
16103 o->write_character(',');
16104 }
16105
16106 // last element
16107 JSON_ASSERT(i != val.m_value.object->cend());
16108 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16109 o->write_character('\"');
16110 dump_escaped(i->first, ensure_ascii);
16111 o->write_characters("\":", 2);
16112 dump(i->second, false, ensure_ascii, indent_step, current_indent);
16113
16114 o->write_character('}');
16115 }
16116
16117 return;
16118 }
16119
16120 case value_t::array:
16121 {
16122 if (val.m_value.array->empty())
16123 {
16124 o->write_characters("[]", 2);
16125 return;
16126 }
16127
16128 if (pretty_print)
16129 {
16130 o->write_characters("[\n", 2);
16131
16132 // variable to hold indentation for recursive calls
16133 const auto new_indent = current_indent + indent_step;
16134 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16135 {
16136 indent_string.resize(indent_string.size() * 2, ' ');
16137 }
16138
16139 // first n-1 elements
16140 for (auto i = val.m_value.array->cbegin();
16141 i != val.m_value.array->cend() - 1; ++i)
16142 {
16143 o->write_characters(indent_string.c_str(), new_indent);
16144 dump(*i, true, ensure_ascii, indent_step, new_indent);
16145 o->write_characters(",\n", 2);
16146 }
16147
16148 // last element
16149 JSON_ASSERT(!val.m_value.array->empty());
16150 o->write_characters(indent_string.c_str(), new_indent);
16151 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
16152
16153 o->write_character('\n');
16154 o->write_characters(indent_string.c_str(), current_indent);
16155 o->write_character(']');
16156 }
16157 else
16158 {
16159 o->write_character('[');
16160
16161 // first n-1 elements
16162 for (auto i = val.m_value.array->cbegin();
16163 i != val.m_value.array->cend() - 1; ++i)
16164 {
16165 dump(*i, false, ensure_ascii, indent_step, current_indent);
16166 o->write_character(',');
16167 }
16168
16169 // last element
16170 JSON_ASSERT(!val.m_value.array->empty());
16171 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
16172
16173 o->write_character(']');
16174 }
16175
16176 return;
16177 }
16178
16179 case value_t::string:
16180 {
16181 o->write_character('\"');
16182 dump_escaped(*val.m_value.string, ensure_ascii);
16183 o->write_character('\"');
16184 return;
16185 }
16186
16187 case value_t::binary:
16188 {
16189 if (pretty_print)
16190 {
16191 o->write_characters("{\n", 2);
16192
16193 // variable to hold indentation for recursive calls
16194 const auto new_indent = current_indent + indent_step;
16195 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16196 {
16197 indent_string.resize(indent_string.size() * 2, ' ');
16198 }
16199
16200 o->write_characters(indent_string.c_str(), new_indent);
16201
16202 o->write_characters("\"bytes\": [", 10);
16203
16204 if (!val.m_value.binary->empty())
16205 {
16206 for (auto i = val.m_value.binary->cbegin();
16207 i != val.m_value.binary->cend() - 1; ++i)
16208 {
16209 dump_integer(*i);
16210 o->write_characters(", ", 2);
16211 }
16212 dump_integer(val.m_value.binary->back());
16213 }
16214
16215 o->write_characters("],\n", 3);
16216 o->write_characters(indent_string.c_str(), new_indent);
16217
16218 o->write_characters("\"subtype\": ", 11);
16219 if (val.m_value.binary->has_subtype())
16220 {
16221 dump_integer(val.m_value.binary->subtype());
16222 }
16223 else
16224 {
16225 o->write_characters("null", 4);
16226 }
16227 o->write_character('\n');
16228 o->write_characters(indent_string.c_str(), current_indent);
16229 o->write_character('}');
16230 }
16231 else
16232 {
16233 o->write_characters("{\"bytes\":[", 10);
16234
16235 if (!val.m_value.binary->empty())
16236 {
16237 for (auto i = val.m_value.binary->cbegin();
16238 i != val.m_value.binary->cend() - 1; ++i)
16239 {
16240 dump_integer(*i);
16241 o->write_character(',');
16242 }
16243 dump_integer(val.m_value.binary->back());
16244 }
16245
16246 o->write_characters("],\"subtype\":", 12);
16247 if (val.m_value.binary->has_subtype())
16248 {
16249 dump_integer(val.m_value.binary->subtype());
16250 o->write_character('}');
16251 }
16252 else
16253 {
16254 o->write_characters("null}", 5);
16255 }
16256 }
16257 return;
16258 }
16259
16260 case value_t::boolean:
16261 {
16262 if (val.m_value.boolean)
16263 {
16264 o->write_characters("true", 4);
16265 }
16266 else
16267 {
16268 o->write_characters("false", 5);
16269 }
16270 return;
16271 }
16272
16273 case value_t::number_integer:
16274 {
16275 dump_integer(val.m_value.number_integer);
16276 return;
16277 }
16278
16279 case value_t::number_unsigned:
16280 {
16281 dump_integer(val.m_value.number_unsigned);
16282 return;
16283 }
16284
16285 case value_t::number_float:
16286 {
16287 dump_float(val.m_value.number_float);
16288 return;
16289 }
16290
16291 case value_t::discarded:
16292 {
16293 o->write_characters("<discarded>", 11);
16294 return;
16295 }
16296
16297 case value_t::null:
16298 {
16299 o->write_characters("null", 4);
16300 return;
16301 }
16302
16303 default: // LCOV_EXCL_LINE
16304 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16305 }
16306 }
16307
16308 JSON_PRIVATE_UNLESS_TESTED:
16323 void dump_escaped(const string_t& s, const bool ensure_ascii)
16324 {
16325 std::uint32_t codepoint{};
16326 std::uint8_t state = UTF8_ACCEPT;
16327 std::size_t bytes = 0; // number of bytes written to string_buffer
16328
16329 // number of bytes written at the point of the last valid byte
16330 std::size_t bytes_after_last_accept = 0;
16331 std::size_t undumped_chars = 0;
16332
16333 for (std::size_t i = 0; i < s.size(); ++i)
16334 {
16335 const auto byte = static_cast<uint8_t>(s[i]);
16336
16337 switch (decode(state, codepoint, byte))
16338 {
16339 case UTF8_ACCEPT: // decode found a new code point
16340 {
16341 switch (codepoint)
16342 {
16343 case 0x08: // backspace
16344 {
16345 string_buffer[bytes++] = '\\';
16346 string_buffer[bytes++] = 'b';
16347 break;
16348 }
16349
16350 case 0x09: // horizontal tab
16351 {
16352 string_buffer[bytes++] = '\\';
16353 string_buffer[bytes++] = 't';
16354 break;
16355 }
16356
16357 case 0x0A: // newline
16358 {
16359 string_buffer[bytes++] = '\\';
16360 string_buffer[bytes++] = 'n';
16361 break;
16362 }
16363
16364 case 0x0C: // formfeed
16365 {
16366 string_buffer[bytes++] = '\\';
16367 string_buffer[bytes++] = 'f';
16368 break;
16369 }
16370
16371 case 0x0D: // carriage return
16372 {
16373 string_buffer[bytes++] = '\\';
16374 string_buffer[bytes++] = 'r';
16375 break;
16376 }
16377
16378 case 0x22: // quotation mark
16379 {
16380 string_buffer[bytes++] = '\\';
16381 string_buffer[bytes++] = '\"';
16382 break;
16383 }
16384
16385 case 0x5C: // reverse solidus
16386 {
16387 string_buffer[bytes++] = '\\';
16388 string_buffer[bytes++] = '\\';
16389 break;
16390 }
16391
16392 default:
16393 {
16394 // escape control characters (0x00..0x1F) or, if
16395 // ensure_ascii parameter is used, non-ASCII characters
16396 if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
16397 {
16398 if (codepoint <= 0xFFFF)
16399 {
16400 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16401 (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
16402 static_cast<std::uint16_t>(codepoint));
16403 bytes += 6;
16404 }
16405 else
16406 {
16407 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16408 (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
16409 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
16410 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
16411 bytes += 12;
16412 }
16413 }
16414 else
16415 {
16416 // copy byte to buffer (all previous bytes
16417 // been copied have in default case above)
16418 string_buffer[bytes++] = s[i];
16419 }
16420 break;
16421 }
16422 }
16423
16424 // write buffer and reset index; there must be 13 bytes
16425 // left, as this is the maximal number of bytes to be
16426 // written ("\uxxxx\uxxxx\0") for one code point
16427 if (string_buffer.size() - bytes < 13)
16428 {
16429 o->write_characters(string_buffer.data(), bytes);
16430 bytes = 0;
16431 }
16432
16433 // remember the byte position of this accept
16434 bytes_after_last_accept = bytes;
16435 undumped_chars = 0;
16436 break;
16437 }
16438
16439 case UTF8_REJECT: // decode found invalid UTF-8 byte
16440 {
16441 switch (error_handler)
16442 {
16443 case error_handler_t::strict:
16444 {
16445 std::string sn(3, '\0');
16446 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16447 (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
16448 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn, BasicJsonType()));
16449 }
16450
16451 case error_handler_t::ignore:
16452 case error_handler_t::replace:
16453 {
16454 // in case we saw this character the first time, we
16455 // would like to read it again, because the byte
16456 // may be OK for itself, but just not OK for the
16457 // previous sequence
16458 if (undumped_chars > 0)
16459 {
16460 --i;
16461 }
16462
16463 // reset length buffer to the last accepted index;
16464 // thus removing/ignoring the invalid characters
16465 bytes = bytes_after_last_accept;
16466
16467 if (error_handler == error_handler_t::replace)
16468 {
16469 // add a replacement character
16470 if (ensure_ascii)
16471 {
16472 string_buffer[bytes++] = '\\';
16473 string_buffer[bytes++] = 'u';
16474 string_buffer[bytes++] = 'f';
16475 string_buffer[bytes++] = 'f';
16476 string_buffer[bytes++] = 'f';
16477 string_buffer[bytes++] = 'd';
16478 }
16479 else
16480 {
16481 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
16482 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
16483 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
16484 }
16485
16486 // write buffer and reset index; there must be 13 bytes
16487 // left, as this is the maximal number of bytes to be
16488 // written ("\uxxxx\uxxxx\0") for one code point
16489 if (string_buffer.size() - bytes < 13)
16490 {
16491 o->write_characters(string_buffer.data(), bytes);
16492 bytes = 0;
16493 }
16494
16495 bytes_after_last_accept = bytes;
16496 }
16497
16498 undumped_chars = 0;
16499
16500 // continue processing the string
16501 state = UTF8_ACCEPT;
16502 break;
16503 }
16504
16505 default: // LCOV_EXCL_LINE
16506 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16507 }
16508 break;
16509 }
16510
16511 default: // decode found yet incomplete multi-byte code point
16512 {
16513 if (!ensure_ascii)
16514 {
16515 // code point will not be escaped - copy byte to buffer
16516 string_buffer[bytes++] = s[i];
16517 }
16518 ++undumped_chars;
16519 break;
16520 }
16521 }
16522 }
16523
16524 // we finished processing the string
16525 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
16526 {
16527 // write buffer
16528 if (bytes > 0)
16529 {
16530 o->write_characters(string_buffer.data(), bytes);
16531 }
16532 }
16533 else
16534 {
16535 // we finish reading, but do not accept: string was incomplete
16536 switch (error_handler)
16537 {
16538 case error_handler_t::strict:
16539 {
16540 std::string sn(3, '\0');
16541 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16542 (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
16543 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn, BasicJsonType()));
16544 }
16545
16546 case error_handler_t::ignore:
16547 {
16548 // write all accepted bytes
16549 o->write_characters(string_buffer.data(), bytes_after_last_accept);
16550 break;
16551 }
16552
16553 case error_handler_t::replace:
16554 {
16555 // write all accepted bytes
16556 o->write_characters(string_buffer.data(), bytes_after_last_accept);
16557 // add a replacement character
16558 if (ensure_ascii)
16559 {
16560 o->write_characters("\\ufffd", 6);
16561 }
16562 else
16563 {
16564 o->write_characters("\xEF\xBF\xBD", 3);
16565 }
16566 break;
16567 }
16568
16569 default: // LCOV_EXCL_LINE
16570 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16571 }
16572 }
16573 }
16574
16575 private:
16584 inline unsigned int count_digits(number_unsigned_t x) noexcept
16585 {
16586 unsigned int n_digits = 1;
16587 for (;;)
16588 {
16589 if (x < 10)
16590 {
16591 return n_digits;
16592 }
16593 if (x < 100)
16594 {
16595 return n_digits + 1;
16596 }
16597 if (x < 1000)
16598 {
16599 return n_digits + 2;
16600 }
16601 if (x < 10000)
16602 {
16603 return n_digits + 3;
16604 }
16605 x = x / 10000u;
16606 n_digits += 4;
16607 }
16608 }
16609
16619 template < typename NumberType, detail::enable_if_t <
16620 std::is_same<NumberType, number_unsigned_t>::value ||
16621 std::is_same<NumberType, number_integer_t>::value ||
16622 std::is_same<NumberType, binary_char_t>::value,
16623 int > = 0 >
16624 void dump_integer(NumberType x)
16625 {
16626 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
16627 {
16628 {
16629 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
16630 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
16631 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
16632 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
16633 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
16634 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
16635 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
16636 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
16637 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
16638 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
16639 }
16640 };
16641
16642 // special case for "0"
16643 if (x == 0)
16644 {
16645 o->write_character('0');
16646 return;
16647 }
16648
16649 // use a pointer to fill the buffer
16650 auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16651
16652 const bool is_negative = std::is_same<NumberType, number_integer_t>::value && !(x >= 0); // see issue #755
16653 number_unsigned_t abs_value;
16654
16655 unsigned int n_chars{};
16656
16657 if (is_negative)
16658 {
16659 *buffer_ptr = '-';
16660 abs_value = remove_sign(static_cast<number_integer_t>(x));
16661
16662 // account one more byte for the minus sign
16663 n_chars = 1 + count_digits(abs_value);
16664 }
16665 else
16666 {
16667 abs_value = static_cast<number_unsigned_t>(x);
16668 n_chars = count_digits(abs_value);
16669 }
16670
16671 // spare 1 byte for '\0'
16672 JSON_ASSERT(n_chars < number_buffer.size() - 1);
16673
16674 // jump to the end to generate the string from backward
16675 // so we later avoid reversing the result
16676 buffer_ptr += n_chars;
16677
16678 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
16679 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
16680 while (abs_value >= 100)
16681 {
16682 const auto digits_index = static_cast<unsigned>((abs_value % 100));
16683 abs_value /= 100;
16684 *(--buffer_ptr) = digits_to_99[digits_index][1];
16685 *(--buffer_ptr) = digits_to_99[digits_index][0];
16686 }
16687
16688 if (abs_value >= 10)
16689 {
16690 const auto digits_index = static_cast<unsigned>(abs_value);
16691 *(--buffer_ptr) = digits_to_99[digits_index][1];
16692 *(--buffer_ptr) = digits_to_99[digits_index][0];
16693 }
16694 else
16695 {
16696 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
16697 }
16698
16699 o->write_characters(number_buffer.data(), n_chars);
16700 }
16701
16710 void dump_float(number_float_t x)
16711 {
16712 // NaN / inf
16713 if (!std::isfinite(x))
16714 {
16715 o->write_characters("null", 4);
16716 return;
16717 }
16718
16719 // If number_float_t is an IEEE-754 single or double precision number,
16720 // use the Grisu2 algorithm to produce short numbers which are
16721 // guaranteed to round-trip, using strtof and strtod, resp.
16722 //
16723 // NB: The test below works if <long double> == <double>.
16724 static constexpr bool is_ieee_single_or_double
16725 = (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) ||
16726 (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);
16727
16728 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
16729 }
16730
16731 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
16732 {
16733 auto* begin = number_buffer.data();
16734 auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
16735
16736 o->write_characters(begin, static_cast<size_t>(end - begin));
16737 }
16738
16739 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
16740 {
16741 // get number of digits for a float -> text -> float round-trip
16742 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
16743
16744 // the actual conversion
16745 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16746 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
16747
16748 // negative value indicates an error
16749 JSON_ASSERT(len > 0);
16750 // check if buffer was large enough
16751 JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
16752
16753 // erase thousands separator
16754 if (thousands_sep != '\0')
16755 {
16756 auto* const end = std::remove(number_buffer.begin(),
16757 number_buffer.begin() + len, thousands_sep);
16758 std::fill(end, number_buffer.end(), '\0');
16759 JSON_ASSERT((end - number_buffer.begin()) <= len);
16760 len = (end - number_buffer.begin());
16761 }
16762
16763 // convert decimal point to '.'
16764 if (decimal_point != '\0' && decimal_point != '.')
16765 {
16766 auto* const dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
16767 if (dec_pos != number_buffer.end())
16768 {
16769 *dec_pos = '.';
16770 }
16771 }
16772
16773 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
16774
16775 // determine if need to append ".0"
16776 const bool value_is_int_like =
16777 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
16778 [](char c)
16779 {
16780 return c == '.' || c == 'e';
16781 });
16782
16783 if (value_is_int_like)
16784 {
16785 o->write_characters(".0", 2);
16786 }
16787 }
16788
16810 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
16811 {
16812 static const std::array<std::uint8_t, 400> utf8d =
16813 {
16814 {
16815 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
16816 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
16817 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
16818 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
16819 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
16820 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
16821 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
16822 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
16823 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
16824 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
16825 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
16826 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
16827 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
16828 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
16829 }
16830 };
16831
16832 JSON_ASSERT(byte < utf8d.size());
16833 const std::uint8_t type = utf8d[byte];
16834
16835 codep = (state != UTF8_ACCEPT)
16836 ? (byte & 0x3fu) | (codep << 6u)
16837 : (0xFFu >> type) & (byte);
16838
16839 std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
16840 JSON_ASSERT(index < 400);
16841 state = utf8d[index];
16842 return state;
16843 }
16844
16845 /*
16846 * Overload to make the compiler happy while it is instantiating
16847 * dump_integer for number_unsigned_t.
16848 * Must never be called.
16849 */
16850 number_unsigned_t remove_sign(number_unsigned_t x)
16851 {
16852 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16853 return x; // LCOV_EXCL_LINE
16854 }
16855
16856 /*
16857 * Helper function for dump_integer
16858 *
16859 * This function takes a negative signed integer and returns its absolute
16860 * value as unsigned integer. The plus/minus shuffling is necessary as we can
16861 * not directly remove the sign of an arbitrary signed integer as the
16862 * absolute values of INT_MIN and INT_MAX are usually not the same. See
16863 * #1708 for details.
16864 */
16865 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
16866 {
16867 JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
16868 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
16869 }
16870
16871 private:
16873 output_adapter_t<char> o = nullptr;
16874
16876 std::array<char, 64> number_buffer{{}};
16877
16879 const std::lconv* loc = nullptr;
16881 const char thousands_sep = '\0';
16883 const char decimal_point = '\0';
16884
16886 std::array<char, 512> string_buffer{{}};
16887
16889 const char indent_char;
16891 string_t indent_string;
16892
16894 const error_handler_t error_handler;
16895 };
16896 } // namespace detail
16897 } // namespace nlohmann
16898
16899 // #include <nlohmann/detail/value_t.hpp>
16900
16901 // #include <nlohmann/json_fwd.hpp>
16902
16903 // #include <nlohmann/ordered_map.hpp>
16904
16905
16906 #include <functional> // less
16907 #include <initializer_list> // initializer_list
16908 #include <iterator> // input_iterator_tag, iterator_traits
16909 #include <memory> // allocator
16910 #include <stdexcept> // for out_of_range
16911 #include <type_traits> // enable_if, is_convertible
16912 #include <utility> // pair
16913 #include <vector> // vector
16914
16915 // #include <nlohmann/detail/macro_scope.hpp>
16916
16917
16918 namespace nlohmann
16919 {
16920
16923 template <class Key, class T, class IgnoredLess = std::less<Key>,
16924 class Allocator = std::allocator<std::pair<const Key, T>>>
16925 struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
16926 {
16927 using key_type = Key;
16928 using mapped_type = T;
16929 using Container = std::vector<std::pair<const Key, T>, Allocator>;
16930 using typename Container::iterator;
16931 using typename Container::const_iterator;
16932 using typename Container::size_type;
16933 using typename Container::value_type;
16934
16935 // Explicit constructors instead of `using Container::Container`
16936 // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
16937 ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
16938 template <class It>
16939 ordered_map(It first, It last, const Allocator& alloc = Allocator())
16940 : Container{first, last, alloc} {}
16941 ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
16942 : Container{init, alloc} {}
16943
16944 std::pair<iterator, bool> emplace(const key_type& key, T&& t)
16945 {
16946 for (auto it = this->begin(); it != this->end(); ++it)
16947 {
16948 if (it->first == key)
16949 {
16950 return {it, false};
16951 }
16952 }
16953 Container::emplace_back(key, t);
16954 return {--this->end(), true};
16955 }
16956
16957 T& operator[](const Key& key)
16958 {
16959 return emplace(key, T{}).first->second;
16960 }
16961
16962 const T& operator[](const Key& key) const
16963 {
16964 return at(key);
16965 }
16966
16967 T& at(const Key& key)
16968 {
16969 for (auto it = this->begin(); it != this->end(); ++it)
16970 {
16971 if (it->first == key)
16972 {
16973 return it->second;
16974 }
16975 }
16976
16977 JSON_THROW(std::out_of_range("key not found"));
16978 }
16979
16980 const T& at(const Key& key) const
16981 {
16982 for (auto it = this->begin(); it != this->end(); ++it)
16983 {
16984 if (it->first == key)
16985 {
16986 return it->second;
16987 }
16988 }
16989
16990 JSON_THROW(std::out_of_range("key not found"));
16991 }
16992
16993 size_type erase(const Key& key)
16994 {
16995 for (auto it = this->begin(); it != this->end(); ++it)
16996 {
16997 if (it->first == key)
16998 {
16999 // Since we cannot move const Keys, re-construct them in place
17000 for (auto next = it; ++next != this->end(); ++it)
17001 {
17002 it->~value_type(); // Destroy but keep allocation
17003 new (&*it) value_type{std::move(*next)};
17004 }
17005 Container::pop_back();
17006 return 1;
17007 }
17008 }
17009 return 0;
17010 }
17011
17012 iterator erase(iterator pos)
17013 {
17014 auto it = pos;
17015
17016 // Since we cannot move const Keys, re-construct them in place
17017 for (auto next = it; ++next != this->end(); ++it)
17018 {
17019 it->~value_type(); // Destroy but keep allocation
17020 new (&*it) value_type{std::move(*next)};
17021 }
17022 Container::pop_back();
17023 return pos;
17024 }
17025
17026 size_type count(const Key& key) const
17027 {
17028 for (auto it = this->begin(); it != this->end(); ++it)
17029 {
17030 if (it->first == key)
17031 {
17032 return 1;
17033 }
17034 }
17035 return 0;
17036 }
17037
17038 iterator find(const Key& key)
17039 {
17040 for (auto it = this->begin(); it != this->end(); ++it)
17041 {
17042 if (it->first == key)
17043 {
17044 return it;
17045 }
17046 }
17047 return Container::end();
17048 }
17049
17050 const_iterator find(const Key& key) const
17051 {
17052 for (auto it = this->begin(); it != this->end(); ++it)
17053 {
17054 if (it->first == key)
17055 {
17056 return it;
17057 }
17058 }
17059 return Container::end();
17060 }
17061
17062 std::pair<iterator, bool> insert( value_type&& value )
17063 {
17064 return emplace(value.first, std::move(value.second));
17065 }
17066
17067 std::pair<iterator, bool> insert( const value_type& value )
17068 {
17069 for (auto it = this->begin(); it != this->end(); ++it)
17070 {
17071 if (it->first == value.first)
17072 {
17073 return {it, false};
17074 }
17075 }
17076 Container::push_back(value);
17077 return {--this->end(), true};
17078 }
17079
17080 template<typename InputIt>
17081 using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
17082 std::input_iterator_tag>::value>::type;
17083
17084 template<typename InputIt, typename = require_input_iter<InputIt>>
17085 void insert(InputIt first, InputIt last)
17086 {
17087 for (auto it = first; it != last; ++it)
17088 {
17089 insert(*it);
17090 }
17091 }
17092 };
17093
17094 } // namespace nlohmann
17095
17096
17097 #if defined(JSON_HAS_CPP_17)
17098 #include <string_view>
17099 #endif
17100
17106 namespace nlohmann
17107 {
17108
17193 NLOHMANN_BASIC_JSON_TPL_DECLARATION
17194 class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
17195 {
17196 private:
17197 template<detail::value_t> friend struct detail::external_constructor;
17198 friend ::nlohmann::json_pointer<basic_json>;
17199
17200 template<typename BasicJsonType, typename InputType>
17201 friend class ::nlohmann::detail::parser;
17202 friend ::nlohmann::detail::serializer<basic_json>;
17203 template<typename BasicJsonType>
17204 friend class ::nlohmann::detail::iter_impl;
17205 template<typename BasicJsonType, typename CharType>
17206 friend class ::nlohmann::detail::binary_writer;
17207 template<typename BasicJsonType, typename InputType, typename SAX>
17208 friend class ::nlohmann::detail::binary_reader;
17209 template<typename BasicJsonType>
17210 friend class ::nlohmann::detail::json_sax_dom_parser;
17211 template<typename BasicJsonType>
17212 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
17213 friend class ::nlohmann::detail::exception;
17214
17216 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
17217
17218 JSON_PRIVATE_UNLESS_TESTED:
17219 // convenience aliases for types residing in namespace detail;
17220 using lexer = ::nlohmann::detail::lexer_base<basic_json>;
17221
17222 template<typename InputAdapterType>
17223 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
17224 InputAdapterType adapter,
17225 detail::parser_callback_t<basic_json>cb = nullptr,
17226 const bool allow_exceptions = true,
17227 const bool ignore_comments = false
17228 )
17229 {
17230 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
17231 std::move(cb), allow_exceptions, ignore_comments);
17232 }
17233
17234 private:
17235 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
17236 template<typename BasicJsonType>
17237 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
17238 template<typename BasicJsonType>
17239 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
17240 template<typename Iterator>
17241 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
17242 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
17243
17244 template<typename CharType>
17245 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
17246
17247 template<typename InputType>
17248 using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
17249 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
17250
17251 JSON_PRIVATE_UNLESS_TESTED:
17252 using serializer = ::nlohmann::detail::serializer<basic_json>;
17253
17254 public:
17255 using value_t = detail::value_t;
17257 using json_pointer = ::nlohmann::json_pointer<basic_json>;
17258 template<typename T, typename SFINAE>
17259 using json_serializer = JSONSerializer<T, SFINAE>;
17261 using error_handler_t = detail::error_handler_t;
17263 using cbor_tag_handler_t = detail::cbor_tag_handler_t;
17265 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
17266
17267 using input_format_t = detail::input_format_t;
17269 using json_sax_t = json_sax<basic_json>;
17270
17272 // exceptions //
17274
17278
17280 using exception = detail::exception;
17282 using parse_error = detail::parse_error;
17284 using invalid_iterator = detail::invalid_iterator;
17286 using type_error = detail::type_error;
17288 using out_of_range = detail::out_of_range;
17290 using other_error = detail::other_error;
17291
17293
17294
17296 // container types //
17298
17303
17305 using value_type = basic_json;
17306
17308 using reference = value_type&;
17310 using const_reference = const value_type&;
17311
17313 using difference_type = std::ptrdiff_t;
17315 using size_type = std::size_t;
17316
17318 using allocator_type = AllocatorType<basic_json>;
17319
17321 using pointer = typename std::allocator_traits<allocator_type>::pointer;
17323 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
17324
17326 using iterator = iter_impl<basic_json>;
17328 using const_iterator = iter_impl<const basic_json>;
17330 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
17332 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
17333
17335
17336
17340 static allocator_type get_allocator()
17341 {
17342 return allocator_type();
17343 }
17344
17371 JSON_HEDLEY_WARN_UNUSED_RESULT
17372 static basic_json meta()
17373 {
17374 basic_json result;
17375
17376 result["copyright"] = "(C) 2013-2021 Niels Lohmann";
17377 result["name"] = "JSON for Modern C++";
17378 result["url"] = "https://github.com/nlohmann/json";
17379 result["version"]["string"] =
17380 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
17381 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
17382 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
17383 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
17384 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
17385 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
17386
17387 #ifdef _WIN32
17388 result["platform"] = "win32";
17389 #elif defined __linux__
17390 result["platform"] = "linux";
17391 #elif defined __APPLE__
17392 result["platform"] = "apple";
17393 #elif defined __unix__
17394 result["platform"] = "unix";
17395 #else
17396 result["platform"] = "unknown";
17397 #endif
17398
17399 #if defined(__ICC) || defined(__INTEL_COMPILER)
17400 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
17401 #elif defined(__clang__)
17402 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
17403 #elif defined(__GNUC__) || defined(__GNUG__)
17404 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
17405 #elif defined(__HP_cc) || defined(__HP_aCC)
17406 result["compiler"] = "hp"
17407 #elif defined(__IBMCPP__)
17408 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
17409 #elif defined(_MSC_VER)
17410 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
17411 #elif defined(__PGI)
17412 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
17413 #elif defined(__SUNPRO_CC)
17414 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
17415 #else
17416 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
17417 #endif
17418
17419 #ifdef __cplusplus
17420 result["compiler"]["c++"] = std::to_string(__cplusplus);
17421 #else
17422 result["compiler"]["c++"] = "unknown";
17423 #endif
17424 return result;
17425 }
17426
17427
17429 // JSON value data types //
17431
17436
17437 #if defined(JSON_HAS_CPP_14)
17438 // Use transparent comparator if possible, combined with perfect forwarding
17439 // on find() and count() calls prevents unnecessary string construction.
17440 using object_comparator_t = std::less<>;
17441 #else
17442 using object_comparator_t = std::less<StringType>;
17443 #endif
17444
17528 using object_t = ObjectType<StringType,
17529 basic_json,
17530 object_comparator_t,
17531 AllocatorType<std::pair<const StringType,
17532 basic_json>>>;
17533
17578 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
17579
17631 using string_t = StringType;
17632
17657 using boolean_t = BooleanType;
17658
17729 using number_integer_t = NumberIntegerType;
17730
17800 using number_unsigned_t = NumberUnsignedType;
17801
17868 using number_float_t = NumberFloatType;
17869
17939 using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
17941
17942 private:
17943
17945 template<typename T, typename... Args>
17946 JSON_HEDLEY_RETURNS_NON_NULL
17947 static T* create(Args&& ... args)
17948 {
17949 AllocatorType<T> alloc;
17950 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
17951
17952 auto deleter = [&](T * obj)
17953 {
17954 AllocatorTraits::deallocate(alloc, obj, 1);
17955 };
17956 std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
17957 AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
17958 JSON_ASSERT(obj != nullptr);
17959 return obj.release();
17960 }
17961
17963 // JSON value storage //
17965
17966 JSON_PRIVATE_UNLESS_TESTED:
17992 union json_value
17993 {
17995 object_t* object;
17997 array_t* array;
17999 string_t* string;
18001 binary_t* binary;
18003 boolean_t boolean;
18005 number_integer_t number_integer;
18007 number_unsigned_t number_unsigned;
18009 number_float_t number_float;
18010
18012 json_value() = default;
18014 json_value(boolean_t v) noexcept : boolean(v) {}
18016 json_value(number_integer_t v) noexcept : number_integer(v) {}
18018 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
18020 json_value(number_float_t v) noexcept : number_float(v) {}
18022 json_value(value_t t)
18023 {
18024 switch (t)
18025 {
18026 case value_t::object:
18027 {
18028 object = create<object_t>();
18029 break;
18030 }
18031
18032 case value_t::array:
18033 {
18034 array = create<array_t>();
18035 break;
18036 }
18037
18038 case value_t::string:
18039 {
18040 string = create<string_t>("");
18041 break;
18042 }
18043
18044 case value_t::binary:
18045 {
18046 binary = create<binary_t>();
18047 break;
18048 }
18049
18050 case value_t::boolean:
18051 {
18052 boolean = boolean_t(false);
18053 break;
18054 }
18055
18056 case value_t::number_integer:
18057 {
18058 number_integer = number_integer_t(0);
18059 break;
18060 }
18061
18062 case value_t::number_unsigned:
18063 {
18064 number_unsigned = number_unsigned_t(0);
18065 break;
18066 }
18067
18068 case value_t::number_float:
18069 {
18070 number_float = number_float_t(0.0);
18071 break;
18072 }
18073
18074 case value_t::null:
18075 {
18076 object = nullptr; // silence warning, see #821
18077 break;
18078 }
18079
18080 default:
18081 {
18082 object = nullptr; // silence warning, see #821
18083 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
18084 {
18085 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.9.1", basic_json())); // LCOV_EXCL_LINE
18086 }
18087 break;
18088 }
18089 }
18090 }
18091
18093 json_value(const string_t& value)
18094 {
18095 string = create<string_t>(value);
18096 }
18097
18099 json_value(string_t&& value)
18100 {
18101 string = create<string_t>(std::move(value));
18102 }
18103
18105 json_value(const object_t& value)
18106 {
18107 object = create<object_t>(value);
18108 }
18109
18111 json_value(object_t&& value)
18112 {
18113 object = create<object_t>(std::move(value));
18114 }
18115
18117 json_value(const array_t& value)
18118 {
18119 array = create<array_t>(value);
18120 }
18121
18123 json_value(array_t&& value)
18124 {
18125 array = create<array_t>(std::move(value));
18126 }
18127
18129 json_value(const typename binary_t::container_type& value)
18130 {
18131 binary = create<binary_t>(value);
18132 }
18133
18135 json_value(typename binary_t::container_type&& value)
18136 {
18137 binary = create<binary_t>(std::move(value));
18138 }
18139
18141 json_value(const binary_t& value)
18142 {
18143 binary = create<binary_t>(value);
18144 }
18145
18147 json_value(binary_t&& value)
18148 {
18149 binary = create<binary_t>(std::move(value));
18150 }
18151
18152 void destroy(value_t t) noexcept
18153 {
18154 // flatten the current json_value to a heap-allocated stack
18155 std::vector<basic_json> stack;
18156
18157 // move the top-level items to stack
18158 if (t == value_t::array)
18159 {
18160 stack.reserve(array->size());
18161 std::move(array->begin(), array->end(), std::back_inserter(stack));
18162 }
18163 else if (t == value_t::object)
18164 {
18165 stack.reserve(object->size());
18166 for (auto&& it : *object)
18167 {
18168 stack.push_back(std::move(it.second));
18169 }
18170 }
18171
18172 while (!stack.empty())
18173 {
18174 // move the last item to local variable to be processed
18175 basic_json current_item(std::move(stack.back()));
18176 stack.pop_back();
18177
18178 // if current_item is array/object, move
18179 // its children to the stack to be processed later
18180 if (current_item.is_array())
18181 {
18182 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
18183 std::back_inserter(stack));
18184
18185 current_item.m_value.array->clear();
18186 }
18187 else if (current_item.is_object())
18188 {
18189 for (auto&& it : *current_item.m_value.object)
18190 {
18191 stack.push_back(std::move(it.second));
18192 }
18193
18194 current_item.m_value.object->clear();
18195 }
18196
18197 // it's now safe that current_item get destructed
18198 // since it doesn't have any children
18199 }
18200
18201 switch (t)
18202 {
18203 case value_t::object:
18204 {
18205 AllocatorType<object_t> alloc;
18206 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
18207 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
18208 break;
18209 }
18210
18211 case value_t::array:
18212 {
18213 AllocatorType<array_t> alloc;
18214 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
18215 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
18216 break;
18217 }
18218
18219 case value_t::string:
18220 {
18221 AllocatorType<string_t> alloc;
18222 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
18223 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
18224 break;
18225 }
18226
18227 case value_t::binary:
18228 {
18229 AllocatorType<binary_t> alloc;
18230 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
18231 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
18232 break;
18233 }
18234
18235 default:
18236 {
18237 break;
18238 }
18239 }
18240 }
18241 };
18242
18243 private:
18262 void assert_invariant(bool check_parents = true) const noexcept
18263 {
18264 JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
18265 JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
18266 JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
18267 JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
18268
18269 #if JSON_DIAGNOSTICS
18270 JSON_TRY
18271 {
18272 // cppcheck-suppress assertWithSideEffect
18273 JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
18274 {
18275 return j.m_parent == this;
18276 }));
18277 }
18278 JSON_CATCH(...) {} // LCOV_EXCL_LINE
18279 #endif
18280 static_cast<void>(check_parents);
18281 }
18282
18283 void set_parents()
18284 {
18285 #if JSON_DIAGNOSTICS
18286 switch (m_type)
18287 {
18288 case value_t::array:
18289 {
18290 for (auto& element : *m_value.array)
18291 {
18292 element.m_parent = this;
18293 }
18294 break;
18295 }
18296
18297 case value_t::object:
18298 {
18299 for (auto& element : *m_value.object)
18300 {
18301 element.second.m_parent = this;
18302 }
18303 break;
18304 }
18305
18306 default:
18307 break;
18308 }
18309 #endif
18310 }
18311
18312 iterator set_parents(iterator it, typename iterator::difference_type count)
18313 {
18314 #if JSON_DIAGNOSTICS
18315 for (typename iterator::difference_type i = 0; i < count; ++i)
18316 {
18317 (it + i)->m_parent = this;
18318 }
18319 #else
18320 static_cast<void>(count);
18321 #endif
18322 return it;
18323 }
18324
18325 reference set_parent(reference j)
18326 {
18327 #if JSON_DIAGNOSTICS
18328 j.m_parent = this;
18329 #else
18330 static_cast<void>(j);
18331 #endif
18332 return j;
18333 }
18334
18335 public:
18337 // JSON parser callback //
18339
18355 using parse_event_t = detail::parse_event_t;
18356
18406 using parser_callback_t = detail::parser_callback_t<basic_json>;
18407
18409 // constructors //
18411
18416
18447 basic_json(const value_t v)
18448 : m_type(v), m_value(v)
18449 {
18450 assert_invariant();
18451 }
18452
18471 basic_json(std::nullptr_t = nullptr) noexcept
18472 : basic_json(value_t::null)
18473 {
18474 assert_invariant();
18475 }
18476
18539 template < typename CompatibleType,
18540 typename U = detail::uncvref_t<CompatibleType>,
18541 detail::enable_if_t <
18542 !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
18543 basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
18544 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
18545 std::forward<CompatibleType>(val))))
18546 {
18547 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
18548 set_parents();
18549 assert_invariant();
18550 }
18551
18578 template < typename BasicJsonType,
18579 detail::enable_if_t <
18580 detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
18581 basic_json(const BasicJsonType& val)
18582 {
18583 using other_boolean_t = typename BasicJsonType::boolean_t;
18584 using other_number_float_t = typename BasicJsonType::number_float_t;
18585 using other_number_integer_t = typename BasicJsonType::number_integer_t;
18586 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
18587 using other_string_t = typename BasicJsonType::string_t;
18588 using other_object_t = typename BasicJsonType::object_t;
18589 using other_array_t = typename BasicJsonType::array_t;
18590 using other_binary_t = typename BasicJsonType::binary_t;
18591
18592 switch (val.type())
18593 {
18594 case value_t::boolean:
18595 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
18596 break;
18597 case value_t::number_float:
18598 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
18599 break;
18600 case value_t::number_integer:
18601 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
18602 break;
18603 case value_t::number_unsigned:
18604 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
18605 break;
18606 case value_t::string:
18607 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
18608 break;
18609 case value_t::object:
18610 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
18611 break;
18612 case value_t::array:
18613 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
18614 break;
18615 case value_t::binary:
18616 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
18617 break;
18618 case value_t::null:
18619 *this = nullptr;
18620 break;
18621 case value_t::discarded:
18622 m_type = value_t::discarded;
18623 break;
18624 default: // LCOV_EXCL_LINE
18625 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18626 }
18627 set_parents();
18628 assert_invariant();
18629 }
18630
18705 basic_json(initializer_list_t init,
18706 bool type_deduction = true,
18707 value_t manual_type = value_t::array)
18708 {
18709 // check if each element is an array with two elements whose first
18710 // element is a string
18711 bool is_an_object = std::all_of(init.begin(), init.end(),
18712 [](const detail::json_ref<basic_json>& element_ref)
18713 {
18714 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
18715 });
18716
18717 // adjust type if type deduction is not wanted
18718 if (!type_deduction)
18719 {
18720 // if array is wanted, do not create an object though possible
18721 if (manual_type == value_t::array)
18722 {
18723 is_an_object = false;
18724 }
18725
18726 // if object is wanted but impossible, throw an exception
18727 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
18728 {
18729 JSON_THROW(type_error::create(301, "cannot create object from initializer list", basic_json()));
18730 }
18731 }
18732
18733 if (is_an_object)
18734 {
18735 // the initializer list is a list of pairs -> create object
18736 m_type = value_t::object;
18737 m_value = value_t::object;
18738
18739 for (auto& element_ref : init)
18740 {
18741 auto element = element_ref.moved_or_copied();
18742 m_value.object->emplace(
18743 std::move(*((*element.m_value.array)[0].m_value.string)),
18744 std::move((*element.m_value.array)[1]));
18745 }
18746 }
18747 else
18748 {
18749 // the initializer list describes an array -> create array
18750 m_type = value_t::array;
18751 m_value.array = create<array_t>(init.begin(), init.end());
18752 }
18753
18754 set_parents();
18755 assert_invariant();
18756 }
18757
18785 JSON_HEDLEY_WARN_UNUSED_RESULT
18786 static basic_json binary(const typename binary_t::container_type& init)
18787 {
18788 auto res = basic_json();
18789 res.m_type = value_t::binary;
18790 res.m_value = init;
18791 return res;
18792 }
18793
18822 JSON_HEDLEY_WARN_UNUSED_RESULT
18823 static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype)
18824 {
18825 auto res = basic_json();
18826 res.m_type = value_t::binary;
18827 res.m_value = binary_t(init, subtype);
18828 return res;
18829 }
18830
18832 JSON_HEDLEY_WARN_UNUSED_RESULT
18833 static basic_json binary(typename binary_t::container_type&& init)
18834 {
18835 auto res = basic_json();
18836 res.m_type = value_t::binary;
18837 res.m_value = std::move(init);
18838 return res;
18839 }
18840
18842 JSON_HEDLEY_WARN_UNUSED_RESULT
18843 static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype)
18844 {
18845 auto res = basic_json();
18846 res.m_type = value_t::binary;
18847 res.m_value = binary_t(std::move(init), subtype);
18848 return res;
18849 }
18850
18888 JSON_HEDLEY_WARN_UNUSED_RESULT
18889 static basic_json array(initializer_list_t init = {})
18890 {
18891 return basic_json(init, false, value_t::array);
18892 }
18893
18932 JSON_HEDLEY_WARN_UNUSED_RESULT
18933 static basic_json object(initializer_list_t init = {})
18934 {
18935 return basic_json(init, false, value_t::object);
18936 }
18937
18960 basic_json(size_type cnt, const basic_json& val)
18961 : m_type(value_t::array)
18962 {
18963 m_value.array = create<array_t>(cnt, val);
18964 set_parents();
18965 assert_invariant();
18966 }
18967
19023 template < class InputIT, typename std::enable_if <
19024 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
19025 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
19026 basic_json(InputIT first, InputIT last)
19027 {
19028 JSON_ASSERT(first.m_object != nullptr);
19029 JSON_ASSERT(last.m_object != nullptr);
19030
19031 // make sure iterator fits the current value
19032 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19033 {
19034 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", basic_json()));
19035 }
19036
19037 // copy type from first iterator
19038 m_type = first.m_object->m_type;
19039
19040 // check if iterator range is complete for primitive values
19041 switch (m_type)
19042 {
19043 case value_t::boolean:
19044 case value_t::number_float:
19045 case value_t::number_integer:
19046 case value_t::number_unsigned:
19047 case value_t::string:
19048 {
19049 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
19050 || !last.m_it.primitive_iterator.is_end()))
19051 {
19052 JSON_THROW(invalid_iterator::create(204, "iterators out of range", *first.m_object));
19053 }
19054 break;
19055 }
19056
19057 default:
19058 break;
19059 }
19060
19061 switch (m_type)
19062 {
19063 case value_t::number_integer:
19064 {
19065 m_value.number_integer = first.m_object->m_value.number_integer;
19066 break;
19067 }
19068
19069 case value_t::number_unsigned:
19070 {
19071 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
19072 break;
19073 }
19074
19075 case value_t::number_float:
19076 {
19077 m_value.number_float = first.m_object->m_value.number_float;
19078 break;
19079 }
19080
19081 case value_t::boolean:
19082 {
19083 m_value.boolean = first.m_object->m_value.boolean;
19084 break;
19085 }
19086
19087 case value_t::string:
19088 {
19089 m_value = *first.m_object->m_value.string;
19090 break;
19091 }
19092
19093 case value_t::object:
19094 {
19095 m_value.object = create<object_t>(first.m_it.object_iterator,
19096 last.m_it.object_iterator);
19097 break;
19098 }
19099
19100 case value_t::array:
19101 {
19102 m_value.array = create<array_t>(first.m_it.array_iterator,
19103 last.m_it.array_iterator);
19104 break;
19105 }
19106
19107 case value_t::binary:
19108 {
19109 m_value = *first.m_object->m_value.binary;
19110 break;
19111 }
19112
19113 default:
19114 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object));
19115 }
19116
19117 set_parents();
19118 assert_invariant();
19119 }
19120
19121
19123 // other constructors and destructor //
19125
19126 template<typename JsonRef,
19127 detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
19128 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
19129 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
19130
19156 basic_json(const basic_json& other)
19157 : m_type(other.m_type)
19158 {
19159 // check of passed value is valid
19160 other.assert_invariant();
19161
19162 switch (m_type)
19163 {
19164 case value_t::object:
19165 {
19166 m_value = *other.m_value.object;
19167 break;
19168 }
19169
19170 case value_t::array:
19171 {
19172 m_value = *other.m_value.array;
19173 break;
19174 }
19175
19176 case value_t::string:
19177 {
19178 m_value = *other.m_value.string;
19179 break;
19180 }
19181
19182 case value_t::boolean:
19183 {
19184 m_value = other.m_value.boolean;
19185 break;
19186 }
19187
19188 case value_t::number_integer:
19189 {
19190 m_value = other.m_value.number_integer;
19191 break;
19192 }
19193
19194 case value_t::number_unsigned:
19195 {
19196 m_value = other.m_value.number_unsigned;
19197 break;
19198 }
19199
19200 case value_t::number_float:
19201 {
19202 m_value = other.m_value.number_float;
19203 break;
19204 }
19205
19206 case value_t::binary:
19207 {
19208 m_value = *other.m_value.binary;
19209 break;
19210 }
19211
19212 default:
19213 break;
19214 }
19215
19216 set_parents();
19217 assert_invariant();
19218 }
19219
19246 basic_json(basic_json&& other) noexcept
19247 : m_type(std::move(other.m_type)),
19248 m_value(std::move(other.m_value))
19249 {
19250 // check that passed value is valid
19251 other.assert_invariant(false);
19252
19253 // invalidate payload
19254 other.m_type = value_t::null;
19255 other.m_value = {};
19256
19257 set_parents();
19258 assert_invariant();
19259 }
19260
19284 basic_json& operator=(basic_json other) noexcept (
19285 std::is_nothrow_move_constructible<value_t>::value&&
19286 std::is_nothrow_move_assignable<value_t>::value&&
19287 std::is_nothrow_move_constructible<json_value>::value&&
19288 std::is_nothrow_move_assignable<json_value>::value
19289 )
19290 {
19291 // check that passed value is valid
19292 other.assert_invariant();
19293
19294 using std::swap;
19295 swap(m_type, other.m_type);
19296 swap(m_value, other.m_value);
19297
19298 set_parents();
19299 assert_invariant();
19300 return *this;
19301 }
19302
19318 ~basic_json() noexcept
19319 {
19320 assert_invariant(false);
19321 m_value.destroy(m_type);
19322 }
19323
19325
19326 public:
19328 // object inspection //
19330
19334
19382 string_t dump(const int indent = -1,
19383 const char indent_char = ' ',
19384 const bool ensure_ascii = false,
19385 const error_handler_t error_handler = error_handler_t::strict) const
19386 {
19387 string_t result;
19388 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
19389
19390 if (indent >= 0)
19391 {
19392 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
19393 }
19394 else
19395 {
19396 s.dump(*this, false, ensure_ascii, 0);
19397 }
19398
19399 return result;
19400 }
19401
19435 constexpr value_t type() const noexcept
19436 {
19437 return m_type;
19438 }
19439
19466 constexpr bool is_primitive() const noexcept
19467 {
19468 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
19469 }
19470
19493 constexpr bool is_structured() const noexcept
19494 {
19495 return is_array() || is_object();
19496 }
19497
19515 constexpr bool is_null() const noexcept
19516 {
19517 return m_type == value_t::null;
19518 }
19519
19537 constexpr bool is_boolean() const noexcept
19538 {
19539 return m_type == value_t::boolean;
19540 }
19541
19567 constexpr bool is_number() const noexcept
19568 {
19569 return is_number_integer() || is_number_float();
19570 }
19571
19596 constexpr bool is_number_integer() const noexcept
19597 {
19598 return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
19599 }
19600
19624 constexpr bool is_number_unsigned() const noexcept
19625 {
19626 return m_type == value_t::number_unsigned;
19627 }
19628
19652 constexpr bool is_number_float() const noexcept
19653 {
19654 return m_type == value_t::number_float;
19655 }
19656
19674 constexpr bool is_object() const noexcept
19675 {
19676 return m_type == value_t::object;
19677 }
19678
19696 constexpr bool is_array() const noexcept
19697 {
19698 return m_type == value_t::array;
19699 }
19700
19718 constexpr bool is_string() const noexcept
19719 {
19720 return m_type == value_t::string;
19721 }
19722
19740 constexpr bool is_binary() const noexcept
19741 {
19742 return m_type == value_t::binary;
19743 }
19744
19767 constexpr bool is_discarded() const noexcept
19768 {
19769 return m_type == value_t::discarded;
19770 }
19771
19793 constexpr operator value_t() const noexcept
19794 {
19795 return m_type;
19796 }
19797
19799
19800 private:
19802 // value access //
19804
19806 boolean_t get_impl(boolean_t* /*unused*/) const
19807 {
19808 if (JSON_HEDLEY_LIKELY(is_boolean()))
19809 {
19810 return m_value.boolean;
19811 }
19812
19813 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()), *this));
19814 }
19815
19817 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
19818 {
19819 return is_object() ? m_value.object : nullptr;
19820 }
19821
19823 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
19824 {
19825 return is_object() ? m_value.object : nullptr;
19826 }
19827
19829 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
19830 {
19831 return is_array() ? m_value.array : nullptr;
19832 }
19833
19835 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
19836 {
19837 return is_array() ? m_value.array : nullptr;
19838 }
19839
19841 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
19842 {
19843 return is_string() ? m_value.string : nullptr;
19844 }
19845
19847 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
19848 {
19849 return is_string() ? m_value.string : nullptr;
19850 }
19851
19853 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
19854 {
19855 return is_boolean() ? &m_value.boolean : nullptr;
19856 }
19857
19859 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
19860 {
19861 return is_boolean() ? &m_value.boolean : nullptr;
19862 }
19863
19865 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
19866 {
19867 return is_number_integer() ? &m_value.number_integer : nullptr;
19868 }
19869
19871 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
19872 {
19873 return is_number_integer() ? &m_value.number_integer : nullptr;
19874 }
19875
19877 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
19878 {
19879 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19880 }
19881
19883 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
19884 {
19885 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19886 }
19887
19889 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
19890 {
19891 return is_number_float() ? &m_value.number_float : nullptr;
19892 }
19893
19895 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
19896 {
19897 return is_number_float() ? &m_value.number_float : nullptr;
19898 }
19899
19901 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
19902 {
19903 return is_binary() ? m_value.binary : nullptr;
19904 }
19905
19907 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
19908 {
19909 return is_binary() ? m_value.binary : nullptr;
19910 }
19911
19923 template<typename ReferenceType, typename ThisType>
19924 static ReferenceType get_ref_impl(ThisType& obj)
19925 {
19926 // delegate the call to get_ptr<>()
19927 auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
19928
19929 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
19930 {
19931 return *ptr;
19932 }
19933
19934 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()), obj));
19935 }
19936
19937 public:
19941
19968 template<typename PointerType, typename std::enable_if<
19969 std::is_pointer<PointerType>::value, int>::type = 0>
19970 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19971 {
19972 // delegate the call to get_impl_ptr<>()
19973 return get_impl_ptr(static_cast<PointerType>(nullptr));
19974 }
19975
19980 template < typename PointerType, typename std::enable_if <
19981 std::is_pointer<PointerType>::value&&
19982 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
19983 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19984 {
19985 // delegate the call to get_impl_ptr<>() const
19986 return get_impl_ptr(static_cast<PointerType>(nullptr));
19987 }
19988
19989 private:
20028 template < typename ValueType,
20029 detail::enable_if_t <
20030 detail::is_default_constructible<ValueType>::value&&
20031 detail::has_from_json<basic_json_t, ValueType>::value,
20032 int > = 0 >
20033 ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20034 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20035 {
20036 ValueType ret{};
20037 JSONSerializer<ValueType>::from_json(*this, ret);
20038 return ret;
20039 }
20040
20071 template < typename ValueType,
20072 detail::enable_if_t <
20073 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
20074 int > = 0 >
20075 ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20076 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20077 {
20078 return JSONSerializer<ValueType>::from_json(*this);
20079 }
20080
20096 template < typename BasicJsonType,
20097 detail::enable_if_t <
20098 detail::is_basic_json<BasicJsonType>::value,
20099 int > = 0 >
20100 BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20101 {
20102 return *this;
20103 }
20104
20119 template<typename BasicJsonType,
20120 detail::enable_if_t<
20121 std::is_same<BasicJsonType, basic_json_t>::value,
20122 int> = 0>
20123 basic_json get_impl(detail::priority_tag<3> /*unused*/) const
20124 {
20125 return *this;
20126 }
20127
20132 template<typename PointerType,
20133 detail::enable_if_t<
20134 std::is_pointer<PointerType>::value,
20135 int> = 0>
20136 constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
20137 -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
20138 {
20139 // delegate the call to get_ptr
20140 return get_ptr<PointerType>();
20141 }
20142
20143 public:
20167 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
20168 #if defined(JSON_HAS_CPP_14)
20169 constexpr
20170 #endif
20171 auto get() const noexcept(
20172 noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
20173 -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
20174 {
20175 // we cannot static_assert on ValueTypeCV being non-const, because
20176 // there is support for get<const basic_json_t>(), which is why we
20177 // still need the uncvref
20178 static_assert(!std::is_reference<ValueTypeCV>::value,
20179 "get() cannot be used with reference types, you might want to use get_ref()");
20180 return get_impl<ValueType>(detail::priority_tag<4> {});
20181 }
20182
20210 template<typename PointerType, typename std::enable_if<
20211 std::is_pointer<PointerType>::value, int>::type = 0>
20212 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
20213 {
20214 // delegate the call to get_ptr
20215 return get_ptr<PointerType>();
20216 }
20217
20251 template < typename ValueType,
20252 detail::enable_if_t <
20253 !detail::is_basic_json<ValueType>::value&&
20254 detail::has_from_json<basic_json_t, ValueType>::value,
20255 int > = 0 >
20256 ValueType & get_to(ValueType& v) const noexcept(noexcept(
20257 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
20258 {
20259 JSONSerializer<ValueType>::from_json(*this, v);
20260 return v;
20261 }
20262
20263 // specialization to allow to call get_to with a basic_json value
20264 // see https://github.com/nlohmann/json/issues/2175
20265 template<typename ValueType,
20266 detail::enable_if_t <
20267 detail::is_basic_json<ValueType>::value,
20268 int> = 0>
20269 ValueType & get_to(ValueType& v) const
20270 {
20271 v = *this;
20272 return v;
20273 }
20274
20275 template <
20276 typename T, std::size_t N,
20277 typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20278 detail::enable_if_t <
20279 detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
20280 Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20281 noexcept(noexcept(JSONSerializer<Array>::from_json(
20282 std::declval<const basic_json_t&>(), v)))
20283 {
20284 JSONSerializer<Array>::from_json(*this, v);
20285 return v;
20286 }
20287
20314 template<typename ReferenceType, typename std::enable_if<
20315 std::is_reference<ReferenceType>::value, int>::type = 0>
20316 ReferenceType get_ref()
20317 {
20318 // delegate call to get_ref_impl
20319 return get_ref_impl<ReferenceType>(*this);
20320 }
20321
20326 template < typename ReferenceType, typename std::enable_if <
20327 std::is_reference<ReferenceType>::value&&
20328 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
20329 ReferenceType get_ref() const
20330 {
20331 // delegate call to get_ref_impl
20332 return get_ref_impl<ReferenceType>(*this);
20333 }
20334
20364 template < typename ValueType, typename std::enable_if <
20365 !std::is_pointer<ValueType>::value&&
20366 !std::is_same<ValueType, detail::json_ref<basic_json>>::value&&
20367 !std::is_same<ValueType, typename string_t::value_type>::value&&
20368 !detail::is_basic_json<ValueType>::value
20369 && !std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
20370 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
20371 && !std::is_same<ValueType, typename std::string_view>::value
20372 #endif
20373 && detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
20374 , int >::type = 0 >
20375 JSON_EXPLICIT operator ValueType() const
20376 {
20377 // delegate the call to get<>() const
20378 return get<ValueType>();
20379 }
20380
20390 binary_t& get_binary()
20391 {
20392 if (!is_binary())
20393 {
20394 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20395 }
20396
20397 return *get_ptr<binary_t*>();
20398 }
20399
20401 const binary_t& get_binary() const
20402 {
20403 if (!is_binary())
20404 {
20405 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20406 }
20407
20408 return *get_ptr<const binary_t*>();
20409 }
20410
20412
20413
20415 // element access //
20417
20421
20448 reference at(size_type idx)
20449 {
20450 // at only works for arrays
20451 if (JSON_HEDLEY_LIKELY(is_array()))
20452 {
20453 JSON_TRY
20454 {
20455 return set_parent(m_value.array->at(idx));
20456 }
20457 JSON_CATCH (std::out_of_range&)
20458 {
20459 // create better exception explanation
20460 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
20461 }
20462 }
20463 else
20464 {
20465 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
20466 }
20467 }
20468
20495 const_reference at(size_type idx) const
20496 {
20497 // at only works for arrays
20498 if (JSON_HEDLEY_LIKELY(is_array()))
20499 {
20500 JSON_TRY
20501 {
20502 return m_value.array->at(idx);
20503 }
20504 JSON_CATCH (std::out_of_range&)
20505 {
20506 // create better exception explanation
20507 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
20508 }
20509 }
20510 else
20511 {
20512 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
20513 }
20514 }
20515
20546 reference at(const typename object_t::key_type& key)
20547 {
20548 // at only works for objects
20549 if (JSON_HEDLEY_LIKELY(is_object()))
20550 {
20551 JSON_TRY
20552 {
20553 return set_parent(m_value.object->at(key));
20554 }
20555 JSON_CATCH (std::out_of_range&)
20556 {
20557 // create better exception explanation
20558 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
20559 }
20560 }
20561 else
20562 {
20563 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
20564 }
20565 }
20566
20597 const_reference at(const typename object_t::key_type& key) const
20598 {
20599 // at only works for objects
20600 if (JSON_HEDLEY_LIKELY(is_object()))
20601 {
20602 JSON_TRY
20603 {
20604 return m_value.object->at(key);
20605 }
20606 JSON_CATCH (std::out_of_range&)
20607 {
20608 // create better exception explanation
20609 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
20610 }
20611 }
20612 else
20613 {
20614 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
20615 }
20616 }
20617
20643 reference operator[](size_type idx)
20644 {
20645 // implicitly convert null value to an empty array
20646 if (is_null())
20647 {
20648 m_type = value_t::array;
20649 m_value.array = create<array_t>();
20650 assert_invariant();
20651 }
20652
20653 // operator[] only works for arrays
20654 if (JSON_HEDLEY_LIKELY(is_array()))
20655 {
20656 // fill up array with null values if given idx is outside range
20657 if (idx >= m_value.array->size())
20658 {
20659 #if JSON_DIAGNOSTICS
20660 // remember array size before resizing
20661 const auto previous_size = m_value.array->size();
20662 #endif
20663 m_value.array->resize(idx + 1);
20664
20665 #if JSON_DIAGNOSTICS
20666 // set parent for values added above
20667 set_parents(begin() + static_cast<typename iterator::difference_type>(previous_size), static_cast<typename iterator::difference_type>(idx + 1 - previous_size));
20668 #endif
20669 }
20670
20671 return m_value.array->operator[](idx);
20672 }
20673
20674 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
20675 }
20676
20696 const_reference operator[](size_type idx) const
20697 {
20698 // const operator[] only works for arrays
20699 if (JSON_HEDLEY_LIKELY(is_array()))
20700 {
20701 return m_value.array->operator[](idx);
20702 }
20703
20704 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
20705 }
20706
20734 reference operator[](const typename object_t::key_type& key)
20735 {
20736 // implicitly convert null value to an empty object
20737 if (is_null())
20738 {
20739 m_type = value_t::object;
20740 m_value.object = create<object_t>();
20741 assert_invariant();
20742 }
20743
20744 // operator[] only works for objects
20745 if (JSON_HEDLEY_LIKELY(is_object()))
20746 {
20747 return set_parent(m_value.object->operator[](key));
20748 }
20749
20750 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
20751 }
20752
20783 const_reference operator[](const typename object_t::key_type& key) const
20784 {
20785 // const operator[] only works for objects
20786 if (JSON_HEDLEY_LIKELY(is_object()))
20787 {
20788 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20789 return m_value.object->find(key)->second;
20790 }
20791
20792 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
20793 }
20794
20822 template<typename T>
20823 JSON_HEDLEY_NON_NULL(2)
20824 reference operator[](T* key)
20825 {
20826 // implicitly convert null to object
20827 if (is_null())
20828 {
20829 m_type = value_t::object;
20830 m_value = value_t::object;
20831 assert_invariant();
20832 }
20833
20834 // at only works for objects
20835 if (JSON_HEDLEY_LIKELY(is_object()))
20836 {
20837 return set_parent(m_value.object->operator[](key));
20838 }
20839
20840 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
20841 }
20842
20873 template<typename T>
20874 JSON_HEDLEY_NON_NULL(2)
20875 const_reference operator[](T* key) const
20876 {
20877 // at only works for objects
20878 if (JSON_HEDLEY_LIKELY(is_object()))
20879 {
20880 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20881 return m_value.object->find(key)->second;
20882 }
20883
20884 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
20885 }
20886
20937 // using std::is_convertible in a std::enable_if will fail when using explicit conversions
20938 template < class ValueType, typename std::enable_if <
20939 detail::is_getable<basic_json_t, ValueType>::value
20940 && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
20941 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
20942 {
20943 // at only works for objects
20944 if (JSON_HEDLEY_LIKELY(is_object()))
20945 {
20946 // if key is found, return value and given default value otherwise
20947 const auto it = find(key);
20948 if (it != end())
20949 {
20950 return it->template get<ValueType>();
20951 }
20952
20953 return default_value;
20954 }
20955
20956 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
20957 }
20958
20963 string_t value(const typename object_t::key_type& key, const char* default_value) const
20964 {
20965 return value(key, string_t(default_value));
20966 }
20967
21011 template<class ValueType, typename std::enable_if<
21012 detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
21013 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
21014 {
21015 // at only works for objects
21016 if (JSON_HEDLEY_LIKELY(is_object()))
21017 {
21018 // if pointer resolves a value, return it or use default value
21019 JSON_TRY
21020 {
21021 return ptr.get_checked(this).template get<ValueType>();
21022 }
21023 JSON_INTERNAL_CATCH (out_of_range&)
21024 {
21025 return default_value;
21026 }
21027 }
21028
21029 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21030 }
21031
21036 JSON_HEDLEY_NON_NULL(3)
21037 string_t value(const json_pointer& ptr, const char* default_value) const
21038 {
21039 return value(ptr, string_t(default_value));
21040 }
21041
21067 reference front()
21068 {
21069 return *begin();
21070 }
21071
21075 const_reference front() const
21076 {
21077 return *cbegin();
21078 }
21079
21111 reference back()
21112 {
21113 auto tmp = end();
21114 --tmp;
21115 return *tmp;
21116 }
21117
21121 const_reference back() const
21122 {
21123 auto tmp = cend();
21124 --tmp;
21125 return *tmp;
21126 }
21127
21174 template < class IteratorType, typename std::enable_if <
21175 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21176 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21177 = 0 >
21178 IteratorType erase(IteratorType pos)
21179 {
21180 // make sure iterator fits the current value
21181 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21182 {
21183 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
21184 }
21185
21186 IteratorType result = end();
21187
21188 switch (m_type)
21189 {
21190 case value_t::boolean:
21191 case value_t::number_float:
21192 case value_t::number_integer:
21193 case value_t::number_unsigned:
21194 case value_t::string:
21195 case value_t::binary:
21196 {
21197 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
21198 {
21199 JSON_THROW(invalid_iterator::create(205, "iterator out of range", *this));
21200 }
21201
21202 if (is_string())
21203 {
21204 AllocatorType<string_t> alloc;
21205 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21206 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21207 m_value.string = nullptr;
21208 }
21209 else if (is_binary())
21210 {
21211 AllocatorType<binary_t> alloc;
21212 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21213 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21214 m_value.binary = nullptr;
21215 }
21216
21217 m_type = value_t::null;
21218 assert_invariant();
21219 break;
21220 }
21221
21222 case value_t::object:
21223 {
21224 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
21225 break;
21226 }
21227
21228 case value_t::array:
21229 {
21230 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
21231 break;
21232 }
21233
21234 default:
21235 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21236 }
21237
21238 return result;
21239 }
21240
21287 template < class IteratorType, typename std::enable_if <
21288 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21289 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21290 = 0 >
21291 IteratorType erase(IteratorType first, IteratorType last)
21292 {
21293 // make sure iterator fits the current value
21294 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
21295 {
21296 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", *this));
21297 }
21298
21299 IteratorType result = end();
21300
21301 switch (m_type)
21302 {
21303 case value_t::boolean:
21304 case value_t::number_float:
21305 case value_t::number_integer:
21306 case value_t::number_unsigned:
21307 case value_t::string:
21308 case value_t::binary:
21309 {
21310 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
21311 || !last.m_it.primitive_iterator.is_end()))
21312 {
21313 JSON_THROW(invalid_iterator::create(204, "iterators out of range", *this));
21314 }
21315
21316 if (is_string())
21317 {
21318 AllocatorType<string_t> alloc;
21319 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21320 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21321 m_value.string = nullptr;
21322 }
21323 else if (is_binary())
21324 {
21325 AllocatorType<binary_t> alloc;
21326 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21327 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21328 m_value.binary = nullptr;
21329 }
21330
21331 m_type = value_t::null;
21332 assert_invariant();
21333 break;
21334 }
21335
21336 case value_t::object:
21337 {
21338 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
21339 last.m_it.object_iterator);
21340 break;
21341 }
21342
21343 case value_t::array:
21344 {
21345 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
21346 last.m_it.array_iterator);
21347 break;
21348 }
21349
21350 default:
21351 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21352 }
21353
21354 return result;
21355 }
21356
21386 size_type erase(const typename object_t::key_type& key)
21387 {
21388 // this erase only works for objects
21389 if (JSON_HEDLEY_LIKELY(is_object()))
21390 {
21391 return m_value.object->erase(key);
21392 }
21393
21394 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21395 }
21396
21421 void erase(const size_type idx)
21422 {
21423 // this erase only works for arrays
21424 if (JSON_HEDLEY_LIKELY(is_array()))
21425 {
21426 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21427 {
21428 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21429 }
21430
21431 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
21432 }
21433 else
21434 {
21435 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21436 }
21437 }
21438
21440
21441
21443 // lookup //
21445
21448
21473 template<typename KeyT>
21474 iterator find(KeyT&& key)
21475 {
21476 auto result = end();
21477
21478 if (is_object())
21479 {
21480 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
21481 }
21482
21483 return result;
21484 }
21485
21490 template<typename KeyT>
21491 const_iterator find(KeyT&& key) const
21492 {
21493 auto result = cend();
21494
21495 if (is_object())
21496 {
21497 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
21498 }
21499
21500 return result;
21501 }
21502
21524 template<typename KeyT>
21525 size_type count(KeyT&& key) const
21526 {
21527 // return 0 for all nonobject types
21528 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
21529 }
21530
21556 template < typename KeyT, typename std::enable_if <
21557 !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
21558 bool contains(KeyT && key) const
21559 {
21560 return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
21561 }
21562
21589 bool contains(const json_pointer& ptr) const
21590 {
21591 return ptr.contains(this);
21592 }
21593
21595
21596
21598 // iterators //
21600
21603
21628 iterator begin() noexcept
21629 {
21630 iterator result(this);
21631 result.set_begin();
21632 return result;
21633 }
21634
21638 const_iterator begin() const noexcept
21639 {
21640 return cbegin();
21641 }
21642
21668 const_iterator cbegin() const noexcept
21669 {
21670 const_iterator result(this);
21671 result.set_begin();
21672 return result;
21673 }
21674
21699 iterator end() noexcept
21700 {
21701 iterator result(this);
21702 result.set_end();
21703 return result;
21704 }
21705
21709 const_iterator end() const noexcept
21710 {
21711 return cend();
21712 }
21713
21739 const_iterator cend() const noexcept
21740 {
21741 const_iterator result(this);
21742 result.set_end();
21743 return result;
21744 }
21745
21769 reverse_iterator rbegin() noexcept
21770 {
21771 return reverse_iterator(end());
21772 }
21773
21777 const_reverse_iterator rbegin() const noexcept
21778 {
21779 return crbegin();
21780 }
21781
21806 reverse_iterator rend() noexcept
21807 {
21808 return reverse_iterator(begin());
21809 }
21810
21814 const_reverse_iterator rend() const noexcept
21815 {
21816 return crend();
21817 }
21818
21843 const_reverse_iterator crbegin() const noexcept
21844 {
21845 return const_reverse_iterator(cend());
21846 }
21847
21872 const_reverse_iterator crend() const noexcept
21873 {
21874 return const_reverse_iterator(cbegin());
21875 }
21876
21877 public:
21935 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21936 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
21937 {
21938 return ref.items();
21939 }
21940
21944 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21945 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
21946 {
21947 return ref.items();
21948 }
21949
22018 iteration_proxy<iterator> items() noexcept
22019 {
22020 return iteration_proxy<iterator>(*this);
22021 }
22022
22026 iteration_proxy<const_iterator> items() const noexcept
22027 {
22028 return iteration_proxy<const_iterator>(*this);
22029 }
22030
22032
22033
22035 // capacity //
22037
22040
22083 bool empty() const noexcept
22084 {
22085 switch (m_type)
22086 {
22087 case value_t::null:
22088 {
22089 // null values are empty
22090 return true;
22091 }
22092
22093 case value_t::array:
22094 {
22095 // delegate call to array_t::empty()
22096 return m_value.array->empty();
22097 }
22098
22099 case value_t::object:
22100 {
22101 // delegate call to object_t::empty()
22102 return m_value.object->empty();
22103 }
22104
22105 default:
22106 {
22107 // all other types are nonempty
22108 return false;
22109 }
22110 }
22111 }
22112
22156 size_type size() const noexcept
22157 {
22158 switch (m_type)
22159 {
22160 case value_t::null:
22161 {
22162 // null values are empty
22163 return 0;
22164 }
22165
22166 case value_t::array:
22167 {
22168 // delegate call to array_t::size()
22169 return m_value.array->size();
22170 }
22171
22172 case value_t::object:
22173 {
22174 // delegate call to object_t::size()
22175 return m_value.object->size();
22176 }
22177
22178 default:
22179 {
22180 // all other types have size 1
22181 return 1;
22182 }
22183 }
22184 }
22185
22227 size_type max_size() const noexcept
22228 {
22229 switch (m_type)
22230 {
22231 case value_t::array:
22232 {
22233 // delegate call to array_t::max_size()
22234 return m_value.array->max_size();
22235 }
22236
22237 case value_t::object:
22238 {
22239 // delegate call to object_t::max_size()
22240 return m_value.object->max_size();
22241 }
22242
22243 default:
22244 {
22245 // all other types have max_size() == size()
22246 return size();
22247 }
22248 }
22249 }
22250
22252
22253
22255 // modifiers //
22257
22260
22298 void clear() noexcept
22299 {
22300 switch (m_type)
22301 {
22302 case value_t::number_integer:
22303 {
22304 m_value.number_integer = 0;
22305 break;
22306 }
22307
22308 case value_t::number_unsigned:
22309 {
22310 m_value.number_unsigned = 0;
22311 break;
22312 }
22313
22314 case value_t::number_float:
22315 {
22316 m_value.number_float = 0.0;
22317 break;
22318 }
22319
22320 case value_t::boolean:
22321 {
22322 m_value.boolean = false;
22323 break;
22324 }
22325
22326 case value_t::string:
22327 {
22328 m_value.string->clear();
22329 break;
22330 }
22331
22332 case value_t::binary:
22333 {
22334 m_value.binary->clear();
22335 break;
22336 }
22337
22338 case value_t::array:
22339 {
22340 m_value.array->clear();
22341 break;
22342 }
22343
22344 case value_t::object:
22345 {
22346 m_value.object->clear();
22347 break;
22348 }
22349
22350 default:
22351 break;
22352 }
22353 }
22354
22375 void push_back(basic_json&& val)
22376 {
22377 // push_back only works for null objects or arrays
22378 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22379 {
22380 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22381 }
22382
22383 // transform null object into an array
22384 if (is_null())
22385 {
22386 m_type = value_t::array;
22387 m_value = value_t::array;
22388 assert_invariant();
22389 }
22390
22391 // add element to array (move semantics)
22392 m_value.array->push_back(std::move(val));
22393 set_parent(m_value.array->back());
22394 // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
22395 }
22396
22401 reference operator+=(basic_json&& val)
22402 {
22403 push_back(std::move(val));
22404 return *this;
22405 }
22406
22411 void push_back(const basic_json& val)
22412 {
22413 // push_back only works for null objects or arrays
22414 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22415 {
22416 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22417 }
22418
22419 // transform null object into an array
22420 if (is_null())
22421 {
22422 m_type = value_t::array;
22423 m_value = value_t::array;
22424 assert_invariant();
22425 }
22426
22427 // add element to array
22428 m_value.array->push_back(val);
22429 set_parent(m_value.array->back());
22430 }
22431
22436 reference operator+=(const basic_json& val)
22437 {
22438 push_back(val);
22439 return *this;
22440 }
22441
22462 void push_back(const typename object_t::value_type& val)
22463 {
22464 // push_back only works for null objects or objects
22465 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22466 {
22467 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22468 }
22469
22470 // transform null object into an object
22471 if (is_null())
22472 {
22473 m_type = value_t::object;
22474 m_value = value_t::object;
22475 assert_invariant();
22476 }
22477
22478 // add element to object
22479 auto res = m_value.object->insert(val);
22480 set_parent(res.first->second);
22481 }
22482
22487 reference operator+=(const typename object_t::value_type& val)
22488 {
22489 push_back(val);
22490 return *this;
22491 }
22492
22518 void push_back(initializer_list_t init)
22519 {
22520 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
22521 {
22522 basic_json&& key = init.begin()->moved_or_copied();
22523 push_back(typename object_t::value_type(
22524 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
22525 }
22526 else
22527 {
22528 push_back(basic_json(init));
22529 }
22530 }
22531
22536 reference operator+=(initializer_list_t init)
22537 {
22538 push_back(init);
22539 return *this;
22540 }
22541
22565 template<class... Args>
22566 reference emplace_back(Args&& ... args)
22567 {
22568 // emplace_back only works for null objects or arrays
22569 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22570 {
22571 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()), *this));
22572 }
22573
22574 // transform null object into an array
22575 if (is_null())
22576 {
22577 m_type = value_t::array;
22578 m_value = value_t::array;
22579 assert_invariant();
22580 }
22581
22582 // add element to array (perfect forwarding)
22583 #ifdef JSON_HAS_CPP_17
22584 return set_parent(m_value.array->emplace_back(std::forward<Args>(args)...));
22585 #else
22586 m_value.array->emplace_back(std::forward<Args>(args)...);
22587 return set_parent(m_value.array->back());
22588 #endif
22589 }
22590
22618 template<class... Args>
22619 std::pair<iterator, bool> emplace(Args&& ... args)
22620 {
22621 // emplace only works for null objects or arrays
22622 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22623 {
22624 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()), *this));
22625 }
22626
22627 // transform null object into an object
22628 if (is_null())
22629 {
22630 m_type = value_t::object;
22631 m_value = value_t::object;
22632 assert_invariant();
22633 }
22634
22635 // add element to array (perfect forwarding)
22636 auto res = m_value.object->emplace(std::forward<Args>(args)...);
22637 set_parent(res.first->second);
22638
22639 // create result iterator and set iterator to the result of emplace
22640 auto it = begin();
22641 it.m_it.object_iterator = res.first;
22642
22643 // return pair of iterator and boolean
22644 return {it, res.second};
22645 }
22646
22650 template<typename... Args>
22651 iterator insert_iterator(const_iterator pos, Args&& ... args)
22652 {
22653 iterator result(this);
22654 JSON_ASSERT(m_value.array != nullptr);
22655
22656 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
22657 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
22658 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
22659
22660 // This could have been written as:
22661 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
22662 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
22663
22664 return result;
22665 }
22666
22689 iterator insert(const_iterator pos, const basic_json& val)
22690 {
22691 // insert only works for arrays
22692 if (JSON_HEDLEY_LIKELY(is_array()))
22693 {
22694 // check if iterator pos fits to this JSON value
22695 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22696 {
22697 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
22698 }
22699
22700 // insert to array and return iterator
22701 return set_parents(insert_iterator(pos, val), static_cast<typename iterator::difference_type>(1));
22702 }
22703
22704 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
22705 }
22706
22711 iterator insert(const_iterator pos, basic_json&& val)
22712 {
22713 return insert(pos, val);
22714 }
22715
22740 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
22741 {
22742 // insert only works for arrays
22743 if (JSON_HEDLEY_LIKELY(is_array()))
22744 {
22745 // check if iterator pos fits to this JSON value
22746 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22747 {
22748 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
22749 }
22750
22751 // insert to array and return iterator
22752 return set_parents(insert_iterator(pos, cnt, val), static_cast<typename iterator::difference_type>(cnt));
22753 }
22754
22755 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
22756 }
22757
22788 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
22789 {
22790 // insert only works for arrays
22791 if (JSON_HEDLEY_UNLIKELY(!is_array()))
22792 {
22793 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
22794 }
22795
22796 // check if iterator pos fits to this JSON value
22797 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22798 {
22799 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
22800 }
22801
22802 // check if range iterators belong to the same JSON object
22803 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22804 {
22805 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
22806 }
22807
22808 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
22809 {
22810 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", *this));
22811 }
22812
22813 // insert to array and return iterator
22814 return set_parents(insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator), std::distance(first, last));
22815 }
22816
22841 iterator insert(const_iterator pos, initializer_list_t ilist)
22842 {
22843 // insert only works for arrays
22844 if (JSON_HEDLEY_UNLIKELY(!is_array()))
22845 {
22846 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
22847 }
22848
22849 // check if iterator pos fits to this JSON value
22850 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22851 {
22852 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
22853 }
22854
22855 // insert to array and return iterator
22856 return set_parents(insert_iterator(pos, ilist.begin(), ilist.end()), static_cast<typename iterator::difference_type>(ilist.size()));
22857 }
22858
22882 void insert(const_iterator first, const_iterator last)
22883 {
22884 // insert only works for objects
22885 if (JSON_HEDLEY_UNLIKELY(!is_object()))
22886 {
22887 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
22888 }
22889
22890 // check if range iterators belong to the same JSON object
22891 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22892 {
22893 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
22894 }
22895
22896 // passed iterators must belong to objects
22897 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22898 {
22899 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
22900 }
22901
22902 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
22903 }
22904
22924 void update(const_reference j)
22925 {
22926 // implicitly convert null value to an empty object
22927 if (is_null())
22928 {
22929 m_type = value_t::object;
22930 m_value.object = create<object_t>();
22931 assert_invariant();
22932 }
22933
22934 if (JSON_HEDLEY_UNLIKELY(!is_object()))
22935 {
22936 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
22937 }
22938 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
22939 {
22940 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()), *this));
22941 }
22942
22943 for (auto it = j.cbegin(); it != j.cend(); ++it)
22944 {
22945 m_value.object->operator[](it.key()) = it.value();
22946 }
22947 }
22948
22975 void update(const_iterator first, const_iterator last)
22976 {
22977 // implicitly convert null value to an empty object
22978 if (is_null())
22979 {
22980 m_type = value_t::object;
22981 m_value.object = create<object_t>();
22982 assert_invariant();
22983 }
22984
22985 if (JSON_HEDLEY_UNLIKELY(!is_object()))
22986 {
22987 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
22988 }
22989
22990 // check if range iterators belong to the same JSON object
22991 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22992 {
22993 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
22994 }
22995
22996 // passed iterators must belong to objects
22997 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
22998 || !last.m_object->is_object()))
22999 {
23000 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23001 }
23002
23003 for (auto it = first; it != last; ++it)
23004 {
23005 m_value.object->operator[](it.key()) = it.value();
23006 }
23007 }
23008
23026 void swap(reference other) noexcept (
23027 std::is_nothrow_move_constructible<value_t>::value&&
23028 std::is_nothrow_move_assignable<value_t>::value&&
23029 std::is_nothrow_move_constructible<json_value>::value&&
23030 std::is_nothrow_move_assignable<json_value>::value
23031 )
23032 {
23033 std::swap(m_type, other.m_type);
23034 std::swap(m_value, other.m_value);
23035
23036 set_parents();
23037 other.set_parents();
23038 assert_invariant();
23039 }
23040
23059 friend void swap(reference left, reference right) noexcept (
23060 std::is_nothrow_move_constructible<value_t>::value&&
23061 std::is_nothrow_move_assignable<value_t>::value&&
23062 std::is_nothrow_move_constructible<json_value>::value&&
23063 std::is_nothrow_move_assignable<json_value>::value
23064 )
23065 {
23066 left.swap(right);
23067 }
23068
23089 void swap(array_t& other) // NOLINT(bugprone-exception-escape)
23090 {
23091 // swap only works for arrays
23092 if (JSON_HEDLEY_LIKELY(is_array()))
23093 {
23094 std::swap(*(m_value.array), other);
23095 }
23096 else
23097 {
23098 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23099 }
23100 }
23101
23122 void swap(object_t& other) // NOLINT(bugprone-exception-escape)
23123 {
23124 // swap only works for objects
23125 if (JSON_HEDLEY_LIKELY(is_object()))
23126 {
23127 std::swap(*(m_value.object), other);
23128 }
23129 else
23130 {
23131 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23132 }
23133 }
23134
23155 void swap(string_t& other) // NOLINT(bugprone-exception-escape)
23156 {
23157 // swap only works for strings
23158 if (JSON_HEDLEY_LIKELY(is_string()))
23159 {
23160 std::swap(*(m_value.string), other);
23161 }
23162 else
23163 {
23164 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23165 }
23166 }
23167
23188 void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
23189 {
23190 // swap only works for strings
23191 if (JSON_HEDLEY_LIKELY(is_binary()))
23192 {
23193 std::swap(*(m_value.binary), other);
23194 }
23195 else
23196 {
23197 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23198 }
23199 }
23200
23202 void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
23203 {
23204 // swap only works for strings
23205 if (JSON_HEDLEY_LIKELY(is_binary()))
23206 {
23207 std::swap(*(m_value.binary), other);
23208 }
23209 else
23210 {
23211 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23212 }
23213 }
23214
23216
23217 public:
23219 // lexicographical comparison operators //
23221
23224
23280 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
23281 {
23282 const auto lhs_type = lhs.type();
23283 const auto rhs_type = rhs.type();
23284
23285 if (lhs_type == rhs_type)
23286 {
23287 switch (lhs_type)
23288 {
23289 case value_t::array:
23290 return *lhs.m_value.array == *rhs.m_value.array;
23291
23292 case value_t::object:
23293 return *lhs.m_value.object == *rhs.m_value.object;
23294
23295 case value_t::null:
23296 return true;
23297
23298 case value_t::string:
23299 return *lhs.m_value.string == *rhs.m_value.string;
23300
23301 case value_t::boolean:
23302 return lhs.m_value.boolean == rhs.m_value.boolean;
23303
23304 case value_t::number_integer:
23305 return lhs.m_value.number_integer == rhs.m_value.number_integer;
23306
23307 case value_t::number_unsigned:
23308 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
23309
23310 case value_t::number_float:
23311 return lhs.m_value.number_float == rhs.m_value.number_float;
23312
23313 case value_t::binary:
23314 return *lhs.m_value.binary == *rhs.m_value.binary;
23315
23316 default:
23317 return false;
23318 }
23319 }
23320 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
23321 {
23322 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
23323 }
23324 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
23325 {
23326 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
23327 }
23328 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
23329 {
23330 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
23331 }
23332 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
23333 {
23334 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
23335 }
23336 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
23337 {
23338 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
23339 }
23340 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
23341 {
23342 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
23343 }
23344
23345 return false;
23346 }
23347
23352 template<typename ScalarType, typename std::enable_if<
23353 std::is_scalar<ScalarType>::value, int>::type = 0>
23354 friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
23355 {
23356 return lhs == basic_json(rhs);
23357 }
23358
23363 template<typename ScalarType, typename std::enable_if<
23364 std::is_scalar<ScalarType>::value, int>::type = 0>
23365 friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
23366 {
23367 return basic_json(lhs) == rhs;
23368 }
23369
23388 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
23389 {
23390 return !(lhs == rhs);
23391 }
23392
23397 template<typename ScalarType, typename std::enable_if<
23398 std::is_scalar<ScalarType>::value, int>::type = 0>
23399 friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23400 {
23401 return lhs != basic_json(rhs);
23402 }
23403
23408 template<typename ScalarType, typename std::enable_if<
23409 std::is_scalar<ScalarType>::value, int>::type = 0>
23410 friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
23411 {
23412 return basic_json(lhs) != rhs;
23413 }
23414
23441 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
23442 {
23443 const auto lhs_type = lhs.type();
23444 const auto rhs_type = rhs.type();
23445
23446 if (lhs_type == rhs_type)
23447 {
23448 switch (lhs_type)
23449 {
23450 case value_t::array:
23451 // note parentheses are necessary, see
23452 // https://github.com/nlohmann/json/issues/1530
23453 return (*lhs.m_value.array) < (*rhs.m_value.array);
23454
23455 case value_t::object:
23456 return (*lhs.m_value.object) < (*rhs.m_value.object);
23457
23458 case value_t::null:
23459 return false;
23460
23461 case value_t::string:
23462 return (*lhs.m_value.string) < (*rhs.m_value.string);
23463
23464 case value_t::boolean:
23465 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
23466
23467 case value_t::number_integer:
23468 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
23469
23470 case value_t::number_unsigned:
23471 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
23472
23473 case value_t::number_float:
23474 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
23475
23476 case value_t::binary:
23477 return (*lhs.m_value.binary) < (*rhs.m_value.binary);
23478
23479 default:
23480 return false;
23481 }
23482 }
23483 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
23484 {
23485 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
23486 }
23487 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
23488 {
23489 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
23490 }
23491 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
23492 {
23493 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
23494 }
23495 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
23496 {
23497 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
23498 }
23499 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
23500 {
23501 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
23502 }
23503 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
23504 {
23505 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
23506 }
23507
23508 // We only reach this line if we cannot compare values. In that case,
23509 // we compare types. Note we have to call the operator explicitly,
23510 // because MSVC has problems otherwise.
23511 return operator<(lhs_type, rhs_type);
23512 }
23513
23518 template<typename ScalarType, typename std::enable_if<
23519 std::is_scalar<ScalarType>::value, int>::type = 0>
23520 friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
23521 {
23522 return lhs < basic_json(rhs);
23523 }
23524
23529 template<typename ScalarType, typename std::enable_if<
23530 std::is_scalar<ScalarType>::value, int>::type = 0>
23531 friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
23532 {
23533 return basic_json(lhs) < rhs;
23534 }
23535
23555 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
23556 {
23557 return !(rhs < lhs);
23558 }
23559
23564 template<typename ScalarType, typename std::enable_if<
23565 std::is_scalar<ScalarType>::value, int>::type = 0>
23566 friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
23567 {
23568 return lhs <= basic_json(rhs);
23569 }
23570
23575 template<typename ScalarType, typename std::enable_if<
23576 std::is_scalar<ScalarType>::value, int>::type = 0>
23577 friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
23578 {
23579 return basic_json(lhs) <= rhs;
23580 }
23581
23601 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
23602 {
23603 return !(lhs <= rhs);
23604 }
23605
23610 template<typename ScalarType, typename std::enable_if<
23611 std::is_scalar<ScalarType>::value, int>::type = 0>
23612 friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
23613 {
23614 return lhs > basic_json(rhs);
23615 }
23616
23621 template<typename ScalarType, typename std::enable_if<
23622 std::is_scalar<ScalarType>::value, int>::type = 0>
23623 friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
23624 {
23625 return basic_json(lhs) > rhs;
23626 }
23627
23647 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
23648 {
23649 return !(lhs < rhs);
23650 }
23651
23656 template<typename ScalarType, typename std::enable_if<
23657 std::is_scalar<ScalarType>::value, int>::type = 0>
23658 friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
23659 {
23660 return lhs >= basic_json(rhs);
23661 }
23662
23667 template<typename ScalarType, typename std::enable_if<
23668 std::is_scalar<ScalarType>::value, int>::type = 0>
23669 friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
23670 {
23671 return basic_json(lhs) >= rhs;
23672 }
23673
23675
23677 // serialization //
23679
23682
23714 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
23715 {
23716 // read width member and use it as indentation parameter if nonzero
23717 const bool pretty_print = o.width() > 0;
23718 const auto indentation = pretty_print ? o.width() : 0;
23719
23720 // reset width to 0 for subsequent calls to this stream
23721 o.width(0);
23722
23723 // do the actual serialization
23724 serializer s(detail::output_adapter<char>(o), o.fill());
23725 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
23726 return o;
23727 }
23728
23737 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
23738 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
23739 {
23740 return o << j;
23741 }
23742
23744
23745
23747 // deserialization //
23749
23752
23804 template<typename InputType>
23805 JSON_HEDLEY_WARN_UNUSED_RESULT
23806 static basic_json parse(InputType&& i,
23807 const parser_callback_t cb = nullptr,
23808 const bool allow_exceptions = true,
23809 const bool ignore_comments = false)
23810 {
23811 basic_json result;
23812 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
23813 return result;
23814 }
23815
23842 template<typename IteratorType>
23843 JSON_HEDLEY_WARN_UNUSED_RESULT
23844 static basic_json parse(IteratorType first,
23845 IteratorType last,
23846 const parser_callback_t cb = nullptr,
23847 const bool allow_exceptions = true,
23848 const bool ignore_comments = false)
23849 {
23850 basic_json result;
23851 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
23852 return result;
23853 }
23854
23855 JSON_HEDLEY_WARN_UNUSED_RESULT
23856 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
23857 static basic_json parse(detail::span_input_adapter&& i,
23858 const parser_callback_t cb = nullptr,
23859 const bool allow_exceptions = true,
23860 const bool ignore_comments = false)
23861 {
23862 basic_json result;
23863 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
23864 return result;
23865 }
23866
23897 template<typename InputType>
23898 static bool accept(InputType&& i,
23899 const bool ignore_comments = false)
23900 {
23901 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
23902 }
23903
23904 template<typename IteratorType>
23905 static bool accept(IteratorType first, IteratorType last,
23906 const bool ignore_comments = false)
23907 {
23908 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
23909 }
23910
23911 JSON_HEDLEY_WARN_UNUSED_RESULT
23912 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
23913 static bool accept(detail::span_input_adapter&& i,
23914 const bool ignore_comments = false)
23915 {
23916 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
23917 }
23918
23959 template <typename InputType, typename SAX>
23960 JSON_HEDLEY_NON_NULL(2)
23961 static bool sax_parse(InputType&& i, SAX* sax,
23962 input_format_t format = input_format_t::json,
23963 const bool strict = true,
23964 const bool ignore_comments = false)
23965 {
23966 auto ia = detail::input_adapter(std::forward<InputType>(i));
23967 return format == input_format_t::json
23968 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23969 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23970 }
23971
23972 template<class IteratorType, class SAX>
23973 JSON_HEDLEY_NON_NULL(3)
23974 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
23975 input_format_t format = input_format_t::json,
23976 const bool strict = true,
23977 const bool ignore_comments = false)
23978 {
23979 auto ia = detail::input_adapter(std::move(first), std::move(last));
23980 return format == input_format_t::json
23981 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23982 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23983 }
23984
23985 template <typename SAX>
23986 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
23987 JSON_HEDLEY_NON_NULL(2)
23988 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
23989 input_format_t format = input_format_t::json,
23990 const bool strict = true,
23991 const bool ignore_comments = false)
23992 {
23993 auto ia = i.get();
23994 return format == input_format_t::json
23995 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23996 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23997 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23998 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23999 }
24000
24009 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
24010 friend std::istream& operator<<(basic_json& j, std::istream& i)
24011 {
24012 return operator>>(i, j);
24013 }
24014
24040 friend std::istream& operator>>(std::istream& i, basic_json& j)
24041 {
24042 parser(detail::input_adapter(i)).parse(false, j);
24043 return i;
24044 }
24045
24047
24049 // convenience functions //
24051
24083 JSON_HEDLEY_RETURNS_NON_NULL
24084 const char* type_name() const noexcept
24085 {
24086 {
24087 switch (m_type)
24088 {
24089 case value_t::null:
24090 return "null";
24091 case value_t::object:
24092 return "object";
24093 case value_t::array:
24094 return "array";
24095 case value_t::string:
24096 return "string";
24097 case value_t::boolean:
24098 return "boolean";
24099 case value_t::binary:
24100 return "binary";
24101 case value_t::discarded:
24102 return "discarded";
24103 default:
24104 return "number";
24105 }
24106 }
24107 }
24108
24109
24110 JSON_PRIVATE_UNLESS_TESTED:
24112 // member variables //
24114
24116 value_t m_type = value_t::null;
24117
24119 json_value m_value = {};
24120
24121 #if JSON_DIAGNOSTICS
24122 basic_json* m_parent = nullptr;
24124 #endif
24125
24127 // binary serialization/deserialization //
24129
24132
24133 public:
24228 static std::vector<uint8_t> to_cbor(const basic_json& j)
24229 {
24230 std::vector<uint8_t> result;
24231 to_cbor(j, result);
24232 return result;
24233 }
24234
24235 static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
24236 {
24237 binary_writer<uint8_t>(o).write_cbor(j);
24238 }
24239
24240 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
24241 {
24242 binary_writer<char>(o).write_cbor(j);
24243 }
24244
24323 static std::vector<uint8_t> to_msgpack(const basic_json& j)
24324 {
24325 std::vector<uint8_t> result;
24326 to_msgpack(j, result);
24327 return result;
24328 }
24329
24330 static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
24331 {
24332 binary_writer<uint8_t>(o).write_msgpack(j);
24333 }
24334
24335 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
24336 {
24337 binary_writer<char>(o).write_msgpack(j);
24338 }
24339
24426 static std::vector<uint8_t> to_ubjson(const basic_json& j,
24427 const bool use_size = false,
24428 const bool use_type = false)
24429 {
24430 std::vector<uint8_t> result;
24431 to_ubjson(j, result, use_size, use_type);
24432 return result;
24433 }
24434
24435 static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
24436 const bool use_size = false, const bool use_type = false)
24437 {
24438 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
24439 }
24440
24441 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
24442 const bool use_size = false, const bool use_type = false)
24443 {
24444 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
24445 }
24446
24447
24504 static std::vector<uint8_t> to_bson(const basic_json& j)
24505 {
24506 std::vector<uint8_t> result;
24507 to_bson(j, result);
24508 return result;
24509 }
24510
24519 static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
24520 {
24521 binary_writer<uint8_t>(o).write_bson(j);
24522 }
24523
24527 static void to_bson(const basic_json& j, detail::output_adapter<char> o)
24528 {
24529 binary_writer<char>(o).write_bson(j);
24530 }
24531
24532
24635 template<typename InputType>
24636 JSON_HEDLEY_WARN_UNUSED_RESULT
24637 static basic_json from_cbor(InputType&& i,
24638 const bool strict = true,
24639 const bool allow_exceptions = true,
24640 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24641 {
24642 basic_json result;
24643 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24644 auto ia = detail::input_adapter(std::forward<InputType>(i));
24645 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24646 return res ? result : basic_json(value_t::discarded);
24647 }
24648
24652 template<typename IteratorType>
24653 JSON_HEDLEY_WARN_UNUSED_RESULT
24654 static basic_json from_cbor(IteratorType first, IteratorType last,
24655 const bool strict = true,
24656 const bool allow_exceptions = true,
24657 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24658 {
24659 basic_json result;
24660 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24661 auto ia = detail::input_adapter(std::move(first), std::move(last));
24662 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24663 return res ? result : basic_json(value_t::discarded);
24664 }
24665
24666 template<typename T>
24667 JSON_HEDLEY_WARN_UNUSED_RESULT
24668 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
24669 static basic_json from_cbor(const T* ptr, std::size_t len,
24670 const bool strict = true,
24671 const bool allow_exceptions = true,
24672 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24673 {
24674 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
24675 }
24676
24677
24678 JSON_HEDLEY_WARN_UNUSED_RESULT
24679 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
24680 static basic_json from_cbor(detail::span_input_adapter&& i,
24681 const bool strict = true,
24682 const bool allow_exceptions = true,
24683 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24684 {
24685 basic_json result;
24686 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24687 auto ia = i.get();
24688 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24689 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24690 return res ? result : basic_json(value_t::discarded);
24691 }
24692
24779 template<typename InputType>
24780 JSON_HEDLEY_WARN_UNUSED_RESULT
24781 static basic_json from_msgpack(InputType&& i,
24782 const bool strict = true,
24783 const bool allow_exceptions = true)
24784 {
24785 basic_json result;
24786 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24787 auto ia = detail::input_adapter(std::forward<InputType>(i));
24788 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24789 return res ? result : basic_json(value_t::discarded);
24790 }
24791
24795 template<typename IteratorType>
24796 JSON_HEDLEY_WARN_UNUSED_RESULT
24797 static basic_json from_msgpack(IteratorType first, IteratorType last,
24798 const bool strict = true,
24799 const bool allow_exceptions = true)
24800 {
24801 basic_json result;
24802 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24803 auto ia = detail::input_adapter(std::move(first), std::move(last));
24804 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24805 return res ? result : basic_json(value_t::discarded);
24806 }
24807
24808
24809 template<typename T>
24810 JSON_HEDLEY_WARN_UNUSED_RESULT
24811 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
24812 static basic_json from_msgpack(const T* ptr, std::size_t len,
24813 const bool strict = true,
24814 const bool allow_exceptions = true)
24815 {
24816 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
24817 }
24818
24819 JSON_HEDLEY_WARN_UNUSED_RESULT
24820 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
24821 static basic_json from_msgpack(detail::span_input_adapter&& i,
24822 const bool strict = true,
24823 const bool allow_exceptions = true)
24824 {
24825 basic_json result;
24826 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24827 auto ia = i.get();
24828 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24829 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24830 return res ? result : basic_json(value_t::discarded);
24831 }
24832
24833
24896 template<typename InputType>
24897 JSON_HEDLEY_WARN_UNUSED_RESULT
24898 static basic_json from_ubjson(InputType&& i,
24899 const bool strict = true,
24900 const bool allow_exceptions = true)
24901 {
24902 basic_json result;
24903 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24904 auto ia = detail::input_adapter(std::forward<InputType>(i));
24905 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24906 return res ? result : basic_json(value_t::discarded);
24907 }
24908
24912 template<typename IteratorType>
24913 JSON_HEDLEY_WARN_UNUSED_RESULT
24914 static basic_json from_ubjson(IteratorType first, IteratorType last,
24915 const bool strict = true,
24916 const bool allow_exceptions = true)
24917 {
24918 basic_json result;
24919 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24920 auto ia = detail::input_adapter(std::move(first), std::move(last));
24921 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24922 return res ? result : basic_json(value_t::discarded);
24923 }
24924
24925 template<typename T>
24926 JSON_HEDLEY_WARN_UNUSED_RESULT
24927 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
24928 static basic_json from_ubjson(const T* ptr, std::size_t len,
24929 const bool strict = true,
24930 const bool allow_exceptions = true)
24931 {
24932 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
24933 }
24934
24935 JSON_HEDLEY_WARN_UNUSED_RESULT
24936 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
24937 static basic_json from_ubjson(detail::span_input_adapter&& i,
24938 const bool strict = true,
24939 const bool allow_exceptions = true)
24940 {
24941 basic_json result;
24942 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24943 auto ia = i.get();
24944 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24945 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24946 return res ? result : basic_json(value_t::discarded);
24947 }
24948
24949
25010 template<typename InputType>
25011 JSON_HEDLEY_WARN_UNUSED_RESULT
25012 static basic_json from_bson(InputType&& i,
25013 const bool strict = true,
25014 const bool allow_exceptions = true)
25015 {
25016 basic_json result;
25017 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25018 auto ia = detail::input_adapter(std::forward<InputType>(i));
25019 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25020 return res ? result : basic_json(value_t::discarded);
25021 }
25022
25026 template<typename IteratorType>
25027 JSON_HEDLEY_WARN_UNUSED_RESULT
25028 static basic_json from_bson(IteratorType first, IteratorType last,
25029 const bool strict = true,
25030 const bool allow_exceptions = true)
25031 {
25032 basic_json result;
25033 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25034 auto ia = detail::input_adapter(std::move(first), std::move(last));
25035 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25036 return res ? result : basic_json(value_t::discarded);
25037 }
25038
25039 template<typename T>
25040 JSON_HEDLEY_WARN_UNUSED_RESULT
25041 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25042 static basic_json from_bson(const T* ptr, std::size_t len,
25043 const bool strict = true,
25044 const bool allow_exceptions = true)
25045 {
25046 return from_bson(ptr, ptr + len, strict, allow_exceptions);
25047 }
25048
25049 JSON_HEDLEY_WARN_UNUSED_RESULT
25050 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25051 static basic_json from_bson(detail::span_input_adapter&& i,
25052 const bool strict = true,
25053 const bool allow_exceptions = true)
25054 {
25055 basic_json result;
25056 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25057 auto ia = i.get();
25058 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25059 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25060 return res ? result : basic_json(value_t::discarded);
25061 }
25063
25065 // JSON Pointer support //
25067
25070
25104 reference operator[](const json_pointer& ptr)
25105 {
25106 return ptr.get_unchecked(this);
25107 }
25108
25132 const_reference operator[](const json_pointer& ptr) const
25133 {
25134 return ptr.get_unchecked(this);
25135 }
25136
25175 reference at(const json_pointer& ptr)
25176 {
25177 return ptr.get_checked(this);
25178 }
25179
25218 const_reference at(const json_pointer& ptr) const
25219 {
25220 return ptr.get_checked(this);
25221 }
25222
25245 basic_json flatten() const
25246 {
25247 basic_json result(value_t::object);
25248 json_pointer::flatten("", *this, result);
25249 return result;
25250 }
25251
25282 basic_json unflatten() const
25283 {
25284 return json_pointer::unflatten(*this);
25285 }
25286
25288
25290 // JSON Patch functions //
25292
25295
25343 basic_json patch(const basic_json& json_patch) const
25344 {
25345 // make a working copy to apply the patch to
25346 basic_json result = *this;
25347
25348 // the valid JSON Patch operations
25349 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
25350
25351 const auto get_op = [](const std::string & op)
25352 {
25353 if (op == "add")
25354 {
25355 return patch_operations::add;
25356 }
25357 if (op == "remove")
25358 {
25359 return patch_operations::remove;
25360 }
25361 if (op == "replace")
25362 {
25363 return patch_operations::replace;
25364 }
25365 if (op == "move")
25366 {
25367 return patch_operations::move;
25368 }
25369 if (op == "copy")
25370 {
25371 return patch_operations::copy;
25372 }
25373 if (op == "test")
25374 {
25375 return patch_operations::test;
25376 }
25377
25378 return patch_operations::invalid;
25379 };
25380
25381 // wrapper for "add" operation; add value at ptr
25382 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
25383 {
25384 // adding to the root of the target document means replacing it
25385 if (ptr.empty())
25386 {
25387 result = val;
25388 return;
25389 }
25390
25391 // make sure the top element of the pointer exists
25392 json_pointer top_pointer = ptr.top();
25393 if (top_pointer != ptr)
25394 {
25395 result.at(top_pointer);
25396 }
25397
25398 // get reference to parent of JSON pointer ptr
25399 const auto last_path = ptr.back();
25400 ptr.pop_back();
25401 basic_json& parent = result[ptr];
25402
25403 switch (parent.m_type)
25404 {
25405 case value_t::null:
25406 case value_t::object:
25407 {
25408 // use operator[] to add value
25409 parent[last_path] = val;
25410 break;
25411 }
25412
25413 case value_t::array:
25414 {
25415 if (last_path == "-")
25416 {
25417 // special case: append to back
25418 parent.push_back(val);
25419 }
25420 else
25421 {
25422 const auto idx = json_pointer::array_index(last_path);
25423 if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
25424 {
25425 // avoid undefined behavior
25426 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", parent));
25427 }
25428
25429 // default case: insert add offset
25430 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
25431 }
25432 break;
25433 }
25434
25435 // if there exists a parent it cannot be primitive
25436 default: // LCOV_EXCL_LINE
25437 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
25438 }
25439 };
25440
25441 // wrapper for "remove" operation; remove value at ptr
25442 const auto operation_remove = [this, &result](json_pointer & ptr)
25443 {
25444 // get reference to parent of JSON pointer ptr
25445 const auto last_path = ptr.back();
25446 ptr.pop_back();
25447 basic_json& parent = result.at(ptr);
25448
25449 // remove child
25450 if (parent.is_object())
25451 {
25452 // perform range check
25453 auto it = parent.find(last_path);
25454 if (JSON_HEDLEY_LIKELY(it != parent.end()))
25455 {
25456 parent.erase(it);
25457 }
25458 else
25459 {
25460 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found", *this));
25461 }
25462 }
25463 else if (parent.is_array())
25464 {
25465 // note erase performs range check
25466 parent.erase(json_pointer::array_index(last_path));
25467 }
25468 };
25469
25470 // type check: top level value must be an array
25471 if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
25472 {
25473 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", json_patch));
25474 }
25475
25476 // iterate and apply the operations
25477 for (const auto& val : json_patch)
25478 {
25479 // wrapper to get a value for an operation
25480 const auto get_value = [&val](const std::string & op,
25481 const std::string & member,
25482 bool string_type) -> basic_json &
25483 {
25484 // find value
25485 auto it = val.m_value.object->find(member);
25486
25487 // context-sensitive error message
25488 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
25489
25490 // check if desired value is present
25491 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
25492 {
25493 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
25494 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'", val));
25495 }
25496
25497 // check if result is of type string
25498 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
25499 {
25500 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
25501 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'", val));
25502 }
25503
25504 // no error: return value
25505 return it->second;
25506 };
25507
25508 // type check: every element of the array must be an object
25509 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
25510 {
25511 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", val));
25512 }
25513
25514 // collect mandatory members
25515 const auto op = get_value("op", "op", true).template get<std::string>();
25516 const auto path = get_value(op, "path", true).template get<std::string>();
25517 json_pointer ptr(path);
25518
25519 switch (get_op(op))
25520 {
25521 case patch_operations::add:
25522 {
25523 operation_add(ptr, get_value("add", "value", false));
25524 break;
25525 }
25526
25527 case patch_operations::remove:
25528 {
25529 operation_remove(ptr);
25530 break;
25531 }
25532
25533 case patch_operations::replace:
25534 {
25535 // the "path" location must exist - use at()
25536 result.at(ptr) = get_value("replace", "value", false);
25537 break;
25538 }
25539
25540 case patch_operations::move:
25541 {
25542 const auto from_path = get_value("move", "from", true).template get<std::string>();
25543 json_pointer from_ptr(from_path);
25544
25545 // the "from" location must exist - use at()
25546 basic_json v = result.at(from_ptr);
25547
25548 // The move operation is functionally identical to a
25549 // "remove" operation on the "from" location, followed
25550 // immediately by an "add" operation at the target
25551 // location with the value that was just removed.
25552 operation_remove(from_ptr);
25553 operation_add(ptr, v);
25554 break;
25555 }
25556
25557 case patch_operations::copy:
25558 {
25559 const auto from_path = get_value("copy", "from", true).template get<std::string>();
25560 const json_pointer from_ptr(from_path);
25561
25562 // the "from" location must exist - use at()
25563 basic_json v = result.at(from_ptr);
25564
25565 // The copy is functionally identical to an "add"
25566 // operation at the target location using the value
25567 // specified in the "from" member.
25568 operation_add(ptr, v);
25569 break;
25570 }
25571
25572 case patch_operations::test:
25573 {
25574 bool success = false;
25575 JSON_TRY
25576 {
25577 // check if "value" matches the one at "path"
25578 // the "path" location must exist - use at()
25579 success = (result.at(ptr) == get_value("test", "value", false));
25580 }
25581 JSON_INTERNAL_CATCH (out_of_range&)
25582 {
25583 // ignore out of range errors: success remains false
25584 }
25585
25586 // throw an exception if test fails
25587 if (JSON_HEDLEY_UNLIKELY(!success))
25588 {
25589 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump(), val));
25590 }
25591
25592 break;
25593 }
25594
25595 default:
25596 {
25597 // op must be "add", "remove", "replace", "move", "copy", or
25598 // "test"
25599 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid", val));
25600 }
25601 }
25602 }
25603
25604 return result;
25605 }
25606
25640 JSON_HEDLEY_WARN_UNUSED_RESULT
25641 static basic_json diff(const basic_json& source, const basic_json& target,
25642 const std::string& path = "")
25643 {
25644 // the patch
25645 basic_json result(value_t::array);
25646
25647 // if the values are the same, return empty patch
25648 if (source == target)
25649 {
25650 return result;
25651 }
25652
25653 if (source.type() != target.type())
25654 {
25655 // different types: replace value
25656 result.push_back(
25657 {
25658 {"op", "replace"}, {"path", path}, {"value", target}
25659 });
25660 return result;
25661 }
25662
25663 switch (source.type())
25664 {
25665 case value_t::array:
25666 {
25667 // first pass: traverse common elements
25668 std::size_t i = 0;
25669 while (i < source.size() && i < target.size())
25670 {
25671 // recursive call to compare array values at index i
25672 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
25673 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
25674 ++i;
25675 }
25676
25677 // i now reached the end of at least one array
25678 // in a second pass, traverse the remaining elements
25679
25680 // remove my remaining elements
25681 const auto end_index = static_cast<difference_type>(result.size());
25682 while (i < source.size())
25683 {
25684 // add operations in reverse order to avoid invalid
25685 // indices
25686 result.insert(result.begin() + end_index, object(
25687 {
25688 {"op", "remove"},
25689 {"path", path + "/" + std::to_string(i)}
25690 }));
25691 ++i;
25692 }
25693
25694 // add other remaining elements
25695 while (i < target.size())
25696 {
25697 result.push_back(
25698 {
25699 {"op", "add"},
25700 {"path", path + "/-"},
25701 {"value", target[i]}
25702 });
25703 ++i;
25704 }
25705
25706 break;
25707 }
25708
25709 case value_t::object:
25710 {
25711 // first pass: traverse this object's elements
25712 for (auto it = source.cbegin(); it != source.cend(); ++it)
25713 {
25714 // escape the key name to be used in a JSON patch
25715 const auto path_key = path + "/" + detail::escape(it.key());
25716
25717 if (target.find(it.key()) != target.end())
25718 {
25719 // recursive call to compare object values at key it
25720 auto temp_diff = diff(it.value(), target[it.key()], path_key);
25721 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
25722 }
25723 else
25724 {
25725 // found a key that is not in o -> remove it
25726 result.push_back(object(
25727 {
25728 {"op", "remove"}, {"path", path_key}
25729 }));
25730 }
25731 }
25732
25733 // second pass: traverse other object's elements
25734 for (auto it = target.cbegin(); it != target.cend(); ++it)
25735 {
25736 if (source.find(it.key()) == source.end())
25737 {
25738 // found a key that is not in this -> add it
25739 const auto path_key = path + "/" + detail::escape(it.key());
25740 result.push_back(
25741 {
25742 {"op", "add"}, {"path", path_key},
25743 {"value", it.value()}
25744 });
25745 }
25746 }
25747
25748 break;
25749 }
25750
25751 default:
25752 {
25753 // both primitive type: replace value
25754 result.push_back(
25755 {
25756 {"op", "replace"}, {"path", path}, {"value", target}
25757 });
25758 break;
25759 }
25760 }
25761
25762 return result;
25763 }
25764
25766
25768 // JSON Merge Patch functions //
25770
25773
25816 void merge_patch(const basic_json& apply_patch)
25817 {
25818 if (apply_patch.is_object())
25819 {
25820 if (!is_object())
25821 {
25822 *this = object();
25823 }
25824 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
25825 {
25826 if (it.value().is_null())
25827 {
25828 erase(it.key());
25829 }
25830 else
25831 {
25832 operator[](it.key()).merge_patch(it.value());
25833 }
25834 }
25835 }
25836 else
25837 {
25838 *this = apply_patch;
25839 }
25840 }
25841
25843 };
25844
25854 NLOHMANN_BASIC_JSON_TPL_DECLARATION
25855 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
25856 {
25857 return j.dump();
25858 }
25859 } // namespace nlohmann
25860
25862 // nonmember support //
25864
25865 // specialization of std::swap, and std::hash
25866 namespace std
25867 {
25868
25870 template<>
25871 struct hash<nlohmann::json>
25872 {
25878 std::size_t operator()(const nlohmann::json& j) const
25879 {
25880 return nlohmann::detail::hash(j);
25881 }
25882 };
25883
25887 template<>
25888 struct less<::nlohmann::detail::value_t>
25889 {
25894 bool operator()(nlohmann::detail::value_t lhs,
25895 nlohmann::detail::value_t rhs) const noexcept
25896 {
25897 return nlohmann::detail::operator<(lhs, rhs);
25898 }
25899 };
25900
25901 // C++20 prohibit function specialization in the std namespace.
25902 #ifndef JSON_HAS_CPP_20
25903
25909 template<>
25910 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
25911 is_nothrow_move_constructible<nlohmann::json>::value&& // NOLINT(misc-redundant-expression)
25912 is_nothrow_move_assignable<nlohmann::json>::value
25913 )
25914 {
25915 j1.swap(j2);
25916 }
25917
25918 #endif
25919
25920 } // namespace std
25921
25935 JSON_HEDLEY_NON_NULL(1)
25936 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
25937 {
25938 return nlohmann::json::parse(s, s + n);
25939 }
25940
25954 JSON_HEDLEY_NON_NULL(1)
25955 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
25956 {
25957 return nlohmann::json::json_pointer(std::string(s, n));
25958 }
25959
25960 // #include <nlohmann/detail/macro_unscope.hpp>
25961
25962
25963 // restore GCC/clang diagnostic settings
25964 #if defined(__clang__)
25965 #pragma GCC diagnostic pop
25966 #endif
25967
25968 // clean up
25969 #undef JSON_ASSERT
25970 #undef JSON_INTERNAL_CATCH
25971 #undef JSON_CATCH
25972 #undef JSON_THROW
25973 #undef JSON_TRY
25974 #undef JSON_PRIVATE_UNLESS_TESTED
25975 #undef JSON_HAS_CPP_14
25976 #undef JSON_HAS_CPP_17
25977 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
25978 #undef NLOHMANN_BASIC_JSON_TPL
25979 #undef JSON_EXPLICIT
25980
25981 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
25982
25983
25984 #undef JSON_HEDLEY_ALWAYS_INLINE
25985 #undef JSON_HEDLEY_ARM_VERSION
25986 #undef JSON_HEDLEY_ARM_VERSION_CHECK
25987 #undef JSON_HEDLEY_ARRAY_PARAM
25988 #undef JSON_HEDLEY_ASSUME
25989 #undef JSON_HEDLEY_BEGIN_C_DECLS
25990 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
25991 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
25992 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
25993 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
25994 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
25995 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
25996 #undef JSON_HEDLEY_CLANG_HAS_WARNING
25997 #undef JSON_HEDLEY_COMPCERT_VERSION
25998 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
25999 #undef JSON_HEDLEY_CONCAT
26000 #undef JSON_HEDLEY_CONCAT3
26001 #undef JSON_HEDLEY_CONCAT3_EX
26002 #undef JSON_HEDLEY_CONCAT_EX
26003 #undef JSON_HEDLEY_CONST
26004 #undef JSON_HEDLEY_CONSTEXPR
26005 #undef JSON_HEDLEY_CONST_CAST
26006 #undef JSON_HEDLEY_CPP_CAST
26007 #undef JSON_HEDLEY_CRAY_VERSION
26008 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
26009 #undef JSON_HEDLEY_C_DECL
26010 #undef JSON_HEDLEY_DEPRECATED
26011 #undef JSON_HEDLEY_DEPRECATED_FOR
26012 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
26013 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
26014 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
26015 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
26016 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
26017 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
26018 #undef JSON_HEDLEY_DIAGNOSTIC_POP
26019 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
26020 #undef JSON_HEDLEY_DMC_VERSION
26021 #undef JSON_HEDLEY_DMC_VERSION_CHECK
26022 #undef JSON_HEDLEY_EMPTY_BASES
26023 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
26024 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
26025 #undef JSON_HEDLEY_END_C_DECLS
26026 #undef JSON_HEDLEY_FLAGS
26027 #undef JSON_HEDLEY_FLAGS_CAST
26028 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
26029 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
26030 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
26031 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
26032 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
26033 #undef JSON_HEDLEY_GCC_HAS_FEATURE
26034 #undef JSON_HEDLEY_GCC_HAS_WARNING
26035 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
26036 #undef JSON_HEDLEY_GCC_VERSION
26037 #undef JSON_HEDLEY_GCC_VERSION_CHECK
26038 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
26039 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
26040 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
26041 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
26042 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
26043 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
26044 #undef JSON_HEDLEY_GNUC_HAS_WARNING
26045 #undef JSON_HEDLEY_GNUC_VERSION
26046 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
26047 #undef JSON_HEDLEY_HAS_ATTRIBUTE
26048 #undef JSON_HEDLEY_HAS_BUILTIN
26049 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
26050 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
26051 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
26052 #undef JSON_HEDLEY_HAS_EXTENSION
26053 #undef JSON_HEDLEY_HAS_FEATURE
26054 #undef JSON_HEDLEY_HAS_WARNING
26055 #undef JSON_HEDLEY_IAR_VERSION
26056 #undef JSON_HEDLEY_IAR_VERSION_CHECK
26057 #undef JSON_HEDLEY_IBM_VERSION
26058 #undef JSON_HEDLEY_IBM_VERSION_CHECK
26059 #undef JSON_HEDLEY_IMPORT
26060 #undef JSON_HEDLEY_INLINE
26061 #undef JSON_HEDLEY_INTEL_CL_VERSION
26062 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
26063 #undef JSON_HEDLEY_INTEL_VERSION
26064 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
26065 #undef JSON_HEDLEY_IS_CONSTANT
26066 #undef JSON_HEDLEY_IS_CONSTEXPR_
26067 #undef JSON_HEDLEY_LIKELY
26068 #undef JSON_HEDLEY_MALLOC
26069 #undef JSON_HEDLEY_MCST_LCC_VERSION
26070 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
26071 #undef JSON_HEDLEY_MESSAGE
26072 #undef JSON_HEDLEY_MSVC_VERSION
26073 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
26074 #undef JSON_HEDLEY_NEVER_INLINE
26075 #undef JSON_HEDLEY_NON_NULL
26076 #undef JSON_HEDLEY_NO_ESCAPE
26077 #undef JSON_HEDLEY_NO_RETURN
26078 #undef JSON_HEDLEY_NO_THROW
26079 #undef JSON_HEDLEY_NULL
26080 #undef JSON_HEDLEY_PELLES_VERSION
26081 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
26082 #undef JSON_HEDLEY_PGI_VERSION
26083 #undef JSON_HEDLEY_PGI_VERSION_CHECK
26084 #undef JSON_HEDLEY_PREDICT
26085 #undef JSON_HEDLEY_PRINTF_FORMAT
26086 #undef JSON_HEDLEY_PRIVATE
26087 #undef JSON_HEDLEY_PUBLIC
26088 #undef JSON_HEDLEY_PURE
26089 #undef JSON_HEDLEY_REINTERPRET_CAST
26090 #undef JSON_HEDLEY_REQUIRE
26091 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
26092 #undef JSON_HEDLEY_REQUIRE_MSG
26093 #undef JSON_HEDLEY_RESTRICT
26094 #undef JSON_HEDLEY_RETURNS_NON_NULL
26095 #undef JSON_HEDLEY_SENTINEL
26096 #undef JSON_HEDLEY_STATIC_ASSERT
26097 #undef JSON_HEDLEY_STATIC_CAST
26098 #undef JSON_HEDLEY_STRINGIFY
26099 #undef JSON_HEDLEY_STRINGIFY_EX
26100 #undef JSON_HEDLEY_SUNPRO_VERSION
26101 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
26102 #undef JSON_HEDLEY_TINYC_VERSION
26103 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
26104 #undef JSON_HEDLEY_TI_ARMCL_VERSION
26105 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
26106 #undef JSON_HEDLEY_TI_CL2000_VERSION
26107 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
26108 #undef JSON_HEDLEY_TI_CL430_VERSION
26109 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
26110 #undef JSON_HEDLEY_TI_CL6X_VERSION
26111 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
26112 #undef JSON_HEDLEY_TI_CL7X_VERSION
26113 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
26114 #undef JSON_HEDLEY_TI_CLPRU_VERSION
26115 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
26116 #undef JSON_HEDLEY_TI_VERSION
26117 #undef JSON_HEDLEY_TI_VERSION_CHECK
26118 #undef JSON_HEDLEY_UNAVAILABLE
26119 #undef JSON_HEDLEY_UNLIKELY
26120 #undef JSON_HEDLEY_UNPREDICTABLE
26121 #undef JSON_HEDLEY_UNREACHABLE
26122 #undef JSON_HEDLEY_UNREACHABLE_RETURN
26123 #undef JSON_HEDLEY_VERSION
26124 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
26125 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
26126 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
26127 #undef JSON_HEDLEY_VERSION_ENCODE
26128 #undef JSON_HEDLEY_WARNING
26129 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
26130 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
26131 #undef JSON_HEDLEY_FALL_THROUGH
26132
26133
26134
26135 #endif // INCLUDE_NLOHMANN_JSON_HPP_
nlohmann::detail::json_ref::moved_or_copied
value_type moved_or_copied() const
Definition: json.hpp:13067
nlohmann::basic_json::operator[]
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
Definition: json.hpp:20783
nlohmann::detail::binary_writer::write_number_with_ubjson_prefix
void write_number_with_ubjson_prefix(const NumberType n, const bool add_prefix)
Definition: json.hpp:14497
nlohmann::detail::binary_writer::get_ubjson_float_prefix
static constexpr CharType get_ubjson_float_prefix(float)
Definition: json.hpp:14717
nlohmann::detail::dtoa_impl::cached_power::e
int e
Definition: json.hpp:15157
nlohmann::detail::iter_impl::operator=
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition: json.hpp:11450
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:12207
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:21525
nlohmann::detail::iter_impl::other_iter_impl
friend other_iter_impl
allow basic_json to access private members
Definition: json.hpp:11353
nlohmann::json_pointer::contains
bool contains(const BasicJsonType *ptr) const
Definition: json.hpp:12745
nlohmann::detail::json_sax_acceptor::parse_error
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition: json.hpp:6411
nlohmann::detail::string_function_t
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
Definition: json.hpp:8087
nlohmann::detail::input_stream_adapter::~input_stream_adapter
~input_stream_adapter()
Definition: json.hpp:5302
nlohmann::detail::iterator_traits< T *, enable_if_t< std::is_object< T >::value > >::iterator_category
std::random_access_iterator_tag iterator_category
Definition: json.hpp:3254
nlohmann::basic_json::binary
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init, std::uint8_t subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:18843
nlohmann::detail::dtoa_impl::diyfp
Definition: json.hpp:14897
nlohmann::detail::make_integer_sequence
typename utility_internal::Gen< T, N >::type make_integer_sequence
Definition: json.hpp:3136
nlohmann::detail::is_compatible_integer_type_impl< RealIntegerType, CompatibleNumberIntegerType, enable_if_t< std::is_integral< RealIntegerType >::value &&std::is_integral< CompatibleNumberIntegerType >::value &&!std::is_same< bool, CompatibleNumberIntegerType >::value > >::CompatibleLimits
std::numeric_limits< CompatibleNumberIntegerType > CompatibleLimits
Definition: json.hpp:3795
nlohmann::detail::json_sax_acceptor::boolean
bool boolean(bool)
Definition: json.hpp:6356
nlohmann::detail::from_json_array_impl
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
Definition: json.hpp:3989
nlohmann::detail::detector< Default, void_t< Op< Args... > >, Op, Args... >::value_t
std::true_type value_t
Definition: json.hpp:3303
nlohmann::detail::iteration_proxy_value::key
const string_type & key() const
return key of the iterator
Definition: json.hpp:4361
nlohmann::basic_json::json_pointer
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:17257
nlohmann::basic_json::number_unsigned
number_unsigned_t number_unsigned
number (unsigned integer)
Definition: json.hpp:18007
nlohmann::detail::external_constructor< value_t::array >::construct
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.hpp:4605
nlohmann::detail::binary_reader::get_cbor_binary
bool get_cbor_binary(binary_t &result)
reads a CBOR byte array
Definition: json.hpp:9127
nlohmann::detail::lexer::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6530
nlohmann::detail::pointer_t
typename T::pointer pointer_t
Definition: json.hpp:3469
nlohmann::detail::exception::id
const int id
the id of the exception
Definition: json.hpp:2652
nlohmann::basic_json::operator==
friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
comparison: equal
Definition: json.hpp:23354
nlohmann::detail::value_t::null
null value
nlohmann::basic_json::get_impl_ptr
binary_t * get_impl_ptr(binary_t *) noexcept
get a pointer to the value (binary)
Definition: json.hpp:19901
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:18543
nlohmann::detail::dtoa_impl::cached_power::f
std::uint64_t f
Definition: json.hpp:15156
nlohmann::detail::json_sax_acceptor::end_array
bool end_array()
Definition: json.hpp:6406
nlohmann::detail::iter_impl::operator+
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.hpp:11842
JSON_HEDLEY_PURE
#define JSON_HEDLEY_PURE
Definition: json.hpp:1637
nlohmann::detail::parse_error::parse_error
parse_error(int id_, std::size_t byte_, const char *what_arg)
Definition: json.hpp:2810
nlohmann::detail::external_constructor< value_t::string >::construct
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition: json.hpp:4517
nlohmann::basic_json::erase
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:21291
nlohmann::detail::make_void
Definition: json.hpp:3207
nlohmann::detail::little_endianess
static bool little_endianess(int num=1) noexcept
determine system byte order
Definition: json.hpp:8225
nlohmann::detail::from_json_fn
Definition: json.hpp:4248
nlohmann::basic_json::basic_json
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:19026
nlohmann::detail::from_json
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition: json.hpp:3841
nlohmann::detail::binary_writer::get_cbor_float_prefix
static constexpr CharType get_cbor_float_prefix(float)
Definition: json.hpp:14466
nlohmann::basic_json::begin
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:21628
nlohmann::detail::iteration_proxy_value::value
IteratorType::reference value() const
return value of the iterator
Definition: json.hpp:4389
nlohmann::detail::primitive_iterator_t
Definition: json.hpp:11175
nlohmann::basic_json::array
array_t * array
array (stored with pointer to save storage)
Definition: json.hpp:17997
nlohmann::detail::binary_reader::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:8245
nlohmann::basic_json::json_value
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
Definition: json.hpp:18020
nlohmann::detail::is_json_ref
Definition: json.hpp:3447
nlohmann::basic_json::operator<
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:23441
nlohmann::detail::parser_callback_t
std::function< bool(int, parse_event_t, BasicJsonType &)> parser_callback_t
Definition: json.hpp:10700
nlohmann::detail::utility_internal::Gen
Definition: json.hpp:3114
nlohmann::detail::error_handler_t
error_handler_t
how to treat decoding errors
Definition: json.hpp:15975
nlohmann::detail::lexer::char_int_type
typename std::char_traits< char_type >::int_type char_int_type
Definition: json.hpp:6533
nlohmann::detail::iteration_proxy_value::iteration_proxy_value
iteration_proxy_value(IteratorType it) noexcept
Definition: json.hpp:4329
nlohmann::detail::serializer::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:15986
nlohmann::detail::binary_writer::calc_bson_string_size
static std::size_t calc_bson_string_size(const string_t &value)
Definition: json.hpp:14185
nlohmann::detail::lexer_base
Definition: json.hpp:6449
JSON_CATCH
#define JSON_CATCH(exception)
Definition: json.hpp:2265
nlohmann::detail::wide_string_input_adapter::wide_string_input_adapter
wide_string_input_adapter(BaseInputAdapter base)
Definition: json.hpp:5516
nlohmann::basic_json::size
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:22156
nlohmann::ordered_map::insert
void insert(InputIt first, InputIt last)
Definition: json.hpp:17085
nlohmann::detail::lexer::unget
void unget()
unget current character (read it again on next get)
Definition: json.hpp:7789
nlohmann::detail::json_reverse_iterator::operator[]
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:12058
nlohmann::basic_json::basic_json_t
NLOHMANN_BASIC_JSON_TPL basic_json_t
workaround type for MSVC
Definition: json.hpp:17216
nlohmann::basic_json::type_name
JSON_HEDLEY_RETURNS_NON_NULL const char * type_name() const noexcept
return the type as string
Definition: json.hpp:24084
nlohmann::detail::json_sax_dom_callback_parser::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:6041
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:25855
JSON_HEDLEY_DIAGNOSTIC_POP
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition: json.hpp:953
nlohmann::detail::iterator_input_adapter::char_type
typename std::iterator_traits< IteratorType >::value_type char_type
Definition: json.hpp:5354
nlohmann::detail::dtoa_impl::diyfp::sub
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.hpp:14910
nlohmann::detail::contiguous_bytes_input_adapter
decltype(input_adapter(std::declval< const char * >(), std::declval< const char * >())) contiguous_bytes_input_adapter
Definition: json.hpp:5649
nlohmann::detail::iter_impl::operator+=
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:11804
nlohmann::detail::boolean_function_t
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
Definition: json.hpp:8071
nlohmann::detail::binary_reader::parse_cbor_internal
bool parse_cbor_internal(const bool get_char, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:8586
nlohmann::detail::iterator_input_adapter_factory
Definition: json.hpp:5556
nlohmann::detail::iter_impl::operator>
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:11786
nlohmann::detail::value_t
value_t
the JSON type enumeration
Definition: json.hpp:118
nlohmann::detail::binary_reader::binary_reader
binary_reader(InputAdapterType &&adapter) noexcept
create a binary reader
Definition: json.hpp:8256
nlohmann::detail::primitive_iterator_t::operator+=
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition: json.hpp:11264
nlohmann::detail::iter_impl::operator-
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:11864
nlohmann::detail::dtoa_impl::grisu2_digit_gen
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: json.hpp:15427
nlohmann::detail::json_reverse_iterator::key
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.hpp:12064
nlohmann::detail::json_reverse_iterator::operator--
json_reverse_iterator const operator--(int)
post-decrement (it–)
Definition: json.hpp:12022
nlohmann::basic_json::push_back
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:22375
nlohmann::json_pointer::array_index
static BasicJsonType::size_type array_index(const std::string &s)
Definition: json.hpp:12420
nlohmann::detail::binary_reader::get_msgpack_object
bool get_msgpack_object(const std::size_t len)
Definition: json.hpp:9907
nlohmann::detail::external_constructor< value_t::number_float >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: json.hpp:4549
nlohmann::detail::binary_writer::write_bson_object
void write_bson_object(const typename BasicJsonType::object_t &value)
Definition: json.hpp:14450
nlohmann::basic_json::operator[]
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:25132
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:4957
nlohmann::detail::serializer
Definition: json.hpp:15983
nlohmann::detail::output_adapter
Definition: json.hpp:13226
nlohmann::detail::json_reverse_iterator::value
reference value() const
return the value of an iterator
Definition: json.hpp:12071
nlohmann::basic_json::end
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:21699
nlohmann::detail::iterator_types
Definition: json.hpp:3223
nlohmann::basic_json::get_impl_ptr
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
Definition: json.hpp:19877
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:20280
nlohmann::basic_json::contains
bool contains(KeyT &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:21558
nlohmann::detail::uncvref_t
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.hpp:3034
nlohmann::basic_json::push_back
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:22462
nlohmann::detail::external_constructor< value_t::array >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition: json.hpp:4594
nlohmann::detail::json_sax_dom_parser::start_array
bool start_array(std::size_t len)
Definition: json.hpp:5954
nlohmann::detail::unescape
static void unescape(std::string &s)
string unescaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:2565
nlohmann::basic_json::insert
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:22788
nlohmann::detail::lexer::char_type
typename InputAdapterType::char_type char_type
Definition: json.hpp:6532
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:22619
nlohmann::detail::json_sax_dom_parser::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:5867
nlohmann::basic_json::json_value
json_value(const string_t &value)
constructor for strings
Definition: json.hpp:18093
nlohmann::ordered_map::count
size_type count(const Key &key) const
Definition: json.hpp:17026
nlohmann::detail::primitive_iterator_t::operator++
primitive_iterator_t & operator++() noexcept
Definition: json.hpp:11238
nlohmann::basic_json::push_back
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:22411
nlohmann::detail::exception::what
const char * what() const noexcept override
returns the explanatory string
Definition: json.hpp:2646
nlohmann::detail::cbor_tag_handler_t::error
throw a parse_error exception in case of a tag
JSON_EXPLICIT
#define JSON_EXPLICIT
Definition: json.hpp:2509
nlohmann::detail::json_sax_dom_parser::number_integer
bool number_integer(number_integer_t val)
Definition: json.hpp:5898
nlohmann::detail::json_reverse_iterator::base_iterator
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.hpp:11998
nlohmann::detail::json_sax_dom_parser::boolean
bool boolean(bool val)
Definition: json.hpp:5892
nlohmann::detail::external_constructor
Definition: json.hpp:4481
nlohmann::basic_json::insert
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
Definition: json.hpp:22740
nlohmann::detail::dtoa_impl::kAlpha
constexpr int kAlpha
Definition: json.hpp:15151
nlohmann::detail::value_t::array
array (ordered collection of values)
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:19284
nlohmann::detail::binary_writer::write_bson_double
void write_bson_double(const string_t &name, const double value)
Writes a BSON element with key name and double value value.
Definition: json.hpp:14175
nlohmann::basic_json::parser_callback_t
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:18406
nlohmann::json_pointer::json_pointer
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.hpp:12133
nlohmann::detail::lexer::ia
InputAdapterType ia
input adapter
Definition: json.hpp:8014
nlohmann::detail::primitive_iterator_t::operator+
primitive_iterator_t operator+(difference_type n) noexcept
Definition: json.hpp:11226
nlohmann::basic_json::basic_json
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:18581
nlohmann::basic_json::object_comparator_t
std::less< StringType > object_comparator_t
Definition: json.hpp:17442
nlohmann::detail::binary_reader::parse_msgpack_internal
bool parse_msgpack_internal()
Definition: json.hpp:9312
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:19983
nlohmann::detail::iter_impl::operator++
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:11637
nlohmann::basic_json::emplace_back
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:22566
nlohmann::basic_json::get_impl
ValueType get_impl(detail::priority_tag< 1 >) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t &>())))
get a value (explicit); special case
Definition: json.hpp:20075
nlohmann::detail::binary_writer::to_char_type
static constexpr CharType to_char_type(InputCharType x) noexcept
Definition: json.hpp:14815
nlohmann::detail::is_compatible_string_type
Definition: json.hpp:3694
nlohmann::basic_json::back
reference back()
access the last element
Definition: json.hpp:21111
nlohmann::detail::json_reverse_iterator
a template for a reverse iterator class
Definition: json.hpp:11993
nlohmann::detail::json_sax_acceptor::start_object
bool start_object(std::size_t=std::size_t(-1))
Definition: json.hpp:6386
nlohmann::detail::serializer::indent_char
const char indent_char
the indentation character
Definition: json.hpp:16889
nlohmann::detail::iter_impl::iter_impl
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.hpp:11465
nlohmann::detail::exception::m
std::runtime_error m
an exception object as storage for error messages
Definition: json.hpp:2721
nlohmann::basic_json
a class to store JSON values
Definition: json.hpp:3366
nlohmann::detail::json_sax_dom_callback_parser::end_array
bool end_array()
Definition: json.hpp:6191
nlohmann::detail::dtoa_impl::kGamma
constexpr int kGamma
Definition: json.hpp:15152
nlohmann::basic_json::from_msgpack
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:24797
nlohmann::detail::make_void::type
void type
Definition: json.hpp:3209
nlohmann::detail::integer_sequence::size
static constexpr std::size_t size() noexcept
Definition: json.hpp:3078
nlohmann::basic_json::get_impl_ptr
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
Definition: json.hpp:19853
nlohmann::detail::iterator_t
typename T::iterator iterator_t
Definition: json.hpp:3478
JSON_HEDLEY_DIAGNOSTIC_PUSH
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition: json.hpp:952
nlohmann::basic_json::destroy
void destroy(value_t t) noexcept
Definition: json.hpp:18152
nlohmann::detail::to_json
void to_json(BasicJsonType &j, const T &b)
Definition: json.hpp:4803
nlohmann::detail::json_sax_dom_callback_parser::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6042
nlohmann::detail::output_stream_adapter::output_stream_adapter
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition: json.hpp:13182
nlohmann::json_pointer::to_string
std::string to_string() const
return a string representation of the JSON pointer
Definition: json.hpp:12151
nlohmann::detail::json_sax_acceptor::end_object
bool end_object()
Definition: json.hpp:6396
nlohmann::basic_json::operator>=
friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:23669
nlohmann::detail::json_sax_dom_parser::string
bool string(string_t &val)
Definition: json.hpp:5916
nlohmann::detail::iter_impl::operator>=
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:11795
nlohmann::basic_json::get_impl_ptr
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
Definition: json.hpp:19841
nlohmann::detail::input_format_t::bson
nlohmann::ordered_map::Container
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.hpp:16929
nlohmann::detail::input_stream_adapter::get_character
std::char_traits< char >::int_type get_character()
Definition: json.hpp:5331
nlohmann::detail::is_sax::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:8126
nlohmann::adl_serializer
default JSONSerializer template argument
Definition: json.hpp:3353
nlohmann::detail::iter_impl::operator--
iter_impl const operator--(int)
post-decrement (it–)
Definition: json.hpp:11669
nlohmann::detail::json_reverse_iterator::difference_type
std::ptrdiff_t difference_type
Definition: json.hpp:11996
nlohmann::detail::input_stream_adapter
Definition: json.hpp:5297
nlohmann::basic_json::json_value
json_value(const array_t &value)
constructor for arrays
Definition: json.hpp:18117
nlohmann::json_pointer::get_and_create
BasicJsonType & get_and_create(BasicJsonType &j) const
create and return a reference to the pointed to value
Definition: json.hpp:12485
nlohmann::detail::priority_tag< 0 >
Definition: json.hpp:3160
nlohmann::detail::binary_writer::write_compact_float
void write_compact_float(const number_float_t n, detail::input_format_t format)
Definition: json.hpp:14759
nlohmann::basic_json::operator<<
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:23714
nlohmann::detail::lexer::get_number_float
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:7839
nlohmann::basic_json::json_value
json_value(string_t &&value)
constructor for rvalue strings
Definition: json.hpp:18099
nlohmann::detail::binary_writer::write_bson_object_entry
void write_bson_object_entry(const string_t &name, const typename BasicJsonType::object_t &value)
Writes a BSON element with key name and object value.
Definition: json.hpp:14275
nlohmann::basic_json::cend
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:21739
nlohmann::basic_json::accept
static bool accept(IteratorType first, IteratorType last, const bool ignore_comments=false)
Definition: json.hpp:23905
nlohmann::detail::is_compatible_type
Definition: json.hpp:3822
nlohmann::basic_json::swap
void swap(binary_t &other)
exchanges the values
Definition: json.hpp:23188
nlohmann::detail::iter_impl::operator<
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:11750
nlohmann::detail::is_getable
Definition: json.hpp:3498
nlohmann::detail::to_json_fn::operator()
auto operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
Definition: json.hpp:4823
nlohmann::basic_json::output_adapter_t
::nlohmann::detail::output_adapter_t< CharType > output_adapter_t
Definition: json.hpp:17245
nlohmann::detail::lexer::get_token_string
std::string get_token_string() const
Definition: json.hpp:7863
nlohmann::detail::dtoa_impl::diyfp::normalize_to
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
Definition: json.hpp:15004
nlohmann::detail::wide_string_input_adapter::base_adapter
BaseInputAdapter base_adapter
Definition: json.hpp:5537
nlohmann::detail::json_sax_dom_callback_parser::start_array
bool start_array(std::size_t len)
Definition: json.hpp:6174
nlohmann::detail::parse_error::position_string
static std::string position_string(const position_t &pos)
Definition: json.hpp:2813
JSON_HEDLEY_WARN_UNUSED_RESULT
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition: json.hpp:1298
nlohmann::detail::value_t::number_integer
number value (signed integer)
nlohmann::detail::json_sax_dom_callback_parser::string
bool string(string_t &val)
Definition: json.hpp:6091
nlohmann::detail::iter_impl::key
const object_t::key_type & key() const
return the key of an object iterator
Definition: json.hpp:11927
nlohmann::basic_json::get_impl
constexpr auto get_impl(detail::priority_tag< 4 >) const noexcept -> decltype(std::declval< const basic_json_t &>().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:20136
JSON_INTERNAL_CATCH
#define JSON_INTERNAL_CATCH(exception)
Definition: json.hpp:2266
nlohmann::detail::lexer::reset
void reset() noexcept
reset token_buffer; current character is beginning of token
Definition: json.hpp:7735
nlohmann::detail::dtoa_impl::reinterpret_bits
Target reinterpret_bits(const Source source)
Definition: json.hpp:14888
nlohmann::basic_json::pointer
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:17321
nlohmann::basic_json::number_integer_t
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:17729
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:20941
std
STL namespace.
nlohmann::detail::lexer::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6529
nlohmann::detail::parse_event_t::array_start
the parser read [ and started to process a JSON array
nlohmann::detail::output_adapter::output_adapter
output_adapter(StringType &s)
Definition: json.hpp:13235
nlohmann::detail::external_constructor< value_t::string >::construct
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: json.hpp:4499
nlohmann::detail::json_reverse_iterator::operator+=
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:12034
nlohmann::detail::dtoa_impl::grisu2_round
void grisu2_round(char *buf, int len, std::uint64_t dist, std::uint64_t delta, std::uint64_t rest, std::uint64_t ten_k)
Definition: json.hpp:15386
nlohmann::detail::binary_reader::exception_message
std::string exception_message(const input_format_t format, const std::string &detail, const std::string &context) const
Definition: json.hpp:10595
nlohmann::detail::json_sax_dom_parser::key
bool key(string_t &val)
Definition: json.hpp:5940
nlohmann::detail::binary_writer::get_ubjson_float_prefix
static constexpr CharType get_ubjson_float_prefix(double)
Definition: json.hpp:14722
nlohmann::detail::value_t::boolean
boolean value
nlohmann::detail::json_ref::json_ref
json_ref(Args &&... args)
Definition: json.hpp:13056
nlohmann::basic_json::crend
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:21872
nlohmann::detail::serializer::dump
void dump(const BasicJsonType &val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
Definition: json.hpp:16039
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:24323
nlohmann::detail::iteration_proxy::iteration_proxy
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.hpp:4404
nlohmann::detail::iter_impl::operator-=
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:11833
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:19970
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:12385
nlohmann::basic_json::from_cbor
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:24654
nlohmann::json_pointer::get_unchecked
BasicJsonType & get_unchecked(BasicJsonType *ptr) const
return a reference to the pointed to value
Definition: json.hpp:12557
nlohmann::detail::iter_impl::set_end
void set_end() noexcept
set the iterator past the last value
Definition: json.hpp:11524
nlohmann::detail::json_sax_dom_callback_parser::start_object
bool start_object(std::size_t len)
Definition: json.hpp:6103
nlohmann::detail::iter_impl
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition: json.hpp:11348
nlohmann::detail::binary_reader::char_type
typename InputAdapterType::char_type char_type
Definition: json.hpp:8247
nlohmann::detail::json_sax_acceptor::string
bool string(string_t &)
Definition: json.hpp:6376
nlohmann::detail::binary_reader::parse_bson_element_list
bool parse_bson_element_list(const bool is_array)
Read a BSON element list (as specified in the BSON-spec)
Definition: json.hpp:8518
nlohmann::detail::hash
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:5117
nlohmann::detail::get_arithmetic_value
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:3855
nlohmann::detail::binary_reader::get_ubjson_array
bool get_ubjson_array()
Definition: json.hpp:10236
nlohmann::detail::position_t::chars_read_current_line
std::size_t chars_read_current_line
the number of characters read in the current line
Definition: json.hpp:2589
nlohmann::detail::iter_impl::iterator_category
std::bidirectional_iterator_tag iterator_category
Definition: json.hpp:11371
nlohmann::basic_json::operator>
friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:23623
nlohmann::basic_json::diff
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition: json.hpp:25641
nlohmann::detail::output_adapter::output_adapter
output_adapter(std::basic_ostream< CharType > &s)
Definition: json.hpp:13232
nlohmann::basic_json::begin
const_iterator begin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:21638
nlohmann::detail::output_string_adapter::write_character
void write_character(CharType c) override
Definition: json.hpp:13210
nlohmann::detail::dtoa_impl::get_cached_power_for_binary_exponent
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.hpp:15168
nlohmann::detail::is_sax
Definition: json.hpp:8117
nlohmann::detail::start_array_function_t
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
Definition: json.hpp:8106
nlohmann::detail::json_sax_acceptor::key
bool key(string_t &)
Definition: json.hpp:6391
nlohmann::detail::json_reverse_iterator::json_reverse_iterator
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:12003
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:4947
nlohmann::detail::is_sax::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:8127
nlohmann::detail::serializer::binary_char_t
typename BasicJsonType::binary_t::value_type binary_char_t
Definition: json.hpp:15989
nlohmann::json_pointer::split
static std::vector< std::string > split(const std::string &reference_string)
split the string input to reference tokens
Definition: json.hpp:12825
nlohmann::basic_json::get_impl_ptr
constexpr const number_integer_t * get_impl_ptr(const number_integer_t *) const noexcept
get a pointer to the value (integer number)
Definition: json.hpp:19871
nlohmann::detail::from_json_fn::operator()
auto operator()(const BasicJsonType &j, T &&val) const noexcept(noexcept(from_json(j, std::forward< T >(val)))) -> decltype(from_json(j, std::forward< T >(val)))
Definition: json.hpp:4251
nlohmann::detail::lexer
lexical analysis
Definition: json.hpp:6526
nlohmann::basic_json::erase
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:21386
nlohmann::detail::external_constructor< value_t::number_unsigned >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: json.hpp:4561
nlohmann::basic_json::get_impl
basic_json get_impl(detail::priority_tag< 3 >) const
get special-case overload
Definition: json.hpp:20123
nlohmann::detail::binary_writer::write_bson
void write_bson(const BasicJsonType &j)
Definition: json.hpp:13283
nlohmann::detail::utility_internal::Gen::type
typename Extend< typename Gen< T, N/2 >::type, N/2, N % 2 >::type type
Definition: json.hpp:3117
nlohmann::basic_json::json_value
json_value(const binary_t &value)
constructor for binary arrays (internal type)
Definition: json.hpp:18141
nlohmann::detail::is_compatible_type_impl
Definition: json.hpp:3810
nlohmann::detail::primitive_iterator_t::set_end
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:11199
nlohmann::detail::out_of_range::create
static out_of_range create(int id_, const std::string &what_arg, const BasicJsonType &context)
Definition: json.hpp:2964
nlohmann::detail::json_sax_acceptor::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6345
nlohmann::byte_container_with_subtype::subtype
constexpr std::uint8_t subtype() const noexcept
return the binary subtype
Definition: json.hpp:5019
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:12994
nlohmann::detail::from_json
void from_json(const BasicJsonType &j, std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > &m)
Definition: json.hpp:4231
nlohmann::detail::binary_reader::get_bson_binary
bool get_bson_binary(const NumberType len, binary_t &result)
Parses a byte array input of length len from the BSON input.
Definition: json.hpp:8414
nlohmann::detail::parser
syntax analysis
Definition: json.hpp:10708
nlohmann::basic_json::get_impl_ptr
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
Definition: json.hpp:19823
nlohmann::detail::binary_writer
serialization to CBOR and MessagePack values
Definition: json.hpp:13262
nlohmann::detail::dtoa_impl::boundaries::minus
diyfp minus
Definition: json.hpp:15018
nlohmann::detail::has_from_json
Definition: json.hpp:3491
nlohmann::basic_json::from_cbor
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:24637
nlohmann::detail::detector::value_t
std::false_type value_t
Definition: json.hpp:3296
nlohmann::basic_json::insert
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements
Definition: json.hpp:22841
nlohmann::detail::output_vector_adapter
output adapter for byte vectors
Definition: json.hpp:13155
nlohmann::detail::iter_impl::operator->
pointer operator->() const
dereference the iterator
Definition: json.hpp:11592
nlohmann::detail::lexer_base::token_type_name
JSON_HEDLEY_RETURNS_NON_NULL static JSON_HEDLEY_CONST const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
Definition: json.hpp:6477
nlohmann::detail::lexer::skip_whitespace
void skip_whitespace()
Definition: json.hpp:7915
nlohmann::detail::binary_reader::get_token_string
std::string get_token_string() const
Definition: json.hpp:10582
nlohmann::detail::parse_error::byte
const std::size_t byte
byte index of the parse error
Definition: json.hpp:2807
nlohmann::detail::binary_reader::get_cbor_array
bool get_cbor_array(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:9221
nlohmann::json_sax::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:5733
nlohmann::detail::iterator_input_adapter::get_character
std::char_traits< char_type >::int_type get_character()
Definition: json.hpp:5360
nlohmann::detail::binary_reader::get_ubjson_value
bool get_ubjson_value(const char_int_type prefix)
Definition: json.hpp:10135
nlohmann::detail::internal_iterator::object_iterator
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition: json.hpp:11293
nlohmann::detail::to_json
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.hpp:4686
nlohmann::detail::iterator_traits< T *, enable_if_t< std::is_object< T >::value > >::difference_type
ptrdiff_t difference_type
Definition: json.hpp:3256
nlohmann::detail::index_sequence
integer_sequence< size_t, Ints... > index_sequence
Definition: json.hpp:3090
nlohmann::byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:4939
nlohmann::basic_json::get_impl_ptr
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
Definition: json.hpp:19865
nlohmann::ordered_map::find
const_iterator find(const Key &key) const
Definition: json.hpp:17050
nlohmann::detail::json_sax_dom_callback_parser::end_object
bool end_object()
Definition: json.hpp:6138
nlohmann::detail::iteration_proxy_value
Definition: json.hpp:4306
nlohmann::basic_json::is_boolean
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:19537
nlohmann::detail::error_handler_t::strict
throw a type_error exception in case of invalid UTF-8
nlohmann::detail::parser::accept
bool accept(const bool strict=true)
public accept interface
Definition: json.hpp:10801
nlohmann::ordered_map::mapped_type
T mapped_type
Definition: json.hpp:16928
nlohmann::detail::lexer::scan
token_type scan()
Definition: json.hpp:7924
nlohmann::detail::lexer::skip_bom
bool skip_bom()
skip the UTF-8 byte order mark
Definition: json.hpp:7901
nlohmann::basic_json::front
const_reference front() const
access the first element
Definition: json.hpp:21075
nlohmann::detail::json_sax_dom_parser::number_float
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:5910
nlohmann::detail::iterator_input_adapter_factory::char_type
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:5559
nlohmann::detail::out_of_range
exception indicating access out of the defined range
Definition: json.hpp:2960
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:4943
nlohmann::basic_json::operator!=
friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:23410
nlohmann::basic_json::rend
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:21806
nlohmann::detail::json_sax_dom_callback_parser::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6039
nlohmann::detail::priority_tag
Definition: json.hpp:3159
nlohmann::detail::json_sax_dom_parser::handle_value
JSON_HEDLEY_RETURNS_NON_NULL BasicJsonType * handle_value(Value &&v)
Definition: json.hpp:6000
nlohmann::detail::primitive_iterator_t::operator--
primitive_iterator_t & operator--() noexcept
Definition: json.hpp:11251
nlohmann::detail::value_t::binary
binary array (ordered collection of bytes)
nlohmann::detail::is_compatible_integer_type
Definition: json.hpp:3805
nlohmann::detail::json_sax_dom_parser::end_object
bool end_object()
Definition: json.hpp:5947
nlohmann::detail::primitive_iterator_t::set_begin
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:11193
nlohmann::detail::get_template_function
decltype(std::declval< T >().template get< U >()) get_template_function
Definition: json.hpp:3487
nlohmann::detail::is_constructible_array_type
Definition: json.hpp:3779
nlohmann::detail::binary_writer::write_msgpack
void write_msgpack(const BasicJsonType &j)
Definition: json.hpp:13608
nlohmann::detail::parse_event_t::array_end
the parser read ] and finished processing a JSON array
nlohmann::detail::is_iterator_of_multibyte::value_type
typename std::iterator_traits< T >::value_type value_type
Definition: json.hpp:5571
nlohmann::detail::binary_writer::calc_bson_unsigned_size
static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
Definition: json.hpp:14243
nlohmann::detail::binary_reader::get_bson_string
bool get_bson_string(const NumberType len, string_t &result)
Parses a zero-terminated string of length len from the BSON input.
Definition: json.hpp:8393
nlohmann::basic_json::erase
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:21178
nlohmann::basic_json::swap
void swap(typename binary_t::container_type &other)
exchanges the values
Definition: json.hpp:23202
nlohmann::detail::dtoa_impl::diyfp::normalize
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.hpp:14987
nlohmann::detail::is_compatible_object_type_impl< BasicJsonType, CompatibleObjectType, enable_if_t< is_detected< mapped_type_t, CompatibleObjectType >::value &&is_detected< key_type_t, CompatibleObjectType >::value > >::object_t
typename BasicJsonType::object_t object_t
Definition: json.hpp:3632
nlohmann::detail::iteration_proxy_value::operator==
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition: json.hpp:4349
nlohmann::detail::is_sax::exception_t
typename BasicJsonType::exception exception_t
Definition: json.hpp:8128
nlohmann::detail::primitive_iterator_t::operator++
primitive_iterator_t const operator++(int) noexcept
Definition: json.hpp:11244
nlohmann::basic_json::from_msgpack
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:24781
nlohmann::basic_json::get_ref
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:20329
nlohmann::detail::difference_type_t
typename T::difference_type difference_type_t
Definition: json.hpp:3466
nlohmann::detail::json_sax_dom_callback_parser::parser_callback_t
typename BasicJsonType::parser_callback_t parser_callback_t
Definition: json.hpp:6043
nlohmann::detail::binary_writer::write_bson_string
void write_bson_string(const string_t &name, const string_t &value)
Writes a BSON element with key name and string value value.
Definition: json.hpp:14193
nlohmann::detail::iter_impl::operator++
iter_impl const operator++(int)
post-increment (it++)
Definition: json.hpp:11626
nlohmann::detail::wide_string_input_helper< BaseInputAdapter, 2 >::fill_buffer
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.hpp:5451
nlohmann::basic_json::get_impl
BasicJsonType get_impl(detail::priority_tag< 2 >) const
get special-case overload
Definition: json.hpp:20100
nlohmann::detail::binary_reader::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:8243
nlohmann::detail::end_object_function_t
decltype(std::declval< T & >().end_object()) end_object_function_t
Definition: json.hpp:8102
nlohmann::basic_json::basic_json
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:19156
nlohmann::detail::is_detected_convertible
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition: json.hpp:3324
nlohmann::detail::iterator_input_adapter_factory::iterator_type
IteratorType iterator_type
Definition: json.hpp:5558
nlohmann::detail::iterator_types< It, void_t< typename It::difference_type, typename It::value_type, typename It::pointer, typename It::reference, typename It::iterator_category > >::value_type
typename It::value_type value_type
Definition: json.hpp:3232
nlohmann::detail::container_input_adapter_factory_impl::container_input_adapter_factory< ContainerType, void_t< decltype(begin(std::declval< ContainerType >()), end(std::declval< ContainerType >()))> >::adapter_type
decltype(input_adapter(begin(std::declval< ContainerType >()), end(std::declval< ContainerType >()))) adapter_type
Definition: json.hpp:5617
nlohmann::detail::json_sax_dom_parser
SAX implementation to create a JSON value from SAX events.
Definition: json.hpp:5861
nlohmann::detail::detected_t
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition: json.hpp:3311
nlohmann::detail::is_constructible
Definition: json.hpp:3579
nlohmann::detail::external_constructor< value_t::object >::construct
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.hpp:4649
nlohmann::detail::lexer::scan_number
token_type scan_number()
scan a number literal
Definition: json.hpp:7384
nlohmann::detail::lexer_base::token_type
token_type
token types for the parser
Definition: json.hpp:6453
nlohmann::basic_json::value
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
Definition: json.hpp:20963
nlohmann::basic_json::to_msgpack
static void to_msgpack(const basic_json &j, detail::output_adapter< char > o)
Definition: json.hpp:24335
nlohmann::detail::json_reverse_iterator::operator-
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:12046
nlohmann::basic_json::is_binary
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:19740
nlohmann::basic_json::number_float_t
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:17868
nlohmann::detail::parse_event_t::key
the parser read a key of a value in an object
nlohmann::detail::is_constructible_array_type_impl
Definition: json.hpp:3740
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:17082
nlohmann::detail::cbor_tag_handler_t::ignore
ignore tags
nlohmann::detail::wide_string_input_helper< BaseInputAdapter, 4 >::fill_buffer
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.hpp:5393
nlohmann::detail::is_sax::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:8124
nlohmann::detail::span_input_adapter::span_input_adapter
span_input_adapter(CharT b, std::size_t l)
Definition: json.hpp:5684
nlohmann::basic_json::erase
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:21421
nlohmann::detail::binary_reader::get_cbor_string
bool get_cbor_string(string_t &result)
reads a CBOR string
Definition: json.hpp:9032
nlohmann::detail::parse_error
exception indicating a parse error
Definition: json.hpp:2769
nlohmann::detail::json_sax_dom_parser::null
bool null()
Definition: json.hpp:5886
nlohmann::detail::input_stream_adapter::input_stream_adapter
input_stream_adapter(input_stream_adapter &&rhs) noexcept
Definition: json.hpp:5321
JSON_THROW
#define JSON_THROW(exception)
Definition: json.hpp:2263
nlohmann::detail::iter_impl::operator-
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:11875
nlohmann::detail::json_reverse_iterator::json_reverse_iterator
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:12007
nlohmann::detail::wide_string_input_adapter::char_type
char char_type
Definition: json.hpp:5514
nlohmann::detail::parse_error_function_t
decltype(std::declval< T & >().parse_error(std::declval< std::size_t >(), std::declval< const std::string & >(), std::declval< const Exception & >())) parse_error_function_t
Definition: json.hpp:8114
nlohmann::detail::binary_reader::get_binary
bool get_binary(const input_format_t format, const NumberType len, binary_t &result)
create a byte array by reading bytes from the input
Definition: json.hpp:10545
nlohmann::detail::is_detected
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition: json.hpp:3308
nlohmann::detail::json_reverse_iterator::operator++
json_reverse_iterator const operator++(int)
post-increment (it++)
Definition: json.hpp:12010
nlohmann::detail::json_sax_dom_callback_parser::number_unsigned
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:6079
nlohmann::detail::external_constructor< value_t::array >::construct
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.hpp:4585
nlohmann::detail::binary_reader::get_string
bool get_string(const input_format_t format, const NumberType len, string_t &result)
create a string by reading characters from the input
Definition: json.hpp:10512
nlohmann::detail::end_array_function_t
decltype(std::declval< T & >().end_array()) end_array_function_t
Definition: json.hpp:8109
nlohmann::basic_json::json_value
json_value(boolean_t v) noexcept
constructor for booleans
Definition: json.hpp:18014
nlohmann::detail::output_vector_adapter::v
std::vector< CharType > & v
Definition: json.hpp:13174
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:12290
nlohmann::detail::binary_reader::parse_bson_internal
bool parse_bson_internal()
Reads in a BSON-object and passes it to the SAX-parser.
Definition: json.hpp:8338
nlohmann::basic_json::cbegin
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:21668
nlohmann::basic_json::rbegin
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:21769
nlohmann::detail::iteration_proxy_value::difference_type
std::ptrdiff_t difference_type
Definition: json.hpp:4309
nlohmann::detail::json_reverse_iterator::reference
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:12000
JSON_HEDLEY_RETURNS_NON_NULL
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition: json.hpp:1897
nlohmann::detail::internal_iterator::primitive_iterator
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:11297
nlohmann::detail::container_input_adapter_factory_impl::container_input_adapter_factory
Definition: json.hpp:5611
nlohmann::detail::output_adapter_protocol
abstract output adapter interface
Definition: json.hpp:13136
nlohmann::basic_json::back
const_reference back() const
access the last element
Definition: json.hpp:21121
nlohmann::detail::output_vector_adapter::write_character
void write_character(CharType c) override
Definition: json.hpp:13162
nlohmann::detail::dtoa_impl::diyfp::f
std::uint64_t f
Definition: json.hpp:14901
nlohmann::detail::exception
general exception of the basic_json class
Definition: json.hpp:2642
nlohmann::detail::iteration_proxy::container
IteratorType::reference container
the container to iterate
Definition: json.hpp:4400
nlohmann::basic_json::get_impl_ptr
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
Definition: json.hpp:19889
nlohmann::detail::dtoa_impl::append_exponent
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.hpp:15768
nlohmann::byte_container_with_subtype::operator!=
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:4969
nlohmann::detail::dtoa_impl::compute_boundaries
boundaries compute_boundaries(FloatType value)
Definition: json.hpp:15029
nlohmann::detail::is_basic_json
Definition: json.hpp:3434
nlohmann::basic_json::is_object
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:19674
nlohmann::basic_json::json_value
json_value(value_t t)
constructor for empty values of a given type
Definition: json.hpp:18022
nlohmann::basic_json::get_impl_ptr
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
Definition: json.hpp:19835
nlohmann::detail::parser::token_type
typename lexer_t::token_type token_type
Definition: json.hpp:10715
nlohmann::basic_json::json_value
json_value(binary_t &&value)
constructor for rvalue binary arrays (internal type)
Definition: json.hpp:18147
nlohmann::detail::iteration_proxy_value::operator!=
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition: json.hpp:4355
nlohmann::detail::is_complete_type
Definition: json.hpp:3617
nlohmann::detail::parse_error::create
static parse_error create(int id_, const position_t &pos, const std::string &what_arg, const BasicJsonType &context)
create a parse error exception
Definition: json.hpp:2782
nlohmann::basic_json::from_ubjson
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:24898
nlohmann::detail::binary_writer::write_bson_null
void write_bson_null(const string_t &name)
Writes a BSON element with key name and null value.
Definition: json.hpp:14207
nlohmann::basic_json::clear
void clear() noexcept
clears the contents
Definition: json.hpp:22298
nlohmann::detail::binary_reader::get_msgpack_array
bool get_msgpack_array(const std::size_t len)
Definition: json.hpp:9885
nlohmann::detail::is_compatible_integer_type_impl
Definition: json.hpp:3784
nlohmann::basic_json::crbegin
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:21843
nlohmann::detail::serializer::error_handler
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition: json.hpp:16894
nlohmann::detail::external_constructor< value_t::number_integer >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: json.hpp:4573
nlohmann::detail::internal_iterator::array_iterator
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:11295
nlohmann::detail::iterator_input_adapter::current
IteratorType current
Definition: json.hpp:5373
nlohmann::detail::parser::exception_message
std::string exception_message(const token_type expected, const std::string &context)
Definition: json.hpp:11107
nlohmann::detail::iter_impl::reference
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition: json.hpp:11385
nlohmann::detail::json_sax_dom_callback_parser::number_integer
bool number_integer(number_integer_t val)
Definition: json.hpp:6073
nlohmann::basic_json::patch
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:25343
nlohmann::detail::output_adapter::output_adapter
output_adapter(std::vector< CharType > &vec)
Definition: json.hpp:13229
nlohmann::byte_container_with_subtype
an internal type for a backed binary type
Definition: json.hpp:4933
nlohmann::json_pointer::result
return result
Definition: json.hpp:12473
nlohmann::detail::iter_impl::m_it
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition: json.hpp:11952
nlohmann::detail::iteration_proxy_value::string_type
typename std::remove_cv< typename std::remove_reference< decltype(std::declval< IteratorType >().key()) >::type >::type string_type
Definition: json.hpp:4314
nlohmann::detail::binary_writer::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:13266
nlohmann::detail::parse_event_t::object_end
the parser read } and finished processing a JSON object
nlohmann::detail::span_input_adapter::ia
contiguous_bytes_input_adapter ia
Definition: json.hpp:5700
nlohmann::detail::lexer::next_byte_in_range
bool next_byte_in_range(std::initializer_list< char_int_type > ranges)
check if the next byte(s) are inside a given range
Definition: json.hpp:6632
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:12379
nlohmann::basic_json::from_bson
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
Definition: json.hpp:25028
nlohmann::detail::invalid_iterator
exception indicating errors with iterators
Definition: json.hpp:2857
nlohmann::detail::dtoa_impl::diyfp::e
int e
Definition: json.hpp:14902
nlohmann::detail::has_non_default_from_json
Definition: json.hpp:3516
nlohmann::basic_json::swap
void swap(array_t &other)
exchanges the values
Definition: json.hpp:23089
nlohmann::json_pointer::get_unchecked
const BasicJsonType & get_unchecked(const BasicJsonType *ptr) const
return a const reference to the pointed to value
Definition: json.hpp:12665
nlohmann::detail::operator<
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:145
nlohmann::basic_json::max_size
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:22227
nlohmann::detail::json_sax_acceptor
Definition: json.hpp:6342
nlohmann::basic_json::meta
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition: json.hpp:17372
nlohmann::detail::dtoa_impl::grisu2
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition: json.hpp:15668
nlohmann::basic_json::operator+=
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:22401
nlohmann::detail::iterator_types< It, void_t< typename It::difference_type, typename It::value_type, typename It::pointer, typename It::reference, typename It::iterator_category > >::pointer
typename It::pointer pointer
Definition: json.hpp:3233
nlohmann::basic_json::object
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:18933
nlohmann
namespace for Niels Lohmann
Definition: json.hpp:86
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:24426
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:19382
nlohmann::detail::json_sax_acceptor::number_integer
bool number_integer(number_integer_t)
Definition: json.hpp:6361
nlohmann::detail::json_sax_dom_callback_parser::number_float
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:6085
nlohmann::detail::lexer::scan_string
token_type scan_string()
scan a string literal
Definition: json.hpp:6669
nlohmann::detail::type_error::create
static type_error create(int id_, const std::string &what_arg, const BasicJsonType &context)
Definition: json.hpp:2916
JSON_HEDLEY_CONST
#define JSON_HEDLEY_CONST
Definition: json.hpp:1668
nlohmann::detail::json_ref::json_ref
json_ref(std::initializer_list< json_ref > init)
Definition: json.hpp:13049
nlohmann::detail::iterator_input_adapter_factory< IteratorType, enable_if_t< is_iterator_of_multibyte< IteratorType >::value > >::iterator_type
IteratorType iterator_type
Definition: json.hpp:5581
nlohmann::detail::json_sax_dom_parser::parse_error
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:5974
nlohmann::detail::binary_reader::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:8244
nlohmann::basic_json::type
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:19435
nlohmann::detail::primitive_iterator_t::get_value
constexpr difference_type get_value() const noexcept
Definition: json.hpp:11187
nlohmann::detail::wide_string_input_adapter::get_character
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:5519
nlohmann::detail::json_reverse_iterator::operator+
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:12040
nlohmann::detail::lexer::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:6531
nlohmann::detail::serializer::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:15987
nlohmann::detail::json_sax_dom_parser::start_object
bool start_object(std::size_t len)
Definition: json.hpp:5928
nlohmann::detail::value_t::object
object (unordered set of name/value pairs)
nlohmann::detail::binary_writer::write_number
void write_number(const NumberType n)
Definition: json.hpp:14743
nlohmann::detail::json_sax_dom_callback_parser::is_errored
constexpr bool is_errored() const
Definition: json.hpp:6236
nlohmann::detail::integer_sequence
Definition: json.hpp:3075
nlohmann::detail::parser::get_token
token_type get_token()
get next token from lexer
Definition: json.hpp:11102
nlohmann::detail::binary_writer::write_bson_unsigned
void write_bson_unsigned(const string_t &name, const BasicJsonType &j)
Writes a BSON element with key name and unsigned value.
Definition: json.hpp:14253
nlohmann::basic_json::number_unsigned_t
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:17800
nlohmann::detail::exception::diagnostics
static std::string diagnostics(const BasicJsonType &leaf_element)
Definition: json.hpp:2664
nlohmann::detail::has_to_json< BasicJsonType, T, enable_if_t< !is_basic_json< T >::value > >::serializer
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3536
nlohmann::detail::to_json_fn
Definition: json.hpp:4820
nlohmann::detail::parser::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:10712
nlohmann::ordered_map::at
T & at(const Key &key)
Definition: json.hpp:16967
nlohmann::detail::iterator_traits< T *, enable_if_t< std::is_object< T >::value > >::reference
T & reference
Definition: json.hpp:3258
nlohmann::detail::iter_impl::operator*
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:11555
nlohmann::basic_json::array
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:18889
nlohmann::detail::dtoa_impl::cached_power
Definition: json.hpp:15154
nlohmann::detail::static_const
Definition: json.hpp:3164
nlohmann::basic_json::find
iterator find(KeyT &&key)
find an element in a JSON object
Definition: json.hpp:21474
nlohmann::basic_json::number_float
number_float_t number_float
number (floating-point)
Definition: json.hpp:18009
nlohmann::detail::enable_if_t
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:3048
nlohmann::basic_json::json_value
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
Definition: json.hpp:18016
nlohmann::ordered_map::ordered_map
ordered_map(const Allocator &alloc=Allocator())
Definition: json.hpp:16937
nlohmann::basic_json::get_to
ValueType & get_to(ValueType &v) const
Definition: json.hpp:20269
nlohmann::basic_json::at
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:20495
nlohmann::detail::iter_impl::pointer
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition: json.hpp:11380
nlohmann::basic_json::basic_json
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:18447
NLOHMANN_BASIC_JSON_TPL
#define NLOHMANN_BASIC_JSON_TPL
Definition: json.hpp:2345
nlohmann::ordered_map::operator[]
const T & operator[](const Key &key) const
Definition: json.hpp:16962
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:13011
nlohmann::detail::type_error
exception indicating executing a member function with a wrong type
Definition: json.hpp:2912
nlohmann::detail::combine
std::size_t combine(std::size_t seed, std::size_t h) noexcept
Definition: json.hpp:5099
nlohmann::basic_json::is_number_unsigned
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:19624
nlohmann::basic_json::from_bson
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
Definition: json.hpp:25012
NLOHMANN_JSON_VERSION_PATCH
#define NLOHMANN_JSON_VERSION_PATCH
Definition: json.hpp:35
nlohmann::basic_json::operator[]
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:20696
nlohmann::json_pointer::flatten
static void flatten(const std::string &reference_string, const BasicJsonType &value, BasicJsonType &result)
Definition: json.hpp:12893
nlohmann::detail::binary_writer::write_bson_entry_header
void write_bson_entry_header(const string_t &name, const std::uint8_t element_type)
Writes the given element_type and name to the output adapter.
Definition: json.hpp:14153
nlohmann::detail::parser::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:10710
nlohmann::detail::binary_writer::get_cbor_float_prefix
static constexpr CharType get_cbor_float_prefix(double)
Definition: json.hpp:14471
nlohmann::detail::primitive_iterator_t::is_begin
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:11205
nlohmann::detail::wide_string_input_helper
Definition: json.hpp:5387
nlohmann::basic_json::is_primitive
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:19466
nlohmann::detail::iterator_input_adapter_factory::create
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:5562
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:4883
nlohmann::detail::json_sax_dom_callback_parser::binary
bool binary(binary_t &val)
Definition: json.hpp:6097
nlohmann::basic_json::boolean
boolean_t boolean
boolean
Definition: json.hpp:18003
nlohmann::detail::json_sax_dom_callback_parser::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6040
nlohmann::basic_json::operator>>
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:24040
nlohmann::detail::binary_reader::get_msgpack_binary
bool get_msgpack_binary(binary_t &result)
reads a MessagePack byte array
Definition: json.hpp:9774
nlohmann::detail::json_sax_dom_callback_parser::parse_event_t
typename BasicJsonType::parse_event_t parse_event_t
Definition: json.hpp:6044
nlohmann::ordered_map::erase
size_type erase(const Key &key)
Definition: json.hpp:16993
nlohmann::basic_json::binary
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition: json.hpp:18786
nlohmann::detail::has_from_json< BasicJsonType, T, enable_if_t< !is_basic_json< T >::value > >::serializer
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3506
nlohmann::basic_json::operator==
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:23280
nlohmann::detail::is_iterator_of_multibyte
Definition: json.hpp:5569
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:12270
nlohmann::detail::cbor_tag_handler_t
cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:8212
nlohmann::detail::external_constructor< value_t::object >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition: json.hpp:4658
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:20256
B1
nlohmann::detail::json_sax_acceptor::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6346
nlohmann::detail::make_index_sequence
make_integer_sequence< size_t, N > make_index_sequence
Definition: json.hpp:3144
nlohmann::detail::number_integer_function_t
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
Definition: json.hpp:8075
JSON_HEDLEY_NON_NULL
#define JSON_HEDLEY_NON_NULL(...)
Definition: json.hpp:1456
nlohmann::basic_json::at
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:25218
nlohmann::detail::external_constructor< value_t::binary >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition: json.hpp:4537
nlohmann::basic_json::create
static JSON_HEDLEY_RETURNS_NON_NULL T * create(Args &&... args)
helper for exception-safe object creation
Definition: json.hpp:17947
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:18705
nlohmann::detail::value_type_t
typename T::value_type value_type_t
Definition: json.hpp:3463
nlohmann::detail::json_sax_dom_parser::is_errored
constexpr bool is_errored() const
Definition: json.hpp:5986
nlohmann::detail::output_vector_adapter::output_vector_adapter
output_vector_adapter(std::vector< CharType > &vec) noexcept
Definition: json.hpp:13158
nlohmann::basic_json::get_impl
ValueType get_impl(detail::priority_tag< 0 >) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t &>(), std::declval< ValueType &>())))
get a value (explicit)
Definition: json.hpp:20033
nlohmann::detail::binary_reader::get_ignore_noop
char_int_type get_ignore_noop()
Definition: json.hpp:10444
nlohmann::ordered_map::emplace
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition: json.hpp:16944
nlohmann::detail::lexer::get_decimal_point
static JSON_HEDLEY_PURE char get_decimal_point() noexcept
return the locale-dependent decimal point
Definition: json.hpp:6558
nlohmann::detail::is_sax_static_asserts::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:8158
nlohmann::basic_json::parser
static ::nlohmann::detail::parser< basic_json, InputAdapterType > parser(InputAdapterType adapter, detail::parser_callback_t< basic_json >cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
Definition: json.hpp:17223
nlohmann::basic_json::array_t
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:17578
nlohmann::detail::json_sax_acceptor::start_array
bool start_array(std::size_t=std::size_t(-1))
Definition: json.hpp:6401
nlohmann::byte_container_with_subtype::operator==
bool operator==(const byte_container_with_subtype &rhs) const
Definition: json.hpp:4963
nlohmann::detail::void
j template void())
Definition: json.hpp:4061
nlohmann::detail::binary_writer::calc_bson_array_size
static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t &value)
Definition: json.hpp:14285
nlohmann::detail::null_function_t
decltype(std::declval< T & >().null()) null_function_t
Definition: json.hpp:8067
nlohmann::detail::primitive_iterator_t::difference_type
std::ptrdiff_t difference_type
Definition: json.hpp:11178
nlohmann::json_pointer::empty
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:12404
nlohmann::basic_json::operator==
friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:23365
nlohmann::json_sax::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:5734
nlohmann::detail::external_constructor< value_t::binary >::construct
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition: json.hpp:4529
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:12229
nlohmann::basic_json::get_impl
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
Definition: json.hpp:19806
nlohmann::detail::iteration_proxy_value::anchor
IteratorType anchor
the iterator
Definition: json.hpp:4318
nlohmann::detail::file_input_adapter
Definition: json.hpp:5260
nlohmann::detail::binary_writer::write_bson_array
void write_bson_array(const string_t &name, const typename BasicJsonType::array_t &value)
Writes a BSON element with key name and array value.
Definition: json.hpp:14308
nlohmann::basic_json::flatten
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:25245
nlohmann::detail::detector< Default, void_t< Op< Args... > >, Op, Args... >::type
Op< Args... > type
Definition: json.hpp:3304
nlohmann::detail::is_constructible_object_type_impl
Definition: json.hpp:3648
nlohmann::detail::parser::parse
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.hpp:10741
nlohmann::basic_json::from_ubjson
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:24914
nlohmann::detail::binary_reader::get_number
bool get_number(const input_format_t format, NumberType &result)
Definition: json.hpp:10469
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:17265
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:17323
std::hash< nlohmann::json >::operator()
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
Definition: json.hpp:25878
nlohmann::json_pointer::get_checked
const BasicJsonType & get_checked(const BasicJsonType *ptr) const
Definition: json.hpp:12705
nlohmann::basic_json::empty
bool empty() const noexcept
checks whether the container is empty.
Definition: json.hpp:22083
nlohmann::detail::is_sax_static_asserts::exception_t
typename BasicJsonType::exception exception_t
Definition: json.hpp:8159
nlohmann::basic_json::assert_invariant
void assert_invariant(bool check_parents=true) const noexcept
checks the class invariants
Definition: json.hpp:18262
nlohmann::basic_json::is_number_float
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:19652
nlohmann::detail::json_sax_dom_parser::root
BasicJsonType & root
the parsed JSON value
Definition: json.hpp:6023
JSON_TRY
#define JSON_TRY
Definition: json.hpp:2264
nlohmann::json_pointer::reference_tokens
result reference_tokens
Definition: json.hpp:12472
nlohmann::detail::binary_writer::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:13265
nlohmann::detail::dtoa_impl::boundaries
Definition: json.hpp:15015
nlohmann::detail::iteration_proxy::begin
iteration_proxy_value< IteratorType > begin() noexcept
return iterator begin (needed for range-based for)
Definition: json.hpp:4408
nlohmann::detail::binary_reader::parse_bson_element_internal
bool parse_bson_element_internal(const char_int_type element_type, const std::size_t element_type_parse_position)
Read a BSON document element of the given element_type.
Definition: json.hpp:8440
nlohmann::detail::file_input_adapter::get_character
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:5277
nlohmann::detail::iterator_types< It, void_t< typename It::difference_type, typename It::value_type, typename It::pointer, typename It::reference, typename It::iterator_category > >::difference_type
typename It::difference_type difference_type
Definition: json.hpp:3231
nlohmann::detail::binary_reader::get_cbor_object
bool get_cbor_object(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:9259
nlohmann::detail::parser::lexer_t
lexer< BasicJsonType, InputAdapterType > lexer_t
Definition: json.hpp:10714
nlohmann::detail::input_stream_adapter::char_type
char char_type
Definition: json.hpp:5300
nlohmann::basic_json::at
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:20448
nlohmann::detail::lexer::add
void add(char_int_type c)
add a character to token_buffer
Definition: json.hpp:7816
nlohmann::basic_json::front
reference front()
access the first element
Definition: json.hpp:21067
nlohmann::detail::key_type_t
typename T::key_type key_type_t
Definition: json.hpp:3460
nlohmann::detail::output_string_adapter
output adapter for basic_string
Definition: json.hpp:13203
nlohmann::detail::binary_reader::char_int_type
typename std::char_traits< char_type >::int_type char_int_type
Definition: json.hpp:8248
nlohmann::detail::parse_event_t::object_start
the parser read { and started to process a JSON object
nlohmann::basic_json::insert_iterator
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.hpp:22651
nlohmann::detail::input_stream_adapter::input_stream_adapter
input_stream_adapter(std::istream &i)
Definition: json.hpp:5312
nlohmann::basic_json::to_ubjson
static void to_ubjson(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
Definition: json.hpp:24441
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:4863
nlohmann::detail::is_sax_static_asserts
Definition: json.hpp:8148
nlohmann::detail::integer_sequence::value_type
T value_type
Definition: json.hpp:3077
nlohmann::detail::output_adapter_t
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.hpp:13151
JSON_HEDLEY_LIKELY
#define JSON_HEDLEY_LIKELY(expr)
Definition: json.hpp:1563
nlohmann::ordered_map::erase
iterator erase(iterator pos)
Definition: json.hpp:17012
nlohmann::detail::binary_reader::get_ubjson_object
bool get_ubjson_object()
Definition: json.hpp:10298
nlohmann::basic_json::string_t
StringType string_t
a type for a string
Definition: json.hpp:17631
nlohmann::basic_json::operator>
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:23601
nlohmann::detail::json_sax_acceptor::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6347
nlohmann::detail::json_sax_acceptor::number_unsigned
bool number_unsigned(number_unsigned_t)
Definition: json.hpp:6366
JSON_PRIVATE_UNLESS_TESTED
#define JSON_PRIVATE_UNLESS_TESTED
Definition: json.hpp:2299
nlohmann::ordered_map::insert
std::pair< iterator, bool > insert(const value_type &value)
Definition: json.hpp:17067
nlohmann::detail::iteration_proxy_value::operator*
iteration_proxy_value & operator*()
dereference operator (needed for range-based for)
Definition: json.hpp:4334
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:23026
nlohmann::detail::binary_writer::binary_writer
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.hpp:13274
nlohmann::json_pointer::unflatten
static BasicJsonType unflatten(const BasicJsonType &value)
Definition: json.hpp:12956
nlohmann::detail::parser::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:10713
nlohmann::detail::output_stream_adapter
output adapter for output streams
Definition: json.hpp:13179
nlohmann::detail::binary_writer::calc_bson_object_size
static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t &value)
Calculates the size of the BSON serialization of the given JSON-object j.
Definition: json.hpp:14435
nlohmann::detail::is_constructible_object_type
Definition: json.hpp:3675
nlohmann::basic_json::string
string_t * string
string (stored with pointer to save storage)
Definition: json.hpp:17999
nlohmann::detail::lexer::get_codepoint
int get_codepoint()
get codepoint from 4 hex characters following \u
Definition: json.hpp:6584
NLOHMANN_JSON_VERSION_MINOR
#define NLOHMANN_JSON_VERSION_MINOR
Definition: json.hpp:34
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:18960
nlohmann::detail::iter_impl::object_t
typename BasicJsonType::object_t object_t
Definition: json.hpp:11358
nlohmann::ordered_map::insert
std::pair< iterator, bool > insert(value_type &&value)
Definition: json.hpp:17062
nlohmann::basic_json::boolean_t
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:17657
nlohmann::basic_json::json_value
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
Definition: json.hpp:18018
nlohmann::detail::iterator_types< It, void_t< typename It::difference_type, typename It::value_type, typename It::pointer, typename It::reference, typename It::iterator_category > >::iterator_category
typename It::iterator_category iterator_category
Definition: json.hpp:3235
nlohmann::basic_json::get_impl_ptr
constexpr const number_unsigned_t * get_impl_ptr(const number_unsigned_t *) const noexcept
get a pointer to the value (unsigned number)
Definition: json.hpp:19883
nlohmann::ordered_map::find
iterator find(const Key &key)
Definition: json.hpp:17038
nlohmann::detail::binary_writer::calc_bson_entry_header_size
static std::size_t calc_bson_entry_header_size(const string_t &name, const BasicJsonType &j)
Definition: json.hpp:14139
nlohmann::detail::json_ref::operator*
value_type const & operator*() const
Definition: json.hpp:13076
nlohmann::basic_json::operator<
friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
comparison: less than
Definition: json.hpp:23520
nlohmann::detail::parse_error::create
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, const BasicJsonType &context)
Definition: json.hpp:2790
nlohmann::detail::json_ref::json_ref
json_ref(value_type &&value)
Definition: json.hpp:13041
nlohmann::ordered_map::key_type
Key key_type
Definition: json.hpp:16927
nlohmann::basic_json::parse
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(InputType &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a compatible input
Definition: json.hpp:23806
nlohmann::detail::other_error
exception indicating other library errors
Definition: json.hpp:2999
nlohmann::json_sax::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:5732
nlohmann::detail::binary_reader::get_ubjson_size_value
bool get_ubjson_size_value(std::size_t &result)
Definition: json.hpp:10017
nlohmann::detail::iteration_proxy_value::iterator_category
std::input_iterator_tag iterator_category
Definition: json.hpp:4313
nlohmann::basic_json::update
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:22924
nlohmann::detail::is_sax_static_asserts::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:8156
nlohmann::detail::lexer::get_error_message
JSON_HEDLEY_RETURNS_NON_NULL constexpr const char * get_error_message() const noexcept
return syntax error message
Definition: json.hpp:7888
nlohmann::detail::number_float_function_t
decltype(std::declval< T & >().number_float(std::declval< Float >(), std::declval< const String & >())) number_float_function_t
Definition: json.hpp:8083
nlohmann::detail::identity_tag
Definition: json.hpp:3183
nlohmann::detail::json_sax_acceptor::binary
bool binary(binary_t &)
Definition: json.hpp:6381
nlohmann::detail::wide_string_input_adapter::fill_buffer
void fill_buffer()
Definition: json.hpp:5540
nlohmann::detail::exception::name
static std::string name(const std::string &ename, int id_)
Definition: json.hpp:2658
nlohmann::detail::primitive_iterator_t::is_end
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:11211
nlohmann::detail::serializer::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:15985
nlohmann::basic_json::set_parent
reference set_parent(reference j)
Definition: json.hpp:18325
nlohmann::basic_json::operator+=
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:22436
nlohmann::detail::iterator_traits
Definition: json.hpp:3241
nlohmann::detail::json_sax_dom_callback_parser::handle_value
std::pair< bool, BasicJsonType * > handle_value(Value &&v, const bool skip_callback=false)
Definition: json.hpp:6258
nlohmann::detail::from_json_tuple_impl_base
std::tuple< Args... > from_json_tuple_impl_base(BasicJsonType &&j, index_sequence< Idx... >)
Definition: json.hpp:4166
nlohmann::detail::start_object_function_t
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
Definition: json.hpp:8095
nlohmann::detail::nonesuch
Definition: json.hpp:3280
nlohmann::detail::invalid_iterator::create
static invalid_iterator create(int id_, const std::string &what_arg, const BasicJsonType &context)
Definition: json.hpp:2861
nlohmann::basic_json::operator[]
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:25104
nlohmann::detail::detector
Definition: json.hpp:3294
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:12183
nlohmann::detail::binary_reader
deserialization of CBOR, MessagePack, and UBJSON values
Definition: json.hpp:8239
nlohmann::basic_json::insert
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:22689
nlohmann::basic_json::basic_json
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:18471
nlohmann::basic_json::swap
friend void swap(reference left, reference right) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:23059
BinaryType
nlohmann::basic_json::allocator_type
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:17318
nlohmann::detail::to_json_tuple_impl
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition: json.hpp:4809
nlohmann::basic_json::is_number_integer
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:19596
nlohmann::basic_json::to_bson
static void to_bson(const basic_json &j, detail::output_adapter< char > o)
Serializes the given JSON object j to BSON and forwards the corresponding BSON-representation to the ...
Definition: json.hpp:24527
nlohmann::detail::iter_impl::value_type
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:11374
nlohmann::basic_json::binary
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array (without subtype)
Definition: json.hpp:18833
nlohmann::detail::json_sax_dom_callback_parser::parse_error
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:6224
nlohmann::detail::lexer::scan_comment
bool scan_comment()
scan a comment
Definition: json.hpp:7259
nlohmann::detail::from_json_inplace_array_impl
std::array< T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType &&j, identity_tag< std::array< T, sizeof...(Idx)>>, index_sequence< Idx... >)
Definition: json.hpp:4072
nlohmann::detail::parse_event_t::value
the parser finished reading a JSON value
nlohmann::detail::position_t::lines_read
std::size_t lines_read
the number of lines read
Definition: json.hpp:2591
nlohmann::detail::number_unsigned_function_t
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
Definition: json.hpp:8079
std::less<::nlohmann::detail::value_t >::operator()
bool operator()(nlohmann::detail::value_t lhs, nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.hpp:25894
nlohmann::detail::json_sax_dom_parser::json_sax_dom_parser
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition: json.hpp:5875
nlohmann::detail::escape
std::string escape(std::string s)
string escaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:2551
nlohmann::byte_container_with_subtype::set_subtype
void set_subtype(std::uint8_t subtype_) noexcept
sets the binary subtype
Definition: json.hpp:4992
nlohmann::detail::binary_reader::get_bson_cstr
bool get_bson_cstr(string_t &result)
Parses a C-style string from the BSON input.
Definition: json.hpp:8363
nlohmann::detail::is_sax::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:8125
nlohmann::detail::binary_writer::calc_bson_integer_size
static std::size_t calc_bson_integer_size(const std::int64_t value)
Definition: json.hpp:14215
nlohmann::basic_json::insert
void insert(const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:22882
nlohmann::detail::primitive_iterator_t::operator==
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:11216
nlohmann::detail::output_stream_adapter::stream
std::basic_ostream< CharType > & stream
Definition: json.hpp:13198
nlohmann::detail::is_constructible_string_type_impl
Definition: json.hpp:3699
nlohmann::detail::binary_reader::ia
InputAdapterType ia
input adapter
Definition: json.hpp:10628
nlohmann::detail::has_to_json
Definition: json.hpp:3531
nlohmann::detail::json_sax_dom_parser::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:5868
nlohmann::basic_json::rbegin
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:21777
nlohmann::detail::value_t::string
string value
nlohmann::basic_json::operator+=
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.hpp:22536
nlohmann::detail::binary_writer::get_msgpack_float_prefix
static constexpr CharType get_msgpack_float_prefix(float)
Definition: json.hpp:14480
nlohmann::detail::binary_reader::get_ubjson_high_precision_number
bool get_ubjson_high_precision_number()
Definition: json.hpp:10373
nlohmann::basic_json::get_impl_ptr
constexpr const number_float_t * get_impl_ptr(const number_float_t *) const noexcept
get a pointer to the value (floating-point number)
Definition: json.hpp:19895
nlohmann::detail::external_constructor< value_t::array >::construct
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: json.hpp:4616
nlohmann::detail::json_sax_dom_callback_parser::key
bool key(string_t &val)
Definition: json.hpp:6121
nlohmann::detail::output_string_adapter::str
StringType & str
Definition: json.hpp:13222
type
nlohmann::basic_json::is_number
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:19567
nlohmann::detail::is_constructible_string_type
Definition: json.hpp:3713
nlohmann::basic_json::get_impl_ptr
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
Definition: json.hpp:19817
nlohmann::detail::output_stream_adapter::write_character
void write_character(CharType c) override
Definition: json.hpp:13186
nlohmann::detail::binary_writer::write_bson_integer
void write_bson_integer(const string_t &name, const std::int64_t value)
Writes a BSON element with key name and integer value.
Definition: json.hpp:14225
nlohmann::detail::json_ref::value_type
BasicJsonType value_type
Definition: json.hpp:13039
nlohmann::detail::from_json_function
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition: json.hpp:3484
nlohmann::detail::iterator_input_adapter
Definition: json.hpp:5351
nlohmann::detail::binary_writer::to_char_type
static CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:14793
nlohmann::detail::iter_impl::operator<=
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:11777
nlohmann::detail::iter_impl::operator=
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.hpp:11475
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:4900
nlohmann::detail::binary_writer::calc_bson_element_size
static std::size_t calc_bson_element_size(const string_t &name, const BasicJsonType &j)
Calculates the size necessary to serialize the JSON value j with its name.
Definition: json.hpp:14342
nlohmann::basic_json::insert
iterator insert(const_iterator pos, basic_json &&val)
inserts element
Definition: json.hpp:22711
nlohmann::detail::is_compatible_object_type
Definition: json.hpp:3643
nlohmann::detail::is_constructible_object_type_impl< BasicJsonType, ConstructibleObjectType, enable_if_t< is_detected< mapped_type_t, ConstructibleObjectType >::value &&is_detected< key_type_t, ConstructibleObjectType >::value > >::object_t
typename BasicJsonType::object_t object_t
Definition: json.hpp:3656
nlohmann::detail::binary_writer::write_bson_boolean
void write_bson_boolean(const string_t &name, const bool value)
Writes a BSON element with key name and boolean value value.
Definition: json.hpp:14165
nlohmann::detail::iter_impl::operator--
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:11680
nlohmann::detail::is_compatible_array_type
Definition: json.hpp:3736
nlohmann::detail::error_handler_t::replace
replace invalid UTF-8 sequences with U+FFFD
nlohmann::byte_container_with_subtype::m_subtype
std::uint8_t m_subtype
Definition: json.hpp:5071
nlohmann::detail::internal_iterator
an iterator value
Definition: json.hpp:11290
nlohmann::basic_json::to_msgpack
static void to_msgpack(const basic_json &j, detail::output_adapter< uint8_t > o)
Definition: json.hpp:24330
nlohmann::detail::void_t
typename make_void< Ts... >::type void_t
Definition: json.hpp:3211
nlohmann::ordered_map::at
const T & at(const Key &key) const
Definition: json.hpp:16980
nlohmann::detail::external_constructor< value_t::array >::construct
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition: json.hpp:4631
nlohmann::basic_json::operator>=
friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:23658
nlohmann::basic_json::is_array
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:19696
nlohmann::basic_json::operator<=
friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:23577
nlohmann::detail::dtoa_impl::boundaries::plus
diyfp plus
Definition: json.hpp:15019
nlohmann::detail::iterator_input_adapter::iterator_input_adapter
iterator_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:5356
nlohmann::detail::file_input_adapter::char_type
char char_type
Definition: json.hpp:5263
nlohmann::detail::binary_writer::to_char_type
static constexpr CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:14786
nlohmann::detail::json_ref
Definition: json.hpp:3444
nlohmann::detail::dtoa_impl::find_largest_pow10
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition: json.hpp:15332
nlohmann::basic_json::update
void update(const_iterator first, const_iterator last)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:22975
nlohmann::detail::parser::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:10711
nlohmann::detail::binary_writer::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:13264
nlohmann::detail::json_sax_dom_callback_parser
Definition: json.hpp:6035
nlohmann::detail::json_sax_dom_callback_parser::json_sax_dom_callback_parser
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
Definition: json.hpp:6046
nlohmann::detail::has_non_default_from_json< BasicJsonType, T, enable_if_t< !is_basic_json< T >::value > >::serializer
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3521
nlohmann::basic_json::to_cbor
static void to_cbor(const basic_json &j, detail::output_adapter< uint8_t > o)
Definition: json.hpp:24235
nlohmann::ordered_map::ordered_map
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition: json.hpp:16939
nlohmann::detail::input_format_t
input_format_t
the supported input formats
Definition: json.hpp:5250
nlohmann::basic_json::at
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:20597
nlohmann::detail::json_sax_dom_callback_parser::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6038
nlohmann::detail::iteration_proxy::end
iteration_proxy_value< IteratorType > end() noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:4414
nlohmann::detail::is_sax_static_asserts::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:8155
nlohmann::basic_json::contains
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition: json.hpp:21589
nlohmann::basic_json::is_null
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:19515
nlohmann::detail::wide_string_input_adapter
Definition: json.hpp:5511
nlohmann::detail::external_constructor< value_t::object >::construct
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.hpp:4668
nlohmann::detail::lexer::get_number_integer
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:7827
nlohmann::basic_json::basic_json
basic_json(const JsonRef &ref)
Definition: json.hpp:19129
nlohmann::detail::binary_reader::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:8241
nlohmann::detail::binary_reader::get_msgpack_string
bool get_msgpack_string(string_t &result)
reads a MessagePack string
Definition: json.hpp:9692
nlohmann::detail::serializer::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:15988
nlohmann::detail::iterator_input_adapter_factory< IteratorType, enable_if_t< is_iterator_of_multibyte< IteratorType >::value > >::char_type
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:5582
nlohmann::detail::is_sax_static_asserts::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:8157
nlohmann::detail::iter_impl::difference_type
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:11376
nlohmann::detail::from_json_tuple_impl
std::pair< A1, A2 > from_json_tuple_impl(BasicJsonType &&j, identity_tag< std::pair< A1, A2 >>, priority_tag< 0 >)
Definition: json.hpp:4172
nlohmann::detail::primitive_iterator_t::operator--
primitive_iterator_t const operator--(int) noexcept
Definition: json.hpp:11257
nlohmann::detail::detected_or_t
typename detected_or< Default, Op, Args... >::type detected_or_t
Definition: json.hpp:3317
nlohmann::detail::iterator_input_adapter_factory< IteratorType, enable_if_t< is_iterator_of_multibyte< IteratorType >::value > >::create
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:5586
nlohmann::basic_json::unflatten
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:25282
nlohmann::detail::iterator_traits< T *, enable_if_t< std::is_object< T >::value > >::value_type
T value_type
Definition: json.hpp:3255
nlohmann::basic_json::swap
void swap(string_t &other)
exchanges the values
Definition: json.hpp:23155
nlohmann::basic_json::get_impl_ptr
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
Definition: json.hpp:19847
nlohmann::ordered_map::operator[]
T & operator[](const Key &key)
Definition: json.hpp:16957
nlohmann::detail::json_sax_dom_callback_parser::root
BasicJsonType & root
the parsed JSON value
Definition: json.hpp:6322
nlohmann::detail::parser::parser
parser(InputAdapterType &&adapter, const parser_callback_t< BasicJsonType > cb=nullptr, const bool allow_exceptions_=true, const bool skip_comments=false)
a parser reading from an input adapter
Definition: json.hpp:10719
nlohmann::detail::dtoa_impl::cached_power::k
int k
Definition: json.hpp:15158
nlohmann::detail::is_compatible_array_type_impl
Definition: json.hpp:3717
nlohmann::detail::binary_writer::write_ubjson
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true)
Definition: json.hpp:13932
nlohmann::basic_json::value
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21013
nlohmann::detail::lexer::get_position
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.hpp:7855
nlohmann::detail::input_format_t::json
nlohmann::json_pointer
JSON Pointer.
Definition: json.hpp:3380
nlohmann::basic_json::swap
void swap(object_t &other)
exchanges the values
Definition: json.hpp:23122
nlohmann::detail::conjunction
Definition: json.hpp:3549
nlohmann::detail::binary_writer::calc_bson_binary_size
static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t &value)
Definition: json.hpp:14300
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:4951
nlohmann::detail::iter_impl::operator[]
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:11896
nlohmann::ordered_map::ordered_map
ordered_map(std::initializer_list< T > init, const Allocator &alloc=Allocator())
Definition: json.hpp:16941
nlohmann::detail::is_default_constructible
Definition: json.hpp:3559
nlohmann::detail::position_t
struct to capture the start position of the current token
Definition: json.hpp:2584
nlohmann::basic_json::to_cbor
static void to_cbor(const basic_json &j, detail::output_adapter< char > o)
Definition: json.hpp:24240
nlohmann::detail::binary_reader::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:8242
nlohmann::detail::iterator_types< It, void_t< typename It::difference_type, typename It::value_type, typename It::pointer, typename It::reference, typename It::iterator_category > >::reference
typename It::reference reference
Definition: json.hpp:3234
nlohmann::basic_json::~basic_json
~basic_json() noexcept
destructor
Definition: json.hpp:19318
nlohmann::basic_json::difference_type
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:17313
nlohmann::detail::binary_reader::parse_ubjson_internal
bool parse_ubjson_internal(const bool get_char=true)
Definition: json.hpp:9944
nlohmann::detail::value_t::number_unsigned
number value (unsigned integer)
nlohmann::basic_json::operator<
friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:23531
nlohmann::basic_json::number_integer
number_integer_t number_integer
number (integer)
Definition: json.hpp:18005
nlohmann::basic_json::accept
static bool accept(InputType &&i, const bool ignore_comments=false)
check if the input is valid JSON
Definition: json.hpp:23898
nlohmann::detail::iter_impl::iter_impl
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition: json.hpp:11440
nlohmann::basic_json::operator+=
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:22487
nlohmann::json_pointer::get_checked
BasicJsonType & get_checked(BasicJsonType *ptr) const
Definition: json.hpp:12616
nlohmann::detail::other_error::create
static other_error create(int id_, const std::string &what_arg, const BasicJsonType &context)
Definition: json.hpp:3003
nlohmann::basic_json::get_ref_impl
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
Definition: json.hpp:19924
nlohmann::detail::iter_impl::array_t
typename BasicJsonType::array_t array_t
Definition: json.hpp:11359
nlohmann::detail::serializer::serializer
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition: json.hpp:15999
nlohmann::basic_json::to_bson
static void to_bson(const basic_json &j, detail::output_adapter< uint8_t > o)
Serializes the given JSON object j to BSON and forwards the corresponding BSON-representation to the ...
Definition: json.hpp:24519
nlohmann::detail::binary_writer::ubjson_prefix
CharType ubjson_prefix(const BasicJsonType &j) const noexcept
determine the type prefix of container values
Definition: json.hpp:14637
nlohmann::basic_json::get_impl_ptr
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
Definition: json.hpp:19829
nlohmann::basic_json::get_binary
const binary_t & get_binary() const
Definition: json.hpp:20401
nlohmann::detail::iter_impl::BasicJsonType
friend BasicJsonType
Definition: json.hpp:11354
nlohmann::detail::key_function_t
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
Definition: json.hpp:8099
nlohmann::detail::file_input_adapter::m_file
std::FILE * m_file
the file pointer to read from
Definition: json.hpp:5284
nlohmann::detail::detector::type
Default type
Definition: json.hpp:3297
nlohmann::detail::parser::m_lexer
lexer_t m_lexer
the lexer
Definition: json.hpp:11142
nlohmann::basic_json::items
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:22026
nlohmann::basic_json::json_value
json_value(const typename binary_t::container_type &value)
constructor for binary arrays
Definition: json.hpp:18129
nlohmann::basic_json::is_structured
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:19493
nlohmann::basic_json::at
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:20546
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:24504
nlohmann::detail::iterator_category_t
typename T::iterator_category iterator_category_t
Definition: json.hpp:3475
nlohmann::detail::primitive_iterator_t::operator-
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:11233
nlohmann::detail::is_sax_static_asserts::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:8154
nlohmann::basic_json::merge_patch
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:25816
nlohmann::basic_json::set_parents
iterator set_parents(iterator it, typename iterator::difference_type count)
Definition: json.hpp:18312
nlohmann::basic_json::get_ref
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:20316
nlohmann::detail::iterator_traits< T *, enable_if_t< std::is_object< T >::value > >::pointer
T * pointer
Definition: json.hpp:3257
nlohmann::detail::span_input_adapter::span_input_adapter
span_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:5691
nlohmann::detail::parse_event_t
parse_event_t
Definition: json.hpp:10682
nlohmann::basic_json::m_value
json_value m_value
the value of the current element
Definition: json.hpp:24119
nlohmann::basic_json::items
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:22018
nlohmann::json_pointer::back
const std::string & back() const
return last reference token
Definition: json.hpp:12357
nlohmann::basic_json::get_allocator
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:17340
nlohmann::detail::dtoa_impl::format_buffer
JSON_HEDLEY_RETURNS_NON_NULL char * format_buffer(char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
prettify v = buf * 10^decimal_exponent
Definition: json.hpp:15820
nlohmann::detail::to_json_function
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition: json.hpp:3481
nlohmann::basic_json::operator!=
friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
comparison: not equal
Definition: json.hpp:23399
nlohmann::detail::json_sax_dom_parser::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:5864
nlohmann::basic_json::json_serializer
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:17259
nlohmann::detail::index_sequence_for
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition: json.hpp:3152
nlohmann::detail::dtoa_impl::grisu2
void grisu2(char *buf, int &len, int &decimal_exponent, FloatType value)
Definition: json.hpp:15728
nlohmann::detail::iterator_input_adapter::empty
bool empty() const
Definition: json.hpp:5379
nlohmann::ordered_map
Definition: json.hpp:3393
nlohmann::basic_json::json_value
json_value(array_t &&value)
constructor for rvalue arrays
Definition: json.hpp:18123
nlohmann::detail::reference_t
typename T::reference reference_t
Definition: json.hpp:3472
nlohmann::basic_json::push_back
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:22518
nlohmann::detail::iter_impl::value
reference value() const
return the value of an iterator
Definition: json.hpp:11943
nlohmann::basic_json::at
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:25175
nlohmann::basic_json::get_impl_ptr
constexpr const binary_t * get_impl_ptr(const binary_t *) const noexcept
get a pointer to the value (binary)
Definition: json.hpp:19907
nlohmann::detail::iteration_proxy
proxy class for the items() function
Definition: json.hpp:4396
nlohmann::detail::input_format_t::ubjson
nlohmann::detail::json_reverse_iterator::operator--
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:12028
nlohmann::detail::json_sax_dom_callback_parser::null
bool null()
Definition: json.hpp:6061
nlohmann::detail::json_sax_acceptor::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6349
nlohmann::basic_json::find
const_iterator find(KeyT &&key) const
find an element in a JSON object
Definition: json.hpp:21491
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:12249
nlohmann::detail::json_sax_dom_parser::number_unsigned
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:5904
nlohmann::basic_json::operator<=
friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
comparison: less than or equal
Definition: json.hpp:23566
nlohmann::basic_json::get_binary
binary_t & get_binary()
Definition: json.hpp:20390
nlohmann::detail::json_sax_dom_parser::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:5866
nlohmann::basic_json::json_value
json_value(const object_t &value)
constructor for objects
Definition: json.hpp:18105
nlohmann::detail::serializer::indent_string
string_t indent_string
the indentation string
Definition: json.hpp:16891
nlohmann::detail::lexer::get_number_unsigned
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:7833
nlohmann::detail::is_compatible_object_type_impl
Definition: json.hpp:3624
nlohmann::detail::binary_reader::json_sax_t
SAX json_sax_t
Definition: json.hpp:8246
nlohmann::basic_json::size_type
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:17315
nlohmann::basic_json::parse
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a pair of character iterators
Definition: json.hpp:23844
nlohmann::detail::primitive_iterator_t::operator<
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:11221
nlohmann::basic_json::operator[]
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:20643
nlohmann::json_sax
SAX interface.
Definition: json.hpp:5730
nlohmann::detail::binary_writer::write_bson_binary
void write_bson_binary(const string_t &name, const binary_t &value)
Writes a BSON element with key name and binary value value.
Definition: json.hpp:14327
nlohmann::detail::json_sax_dom_parser::binary
bool binary(binary_t &val)
Definition: json.hpp:5922
nlohmann::basic_json::get_impl_ptr
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
Definition: json.hpp:19859
nlohmann::basic_json::operator<=
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:23555
nlohmann::detail::input_adapter
iterator_input_adapter_factory< IteratorType >::adapter_type input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:5594
nlohmann::detail::value_t::number_float
number value (floating-point)
nlohmann::detail::json_sax_dom_parser::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:5865
nlohmann::detail::dtoa_impl::diyfp::diyfp
constexpr diyfp(std::uint64_t f_, int e_) noexcept
Definition: json.hpp:14904
nlohmann::basic_json::operator>=
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:23647
nlohmann::detail::is_sax::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:8123
nlohmann::json_pointer::reference_tokens
std::vector< std::string > reference_tokens
the reference tokens
Definition: json.hpp:13018
nlohmann::basic_json::basic_json
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:19246
nlohmann::detail::is_compatible_string_type_impl
Definition: json.hpp:3681
nlohmann::basic_json::operator!=
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:23388
nlohmann::basic_json::is_discarded
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:19767
nlohmann::detail::input_format_t::msgpack
nlohmann::detail::lexer::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6528
nlohmann::detail::binary_writer::write_cbor
void write_cbor(const BasicJsonType &j)
Definition: json.hpp:13303
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:17532
nlohmann::detail::json_sax_acceptor::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:6348
nlohmann::detail::external_constructor< value_t::boolean >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: json.hpp:4487
nlohmann::basic_json::operator[]
reference operator[](const typename object_t::key_type &key)
access specified object element
Definition: json.hpp:20734
nlohmann::detail::position_t::chars_read_total
std::size_t chars_read_total
the total number of characters read
Definition: json.hpp:2587
nlohmann::detail::lexer::token_type
typename lexer_base< BasicJsonType >::token_type token_type
Definition: json.hpp:6536
JSON_HEDLEY_UNLIKELY
#define JSON_HEDLEY_UNLIKELY(expr)
Definition: json.hpp:1564
nlohmann::detail::utility_internal::Extend
Definition: json.hpp:3096
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:24228
nlohmann::detail::external_constructor< value_t::string >::construct
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition: json.hpp:4507
nlohmann::detail::is_compatible_integer_type_impl< RealIntegerType, CompatibleNumberIntegerType, enable_if_t< std::is_integral< RealIntegerType >::value &&std::is_integral< CompatibleNumberIntegerType >::value &&!std::is_same< bool, CompatibleNumberIntegerType >::value > >::RealLimits
std::numeric_limits< RealIntegerType > RealLimits
Definition: json.hpp:3794
nlohmann::basic_json::end
const_iterator end() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:21709
nlohmann::detail::lexer::lexer
lexer(InputAdapterType &&adapter, bool ignore_comments_=false) noexcept
Definition: json.hpp:6538
nlohmann::detail::is_iterator_traits
Definition: json.hpp:3595
nlohmann::detail::iterator_input_adapter::end
IteratorType end
Definition: json.hpp:5374
JSON_HEDLEY_DEPRECATED_FOR
#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
Definition: json.hpp:1246
nlohmann::detail::replace_substring
void replace_substring(std::string &s, const std::string &f, const std::string &t)
replace all occurrences of a substring by another string
Definition: json.hpp:2533
NLOHMANN_BASIC_JSON_TPL_DECLARATION
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition: json.hpp:2336
nlohmann::basic_json::binary
binary_t * binary
binary (stored with pointer to save storage)
Definition: json.hpp:18001
nlohmann::detail::binary_reader::parse_bson_array
bool parse_bson_array()
Reads an array from the BSON input and passes it to the SAX-parser.
Definition: json.hpp:8556
nlohmann::detail::conjunction< B1 >
Definition: json.hpp:3550
nlohmann::detail::is_constructible_tuple
Definition: json.hpp:3826
nlohmann::detail::json_ref::json_ref
json_ref(const value_type &value)
Definition: json.hpp:13045
nlohmann::detail::span_input_adapter
Definition: json.hpp:5675
nlohmann::basic_json::json_value
json_value(object_t &&value)
constructor for rvalue objects
Definition: json.hpp:18111
nlohmann::detail::binary_writer::write_bson_element
void write_bson_element(const string_t &name, const BasicJsonType &j)
Serializes the JSON value j to BSON and associates it with the key name.
Definition: json.hpp:14389
nlohmann::detail::json_sax_dom_callback_parser::boolean
bool boolean(bool val)
Definition: json.hpp:6067
nlohmann::detail::json_reverse_iterator::operator++
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:12016
nlohmann::detail::input_format_t::cbor
nlohmann::basic_json::operator>
friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
comparison: greater than
Definition: json.hpp:23612
nlohmann::detail::json_ref::operator->
value_type const * operator->() const
Definition: json.hpp:13081
nlohmann::detail::int_to_string
void int_to_string(string_type &target, std::size_t value)
Definition: json.hpp:4300
nlohmann::detail::output_string_adapter::output_string_adapter
output_string_adapter(StringType &s) noexcept
Definition: json.hpp:13206
nlohmann::detail::binary_reader::get_ubjson_size_type
bool get_ubjson_size_type(std::pair< std::size_t, char_int_type > &result)
determine the type and size for a container
Definition: json.hpp:10094
nlohmann::detail::primitive_iterator_t::operator-=
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition: json.hpp:11270
nlohmann::basic_json::to_ubjson
static void to_ubjson(const basic_json &j, detail::output_adapter< uint8_t > o, const bool use_size=false, const bool use_type=false)
Definition: json.hpp:24435
nlohmann::basic_json::rend
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:21814
nlohmann::basic_json::set_parents
void set_parents()
Definition: json.hpp:18283
nlohmann::basic_json::json_value
json_value(typename binary_t::container_type &&value)
constructor for rvalue binary arrays
Definition: json.hpp:18135
nlohmann::detail::binary_function_t
decltype(std::declval< T & >().binary(std::declval< Binary & >())) binary_function_t
Definition: json.hpp:8091
nlohmann::detail::binary_writer::get_msgpack_float_prefix
static constexpr CharType get_msgpack_float_prefix(double)
Definition: json.hpp:14485
nlohmann::detail::is_detected_exact
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Definition: json.hpp:3320
nlohmann::detail::to_chars
JSON_HEDLEY_RETURNS_NON_NULL char * to_chars(char *first, const char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
Definition: json.hpp:15905
nlohmann::byte_container_with_subtype::m_has_subtype
bool m_has_subtype
Definition: json.hpp:5072
nlohmann::byte_container_with_subtype::clear_subtype
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:5064
nlohmann::detail::json_sax_dom_parser::end_array
bool end_array()
Definition: json.hpp:5966
nlohmann::detail::json_sax_acceptor::null
bool null()
Definition: json.hpp:6351
nlohmann::detail::container_input_adapter_factory_impl::container_input_adapter_factory< ContainerType, void_t< decltype(begin(std::declval< ContainerType >()), end(std::declval< ContainerType >()))> >::create
static adapter_type create(const ContainerType &container)
Definition: json.hpp:5619
nlohmann::json_sax::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:5735
nlohmann::detail::lexer::get_string
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:7845
nlohmann::detail::iter_impl::operator+
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.hpp:11853
std::tuple_element< N, ::nlohmann::detail::iteration_proxy_value< IteratorType > >::type
decltype(get< N >(std::declval< ::nlohmann::detail::iteration_proxy_value< IteratorType > >())) type
Definition: json.hpp:4459
nlohmann::json_pointer::parent_pointer
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:12308
nlohmann::detail::value_t::discarded
discarded by the parser callback function
nlohmann::json_pointer::pop_back
void pop_back()
remove last reference token
Definition: json.hpp:12333
JSON_ASSERT
#define JSON_ASSERT(x)
Definition: json.hpp:2292
nlohmann::detail::dtoa_impl::boundaries::w
diyfp w
Definition: json.hpp:15017
NLOHMANN_JSON_VERSION_MAJOR
#define NLOHMANN_JSON_VERSION_MAJOR
Definition: json.hpp:33
nlohmann::detail::iteration_proxy_value::operator++
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition: json.hpp:4340
nlohmann::detail::json_reverse_iterator::operator-
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:12052
nlohmann::basic_json::is_string
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:19718
nlohmann::detail::binary_reader::get_ubjson_string
bool get_ubjson_string(string_t &result, const bool get_char=true)
reads a UBJSON string
Definition: json.hpp:9963
nlohmann::detail::mapped_type_t
typename T::mapped_type mapped_type_t
Definition: json.hpp:3457
nlohmann::basic_json::binary
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init, std::uint8_t subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:18823
nlohmann::detail::json_sax_acceptor::number_float
bool number_float(number_float_t, const string_t &)
Definition: json.hpp:6371
nlohmann::detail::dtoa_impl::diyfp::mul
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.hpp:14922
nlohmann::json_sax::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:5736
nlohmann::byte_container_with_subtype::has_subtype
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:5040