xrootd
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
XrdOucJson.hh
Go to the documentation of this file.
1 /*
2  __ _____ _____ _____
3  __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.10.2
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
6 
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 10
35 #define NLOHMANN_JSON_VERSION_PATCH 2
36 
37 #include <algorithm> // all_of, find, for_each
38 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
39 #include <functional> // hash, less
40 #include <initializer_list> // initializer_list
41 #ifndef JSON_NO_IO
42  #include <iosfwd> // istream, ostream
43 #endif // JSON_NO_IO
44 #include <iterator> // random_access_iterator_tag
45 #include <memory> // unique_ptr
46 #include <numeric> // accumulate
47 #include <string> // string, stoi, to_string
48 #include <utility> // declval, forward, move, pair, swap
49 #include <vector> // vector
50 
51 // #include <nlohmann/adl_serializer.hpp>
52 
53 
54 #include <type_traits>
55 #include <utility>
56 
57 // #include <nlohmann/detail/conversions/from_json.hpp>
58 
59 
60 #include <algorithm> // transform
61 #include <array> // array
62 #include <forward_list> // forward_list
63 #include <iterator> // inserter, front_inserter, end
64 #include <map> // map
65 #include <string> // string
66 #include <tuple> // tuple, make_tuple
67 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
68 #include <unordered_map> // unordered_map
69 #include <utility> // pair, declval
70 #include <valarray> // valarray
71 
72 // #include <nlohmann/detail/exceptions.hpp>
73 
74 
75 #include <exception> // exception
76 #include <stdexcept> // runtime_error
77 #include <string> // to_string
78 #include <vector> // vector
79 
80 // #include <nlohmann/detail/value_t.hpp>
81 
82 
83 #include <array> // array
84 #include <cstddef> // size_t
85 #include <cstdint> // uint8_t
86 #include <string> // string
87 
88 namespace nlohmann
89 {
90 namespace detail
91 {
93 // JSON type enumeration //
95 
120 enum class value_t : std::uint8_t
121 {
122  null,
123  object,
124  array,
125  string,
126  boolean,
129  number_float,
130  binary,
131  discarded
132 };
133 
147 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
148 {
149  static constexpr std::array<std::uint8_t, 9> order = {{
150  0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
151  1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
152  6 /* binary */
153  }
154  };
155 
156  const auto l_index = static_cast<std::size_t>(lhs);
157  const auto r_index = static_cast<std::size_t>(rhs);
158  return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
159 }
160 } // namespace detail
161 } // namespace nlohmann
162 
163 // #include <nlohmann/detail/string_escape.hpp>
164 
165 
166 #include <string>
167 // #include <nlohmann/detail/macro_scope.hpp>
168 
169 
170 #include <utility> // pair
171 // #include <nlohmann/thirdparty/hedley/hedley.hpp>
172 
173 
174 /* Hedley - https://nemequ.github.io/hedley
175  * Created by Evan Nemerson <evan@nemerson.com>
176  *
177  * To the extent possible under law, the author(s) have dedicated all
178  * copyright and related and neighboring rights to this software to
179  * the public domain worldwide. This software is distributed without
180  * any warranty.
181  *
182  * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
183  * SPDX-License-Identifier: CC0-1.0
184  */
185 
186 #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
187 #if defined(JSON_HEDLEY_VERSION)
188  #undef JSON_HEDLEY_VERSION
189 #endif
190 #define JSON_HEDLEY_VERSION 15
191 
192 #if defined(JSON_HEDLEY_STRINGIFY_EX)
193  #undef JSON_HEDLEY_STRINGIFY_EX
194 #endif
195 #define JSON_HEDLEY_STRINGIFY_EX(x) #x
196 
197 #if defined(JSON_HEDLEY_STRINGIFY)
198  #undef JSON_HEDLEY_STRINGIFY
199 #endif
200 #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
201 
202 #if defined(JSON_HEDLEY_CONCAT_EX)
203  #undef JSON_HEDLEY_CONCAT_EX
204 #endif
205 #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
206 
207 #if defined(JSON_HEDLEY_CONCAT)
208  #undef JSON_HEDLEY_CONCAT
209 #endif
210 #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
211 
212 #if defined(JSON_HEDLEY_CONCAT3_EX)
213  #undef JSON_HEDLEY_CONCAT3_EX
214 #endif
215 #define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
216 
217 #if defined(JSON_HEDLEY_CONCAT3)
218  #undef JSON_HEDLEY_CONCAT3
219 #endif
220 #define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
221 
222 #if defined(JSON_HEDLEY_VERSION_ENCODE)
223  #undef JSON_HEDLEY_VERSION_ENCODE
224 #endif
225 #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
226 
227 #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
228  #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
229 #endif
230 #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
231 
232 #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
233  #undef JSON_HEDLEY_VERSION_DECODE_MINOR
234 #endif
235 #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
236 
237 #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
238  #undef JSON_HEDLEY_VERSION_DECODE_REVISION
239 #endif
240 #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
241 
242 #if defined(JSON_HEDLEY_GNUC_VERSION)
243  #undef JSON_HEDLEY_GNUC_VERSION
244 #endif
245 #if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
246  #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
247 #elif defined(__GNUC__)
248  #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
249 #endif
250 
251 #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
252  #undef JSON_HEDLEY_GNUC_VERSION_CHECK
253 #endif
254 #if defined(JSON_HEDLEY_GNUC_VERSION)
255  #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
256 #else
257  #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
258 #endif
259 
260 #if defined(JSON_HEDLEY_MSVC_VERSION)
261  #undef JSON_HEDLEY_MSVC_VERSION
262 #endif
263 #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
264  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
265 #elif defined(_MSC_FULL_VER) && !defined(__ICL)
266  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
267 #elif defined(_MSC_VER) && !defined(__ICL)
268  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
269 #endif
270 
271 #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
272  #undef JSON_HEDLEY_MSVC_VERSION_CHECK
273 #endif
274 #if !defined(JSON_HEDLEY_MSVC_VERSION)
275  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
276 #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
277  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
278 #elif defined(_MSC_VER) && (_MSC_VER >= 1200)
279  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
280 #else
281  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
282 #endif
283 
284 #if defined(JSON_HEDLEY_INTEL_VERSION)
285  #undef JSON_HEDLEY_INTEL_VERSION
286 #endif
287 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
288  #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
289 #elif defined(__INTEL_COMPILER) && !defined(__ICL)
290  #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
291 #endif
292 
293 #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
294  #undef JSON_HEDLEY_INTEL_VERSION_CHECK
295 #endif
296 #if defined(JSON_HEDLEY_INTEL_VERSION)
297  #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
298 #else
299  #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
300 #endif
301 
302 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
303  #undef JSON_HEDLEY_INTEL_CL_VERSION
304 #endif
305 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
306  #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
307 #endif
308 
309 #if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
310  #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
311 #endif
312 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
313  #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
314 #else
315  #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
316 #endif
317 
318 #if defined(JSON_HEDLEY_PGI_VERSION)
319  #undef JSON_HEDLEY_PGI_VERSION
320 #endif
321 #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
322  #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
323 #endif
324 
325 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
326  #undef JSON_HEDLEY_PGI_VERSION_CHECK
327 #endif
328 #if defined(JSON_HEDLEY_PGI_VERSION)
329  #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
330 #else
331  #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
332 #endif
333 
334 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
335  #undef JSON_HEDLEY_SUNPRO_VERSION
336 #endif
337 #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
338  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)
339 #elif defined(__SUNPRO_C)
340  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
341 #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
342  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)
343 #elif defined(__SUNPRO_CC)
344  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
345 #endif
346 
347 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
348  #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
349 #endif
350 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
351  #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
352 #else
353  #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
354 #endif
355 
356 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
357  #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
358 #endif
359 #if defined(__EMSCRIPTEN__)
360  #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
361 #endif
362 
363 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
364  #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
365 #endif
366 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
367  #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
368 #else
369  #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
370 #endif
371 
372 #if defined(JSON_HEDLEY_ARM_VERSION)
373  #undef JSON_HEDLEY_ARM_VERSION
374 #endif
375 #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
376  #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
377 #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
378  #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
379 #endif
380 
381 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
382  #undef JSON_HEDLEY_ARM_VERSION_CHECK
383 #endif
384 #if defined(JSON_HEDLEY_ARM_VERSION)
385  #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
386 #else
387  #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
388 #endif
389 
390 #if defined(JSON_HEDLEY_IBM_VERSION)
391  #undef JSON_HEDLEY_IBM_VERSION
392 #endif
393 #if defined(__ibmxl__)
394  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
395 #elif defined(__xlC__) && defined(__xlC_ver__)
396  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
397 #elif defined(__xlC__)
398  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
399 #endif
400 
401 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
402  #undef JSON_HEDLEY_IBM_VERSION_CHECK
403 #endif
404 #if defined(JSON_HEDLEY_IBM_VERSION)
405  #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
406 #else
407  #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
408 #endif
409 
410 #if defined(JSON_HEDLEY_TI_VERSION)
411  #undef JSON_HEDLEY_TI_VERSION
412 #endif
413 #if \
414  defined(__TI_COMPILER_VERSION__) && \
415  ( \
416  defined(__TMS470__) || defined(__TI_ARM__) || \
417  defined(__MSP430__) || \
418  defined(__TMS320C2000__) \
419  )
420 #if (__TI_COMPILER_VERSION__ >= 16000000)
421  #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
422 #endif
423 #endif
424 
425 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
426  #undef JSON_HEDLEY_TI_VERSION_CHECK
427 #endif
428 #if defined(JSON_HEDLEY_TI_VERSION)
429  #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
430 #else
431  #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
432 #endif
433 
434 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
435  #undef JSON_HEDLEY_TI_CL2000_VERSION
436 #endif
437 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
438  #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
439 #endif
440 
441 #if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
442  #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
443 #endif
444 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
445  #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
446 #else
447  #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
448 #endif
449 
450 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
451  #undef JSON_HEDLEY_TI_CL430_VERSION
452 #endif
453 #if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
454  #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
455 #endif
456 
457 #if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
458  #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
459 #endif
460 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
461  #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
462 #else
463  #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
464 #endif
465 
466 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
467  #undef JSON_HEDLEY_TI_ARMCL_VERSION
468 #endif
469 #if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
470  #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
471 #endif
472 
473 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
474  #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
475 #endif
476 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
477  #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
478 #else
479  #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
480 #endif
481 
482 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
483  #undef JSON_HEDLEY_TI_CL6X_VERSION
484 #endif
485 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
486  #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
487 #endif
488 
489 #if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
490  #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
491 #endif
492 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
493  #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
494 #else
495  #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
496 #endif
497 
498 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
499  #undef JSON_HEDLEY_TI_CL7X_VERSION
500 #endif
501 #if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
502  #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
503 #endif
504 
505 #if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
506  #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
507 #endif
508 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
509  #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
510 #else
511  #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
512 #endif
513 
514 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
515  #undef JSON_HEDLEY_TI_CLPRU_VERSION
516 #endif
517 #if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
518  #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
519 #endif
520 
521 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
522  #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
523 #endif
524 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
525  #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
526 #else
527  #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
528 #endif
529 
530 #if defined(JSON_HEDLEY_CRAY_VERSION)
531  #undef JSON_HEDLEY_CRAY_VERSION
532 #endif
533 #if defined(_CRAYC)
534  #if defined(_RELEASE_PATCHLEVEL)
535  #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
536  #else
537  #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
538  #endif
539 #endif
540 
541 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
542  #undef JSON_HEDLEY_CRAY_VERSION_CHECK
543 #endif
544 #if defined(JSON_HEDLEY_CRAY_VERSION)
545  #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
546 #else
547  #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
548 #endif
549 
550 #if defined(JSON_HEDLEY_IAR_VERSION)
551  #undef JSON_HEDLEY_IAR_VERSION
552 #endif
553 #if defined(__IAR_SYSTEMS_ICC__)
554  #if __VER__ > 1000
555  #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
556  #else
557  #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
558  #endif
559 #endif
560 
561 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
562  #undef JSON_HEDLEY_IAR_VERSION_CHECK
563 #endif
564 #if defined(JSON_HEDLEY_IAR_VERSION)
565  #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
566 #else
567  #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
568 #endif
569 
570 #if defined(JSON_HEDLEY_TINYC_VERSION)
571  #undef JSON_HEDLEY_TINYC_VERSION
572 #endif
573 #if defined(__TINYC__)
574  #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
575 #endif
576 
577 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
578  #undef JSON_HEDLEY_TINYC_VERSION_CHECK
579 #endif
580 #if defined(JSON_HEDLEY_TINYC_VERSION)
581  #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
582 #else
583  #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
584 #endif
585 
586 #if defined(JSON_HEDLEY_DMC_VERSION)
587  #undef JSON_HEDLEY_DMC_VERSION
588 #endif
589 #if defined(__DMC__)
590  #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
591 #endif
592 
593 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
594  #undef JSON_HEDLEY_DMC_VERSION_CHECK
595 #endif
596 #if defined(JSON_HEDLEY_DMC_VERSION)
597  #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
598 #else
599  #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
600 #endif
601 
602 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
603  #undef JSON_HEDLEY_COMPCERT_VERSION
604 #endif
605 #if defined(__COMPCERT_VERSION__)
606  #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
607 #endif
608 
609 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
610  #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
611 #endif
612 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
613  #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
614 #else
615  #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
616 #endif
617 
618 #if defined(JSON_HEDLEY_PELLES_VERSION)
619  #undef JSON_HEDLEY_PELLES_VERSION
620 #endif
621 #if defined(__POCC__)
622  #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
623 #endif
624 
625 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
626  #undef JSON_HEDLEY_PELLES_VERSION_CHECK
627 #endif
628 #if defined(JSON_HEDLEY_PELLES_VERSION)
629  #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
630 #else
631  #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
632 #endif
633 
634 #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
635  #undef JSON_HEDLEY_MCST_LCC_VERSION
636 #endif
637 #if defined(__LCC__) && defined(__LCC_MINOR__)
638  #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
639 #endif
640 
641 #if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
642  #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
643 #endif
644 #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
645  #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
646 #else
647  #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
648 #endif
649 
650 #if defined(JSON_HEDLEY_GCC_VERSION)
651  #undef JSON_HEDLEY_GCC_VERSION
652 #endif
653 #if \
654  defined(JSON_HEDLEY_GNUC_VERSION) && \
655  !defined(__clang__) && \
656  !defined(JSON_HEDLEY_INTEL_VERSION) && \
657  !defined(JSON_HEDLEY_PGI_VERSION) && \
658  !defined(JSON_HEDLEY_ARM_VERSION) && \
659  !defined(JSON_HEDLEY_CRAY_VERSION) && \
660  !defined(JSON_HEDLEY_TI_VERSION) && \
661  !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
662  !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
663  !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
664  !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
665  !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
666  !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
667  !defined(__COMPCERT__) && \
668  !defined(JSON_HEDLEY_MCST_LCC_VERSION)
669  #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
670 #endif
671 
672 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
673  #undef JSON_HEDLEY_GCC_VERSION_CHECK
674 #endif
675 #if defined(JSON_HEDLEY_GCC_VERSION)
676  #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
677 #else
678  #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
679 #endif
680 
681 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
682  #undef JSON_HEDLEY_HAS_ATTRIBUTE
683 #endif
684 #if \
685  defined(__has_attribute) && \
686  ( \
687  (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
688  )
689 # define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
690 #else
691 # define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
692 #endif
693 
694 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
695  #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
696 #endif
697 #if defined(__has_attribute)
698  #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
699 #else
700  #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
701 #endif
702 
703 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
704  #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
705 #endif
706 #if defined(__has_attribute)
707  #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
708 #else
709  #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
710 #endif
711 
712 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
713  #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
714 #endif
715 #if \
716  defined(__has_cpp_attribute) && \
717  defined(__cplusplus) && \
718  (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
719  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
720 #else
721  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
722 #endif
723 
724 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
725  #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
726 #endif
727 #if !defined(__cplusplus) || !defined(__has_cpp_attribute)
728  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
729 #elif \
730  !defined(JSON_HEDLEY_PGI_VERSION) && \
731  !defined(JSON_HEDLEY_IAR_VERSION) && \
732  (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
733  (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
734  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
735 #else
736  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
737 #endif
738 
739 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
740  #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
741 #endif
742 #if defined(__has_cpp_attribute) && defined(__cplusplus)
743  #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
744 #else
745  #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
746 #endif
747 
748 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
749  #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
750 #endif
751 #if defined(__has_cpp_attribute) && defined(__cplusplus)
752  #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
753 #else
754  #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
755 #endif
756 
757 #if defined(JSON_HEDLEY_HAS_BUILTIN)
758  #undef JSON_HEDLEY_HAS_BUILTIN
759 #endif
760 #if defined(__has_builtin)
761  #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
762 #else
763  #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
764 #endif
765 
766 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
767  #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
768 #endif
769 #if defined(__has_builtin)
770  #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
771 #else
772  #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
773 #endif
774 
775 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
776  #undef JSON_HEDLEY_GCC_HAS_BUILTIN
777 #endif
778 #if defined(__has_builtin)
779  #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
780 #else
781  #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
782 #endif
783 
784 #if defined(JSON_HEDLEY_HAS_FEATURE)
785  #undef JSON_HEDLEY_HAS_FEATURE
786 #endif
787 #if defined(__has_feature)
788  #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
789 #else
790  #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
791 #endif
792 
793 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
794  #undef JSON_HEDLEY_GNUC_HAS_FEATURE
795 #endif
796 #if defined(__has_feature)
797  #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
798 #else
799  #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
800 #endif
801 
802 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
803  #undef JSON_HEDLEY_GCC_HAS_FEATURE
804 #endif
805 #if defined(__has_feature)
806  #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
807 #else
808  #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
809 #endif
810 
811 #if defined(JSON_HEDLEY_HAS_EXTENSION)
812  #undef JSON_HEDLEY_HAS_EXTENSION
813 #endif
814 #if defined(__has_extension)
815  #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
816 #else
817  #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
818 #endif
819 
820 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
821  #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
822 #endif
823 #if defined(__has_extension)
824  #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
825 #else
826  #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
827 #endif
828 
829 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
830  #undef JSON_HEDLEY_GCC_HAS_EXTENSION
831 #endif
832 #if defined(__has_extension)
833  #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
834 #else
835  #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
836 #endif
837 
838 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
839  #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
840 #endif
841 #if defined(__has_declspec_attribute)
842  #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
843 #else
844  #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
845 #endif
846 
847 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
848  #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
849 #endif
850 #if defined(__has_declspec_attribute)
851  #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
852 #else
853  #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
854 #endif
855 
856 #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
857  #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
858 #endif
859 #if defined(__has_declspec_attribute)
860  #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
861 #else
862  #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
863 #endif
864 
865 #if defined(JSON_HEDLEY_HAS_WARNING)
866  #undef JSON_HEDLEY_HAS_WARNING
867 #endif
868 #if defined(__has_warning)
869  #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
870 #else
871  #define JSON_HEDLEY_HAS_WARNING(warning) (0)
872 #endif
873 
874 #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
875  #undef JSON_HEDLEY_GNUC_HAS_WARNING
876 #endif
877 #if defined(__has_warning)
878  #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
879 #else
880  #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
881 #endif
882 
883 #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
884  #undef JSON_HEDLEY_GCC_HAS_WARNING
885 #endif
886 #if defined(__has_warning)
887  #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
888 #else
889  #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
890 #endif
891 
892 #if \
893  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
894  defined(__clang__) || \
895  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
896  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
897  JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
898  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
899  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
900  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
901  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
902  JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
903  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
904  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
905  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
906  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
907  JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
908  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
909  JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
910  (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
911  #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
912 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
913  #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
914 #else
915  #define JSON_HEDLEY_PRAGMA(value)
916 #endif
917 
918 #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
919  #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
920 #endif
921 #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
922  #undef JSON_HEDLEY_DIAGNOSTIC_POP
923 #endif
924 #if defined(__clang__)
925  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
926  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
927 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
928  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
929  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
930 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
931  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
932  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
933 #elif \
934  JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
935  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
936  #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
937  #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
938 #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
939  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
940  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
941 #elif \
942  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
943  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
944  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
945  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
946  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
947  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
948  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
949  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
950 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
951  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
952  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
953 #else
954  #define JSON_HEDLEY_DIAGNOSTIC_PUSH
955  #define JSON_HEDLEY_DIAGNOSTIC_POP
956 #endif
957 
958 /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
959  HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
960 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
961  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
962 #endif
963 #if defined(__cplusplus)
964 # if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
965 # if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
966 # if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
967 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
968  JSON_HEDLEY_DIAGNOSTIC_PUSH \
969  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
970  _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
971  _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
972  xpr \
973  JSON_HEDLEY_DIAGNOSTIC_POP
974 # else
975 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
976  JSON_HEDLEY_DIAGNOSTIC_PUSH \
977  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
978  _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
979  xpr \
980  JSON_HEDLEY_DIAGNOSTIC_POP
981 # endif
982 # else
983 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
984  JSON_HEDLEY_DIAGNOSTIC_PUSH \
985  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
986  xpr \
987  JSON_HEDLEY_DIAGNOSTIC_POP
988 # endif
989 # endif
990 #endif
991 #if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
992  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
993 #endif
994 
995 #if defined(JSON_HEDLEY_CONST_CAST)
996  #undef JSON_HEDLEY_CONST_CAST
997 #endif
998 #if defined(__cplusplus)
999 # define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1000 #elif \
1001  JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1002  JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1003  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1004 # define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1005  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1006  JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1007  ((T) (expr)); \
1008  JSON_HEDLEY_DIAGNOSTIC_POP \
1009  }))
1010 #else
1011 # define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1012 #endif
1013 
1014 #if defined(JSON_HEDLEY_REINTERPRET_CAST)
1015  #undef JSON_HEDLEY_REINTERPRET_CAST
1016 #endif
1017 #if defined(__cplusplus)
1018  #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1019 #else
1020  #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1021 #endif
1022 
1023 #if defined(JSON_HEDLEY_STATIC_CAST)
1024  #undef JSON_HEDLEY_STATIC_CAST
1025 #endif
1026 #if defined(__cplusplus)
1027  #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1028 #else
1029  #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1030 #endif
1031 
1032 #if defined(JSON_HEDLEY_CPP_CAST)
1033  #undef JSON_HEDLEY_CPP_CAST
1034 #endif
1035 #if defined(__cplusplus)
1036 # if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
1037 # define JSON_HEDLEY_CPP_CAST(T, expr) \
1038  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1039  _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
1040  ((T) (expr)) \
1041  JSON_HEDLEY_DIAGNOSTIC_POP
1042 # elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
1043 # define JSON_HEDLEY_CPP_CAST(T, expr) \
1044  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1045  _Pragma("diag_suppress=Pe137") \
1046  JSON_HEDLEY_DIAGNOSTIC_POP
1047 # else
1048 # define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1049 # endif
1050 #else
1051 # define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1052 #endif
1053 
1054 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1055  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1056 #endif
1057 #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
1058  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
1059 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1060  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1061 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1062  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1063 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1064  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1065 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1066  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1067 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1068  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1069 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1070  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1071 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1072  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1073 #elif \
1074  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1075  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1076  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1077  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1078  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1079  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1080  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1081  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1082  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1083  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1084  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1085  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1086 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1087  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1088 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1089  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1090 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1091  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1092 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1093  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1094 #else
1095  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1096 #endif
1097 
1098 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1099  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1100 #endif
1101 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1102  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1103 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1104  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1105 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1106  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1107 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1108  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1109 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1110  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1111 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1112  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1113 #elif \
1114  JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1115  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1116  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1117  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1118  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1119 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1120  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1121 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1122  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1123 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1124  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1125 #else
1126  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1127 #endif
1128 
1129 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1130  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1131 #endif
1132 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1133  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1134 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1135  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1136 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1137  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1138 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1139  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1140 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1141  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1142 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1143  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1144 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1145  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1146 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1147  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1148 #elif \
1149  JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1150  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1151  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1152  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1153 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1154  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1155 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1156  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1157 #else
1158  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1159 #endif
1160 
1161 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1162  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1163 #endif
1164 #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1165  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1166 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1167  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1168 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1169  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1170 #else
1171  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1172 #endif
1173 
1174 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1175  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1176 #endif
1177 #if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1178  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1179 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1180  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1181 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1182  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1183 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1184  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1185 #else
1186  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1187 #endif
1188 
1189 #if defined(JSON_HEDLEY_DEPRECATED)
1190  #undef JSON_HEDLEY_DEPRECATED
1191 #endif
1192 #if defined(JSON_HEDLEY_DEPRECATED_FOR)
1193  #undef JSON_HEDLEY_DEPRECATED_FOR
1194 #endif
1195 #if \
1196  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1197  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1198  #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1199  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1200 #elif \
1201  (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1202  JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1203  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1204  JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1205  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1206  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1207  JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1208  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1209  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1210  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1211  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1212  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1213  #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1214  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1215 #elif defined(__cplusplus) && (__cplusplus >= 201402L)
1216  #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1217  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1218 #elif \
1219  JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1220  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1221  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1222  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1223  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1224  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1225  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1226  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1227  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1228  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1229  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1230  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1231  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1232  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1233  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1234  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1235  #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1236  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1237 #elif \
1238  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1239  JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1240  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1241  #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1242  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1243 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1244  #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1245  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1246 #else
1247  #define JSON_HEDLEY_DEPRECATED(since)
1248  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1249 #endif
1250 
1251 #if defined(JSON_HEDLEY_UNAVAILABLE)
1252  #undef JSON_HEDLEY_UNAVAILABLE
1253 #endif
1254 #if \
1255  JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1256  JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1257  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1258  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1259  #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1260 #else
1261  #define JSON_HEDLEY_UNAVAILABLE(available_since)
1262 #endif
1263 
1264 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1265  #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1266 #endif
1267 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1268  #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1269 #endif
1270 #if \
1271  JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1272  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1273  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1274  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1275  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1276  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1277  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1278  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1279  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1280  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1281  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1282  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1283  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1284  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1285  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1286  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1287  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1288  #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1289  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1290 #elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1291  #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1292  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1293 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1294  #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1295  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1296 #elif defined(_Check_return_) /* SAL */
1297  #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1298  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1299 #else
1300  #define JSON_HEDLEY_WARN_UNUSED_RESULT
1301  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1302 #endif
1303 
1304 #if defined(JSON_HEDLEY_SENTINEL)
1305  #undef JSON_HEDLEY_SENTINEL
1306 #endif
1307 #if \
1308  JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1309  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1310  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1311  JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1312  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1313  #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1314 #else
1315  #define JSON_HEDLEY_SENTINEL(position)
1316 #endif
1317 
1318 #if defined(JSON_HEDLEY_NO_RETURN)
1319  #undef JSON_HEDLEY_NO_RETURN
1320 #endif
1321 #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1322  #define JSON_HEDLEY_NO_RETURN __noreturn
1323 #elif \
1324  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1325  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1326  #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1327 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1328  #define JSON_HEDLEY_NO_RETURN _Noreturn
1329 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
1330  #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1331 #elif \
1332  JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1333  JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1334  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1335  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1336  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1337  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1338  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1339  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1340  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1341  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1342  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1343  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1344  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1345  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1346  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1347  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1348  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1349  #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1350 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1351  #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1352 #elif \
1353  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1354  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1355  #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1356 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1357  #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1358 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1359  #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1360 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1361  #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1362 #else
1363  #define JSON_HEDLEY_NO_RETURN
1364 #endif
1365 
1366 #if defined(JSON_HEDLEY_NO_ESCAPE)
1367  #undef JSON_HEDLEY_NO_ESCAPE
1368 #endif
1369 #if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1370  #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1371 #else
1372  #define JSON_HEDLEY_NO_ESCAPE
1373 #endif
1374 
1375 #if defined(JSON_HEDLEY_UNREACHABLE)
1376  #undef JSON_HEDLEY_UNREACHABLE
1377 #endif
1378 #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1379  #undef JSON_HEDLEY_UNREACHABLE_RETURN
1380 #endif
1381 #if defined(JSON_HEDLEY_ASSUME)
1382  #undef JSON_HEDLEY_ASSUME
1383 #endif
1384 #if \
1385  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1386  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1387  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1388  #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1389 #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1390  #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1391 #elif \
1392  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1393  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1394  #if defined(__cplusplus)
1395  #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1396  #else
1397  #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1398  #endif
1399 #endif
1400 #if \
1401  (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1402  JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1403  JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1404  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1405  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1406  JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1407  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1408  #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1409 #elif defined(JSON_HEDLEY_ASSUME)
1410  #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1411 #endif
1412 #if !defined(JSON_HEDLEY_ASSUME)
1413  #if defined(JSON_HEDLEY_UNREACHABLE)
1414  #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1415  #else
1416  #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1417  #endif
1418 #endif
1419 #if defined(JSON_HEDLEY_UNREACHABLE)
1420  #if \
1421  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1422  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1423  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1424  #else
1425  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1426  #endif
1427 #else
1428  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1429 #endif
1430 #if !defined(JSON_HEDLEY_UNREACHABLE)
1431  #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1432 #endif
1433 
1435 #if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1436  #pragma clang diagnostic ignored "-Wpedantic"
1437 #endif
1438 #if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1439  #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1440 #endif
1441 #if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1442  #if defined(__clang__)
1443  #pragma clang diagnostic ignored "-Wvariadic-macros"
1444  #elif defined(JSON_HEDLEY_GCC_VERSION)
1445  #pragma GCC diagnostic ignored "-Wvariadic-macros"
1446  #endif
1447 #endif
1448 #if defined(JSON_HEDLEY_NON_NULL)
1449  #undef JSON_HEDLEY_NON_NULL
1450 #endif
1451 #if \
1452  JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1453  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1454  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1455  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1456  #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1457 #else
1458  #define JSON_HEDLEY_NON_NULL(...)
1459 #endif
1461 
1462 #if defined(JSON_HEDLEY_PRINTF_FORMAT)
1463  #undef JSON_HEDLEY_PRINTF_FORMAT
1464 #endif
1465 #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1466  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1467 #elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1468  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1469 #elif \
1470  JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1471  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1472  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1473  JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1474  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1475  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1476  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1477  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1478  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1479  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1480  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1481  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1482  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1483  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1484  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1485  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1486  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1487  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1488 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1489  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1490 #else
1491  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1492 #endif
1493 
1494 #if defined(JSON_HEDLEY_CONSTEXPR)
1495  #undef JSON_HEDLEY_CONSTEXPR
1496 #endif
1497 #if defined(__cplusplus)
1498  #if __cplusplus >= 201103L
1499  #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1500  #endif
1501 #endif
1502 #if !defined(JSON_HEDLEY_CONSTEXPR)
1503  #define JSON_HEDLEY_CONSTEXPR
1504 #endif
1505 
1506 #if defined(JSON_HEDLEY_PREDICT)
1507  #undef JSON_HEDLEY_PREDICT
1508 #endif
1509 #if defined(JSON_HEDLEY_LIKELY)
1510  #undef JSON_HEDLEY_LIKELY
1511 #endif
1512 #if defined(JSON_HEDLEY_UNLIKELY)
1513  #undef JSON_HEDLEY_UNLIKELY
1514 #endif
1515 #if defined(JSON_HEDLEY_UNPREDICTABLE)
1516  #undef JSON_HEDLEY_UNPREDICTABLE
1517 #endif
1518 #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1519  #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1520 #endif
1521 #if \
1522  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1523  JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1524  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1525 # define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1526 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1527 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1528 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1529 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1530 #elif \
1531  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1532  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1533  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1534  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1535  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1536  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1537  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1538  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1539  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1540  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1541  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1542  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1543  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1544  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1545  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1546  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1547 # define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1548  (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1549 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1550  (__extension__ ({ \
1551  double hedley_probability_ = (probability); \
1552  ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1553  }))
1554 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1555  (__extension__ ({ \
1556  double hedley_probability_ = (probability); \
1557  ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1558  }))
1559 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1560 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1561 #else
1562 # define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1563 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1564 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1565 # define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1566 # define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1567 #endif
1568 #if !defined(JSON_HEDLEY_UNPREDICTABLE)
1569  #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1570 #endif
1571 
1572 #if defined(JSON_HEDLEY_MALLOC)
1573  #undef JSON_HEDLEY_MALLOC
1574 #endif
1575 #if \
1576  JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1577  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1578  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1579  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1580  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1581  JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1582  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1583  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1584  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1585  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1586  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1587  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1588  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1589  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1590  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1591  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1592  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1593  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1594  #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1595 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1596  #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1597 #elif \
1598  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1599  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1600  #define JSON_HEDLEY_MALLOC __declspec(restrict)
1601 #else
1602  #define JSON_HEDLEY_MALLOC
1603 #endif
1604 
1605 #if defined(JSON_HEDLEY_PURE)
1606  #undef JSON_HEDLEY_PURE
1607 #endif
1608 #if \
1609  JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1610  JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1611  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1612  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1613  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1614  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1615  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1616  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1617  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1618  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1619  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1620  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1621  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1622  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1623  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1624  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1625  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1626  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1627  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1628 # define JSON_HEDLEY_PURE __attribute__((__pure__))
1629 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1630 # define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1631 #elif defined(__cplusplus) && \
1632  ( \
1633  JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1634  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1635  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1636  )
1637 # define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1638 #else
1639 # define JSON_HEDLEY_PURE
1640 #endif
1641 
1642 #if defined(JSON_HEDLEY_CONST)
1643  #undef JSON_HEDLEY_CONST
1644 #endif
1645 #if \
1646  JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1647  JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1648  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1649  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1650  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1651  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1652  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1653  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1654  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1655  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1656  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1657  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1658  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1659  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1660  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1661  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1662  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1663  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1664  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1665  #define JSON_HEDLEY_CONST __attribute__((__const__))
1666 #elif \
1667  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1668  #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1669 #else
1670  #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1671 #endif
1672 
1673 #if defined(JSON_HEDLEY_RESTRICT)
1674  #undef JSON_HEDLEY_RESTRICT
1675 #endif
1676 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1677  #define JSON_HEDLEY_RESTRICT restrict
1678 #elif \
1679  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1680  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1681  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1682  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1683  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1684  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1685  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1686  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1687  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1688  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1689  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1690  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1691  JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1692  defined(__clang__) || \
1693  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1694  #define JSON_HEDLEY_RESTRICT __restrict
1695 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1696  #define JSON_HEDLEY_RESTRICT _Restrict
1697 #else
1698  #define JSON_HEDLEY_RESTRICT
1699 #endif
1700 
1701 #if defined(JSON_HEDLEY_INLINE)
1702  #undef JSON_HEDLEY_INLINE
1703 #endif
1704 #if \
1705  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1706  (defined(__cplusplus) && (__cplusplus >= 199711L))
1707  #define JSON_HEDLEY_INLINE inline
1708 #elif \
1709  defined(JSON_HEDLEY_GCC_VERSION) || \
1710  JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1711  #define JSON_HEDLEY_INLINE __inline__
1712 #elif \
1713  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1714  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1715  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1716  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1717  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1718  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1719  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1720  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1721  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1722  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1723  #define JSON_HEDLEY_INLINE __inline
1724 #else
1725  #define JSON_HEDLEY_INLINE
1726 #endif
1727 
1728 #if defined(JSON_HEDLEY_ALWAYS_INLINE)
1729  #undef JSON_HEDLEY_ALWAYS_INLINE
1730 #endif
1731 #if \
1732  JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1733  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1734  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1735  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1736  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1737  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1738  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1739  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1740  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1741  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1742  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1743  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1744  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1745  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1746  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1747  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1748  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1749  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1750  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1751 # define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1752 #elif \
1753  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1754  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1755 # define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1756 #elif defined(__cplusplus) && \
1757  ( \
1758  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1759  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1760  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1761  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1762  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1763  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1764  )
1765 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1766 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1767 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1768 #else
1769 # define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1770 #endif
1771 
1772 #if defined(JSON_HEDLEY_NEVER_INLINE)
1773  #undef JSON_HEDLEY_NEVER_INLINE
1774 #endif
1775 #if \
1776  JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1777  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1778  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1779  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1780  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1781  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1782  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1783  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1784  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1785  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1786  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1787  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1788  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1789  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1790  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1791  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1792  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1793  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1794  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1795  #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1796 #elif \
1797  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1798  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1799  #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1800 #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1801  #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1802 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1803  #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1804 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1805  #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1806 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1807  #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1808 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1809  #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1810 #else
1811  #define JSON_HEDLEY_NEVER_INLINE
1812 #endif
1813 
1814 #if defined(JSON_HEDLEY_PRIVATE)
1815  #undef JSON_HEDLEY_PRIVATE
1816 #endif
1817 #if defined(JSON_HEDLEY_PUBLIC)
1818  #undef JSON_HEDLEY_PUBLIC
1819 #endif
1820 #if defined(JSON_HEDLEY_IMPORT)
1821  #undef JSON_HEDLEY_IMPORT
1822 #endif
1823 #if defined(_WIN32) || defined(__CYGWIN__)
1824 # define JSON_HEDLEY_PRIVATE
1825 # define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1826 # define JSON_HEDLEY_IMPORT __declspec(dllimport)
1827 #else
1828 # if \
1829  JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1830  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1831  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1832  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1833  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1834  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1835  ( \
1836  defined(__TI_EABI__) && \
1837  ( \
1838  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1839  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1840  ) \
1841  ) || \
1842  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1843 # define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1844 # define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1845 # else
1846 # define JSON_HEDLEY_PRIVATE
1847 # define JSON_HEDLEY_PUBLIC
1848 # endif
1849 # define JSON_HEDLEY_IMPORT extern
1850 #endif
1851 
1852 #if defined(JSON_HEDLEY_NO_THROW)
1853  #undef JSON_HEDLEY_NO_THROW
1854 #endif
1855 #if \
1856  JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1857  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1858  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1859  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1860  #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1861 #elif \
1862  JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1863  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1864  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1865  #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1866 #else
1867  #define JSON_HEDLEY_NO_THROW
1868 #endif
1869 
1870 #if defined(JSON_HEDLEY_FALL_THROUGH)
1871  #undef JSON_HEDLEY_FALL_THROUGH
1872 #endif
1873 #if \
1874  JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1875  JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
1876  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1877  #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1878 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1879  #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1880 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1881  #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1882 #elif defined(__fallthrough) /* SAL */
1883  #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1884 #else
1885  #define JSON_HEDLEY_FALL_THROUGH
1886 #endif
1887 
1888 #if defined(JSON_HEDLEY_RETURNS_NON_NULL)
1889  #undef JSON_HEDLEY_RETURNS_NON_NULL
1890 #endif
1891 #if \
1892  JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1893  JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1894  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1895  #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
1896 #elif defined(_Ret_notnull_) /* SAL */
1897  #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
1898 #else
1899  #define JSON_HEDLEY_RETURNS_NON_NULL
1900 #endif
1901 
1902 #if defined(JSON_HEDLEY_ARRAY_PARAM)
1903  #undef JSON_HEDLEY_ARRAY_PARAM
1904 #endif
1905 #if \
1906  defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1907  !defined(__STDC_NO_VLA__) && \
1908  !defined(__cplusplus) && \
1909  !defined(JSON_HEDLEY_PGI_VERSION) && \
1910  !defined(JSON_HEDLEY_TINYC_VERSION)
1911  #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1912 #else
1913  #define JSON_HEDLEY_ARRAY_PARAM(name)
1914 #endif
1915 
1916 #if defined(JSON_HEDLEY_IS_CONSTANT)
1917  #undef JSON_HEDLEY_IS_CONSTANT
1918 #endif
1919 #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1920  #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1921 #endif
1922 /* JSON_HEDLEY_IS_CONSTEXPR_ is for
1923  HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1924 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1925  #undef JSON_HEDLEY_IS_CONSTEXPR_
1926 #endif
1927 #if \
1928  JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1929  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1930  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1931  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1932  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1933  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1934  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1935  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1936  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1937  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1938  #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1939 #endif
1940 #if !defined(__cplusplus)
1941 # if \
1942  JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1943  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1944  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1945  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1946  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1947  JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1948  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1949 #if defined(__INTPTR_TYPE__)
1950  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1951 #else
1952  #include <stdint.h>
1953  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1954 #endif
1955 # elif \
1956  ( \
1957  defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1958  !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1959  !defined(JSON_HEDLEY_PGI_VERSION) && \
1960  !defined(JSON_HEDLEY_IAR_VERSION)) || \
1961  (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1962  JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1963  JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1964  JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1965  JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1966 #if defined(__INTPTR_TYPE__)
1967  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1968 #else
1969  #include <stdint.h>
1970  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1971 #endif
1972 # elif \
1973  defined(JSON_HEDLEY_GCC_VERSION) || \
1974  defined(JSON_HEDLEY_INTEL_VERSION) || \
1975  defined(JSON_HEDLEY_TINYC_VERSION) || \
1976  defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1977  JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1978  defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1979  defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1980  defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1981  defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1982  defined(__clang__)
1983 # define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1984  sizeof(void) != \
1985  sizeof(*( \
1986  1 ? \
1987  ((void*) ((expr) * 0L) ) : \
1988 ((struct { char v[sizeof(void) * 2]; } *) 1) \
1989  ) \
1990  ) \
1991  )
1992 # endif
1993 #endif
1994 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1995  #if !defined(JSON_HEDLEY_IS_CONSTANT)
1996  #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1997  #endif
1998  #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
1999 #else
2000  #if !defined(JSON_HEDLEY_IS_CONSTANT)
2001  #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2002  #endif
2003  #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2004 #endif
2005 
2006 #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2007  #undef JSON_HEDLEY_BEGIN_C_DECLS
2008 #endif
2009 #if defined(JSON_HEDLEY_END_C_DECLS)
2010  #undef JSON_HEDLEY_END_C_DECLS
2011 #endif
2012 #if defined(JSON_HEDLEY_C_DECL)
2013  #undef JSON_HEDLEY_C_DECL
2014 #endif
2015 #if defined(__cplusplus)
2016  #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2017  #define JSON_HEDLEY_END_C_DECLS }
2018  #define JSON_HEDLEY_C_DECL extern "C"
2019 #else
2020  #define JSON_HEDLEY_BEGIN_C_DECLS
2021  #define JSON_HEDLEY_END_C_DECLS
2022  #define JSON_HEDLEY_C_DECL
2023 #endif
2024 
2025 #if defined(JSON_HEDLEY_STATIC_ASSERT)
2026  #undef JSON_HEDLEY_STATIC_ASSERT
2027 #endif
2028 #if \
2029  !defined(__cplusplus) && ( \
2030  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2031  (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
2032  JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2033  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2034  defined(_Static_assert) \
2035  )
2036 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2037 #elif \
2038  (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2039  JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2040  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2041 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2042 #else
2043 # define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2044 #endif
2045 
2046 #if defined(JSON_HEDLEY_NULL)
2047  #undef JSON_HEDLEY_NULL
2048 #endif
2049 #if defined(__cplusplus)
2050  #if __cplusplus >= 201103L
2051  #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2052  #elif defined(NULL)
2053  #define JSON_HEDLEY_NULL NULL
2054  #else
2055  #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2056  #endif
2057 #elif defined(NULL)
2058  #define JSON_HEDLEY_NULL NULL
2059 #else
2060  #define JSON_HEDLEY_NULL ((void*) 0)
2061 #endif
2062 
2063 #if defined(JSON_HEDLEY_MESSAGE)
2064  #undef JSON_HEDLEY_MESSAGE
2065 #endif
2066 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2067 # define JSON_HEDLEY_MESSAGE(msg) \
2068  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2069  JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2070  JSON_HEDLEY_PRAGMA(message msg) \
2071  JSON_HEDLEY_DIAGNOSTIC_POP
2072 #elif \
2073  JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2074  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2075 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2076 #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2077 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2078 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2079 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2080 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2081 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2082 #else
2083 # define JSON_HEDLEY_MESSAGE(msg)
2084 #endif
2085 
2086 #if defined(JSON_HEDLEY_WARNING)
2087  #undef JSON_HEDLEY_WARNING
2088 #endif
2089 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2090 # define JSON_HEDLEY_WARNING(msg) \
2091  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2092  JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2093  JSON_HEDLEY_PRAGMA(clang warning msg) \
2094  JSON_HEDLEY_DIAGNOSTIC_POP
2095 #elif \
2096  JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2097  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2098  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2099 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2100 #elif \
2101  JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2102  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2103 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2104 #else
2105 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2106 #endif
2107 
2108 #if defined(JSON_HEDLEY_REQUIRE)
2109  #undef JSON_HEDLEY_REQUIRE
2110 #endif
2111 #if defined(JSON_HEDLEY_REQUIRE_MSG)
2112  #undef JSON_HEDLEY_REQUIRE_MSG
2113 #endif
2114 #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2115 # if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2116 # define JSON_HEDLEY_REQUIRE(expr) \
2117  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2118  _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2119  __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2120  JSON_HEDLEY_DIAGNOSTIC_POP
2121 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2122  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2123  _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2124  __attribute__((diagnose_if(!(expr), msg, "error"))) \
2125  JSON_HEDLEY_DIAGNOSTIC_POP
2126 # else
2127 # define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2128 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2129 # endif
2130 #else
2131 # define JSON_HEDLEY_REQUIRE(expr)
2132 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2133 #endif
2134 
2135 #if defined(JSON_HEDLEY_FLAGS)
2136  #undef JSON_HEDLEY_FLAGS
2137 #endif
2138 #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2139  #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2140 #else
2141  #define JSON_HEDLEY_FLAGS
2142 #endif
2143 
2144 #if defined(JSON_HEDLEY_FLAGS_CAST)
2145  #undef JSON_HEDLEY_FLAGS_CAST
2146 #endif
2147 #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2148 # define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2149  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2150  _Pragma("warning(disable:188)") \
2151  ((T) (expr)); \
2152  JSON_HEDLEY_DIAGNOSTIC_POP \
2153  }))
2154 #else
2155 # define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2156 #endif
2157 
2158 #if defined(JSON_HEDLEY_EMPTY_BASES)
2159  #undef JSON_HEDLEY_EMPTY_BASES
2160 #endif
2161 #if \
2162  (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2163  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2164  #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2165 #else
2166  #define JSON_HEDLEY_EMPTY_BASES
2167 #endif
2168 
2169 /* Remaining macros are deprecated. */
2170 
2171 #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2172  #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2173 #endif
2174 #if defined(__clang__)
2175  #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2176 #else
2177  #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2178 #endif
2179 
2180 #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2181  #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2182 #endif
2183 #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2184 
2185 #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2186  #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2187 #endif
2188 #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2189 
2190 #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2191  #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2192 #endif
2193 #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2194 
2195 #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2196  #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2197 #endif
2198 #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2199 
2200 #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2201  #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2202 #endif
2203 #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2204 
2205 #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2206  #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2207 #endif
2208 #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2209 
2210 #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2211  #undef JSON_HEDLEY_CLANG_HAS_WARNING
2212 #endif
2213 #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2214 
2215 #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2216 
2217 
2218 // This file contains all internal macro definitions
2219 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2220 
2221 // exclude unsupported compilers
2222 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2223  #if defined(__clang__)
2224  #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2225  #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2226  #endif
2227  #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2228  #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2229  #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2230  #endif
2231  #endif
2232 #endif
2233 
2234 // C++ language standard detection
2235 // if the user manually specified the used c++ version this is skipped
2236 #if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2237  #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2238  #define JSON_HAS_CPP_20
2239  #define JSON_HAS_CPP_17
2240  #define JSON_HAS_CPP_14
2241  #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2242  #define JSON_HAS_CPP_17
2243  #define JSON_HAS_CPP_14
2244  #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2245  #define JSON_HAS_CPP_14
2246  #endif
2247  // the cpp 11 flag is always specified because it is the minimal required version
2248  #define JSON_HAS_CPP_11
2249 #endif
2250 
2251 // disable documentation warnings on clang
2252 #if defined(__clang__)
2253  #pragma clang diagnostic push
2254  #pragma clang diagnostic ignored "-Wdocumentation"
2255  #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2256 #endif
2257 
2258 // allow to disable exceptions
2259 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2260  #define JSON_THROW(exception) throw exception
2261  #define JSON_TRY try
2262  #define JSON_CATCH(exception) catch(exception)
2263  #define JSON_INTERNAL_CATCH(exception) catch(exception)
2264 #else
2265  #include <cstdlib>
2266  #define JSON_THROW(exception) std::abort()
2267  #define JSON_TRY if(true)
2268  #define JSON_CATCH(exception) if(false)
2269  #define JSON_INTERNAL_CATCH(exception) if(false)
2270 #endif
2271 
2272 // override exception macros
2273 #if defined(JSON_THROW_USER)
2274  #undef JSON_THROW
2275  #define JSON_THROW JSON_THROW_USER
2276 #endif
2277 #if defined(JSON_TRY_USER)
2278  #undef JSON_TRY
2279  #define JSON_TRY JSON_TRY_USER
2280 #endif
2281 #if defined(JSON_CATCH_USER)
2282  #undef JSON_CATCH
2283  #define JSON_CATCH JSON_CATCH_USER
2284  #undef JSON_INTERNAL_CATCH
2285  #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2286 #endif
2287 #if defined(JSON_INTERNAL_CATCH_USER)
2288  #undef JSON_INTERNAL_CATCH
2289  #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2290 #endif
2291 
2292 // allow to override assert
2293 #if !defined(JSON_ASSERT)
2294  #include <cassert> // assert
2295  #define JSON_ASSERT(x) assert(x)
2296 #endif
2297 
2298 // allow to access some private functions (needed by the test suite)
2299 #if defined(JSON_TESTS_PRIVATE)
2300  #define JSON_PRIVATE_UNLESS_TESTED public
2301 #else
2302  #define JSON_PRIVATE_UNLESS_TESTED private
2303 #endif
2304 
2310 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2311  template<typename BasicJsonType> \
2312  inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2313  { \
2314  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2315  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2316  auto it = std::find_if(std::begin(m), std::end(m), \
2317  [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2318  { \
2319  return ej_pair.first == e; \
2320  }); \
2321  j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2322  } \
2323  template<typename BasicJsonType> \
2324  inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2325  { \
2326  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2327  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2328  auto it = std::find_if(std::begin(m), std::end(m), \
2329  [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2330  { \
2331  return ej_pair.second == j; \
2332  }); \
2333  e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2334  }
2335 
2336 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2337 // may be removed in the future once the class is split.
2338 
2339 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2340  template<template<typename, typename, typename...> class ObjectType, \
2341  template<typename, typename...> class ArrayType, \
2342  class StringType, class BooleanType, class NumberIntegerType, \
2343  class NumberUnsignedType, class NumberFloatType, \
2344  template<typename> class AllocatorType, \
2345  template<typename, typename = void> class JSONSerializer, \
2346  class BinaryType>
2347 
2348 #define NLOHMANN_BASIC_JSON_TPL \
2349  basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2350  NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2351  AllocatorType, JSONSerializer, BinaryType>
2352 
2353 // Macros to simplify conversion from/to types
2354 
2355 #define NLOHMANN_JSON_EXPAND( x ) x
2356 #define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
2357 #define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2358  NLOHMANN_JSON_PASTE64, \
2359  NLOHMANN_JSON_PASTE63, \
2360  NLOHMANN_JSON_PASTE62, \
2361  NLOHMANN_JSON_PASTE61, \
2362  NLOHMANN_JSON_PASTE60, \
2363  NLOHMANN_JSON_PASTE59, \
2364  NLOHMANN_JSON_PASTE58, \
2365  NLOHMANN_JSON_PASTE57, \
2366  NLOHMANN_JSON_PASTE56, \
2367  NLOHMANN_JSON_PASTE55, \
2368  NLOHMANN_JSON_PASTE54, \
2369  NLOHMANN_JSON_PASTE53, \
2370  NLOHMANN_JSON_PASTE52, \
2371  NLOHMANN_JSON_PASTE51, \
2372  NLOHMANN_JSON_PASTE50, \
2373  NLOHMANN_JSON_PASTE49, \
2374  NLOHMANN_JSON_PASTE48, \
2375  NLOHMANN_JSON_PASTE47, \
2376  NLOHMANN_JSON_PASTE46, \
2377  NLOHMANN_JSON_PASTE45, \
2378  NLOHMANN_JSON_PASTE44, \
2379  NLOHMANN_JSON_PASTE43, \
2380  NLOHMANN_JSON_PASTE42, \
2381  NLOHMANN_JSON_PASTE41, \
2382  NLOHMANN_JSON_PASTE40, \
2383  NLOHMANN_JSON_PASTE39, \
2384  NLOHMANN_JSON_PASTE38, \
2385  NLOHMANN_JSON_PASTE37, \
2386  NLOHMANN_JSON_PASTE36, \
2387  NLOHMANN_JSON_PASTE35, \
2388  NLOHMANN_JSON_PASTE34, \
2389  NLOHMANN_JSON_PASTE33, \
2390  NLOHMANN_JSON_PASTE32, \
2391  NLOHMANN_JSON_PASTE31, \
2392  NLOHMANN_JSON_PASTE30, \
2393  NLOHMANN_JSON_PASTE29, \
2394  NLOHMANN_JSON_PASTE28, \
2395  NLOHMANN_JSON_PASTE27, \
2396  NLOHMANN_JSON_PASTE26, \
2397  NLOHMANN_JSON_PASTE25, \
2398  NLOHMANN_JSON_PASTE24, \
2399  NLOHMANN_JSON_PASTE23, \
2400  NLOHMANN_JSON_PASTE22, \
2401  NLOHMANN_JSON_PASTE21, \
2402  NLOHMANN_JSON_PASTE20, \
2403  NLOHMANN_JSON_PASTE19, \
2404  NLOHMANN_JSON_PASTE18, \
2405  NLOHMANN_JSON_PASTE17, \
2406  NLOHMANN_JSON_PASTE16, \
2407  NLOHMANN_JSON_PASTE15, \
2408  NLOHMANN_JSON_PASTE14, \
2409  NLOHMANN_JSON_PASTE13, \
2410  NLOHMANN_JSON_PASTE12, \
2411  NLOHMANN_JSON_PASTE11, \
2412  NLOHMANN_JSON_PASTE10, \
2413  NLOHMANN_JSON_PASTE9, \
2414  NLOHMANN_JSON_PASTE8, \
2415  NLOHMANN_JSON_PASTE7, \
2416  NLOHMANN_JSON_PASTE6, \
2417  NLOHMANN_JSON_PASTE5, \
2418  NLOHMANN_JSON_PASTE4, \
2419  NLOHMANN_JSON_PASTE3, \
2420  NLOHMANN_JSON_PASTE2, \
2421  NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2422 #define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2423 #define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2424 #define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2425 #define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2426 #define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2427 #define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
2428 #define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
2429 #define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
2430 #define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
2431 #define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
2432 #define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
2433 #define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
2434 #define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
2435 #define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
2436 #define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
2437 #define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
2438 #define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
2439 #define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
2440 #define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
2441 #define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
2442 #define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
2443 #define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
2444 #define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
2445 #define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
2446 #define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
2447 #define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
2448 #define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
2449 #define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
2450 #define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
2451 #define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
2452 #define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
2453 #define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
2454 #define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
2455 #define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
2456 #define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
2457 #define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
2458 #define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
2459 #define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
2460 #define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
2461 #define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
2462 #define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
2463 #define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
2464 #define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
2465 #define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
2466 #define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
2467 #define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
2468 #define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
2469 #define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
2470 #define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
2471 #define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
2472 #define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
2473 #define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
2474 #define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
2475 #define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
2476 #define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
2477 #define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
2478 #define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
2479 #define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
2480 #define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
2481 #define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
2482 #define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
2483 #define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
2484 #define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
2485 
2486 #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2487 #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2488 
2494 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2495  friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2496  friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2497 
2503 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2504  inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2505  inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2506 
2507 #ifndef JSON_USE_IMPLICIT_CONVERSIONS
2508  #define JSON_USE_IMPLICIT_CONVERSIONS 1
2509 #endif
2510 
2511 #if JSON_USE_IMPLICIT_CONVERSIONS
2512  #define JSON_EXPLICIT
2513 #else
2514  #define JSON_EXPLICIT explicit
2515 #endif
2516 
2517 #ifndef JSON_DIAGNOSTICS
2518  #define JSON_DIAGNOSTICS 0
2519 #endif
2520 
2521 
2522 namespace nlohmann
2523 {
2524 namespace detail
2525 {
2526 
2540 inline void replace_substring(std::string& s, const std::string& f,
2541  const std::string& t)
2542 {
2543  JSON_ASSERT(!f.empty());
2544  for (auto pos = s.find(f); // find first occurrence of f
2545  pos != std::string::npos; // make sure f was found
2546  s.replace(pos, f.size(), t), // replace with t, and
2547  pos = s.find(f, pos + t.size())) // find next occurrence of f
2548  {}
2549 }
2550 
2559 {
2560  replace_substring(s, "~", "~0");
2561  replace_substring(s, "/", "~1");
2562  return s;
2563 }
2564 
2572 static void unescape(std::string& s)
2573 {
2574  replace_substring(s, "~1", "/");
2575  replace_substring(s, "~0", "~");
2576 }
2577 
2578 } // namespace detail
2579 } // namespace nlohmann
2580 
2581 // #include <nlohmann/detail/input/position_t.hpp>
2582 
2583 
2584 #include <cstddef> // size_t
2585 
2586 namespace nlohmann
2587 {
2588 namespace detail
2589 {
2592 {
2594  std::size_t chars_read_total = 0;
2596  std::size_t chars_read_current_line = 0;
2598  std::size_t lines_read = 0;
2599 
2601  constexpr operator size_t() const
2602  {
2603  return chars_read_total;
2604  }
2605 };
2606 
2607 } // namespace detail
2608 } // namespace nlohmann
2609 
2610 // #include <nlohmann/detail/macro_scope.hpp>
2611 
2612 
2613 namespace nlohmann
2614 {
2615 namespace detail
2616 {
2618 // exceptions //
2620 
2649 class exception : public std::exception
2650 {
2651  public:
2653  const char* what() const noexcept override
2654  {
2655  return m.what();
2656  }
2657 
2659  const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
2660 
2661  protected:
2663  exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
2664 
2665  static std::string name(const std::string& ename, int id_)
2666  {
2667  return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2668  }
2669 
2670  template<typename BasicJsonType>
2671  static std::string diagnostics(const BasicJsonType& leaf_element)
2672  {
2673 #if JSON_DIAGNOSTICS
2674  std::vector<std::string> tokens;
2675  for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent)
2676  {
2677  switch (current->m_parent->type())
2678  {
2679  case value_t::array:
2680  {
2681  for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
2682  {
2683  if (&current->m_parent->m_value.array->operator[](i) == current)
2684  {
2685  tokens.emplace_back(std::to_string(i));
2686  break;
2687  }
2688  }
2689  break;
2690  }
2691 
2692  case value_t::object:
2693  {
2694  for (const auto& element : *current->m_parent->m_value.object)
2695  {
2696  if (&element.second == current)
2697  {
2698  tokens.emplace_back(element.first.c_str());
2699  break;
2700  }
2701  }
2702  break;
2703  }
2704 
2705  case value_t::null: // LCOV_EXCL_LINE
2706  case value_t::string: // LCOV_EXCL_LINE
2707  case value_t::boolean: // LCOV_EXCL_LINE
2708  case value_t::number_integer: // LCOV_EXCL_LINE
2709  case value_t::number_unsigned: // LCOV_EXCL_LINE
2710  case value_t::number_float: // LCOV_EXCL_LINE
2711  case value_t::binary: // LCOV_EXCL_LINE
2712  case value_t::discarded: // LCOV_EXCL_LINE
2713  default: // LCOV_EXCL_LINE
2714  break; // LCOV_EXCL_LINE
2715  }
2716  }
2717 
2718  if (tokens.empty())
2719  {
2720  return "";
2721  }
2722 
2723  return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
2724  [](const std::string & a, const std::string & b)
2725  {
2726  return a + "/" + detail::escape(b);
2727  }) + ") ";
2728 #else
2729  static_cast<void>(leaf_element);
2730  return "";
2731 #endif
2732  }
2733 
2734  private:
2736  std::runtime_error m;
2737 };
2738 
2784 class parse_error : public exception
2785 {
2786  public:
2796  template<typename BasicJsonType>
2797  static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context)
2798  {
2799  std::string w = exception::name("parse_error", id_) + "parse error" +
2800  position_string(pos) + ": " + exception::diagnostics(context) + what_arg;
2801  return parse_error(id_, pos.chars_read_total, w.c_str());
2802  }
2803 
2804  template<typename BasicJsonType>
2805  static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context)
2806  {
2807  std::string w = exception::name("parse_error", id_) + "parse error" +
2808  (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2809  ": " + exception::diagnostics(context) + what_arg;
2810  return parse_error(id_, byte_, w.c_str());
2811  }
2812 
2822  const std::size_t byte;
2823 
2824  private:
2825  parse_error(int id_, std::size_t byte_, const char* what_arg)
2826  : exception(id_, what_arg), byte(byte_) {}
2827 
2829  {
2830  return " at line " + std::to_string(pos.lines_read + 1) +
2831  ", column " + std::to_string(pos.chars_read_current_line);
2832  }
2833 };
2834 
2873 {
2874  public:
2875  template<typename BasicJsonType>
2876  static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context)
2877  {
2878  std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg;
2879  return invalid_iterator(id_, w.c_str());
2880  }
2881 
2882  private:
2884  invalid_iterator(int id_, const char* what_arg)
2885  : exception(id_, what_arg) {}
2886 };
2887 
2927 class type_error : public exception
2928 {
2929  public:
2930  template<typename BasicJsonType>
2931  static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
2932  {
2933  std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg;
2934  return type_error(id_, w.c_str());
2935  }
2936 
2937  private:
2939  type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2940 };
2941 
2975 class out_of_range : public exception
2976 {
2977  public:
2978  template<typename BasicJsonType>
2979  static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context)
2980  {
2981  std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg;
2982  return out_of_range(id_, w.c_str());
2983  }
2984 
2985  private:
2987  out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
2988 };
2989 
3014 class other_error : public exception
3015 {
3016  public:
3017  template<typename BasicJsonType>
3018  static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
3019  {
3020  std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg;
3021  return other_error(id_, w.c_str());
3022  }
3023 
3024  private:
3026  other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
3027 };
3028 } // namespace detail
3029 } // namespace nlohmann
3030 
3031 // #include <nlohmann/detail/macro_scope.hpp>
3032 
3033 // #include <nlohmann/detail/meta/cpp_future.hpp>
3034 
3035 
3036 #include <cstddef> // size_t
3037 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3038 #include <utility> // index_sequence, make_index_sequence, index_sequence_for
3039 
3040 // #include <nlohmann/detail/macro_scope.hpp>
3041 
3042 
3043 namespace nlohmann
3044 {
3045 namespace detail
3046 {
3047 
3048 template<typename T>
3049 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3050 
3051 #ifdef JSON_HAS_CPP_14
3052 
3053 // the following utilities are natively available in C++14
3054 using std::enable_if_t;
3055 using std::index_sequence;
3058 
3059 #else
3060 
3061 // alias templates to reduce boilerplate
3062 template<bool B, typename T = void>
3063 using enable_if_t = typename std::enable_if<B, T>::type;
3064 
3065 // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3066 // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3067 
3069 
3070 // integer_sequence
3071 //
3072 // Class template representing a compile-time integer sequence. An instantiation
3073 // of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3074 // type through its template arguments (which is a common need when
3075 // working with C++11 variadic templates). `absl::integer_sequence` is designed
3076 // to be a drop-in replacement for C++14's `std::integer_sequence`.
3077 //
3078 // Example:
3079 //
3080 // template< class T, T... Ints >
3081 // void user_function(integer_sequence<T, Ints...>);
3082 //
3083 // int main()
3084 // {
3085 // // user_function's `T` will be deduced to `int` and `Ints...`
3086 // // will be deduced to `0, 1, 2, 3, 4`.
3087 // user_function(make_integer_sequence<int, 5>());
3088 // }
3089 template <typename T, T... Ints>
3091 {
3092  using value_type = T;
3093  static constexpr std::size_t size() noexcept
3094  {
3095  return sizeof...(Ints);
3096  }
3097 };
3098 
3099 // index_sequence
3100 //
3101 // A helper template for an `integer_sequence` of `size_t`,
3102 // `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3103 // `std::index_sequence`.
3104 template <size_t... Ints>
3105 using index_sequence = integer_sequence<size_t, Ints...>;
3106 
3107 namespace utility_internal
3108 {
3109 
3110 template <typename Seq, size_t SeqSize, size_t Rem>
3111 struct Extend;
3112 
3113 // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3114 template <typename T, T... Ints, size_t SeqSize>
3115 struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3116 {
3117  using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3118 };
3119 
3120 template <typename T, T... Ints, size_t SeqSize>
3121 struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3122 {
3123  using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3124 };
3125 
3126 // Recursion helper for 'make_integer_sequence<T, N>'.
3127 // 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3128 template <typename T, size_t N>
3129 struct Gen
3130 {
3131  using type =
3132  typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3133 };
3134 
3135 template <typename T>
3136 struct Gen<T, 0>
3137 {
3139 };
3140 
3141 } // namespace utility_internal
3142 
3143 // Compile-time sequences of integers
3144 
3145 // make_integer_sequence
3146 //
3147 // This template alias is equivalent to
3148 // `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3149 // replacement for C++14's `std::make_integer_sequence`.
3150 template <typename T, T N>
3152 
3153 // make_index_sequence
3154 //
3155 // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3156 // and is designed to be a drop-in replacement for C++14's
3157 // `std::make_index_sequence`.
3158 template <size_t N>
3160 
3161 // index_sequence_for
3162 //
3163 // Converts a typename pack into an index sequence of the same length, and
3164 // is designed to be a drop-in replacement for C++14's
3165 // `std::index_sequence_for()`
3166 template <typename... Ts>
3168 
3170 
3171 #endif
3172 
3173 // dispatch utility (taken from ranges-v3)
3174 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3175 template<> struct priority_tag<0> {};
3176 
3177 // taken from ranges-v3
3178 template<typename T>
3180 {
3181  static constexpr T value{};
3182 };
3183 
3184 template<typename T>
3185 constexpr T static_const<T>::value;
3186 
3187 } // namespace detail
3188 } // namespace nlohmann
3189 
3190 // #include <nlohmann/detail/meta/identity_tag.hpp>
3191 
3192 
3193 namespace nlohmann
3194 {
3195 namespace detail
3196 {
3197 // dispatching helper struct
3198 template <class T> struct identity_tag {};
3199 } // namespace detail
3200 } // namespace nlohmann
3201 
3202 // #include <nlohmann/detail/meta/type_traits.hpp>
3203 
3204 
3205 #include <limits> // numeric_limits
3206 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3207 #include <utility> // declval
3208 #include <tuple> // tuple
3209 
3210 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
3211 
3212 
3213 #include <iterator> // random_access_iterator_tag
3214 
3215 // #include <nlohmann/detail/meta/void_t.hpp>
3216 
3217 
3218 namespace nlohmann
3219 {
3220 namespace detail
3221 {
3222 template<typename ...Ts> struct make_void
3223 {
3224  using type = void;
3225 };
3226 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
3227 } // namespace detail
3228 } // namespace nlohmann
3229 
3230 // #include <nlohmann/detail/meta/cpp_future.hpp>
3231 
3232 
3233 namespace nlohmann
3234 {
3235 namespace detail
3236 {
3237 template<typename It, typename = void>
3238 struct iterator_types {};
3239 
3240 template<typename It>
3242  It,
3243  void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3244  typename It::reference, typename It::iterator_category >>
3245 {
3246  using difference_type = typename It::difference_type;
3247  using value_type = typename It::value_type;
3248  using pointer = typename It::pointer;
3249  using reference = typename It::reference;
3250  using iterator_category = typename It::iterator_category;
3251 };
3252 
3253 // This is required as some compilers implement std::iterator_traits in a way that
3254 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3255 template<typename T, typename = void>
3257 {
3258 };
3259 
3260 template<typename T>
3261 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3262  : iterator_types<T>
3263 {
3264 };
3265 
3266 template<typename T>
3268 {
3269  using iterator_category = std::random_access_iterator_tag;
3270  using value_type = T;
3271  using difference_type = ptrdiff_t;
3272  using pointer = T*;
3273  using reference = T&;
3274 };
3275 } // namespace detail
3276 } // namespace nlohmann
3277 
3278 // #include <nlohmann/detail/macro_scope.hpp>
3279 
3280 // #include <nlohmann/detail/meta/cpp_future.hpp>
3281 
3282 // #include <nlohmann/detail/meta/detected.hpp>
3283 
3284 
3285 #include <type_traits>
3286 
3287 // #include <nlohmann/detail/meta/void_t.hpp>
3288 
3289 
3290 // https://en.cppreference.com/w/cpp/experimental/is_detected
3291 namespace nlohmann
3292 {
3293 namespace detail
3294 {
3295 struct nonesuch
3296 {
3297  nonesuch() = delete;
3298  ~nonesuch() = delete;
3299  nonesuch(nonesuch const&) = delete;
3300  nonesuch(nonesuch const&&) = delete;
3301  void operator=(nonesuch const&) = delete;
3302  void operator=(nonesuch&&) = delete;
3303 };
3304 
3305 template<class Default,
3306  class AlwaysVoid,
3307  template<class...> class Op,
3308  class... Args>
3309 struct detector
3310 {
3311  using value_t = std::false_type;
3312  using type = Default;
3313 };
3314 
3315 template<class Default, template<class...> class Op, class... Args>
3316 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
3317 {
3318  using value_t = std::true_type;
3319  using type = Op<Args...>;
3320 };
3321 
3322 template<template<class...> class Op, class... Args>
3323 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
3324 
3325 template<template<class...> class Op, class... Args>
3326 struct is_detected_lazy : is_detected<Op, Args...> { };
3327 
3328 template<template<class...> class Op, class... Args>
3329 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
3330 
3331 template<class Default, template<class...> class Op, class... Args>
3332 using detected_or = detector<Default, void, Op, Args...>;
3333 
3334 template<class Default, template<class...> class Op, class... Args>
3335 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
3336 
3337 template<class Expected, template<class...> class Op, class... Args>
3338 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
3339 
3340 template<class To, template<class...> class Op, class... Args>
3342  std::is_convertible<detected_t<Op, Args...>, To>;
3343 } // namespace detail
3344 } // namespace nlohmann
3345 
3346 // #include <nlohmann/json_fwd.hpp>
3347 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3348 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3349 
3350 #include <cstdint> // int64_t, uint64_t
3351 #include <map> // map
3352 #include <memory> // allocator
3353 #include <string> // string
3354 #include <vector> // vector
3355 
3361 namespace nlohmann
3362 {
3370 template<typename T = void, typename SFINAE = void>
3372 
3373 template<template<typename U, typename V, typename... Args> class ObjectType =
3374  std::map,
3375  template<typename U, typename... Args> class ArrayType = std::vector,
3376  class StringType = std::string, class BooleanType = bool,
3377  class NumberIntegerType = std::int64_t,
3378  class NumberUnsignedType = std::uint64_t,
3379  class NumberFloatType = double,
3380  template<typename U> class AllocatorType = std::allocator,
3381  template<typename T, typename SFINAE = void> class JSONSerializer =
3383  class BinaryType = std::vector<std::uint8_t>>
3385 
3397 template<typename BasicJsonType>
3399 
3409 
3410 template<class Key, class T, class IgnoredLess, class Allocator>
3412 
3421 
3422 } // namespace nlohmann
3423 
3424 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3425 
3426 
3427 namespace nlohmann
3428 {
3437 namespace detail
3438 {
3440 // helpers //
3442 
3443 // Note to maintainers:
3444 //
3445 // Every trait in this file expects a non CV-qualified type.
3446 // The only exceptions are in the 'aliases for detected' section
3447 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3448 //
3449 // In this case, T has to be properly CV-qualified to constraint the function arguments
3450 // (e.g. to_json(BasicJsonType&, const T&))
3451 
3452 template<typename> struct is_basic_json : std::false_type {};
3453 
3455 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3456 
3458 // json_ref helpers //
3460 
3461 template<typename>
3462 class json_ref;
3463 
3464 template<typename>
3465 struct is_json_ref : std::false_type {};
3466 
3467 template<typename T>
3468 struct is_json_ref<json_ref<T>> : std::true_type {};
3469 
3471 // aliases for detected //
3473 
3474 template<typename T>
3475 using mapped_type_t = typename T::mapped_type;
3476 
3477 template<typename T>
3478 using key_type_t = typename T::key_type;
3479 
3480 template<typename T>
3481 using value_type_t = typename T::value_type;
3482 
3483 template<typename T>
3484 using difference_type_t = typename T::difference_type;
3485 
3486 template<typename T>
3487 using pointer_t = typename T::pointer;
3488 
3489 template<typename T>
3490 using reference_t = typename T::reference;
3491 
3492 template<typename T>
3493 using iterator_category_t = typename T::iterator_category;
3494 
3495 template<typename T>
3496 using iterator_t = typename T::iterator;
3497 
3498 template<typename T, typename... Args>
3499 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3500 
3501 template<typename T, typename... Args>
3502 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3503 
3504 template<typename T, typename U>
3505 using get_template_function = decltype(std::declval<T>().template get<U>());
3506 
3507 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3508 template<typename BasicJsonType, typename T, typename = void>
3509 struct has_from_json : std::false_type {};
3510 
3511 // trait checking if j.get<T> is valid
3512 // use this trait instead of std::is_constructible or std::is_convertible,
3513 // both rely on, or make use of implicit conversions, and thus fail when T
3514 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3515 template <typename BasicJsonType, typename T>
3517 {
3519 };
3520 
3521 template<typename BasicJsonType, typename T>
3522 struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3523 {
3524  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3525 
3526  static constexpr bool value =
3528  const BasicJsonType&, T&>::value;
3529 };
3530 
3531 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3532 // this overload is used for non-default-constructible user-defined-types
3533 template<typename BasicJsonType, typename T, typename = void>
3534 struct has_non_default_from_json : std::false_type {};
3535 
3536 template<typename BasicJsonType, typename T>
3537 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3538 {
3539  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3540 
3541  static constexpr bool value =
3543  const BasicJsonType&>::value;
3544 };
3545 
3546 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3547 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3548 template<typename BasicJsonType, typename T, typename = void>
3549 struct has_to_json : std::false_type {};
3550 
3551 template<typename BasicJsonType, typename T>
3552 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3553 {
3554  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3555 
3556  static constexpr bool value =
3558  T>::value;
3559 };
3560 
3561 
3563 // is_ functions //
3565 
3566 // https://en.cppreference.com/w/cpp/types/conjunction
3567 template<class...> struct conjunction : std::true_type { };
3568 template<class B1> struct conjunction<B1> : B1 { };
3569 template<class B1, class... Bn>
3570 struct conjunction<B1, Bn...>
3571 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3572 
3573 // https://en.cppreference.com/w/cpp/types/negation
3574 template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3575 
3576 // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3577 // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3578 // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3579 template <typename T>
3580 struct is_default_constructible : std::is_default_constructible<T> {};
3581 
3582 template <typename T1, typename T2>
3583 struct is_default_constructible<std::pair<T1, T2>>
3584  : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3585 
3586 template <typename T1, typename T2>
3587 struct is_default_constructible<const std::pair<T1, T2>>
3588  : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3589 
3590 template <typename... Ts>
3591 struct is_default_constructible<std::tuple<Ts...>>
3592  : conjunction<is_default_constructible<Ts>...> {};
3593 
3594 template <typename... Ts>
3595 struct is_default_constructible<const std::tuple<Ts...>>
3596  : conjunction<is_default_constructible<Ts>...> {};
3597 
3598 
3599 template <typename T, typename... Args>
3600 struct is_constructible : std::is_constructible<T, Args...> {};
3601 
3602 template <typename T1, typename T2>
3603 struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3604 
3605 template <typename T1, typename T2>
3606 struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3607 
3608 template <typename... Ts>
3609 struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3610 
3611 template <typename... Ts>
3612 struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3613 
3614 
3615 template<typename T, typename = void>
3616 struct is_iterator_traits : std::false_type {};
3617 
3618 template<typename T>
3620 {
3621  private:
3623 
3624  public:
3625  static constexpr auto value =
3631 };
3632 
3633 // The following implementation of is_complete_type is taken from
3634 // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3635 // and is written by Xiang Fan who agreed to using it in this library.
3636 
3637 template<typename T, typename = void>
3638 struct is_complete_type : std::false_type {};
3639 
3640 template<typename T>
3641 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3642 
3643 template<typename BasicJsonType, typename CompatibleObjectType,
3644  typename = void>
3645 struct is_compatible_object_type_impl : std::false_type {};
3646 
3647 template<typename BasicJsonType, typename CompatibleObjectType>
3649  BasicJsonType, CompatibleObjectType,
3650  enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3651  is_detected<key_type_t, CompatibleObjectType>::value >>
3652 {
3653  using object_t = typename BasicJsonType::object_t;
3654 
3655  // macOS's is_constructible does not play well with nonesuch...
3656  static constexpr bool value =
3657  is_constructible<typename object_t::key_type,
3658  typename CompatibleObjectType::key_type>::value &&
3659  is_constructible<typename object_t::mapped_type,
3660  typename CompatibleObjectType::mapped_type>::value;
3661 };
3662 
3663 template<typename BasicJsonType, typename CompatibleObjectType>
3665  : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3666 
3667 template<typename BasicJsonType, typename ConstructibleObjectType,
3668  typename = void>
3669 struct is_constructible_object_type_impl : std::false_type {};
3670 
3671 template<typename BasicJsonType, typename ConstructibleObjectType>
3673  BasicJsonType, ConstructibleObjectType,
3674  enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3675  is_detected<key_type_t, ConstructibleObjectType>::value >>
3676 {
3677  using object_t = typename BasicJsonType::object_t;
3678 
3679  static constexpr bool value =
3681  (std::is_move_assignable<ConstructibleObjectType>::value ||
3682  std::is_copy_assignable<ConstructibleObjectType>::value) &&
3683  (is_constructible<typename ConstructibleObjectType::key_type,
3684  typename object_t::key_type>::value &&
3685  std::is_same <
3686  typename object_t::mapped_type,
3687  typename ConstructibleObjectType::mapped_type >::value)) ||
3688  (has_from_json<BasicJsonType,
3689  typename ConstructibleObjectType::mapped_type>::value ||
3691  BasicJsonType,
3692  typename ConstructibleObjectType::mapped_type >::value);
3693 };
3694 
3695 template<typename BasicJsonType, typename ConstructibleObjectType>
3697  : is_constructible_object_type_impl<BasicJsonType,
3698  ConstructibleObjectType> {};
3699 
3700 template<typename BasicJsonType, typename CompatibleStringType,
3701  typename = void>
3702 struct is_compatible_string_type_impl : std::false_type {};
3703 
3704 template<typename BasicJsonType, typename CompatibleStringType>
3706  BasicJsonType, CompatibleStringType,
3707  enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3708  value_type_t, CompatibleStringType>::value >>
3709 {
3710  static constexpr auto value =
3712 };
3713 
3714 template<typename BasicJsonType, typename ConstructibleStringType>
3716  : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3717 
3718 template<typename BasicJsonType, typename ConstructibleStringType,
3719  typename = void>
3720 struct is_constructible_string_type_impl : std::false_type {};
3721 
3722 template<typename BasicJsonType, typename ConstructibleStringType>
3724  BasicJsonType, ConstructibleStringType,
3725  enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3726  value_type_t, ConstructibleStringType>::value >>
3727 {
3728  static constexpr auto value =
3729  is_constructible<ConstructibleStringType,
3730  typename BasicJsonType::string_t>::value;
3731 };
3732 
3733 template<typename BasicJsonType, typename ConstructibleStringType>
3735  : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3736 
3737 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3738 struct is_compatible_array_type_impl : std::false_type {};
3739 
3740 template<typename BasicJsonType, typename CompatibleArrayType>
3742  BasicJsonType, CompatibleArrayType,
3743  enable_if_t < is_detected<value_type_t, CompatibleArrayType>::value&&
3744  is_detected<iterator_t, CompatibleArrayType>::value&&
3745 // This is needed because json_reverse_iterator has a ::iterator type...
3746 // Therefore it is detected as a CompatibleArrayType.
3747 // The real fix would be to have an Iterable concept.
3749  iterator_traits<CompatibleArrayType >>::value >>
3750 {
3751  static constexpr bool value =
3752  is_constructible<BasicJsonType,
3753  typename CompatibleArrayType::value_type>::value;
3754 };
3755 
3756 template<typename BasicJsonType, typename CompatibleArrayType>
3758  : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3759 
3760 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3761 struct is_constructible_array_type_impl : std::false_type {};
3762 
3763 template<typename BasicJsonType, typename ConstructibleArrayType>
3765  BasicJsonType, ConstructibleArrayType,
3766  enable_if_t<std::is_same<ConstructibleArrayType,
3767  typename BasicJsonType::value_type>::value >>
3768  : std::true_type {};
3769 
3770 template<typename BasicJsonType, typename ConstructibleArrayType>
3772  BasicJsonType, ConstructibleArrayType,
3773  enable_if_t < !std::is_same<ConstructibleArrayType,
3774  typename BasicJsonType::value_type>::value&&
3775  is_default_constructible<ConstructibleArrayType>::value&&
3776 (std::is_move_assignable<ConstructibleArrayType>::value ||
3777  std::is_copy_assignable<ConstructibleArrayType>::value)&&
3778 is_detected<value_type_t, ConstructibleArrayType>::value&&
3779 is_detected<iterator_t, ConstructibleArrayType>::value&&
3781 detected_t<value_type_t, ConstructibleArrayType >>::value >>
3782 {
3783  static constexpr bool value =
3784  // This is needed because json_reverse_iterator has a ::iterator type,
3785  // furthermore, std::back_insert_iterator (and other iterators) have a
3786  // base class `iterator`... Therefore it is detected as a
3787  // ConstructibleArrayType. The real fix would be to have an Iterable
3788  // concept.
3790 
3791  (std::is_same<typename ConstructibleArrayType::value_type,
3792  typename BasicJsonType::array_t::value_type>::value ||
3793  has_from_json<BasicJsonType,
3794  typename ConstructibleArrayType::value_type>::value ||
3796  BasicJsonType, typename ConstructibleArrayType::value_type >::value);
3797 };
3798 
3799 template<typename BasicJsonType, typename ConstructibleArrayType>
3801  : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3802 
3803 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3804  typename = void>
3805 struct is_compatible_integer_type_impl : std::false_type {};
3806 
3807 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3809  RealIntegerType, CompatibleNumberIntegerType,
3810  enable_if_t < std::is_integral<RealIntegerType>::value&&
3811  std::is_integral<CompatibleNumberIntegerType>::value&&
3812  !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3813 {
3814  // is there an assert somewhere on overflows?
3815  using RealLimits = std::numeric_limits<RealIntegerType>;
3816  using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3817 
3818  static constexpr auto value =
3819  is_constructible<RealIntegerType,
3820  CompatibleNumberIntegerType>::value &&
3821  CompatibleLimits::is_integer &&
3822  RealLimits::is_signed == CompatibleLimits::is_signed;
3823 };
3824 
3825 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3827  : is_compatible_integer_type_impl<RealIntegerType,
3828  CompatibleNumberIntegerType> {};
3829 
3830 template<typename BasicJsonType, typename CompatibleType, typename = void>
3831 struct is_compatible_type_impl: std::false_type {};
3832 
3833 template<typename BasicJsonType, typename CompatibleType>
3835  BasicJsonType, CompatibleType,
3836  enable_if_t<is_complete_type<CompatibleType>::value >>
3837 {
3838  static constexpr bool value =
3840 };
3841 
3842 template<typename BasicJsonType, typename CompatibleType>
3844  : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3845 
3846 template<typename T1, typename T2>
3847 struct is_constructible_tuple : std::false_type {};
3848 
3849 template<typename T1, typename... Args>
3850 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3851 
3852 // a naive helper to check if a type is an ordered_map (exploits the fact that
3853 // ordered_map inherits capacity() from std::vector)
3854 template <typename T>
3856 {
3857  using one = char;
3858 
3859  struct two
3860  {
3861  char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3862  };
3863 
3864  template <typename C> static one test( decltype(&C::capacity) ) ;
3865  template <typename C> static two test(...);
3866 
3867  enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
3868 };
3869 
3870 // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3871 template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3873 {
3874  return static_cast<T>(value);
3875 }
3876 
3877 template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3879 {
3880  return value;
3881 }
3882 
3883 } // namespace detail
3884 } // namespace nlohmann
3885 
3886 // #include <nlohmann/detail/value_t.hpp>
3887 
3888 
3889 namespace nlohmann
3890 {
3891 namespace detail
3892 {
3893 template<typename BasicJsonType>
3894 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3895 {
3896  if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
3897  {
3898  JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()), j));
3899  }
3900  n = nullptr;
3901 }
3902 
3903 // overloads for basic_json template parameters
3904 template < typename BasicJsonType, typename ArithmeticType,
3905  enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
3906  !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3907  int > = 0 >
3908 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3909 {
3910  switch (static_cast<value_t>(j))
3911  {
3912  case value_t::number_unsigned:
3913  {
3914  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3915  break;
3916  }
3917  case value_t::number_integer:
3918  {
3919  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3920  break;
3921  }
3922  case value_t::number_float:
3923  {
3924  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3925  break;
3926  }
3927 
3928  case value_t::null:
3929  case value_t::object:
3930  case value_t::array:
3931  case value_t::string:
3932  case value_t::boolean:
3933  case value_t::binary:
3934  case value_t::discarded:
3935  default:
3936  JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
3937  }
3938 }
3939 
3940 template<typename BasicJsonType>
3941 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
3942 {
3943  if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
3944  {
3945  JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()), j));
3946  }
3947  b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
3948 }
3949 
3950 template<typename BasicJsonType>
3951 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
3952 {
3953  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3954  {
3955  JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
3956  }
3957  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3958 }
3959 
3960 template <
3961  typename BasicJsonType, typename ConstructibleStringType,
3962  enable_if_t <
3963  is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&
3964  !std::is_same<typename BasicJsonType::string_t,
3965  ConstructibleStringType>::value,
3966  int > = 0 >
3967 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
3968 {
3969  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3970  {
3971  JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
3972  }
3973 
3974  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3975 }
3976 
3977 template<typename BasicJsonType>
3978 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
3979 {
3980  get_arithmetic_value(j, val);
3981 }
3982 
3983 template<typename BasicJsonType>
3984 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
3985 {
3986  get_arithmetic_value(j, val);
3987 }
3988 
3989 template<typename BasicJsonType>
3990 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
3991 {
3992  get_arithmetic_value(j, val);
3993 }
3994 
3995 template<typename BasicJsonType, typename EnumType,
3996  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
3997 void from_json(const BasicJsonType& j, EnumType& e)
3998 {
3999  typename std::underlying_type<EnumType>::type val;
4000  get_arithmetic_value(j, val);
4001  e = static_cast<EnumType>(val);
4002 }
4003 
4004 // forward_list doesn't have an insert method
4005 template<typename BasicJsonType, typename T, typename Allocator,
4006  enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4007 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4008 {
4009  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4010  {
4011  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4012  }
4013  l.clear();
4014  std::transform(j.rbegin(), j.rend(),
4015  std::front_inserter(l), [](const BasicJsonType & i)
4016  {
4017  return i.template get<T>();
4018  });
4019 }
4020 
4021 // valarray doesn't have an insert method
4022 template<typename BasicJsonType, typename T,
4023  enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4024 void from_json(const BasicJsonType& j, std::valarray<T>& l)
4025 {
4026  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4027  {
4028  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4029  }
4030  l.resize(j.size());
4031  std::transform(j.begin(), j.end(), std::begin(l),
4032  [](const BasicJsonType & elem)
4033  {
4034  return elem.template get<T>();
4035  });
4036 }
4037 
4038 template<typename BasicJsonType, typename T, std::size_t N>
4039 auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4040 -> decltype(j.template get<T>(), void())
4041 {
4042  for (std::size_t i = 0; i < N; ++i)
4043  {
4044  arr[i] = j.at(i).template get<T>();
4045  }
4046 }
4047 
4048 template<typename BasicJsonType>
4049 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4050 {
4051  arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4052 }
4053 
4054 template<typename BasicJsonType, typename T, std::size_t N>
4055 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4056  priority_tag<2> /*unused*/)
4057 -> decltype(j.template get<T>(), void())
4058 {
4059  for (std::size_t i = 0; i < N; ++i)
4060  {
4061  arr[i] = j.at(i).template get<T>();
4062  }
4063 }
4064 
4065 template<typename BasicJsonType, typename ConstructibleArrayType,
4066  enable_if_t<
4067  std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4068  int> = 0>
4069 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4070 -> decltype(
4071  arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4072  j.template get<typename ConstructibleArrayType::value_type>(),
4073  void())
4074 {
4075  using std::end;
4076 
4077  ConstructibleArrayType ret;
4078  ret.reserve(j.size());
4079  std::transform(j.begin(), j.end(),
4080  std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4081  {
4082  // get<BasicJsonType>() returns *this, this won't call a from_json
4083  // method when value_type is BasicJsonType
4084  return i.template get<typename ConstructibleArrayType::value_type>();
4085  });
4086  arr = std::move(ret);
4087 }
4088 
4089 template<typename BasicJsonType, typename ConstructibleArrayType,
4090  enable_if_t<
4091  std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4092  int> = 0>
4093 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4094  priority_tag<0> /*unused*/)
4095 {
4096  using std::end;
4097 
4098  ConstructibleArrayType ret;
4099  std::transform(
4100  j.begin(), j.end(), std::inserter(ret, end(ret)),
4101  [](const BasicJsonType & i)
4102  {
4103  // get<BasicJsonType>() returns *this, this won't call a from_json
4104  // method when value_type is BasicJsonType
4105  return i.template get<typename ConstructibleArrayType::value_type>();
4106  });
4107  arr = std::move(ret);
4108 }
4109 
4110 template < typename BasicJsonType, typename ConstructibleArrayType,
4111  enable_if_t <
4112  is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
4113  !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
4114  !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
4115  !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
4116  !is_basic_json<ConstructibleArrayType>::value,
4117  int > = 0 >
4118 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4119 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4120 j.template get<typename ConstructibleArrayType::value_type>(),
4121 void())
4122 {
4123  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4124  {
4125  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4126  }
4127 
4129 }
4130 
4131 template < typename BasicJsonType, typename T, std::size_t... Idx >
4132 std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4133  identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4134 {
4135  return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4136 }
4137 
4138 template < typename BasicJsonType, typename T, std::size_t N >
4139 auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4140 -> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4141 {
4142  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4143  {
4144  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4145  }
4146 
4147  return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4148 }
4149 
4150 template<typename BasicJsonType>
4151 void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4152 {
4153  if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4154  {
4155  JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()), j));
4156  }
4157 
4158  bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4159 }
4160 
4161 template<typename BasicJsonType, typename ConstructibleObjectType,
4162  enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4163 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4164 {
4165  if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4166  {
4167  JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()), j));
4168  }
4169 
4170  ConstructibleObjectType ret;
4171  const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4172  using value_type = typename ConstructibleObjectType::value_type;
4173  std::transform(
4174  inner_object->begin(), inner_object->end(),
4175  std::inserter(ret, ret.begin()),
4176  [](typename BasicJsonType::object_t::value_type const & p)
4177  {
4178  return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4179  });
4180  obj = std::move(ret);
4181 }
4182 
4183 // overload for arithmetic types, not chosen for basic_json template arguments
4184 // (BooleanType, etc..); note: Is it really necessary to provide explicit
4185 // overloads for boolean_t etc. in case of a custom BooleanType which is not
4186 // an arithmetic type?
4187 template < typename BasicJsonType, typename ArithmeticType,
4188  enable_if_t <
4189  std::is_arithmetic<ArithmeticType>::value&&
4190  !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
4191  !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
4192  !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
4193  !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4194  int > = 0 >
4195 void from_json(const BasicJsonType& j, ArithmeticType& val)
4196 {
4197  switch (static_cast<value_t>(j))
4198  {
4199  case value_t::number_unsigned:
4200  {
4201  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4202  break;
4203  }
4204  case value_t::number_integer:
4205  {
4206  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4207  break;
4208  }
4209  case value_t::number_float:
4210  {
4211  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4212  break;
4213  }
4214  case value_t::boolean:
4215  {
4216  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4217  break;
4218  }
4219 
4220  case value_t::null:
4221  case value_t::object:
4222  case value_t::array:
4223  case value_t::string:
4224  case value_t::binary:
4225  case value_t::discarded:
4226  default:
4227  JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4228  }
4229 }
4230 
4231 template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4232 std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4233 {
4234  return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4235 }
4236 
4237 template < typename BasicJsonType, class A1, class A2 >
4238 std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4239 {
4240  return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4241  std::forward<BasicJsonType>(j).at(1).template get<A2>()};
4242 }
4243 
4244 template<typename BasicJsonType, typename A1, typename A2>
4245 void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4246 {
4247  p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4248 }
4249 
4250 template<typename BasicJsonType, typename... Args>
4251 std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4252 {
4253  return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4254 }
4255 
4256 template<typename BasicJsonType, typename... Args>
4257 void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4258 {
4259  t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4260 }
4261 
4262 template<typename BasicJsonType, typename TupleRelated>
4263 auto from_json(BasicJsonType&& j, TupleRelated&& t)
4264 -> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4265 {
4266  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4267  {
4268  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4269  }
4270 
4271  return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4272 }
4273 
4274 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4275  typename = enable_if_t < !std::is_constructible <
4276  typename BasicJsonType::string_t, Key >::value >>
4277 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4278 {
4279  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4280  {
4281  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4282  }
4283  m.clear();
4284  for (const auto& p : j)
4285  {
4286  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4287  {
4288  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4289  }
4290  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4291  }
4292 }
4293 
4294 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4295  typename = enable_if_t < !std::is_constructible <
4296  typename BasicJsonType::string_t, Key >::value >>
4297 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
4298 {
4299  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4300  {
4301  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4302  }
4303  m.clear();
4304  for (const auto& p : j)
4305  {
4306  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4307  {
4308  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4309  }
4310  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4311  }
4312 }
4313 
4315 {
4316  template<typename BasicJsonType, typename T>
4317  auto operator()(const BasicJsonType& j, T&& val) const
4318  noexcept(noexcept(from_json(j, std::forward<T>(val))))
4319  -> decltype(from_json(j, std::forward<T>(val)))
4320  {
4321  return from_json(j, std::forward<T>(val));
4322  }
4323 };
4324 } // namespace detail
4325 
4329 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4330 {
4331 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4332 } // namespace
4333 } // namespace nlohmann
4334 
4335 // #include <nlohmann/detail/conversions/to_json.hpp>
4336 
4337 
4338 #include <algorithm> // copy
4339 #include <iterator> // begin, end
4340 #include <string> // string
4341 #include <tuple> // tuple, get
4342 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
4343 #include <utility> // move, forward, declval, pair
4344 #include <valarray> // valarray
4345 #include <vector> // vector
4346 
4347 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4348 
4349 
4350 #include <cstddef> // size_t
4351 #include <iterator> // input_iterator_tag
4352 #include <string> // string, to_string
4353 #include <tuple> // tuple_size, get, tuple_element
4354 #include <utility> // move
4355 
4356 // #include <nlohmann/detail/meta/type_traits.hpp>
4357 
4358 // #include <nlohmann/detail/value_t.hpp>
4359 
4360 
4361 namespace nlohmann
4362 {
4363 namespace detail
4364 {
4365 template<typename string_type>
4366 void int_to_string( string_type& target, std::size_t value )
4367 {
4368  // For ADL
4369  using std::to_string;
4370  target = to_string(value);
4371 }
4372 template<typename IteratorType> class iteration_proxy_value
4373 {
4374  public:
4375  using difference_type = std::ptrdiff_t;
4377  using pointer = value_type * ;
4378  using reference = value_type & ;
4379  using iterator_category = std::input_iterator_tag;
4380  using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
4381 
4382  private:
4384  IteratorType anchor;
4386  std::size_t array_index = 0;
4388  mutable std::size_t array_index_last = 0;
4390  mutable string_type array_index_str = "0";
4392  const string_type empty_str{};
4393 
4394  public:
4395  explicit iteration_proxy_value(IteratorType it) noexcept
4396  : anchor(std::move(it))
4397  {}
4398 
4401  {
4402  return *this;
4403  }
4404 
4407  {
4408  ++anchor;
4409  ++array_index;
4410 
4411  return *this;
4412  }
4413 
4415  bool operator==(const iteration_proxy_value& o) const
4416  {
4417  return anchor == o.anchor;
4418  }
4419 
4421  bool operator!=(const iteration_proxy_value& o) const
4422  {
4423  return anchor != o.anchor;
4424  }
4425 
4427  const string_type& key() const
4428  {
4429  JSON_ASSERT(anchor.m_object != nullptr);
4430 
4431  switch (anchor.m_object->type())
4432  {
4433  // use integer array index as key
4434  case value_t::array:
4435  {
4436  if (array_index != array_index_last)
4437  {
4438  int_to_string( array_index_str, array_index );
4439  array_index_last = array_index;
4440  }
4441  return array_index_str;
4442  }
4443 
4444  // use key from the object
4445  case value_t::object:
4446  return anchor.key();
4447 
4448  // use an empty key for all primitive types
4449  case value_t::null:
4450  case value_t::string:
4451  case value_t::boolean:
4452  case value_t::number_integer:
4453  case value_t::number_unsigned:
4454  case value_t::number_float:
4455  case value_t::binary:
4456  case value_t::discarded:
4457  default:
4458  return empty_str;
4459  }
4460  }
4461 
4463  typename IteratorType::reference value() const
4464  {
4465  return anchor.value();
4466  }
4467 };
4468 
4470 template<typename IteratorType> class iteration_proxy
4471 {
4472  private:
4474  typename IteratorType::reference container;
4475 
4476  public:
4478  explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4479  : container(cont) {}
4480 
4483  {
4484  return iteration_proxy_value<IteratorType>(container.begin());
4485  }
4486 
4489  {
4490  return iteration_proxy_value<IteratorType>(container.end());
4491  }
4492 };
4493 // Structured Bindings Support
4494 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4495 // And see https://github.com/nlohmann/json/pull/1391
4496 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
4497 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
4498 {
4499  return i.key();
4500 }
4501 // Structured Bindings Support
4502 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4503 // And see https://github.com/nlohmann/json/pull/1391
4504 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
4505 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
4506 {
4507  return i.value();
4508 }
4509 } // namespace detail
4510 } // namespace nlohmann
4511 
4512 // The Addition to the STD Namespace is required to add
4513 // Structured Bindings Support to the iteration_proxy_value class
4514 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4515 // And see https://github.com/nlohmann/json/pull/1391
4516 namespace std
4517 {
4518 #if defined(__clang__)
4519  // Fix: https://github.com/nlohmann/json/issues/1401
4520  #pragma clang diagnostic push
4521  #pragma clang diagnostic ignored "-Wmismatched-tags"
4522 #endif
4523 template<typename IteratorType>
4524 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4525  : public std::integral_constant<std::size_t, 2> {};
4526 
4527 template<std::size_t N, typename IteratorType>
4528 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4529 {
4530  public:
4531  using type = decltype(
4532  get<N>(std::declval <
4534 };
4535 #if defined(__clang__)
4536  #pragma clang diagnostic pop
4537 #endif
4538 } // namespace std
4539 
4540 // #include <nlohmann/detail/meta/cpp_future.hpp>
4541 
4542 // #include <nlohmann/detail/meta/type_traits.hpp>
4543 
4544 // #include <nlohmann/detail/value_t.hpp>
4545 
4546 
4547 namespace nlohmann
4548 {
4549 namespace detail
4550 {
4552 // constructors //
4554 
4555 /*
4556  * Note all external_constructor<>::construct functions need to call
4557  * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
4558  * allocated value (e.g., a string). See bug issue
4559  * https://github.com/nlohmann/json/issues/2865 for more information.
4560  */
4561 
4562 template<value_t> struct external_constructor;
4563 
4564 template<>
4566 {
4567  template<typename BasicJsonType>
4568  static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4569  {
4570  j.m_value.destroy(j.m_type);
4571  j.m_type = value_t::boolean;
4572  j.m_value = b;
4573  j.assert_invariant();
4574  }
4575 };
4576 
4577 template<>
4579 {
4580  template<typename BasicJsonType>
4581  static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4582  {
4583  j.m_value.destroy(j.m_type);
4584  j.m_type = value_t::string;
4585  j.m_value = s;
4586  j.assert_invariant();
4587  }
4588 
4589  template<typename BasicJsonType>
4590  static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4591  {
4592  j.m_value.destroy(j.m_type);
4593  j.m_type = value_t::string;
4594  j.m_value = std::move(s);
4595  j.assert_invariant();
4596  }
4597 
4598  template < typename BasicJsonType, typename CompatibleStringType,
4600  int > = 0 >
4601  static void construct(BasicJsonType& j, const CompatibleStringType& str)
4602  {
4603  j.m_value.destroy(j.m_type);
4604  j.m_type = value_t::string;
4605  j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4606  j.assert_invariant();
4607  }
4608 };
4609 
4610 template<>
4612 {
4613  template<typename BasicJsonType>
4614  static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4615  {
4616  j.m_value.destroy(j.m_type);
4617  j.m_type = value_t::binary;
4618  j.m_value = typename BasicJsonType::binary_t(b);
4619  j.assert_invariant();
4620  }
4621 
4622  template<typename BasicJsonType>
4623  static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4624  {
4625  j.m_value.destroy(j.m_type);
4626  j.m_type = value_t::binary;
4627  j.m_value = typename BasicJsonType::binary_t(std::move(b));
4628  j.assert_invariant();
4629  }
4630 };
4631 
4632 template<>
4634 {
4635  template<typename BasicJsonType>
4636  static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4637  {
4638  j.m_value.destroy(j.m_type);
4639  j.m_type = value_t::number_float;
4640  j.m_value = val;
4641  j.assert_invariant();
4642  }
4643 };
4644 
4645 template<>
4647 {
4648  template<typename BasicJsonType>
4649  static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4650  {
4651  j.m_value.destroy(j.m_type);
4652  j.m_type = value_t::number_unsigned;
4653  j.m_value = val;
4654  j.assert_invariant();
4655  }
4656 };
4657 
4658 template<>
4660 {
4661  template<typename BasicJsonType>
4662  static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4663  {
4664  j.m_value.destroy(j.m_type);
4665  j.m_type = value_t::number_integer;
4666  j.m_value = val;
4667  j.assert_invariant();
4668  }
4669 };
4670 
4671 template<>
4673 {
4674  template<typename BasicJsonType>
4675  static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4676  {
4677  j.m_value.destroy(j.m_type);
4678  j.m_type = value_t::array;
4679  j.m_value = arr;
4680  j.set_parents();
4681  j.assert_invariant();
4682  }
4683 
4684  template<typename BasicJsonType>
4685  static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4686  {
4687  j.m_value.destroy(j.m_type);
4688  j.m_type = value_t::array;
4689  j.m_value = std::move(arr);
4690  j.set_parents();
4691  j.assert_invariant();
4692  }
4693 
4694  template < typename BasicJsonType, typename CompatibleArrayType,
4696  int > = 0 >
4697  static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4698  {
4699  using std::begin;
4700  using std::end;
4701 
4702  j.m_value.destroy(j.m_type);
4703  j.m_type = value_t::array;
4704  j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4705  j.set_parents();
4706  j.assert_invariant();
4707  }
4708 
4709  template<typename BasicJsonType>
4710  static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4711  {
4712  j.m_value.destroy(j.m_type);
4713  j.m_type = value_t::array;
4714  j.m_value = value_t::array;
4715  j.m_value.array->reserve(arr.size());
4716  for (const bool x : arr)
4717  {
4718  j.m_value.array->push_back(x);
4719  j.set_parent(j.m_value.array->back());
4720  }
4721  j.assert_invariant();
4722  }
4723 
4724  template<typename BasicJsonType, typename T,
4726  static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4727  {
4728  j.m_value.destroy(j.m_type);
4729  j.m_type = value_t::array;
4730  j.m_value = value_t::array;
4731  j.m_value.array->resize(arr.size());
4732  if (arr.size() > 0)
4733  {
4734  std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4735  }
4736  j.set_parents();
4737  j.assert_invariant();
4738  }
4739 };
4740 
4741 template<>
4743 {
4744  template<typename BasicJsonType>
4745  static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
4746  {
4747  j.m_value.destroy(j.m_type);
4748  j.m_type = value_t::object;
4749  j.m_value = obj;
4750  j.set_parents();
4751  j.assert_invariant();
4752  }
4753 
4754  template<typename BasicJsonType>
4755  static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4756  {
4757  j.m_value.destroy(j.m_type);
4758  j.m_type = value_t::object;
4759  j.m_value = std::move(obj);
4760  j.set_parents();
4761  j.assert_invariant();
4762  }
4763 
4764  template < typename BasicJsonType, typename CompatibleObjectType,
4766  static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4767  {
4768  using std::begin;
4769  using std::end;
4770 
4771  j.m_value.destroy(j.m_type);
4772  j.m_type = value_t::object;
4773  j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4774  j.set_parents();
4775  j.assert_invariant();
4776  }
4777 };
4778 
4780 // to_json //
4782 
4783 template<typename BasicJsonType, typename T,
4784  enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
4785 void to_json(BasicJsonType& j, T b) noexcept
4786 {
4788 }
4789 
4790 template<typename BasicJsonType, typename CompatibleString,
4791  enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
4792 void to_json(BasicJsonType& j, const CompatibleString& s)
4793 {
4795 }
4796 
4797 template<typename BasicJsonType>
4798 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4799 {
4801 }
4802 
4803 template<typename BasicJsonType, typename FloatType,
4804  enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
4805 void to_json(BasicJsonType& j, FloatType val) noexcept
4806 {
4807  external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4808 }
4809 
4810 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4811  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
4812 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4813 {
4814  external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4815 }
4816 
4817 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4818  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
4819 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4820 {
4821  external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4822 }
4823 
4824 template<typename BasicJsonType, typename EnumType,
4825  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4826 void to_json(BasicJsonType& j, EnumType e) noexcept
4827 {
4828  using underlying_type = typename std::underlying_type<EnumType>::type;
4829  external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4830 }
4831 
4832 template<typename BasicJsonType>
4833 void to_json(BasicJsonType& j, const std::vector<bool>& e)
4834 {
4836 }
4837 
4838 template < typename BasicJsonType, typename CompatibleArrayType,
4839  enable_if_t < is_compatible_array_type<BasicJsonType,
4840  CompatibleArrayType>::value&&
4841  !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
4842  !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
4843  !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
4844  !is_basic_json<CompatibleArrayType>::value,
4845  int > = 0 >
4846 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4847 {
4849 }
4850 
4851 template<typename BasicJsonType>
4852 void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4853 {
4855 }
4856 
4857 template<typename BasicJsonType, typename T,
4858  enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4859 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4860 {
4862 }
4863 
4864 template<typename BasicJsonType>
4865 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4866 {
4868 }
4869 
4870 template < typename BasicJsonType, typename CompatibleObjectType,
4871  enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
4872 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4873 {
4875 }
4876 
4877 template<typename BasicJsonType>
4878 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4879 {
4881 }
4882 
4883 template <
4884  typename BasicJsonType, typename T, std::size_t N,
4885  enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4886  const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4887  int > = 0 >
4888 void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4889 {
4891 }
4892 
4893 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
4894 void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4895 {
4896  j = { p.first, p.second };
4897 }
4898 
4899 // for https://github.com/nlohmann/json/pull/1134
4900 template<typename BasicJsonType, typename T,
4901  enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
4902 void to_json(BasicJsonType& j, const T& b)
4903 {
4904  j = { {b.key(), b.value()} };
4905 }
4906 
4907 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
4908 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4909 {
4910  j = { std::get<Idx>(t)... };
4911 }
4912 
4913 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
4914 void to_json(BasicJsonType& j, const T& t)
4915 {
4916  to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
4917 }
4918 
4920 {
4921  template<typename BasicJsonType, typename T>
4922  auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
4923  -> decltype(to_json(j, std::forward<T>(val)), void())
4924  {
4925  return to_json(j, std::forward<T>(val));
4926  }
4927 };
4928 } // namespace detail
4929 
4933 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4934 {
4935 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4936 } // namespace
4937 } // namespace nlohmann
4938 
4939 // #include <nlohmann/detail/meta/identity_tag.hpp>
4940 
4941 // #include <nlohmann/detail/meta/type_traits.hpp>
4942 
4943 
4944 namespace nlohmann
4945 {
4946 
4947 template<typename ValueType, typename>
4948 struct adl_serializer
4949 {
4961  template<typename BasicJsonType, typename TargetType = ValueType>
4962  static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
4963  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
4964  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
4965  {
4966  ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
4967  }
4968 
4981  template<typename BasicJsonType, typename TargetType = ValueType>
4982  static auto from_json(BasicJsonType && j) noexcept(
4983  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
4984  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
4985  {
4986  return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
4987  }
4988 
4998  template<typename BasicJsonType, typename TargetType = ValueType>
4999  static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
5000  noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5001  -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5002  {
5003  ::nlohmann::to_json(j, std::forward<TargetType>(val));
5004  }
5005 };
5006 } // namespace nlohmann
5007 
5008 // #include <nlohmann/byte_container_with_subtype.hpp>
5009 
5010 
5011 #include <cstdint> // uint8_t, uint64_t
5012 #include <tuple> // tie
5013 #include <utility> // move
5014 
5015 namespace nlohmann
5016 {
5017 
5031 template<typename BinaryType>
5032 class byte_container_with_subtype : public BinaryType
5033 {
5034  public:
5036  using container_type = BinaryType;
5038  using subtype_type = std::uint64_t;
5039 
5041  : container_type()
5042  {}
5043 
5045  : container_type(b)
5046  {}
5047 
5048  byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5049  : container_type(std::move(b))
5050  {}
5051 
5052  byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
5053  : container_type(b)
5054  , m_subtype(subtype_)
5055  , m_has_subtype(true)
5056  {}
5057 
5058  byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5059  : container_type(std::move(b))
5060  , m_subtype(subtype_)
5061  , m_has_subtype(true)
5062  {}
5063 
5065  {
5066  return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5067  std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5068  }
5069 
5071  {
5072  return !(rhs == *this);
5073  }
5074 
5093  void set_subtype(subtype_type subtype_) noexcept
5094  {
5095  m_subtype = subtype_;
5096  m_has_subtype = true;
5097  }
5098 
5121  constexpr subtype_type subtype() const noexcept
5122  {
5123  return m_has_subtype ? m_subtype : subtype_type(-1);
5124  }
5125 
5142  constexpr bool has_subtype() const noexcept
5143  {
5144  return m_has_subtype;
5145  }
5146 
5166  void clear_subtype() noexcept
5167  {
5168  m_subtype = 0;
5169  m_has_subtype = false;
5170  }
5171 
5172  private:
5173  subtype_type m_subtype = 0;
5174  bool m_has_subtype = false;
5175 };
5176 
5177 } // namespace nlohmann
5178 
5179 // #include <nlohmann/detail/conversions/from_json.hpp>
5180 
5181 // #include <nlohmann/detail/conversions/to_json.hpp>
5182 
5183 // #include <nlohmann/detail/exceptions.hpp>
5184 
5185 // #include <nlohmann/detail/hash.hpp>
5186 
5187 
5188 #include <cstdint> // uint8_t
5189 #include <cstddef> // size_t
5190 #include <functional> // hash
5191 
5192 // #include <nlohmann/detail/macro_scope.hpp>
5193 
5194 // #include <nlohmann/detail/value_t.hpp>
5195 
5196 
5197 namespace nlohmann
5198 {
5199 namespace detail
5200 {
5201 
5202 // boost::hash_combine
5203 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5204 {
5205  seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5206  return seed;
5207 }
5208 
5220 template<typename BasicJsonType>
5221 std::size_t hash(const BasicJsonType& j)
5222 {
5223  using string_t = typename BasicJsonType::string_t;
5224  using number_integer_t = typename BasicJsonType::number_integer_t;
5225  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5226  using number_float_t = typename BasicJsonType::number_float_t;
5227 
5228  const auto type = static_cast<std::size_t>(j.type());
5229  switch (j.type())
5230  {
5231  case BasicJsonType::value_t::null:
5232  case BasicJsonType::value_t::discarded:
5233  {
5234  return combine(type, 0);
5235  }
5236 
5237  case BasicJsonType::value_t::object:
5238  {
5239  auto seed = combine(type, j.size());
5240  for (const auto& element : j.items())
5241  {
5242  const auto h = std::hash<string_t> {}(element.key());
5243  seed = combine(seed, h);
5244  seed = combine(seed, hash(element.value()));
5245  }
5246  return seed;
5247  }
5248 
5249  case BasicJsonType::value_t::array:
5250  {
5251  auto seed = combine(type, j.size());
5252  for (const auto& element : j)
5253  {
5254  seed = combine(seed, hash(element));
5255  }
5256  return seed;
5257  }
5258 
5259  case BasicJsonType::value_t::string:
5260  {
5261  const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
5262  return combine(type, h);
5263  }
5264 
5265  case BasicJsonType::value_t::boolean:
5266  {
5267  const auto h = std::hash<bool> {}(j.template get<bool>());
5268  return combine(type, h);
5269  }
5270 
5271  case BasicJsonType::value_t::number_integer:
5272  {
5273  const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
5274  return combine(type, h);
5275  }
5276 
5277  case BasicJsonType::value_t::number_unsigned:
5278  {
5279  const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
5280  return combine(type, h);
5281  }
5282 
5283  case BasicJsonType::value_t::number_float:
5284  {
5285  const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
5286  return combine(type, h);
5287  }
5288 
5289  case BasicJsonType::value_t::binary:
5290  {
5291  auto seed = combine(type, j.get_binary().size());
5292  const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
5293  seed = combine(seed, h);
5294  seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
5295  for (const auto byte : j.get_binary())
5296  {
5297  seed = combine(seed, std::hash<std::uint8_t> {}(byte));
5298  }
5299  return seed;
5300  }
5301 
5302  default: // LCOV_EXCL_LINE
5303  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
5304  return 0; // LCOV_EXCL_LINE
5305  }
5306 }
5307 
5308 } // namespace detail
5309 } // namespace nlohmann
5310 
5311 // #include <nlohmann/detail/input/binary_reader.hpp>
5312 
5313 
5314 #include <algorithm> // generate_n
5315 #include <array> // array
5316 #include <cmath> // ldexp
5317 #include <cstddef> // size_t
5318 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5319 #include <cstdio> // snprintf
5320 #include <cstring> // memcpy
5321 #include <iterator> // back_inserter
5322 #include <limits> // numeric_limits
5323 #include <string> // char_traits, string
5324 #include <utility> // make_pair, move
5325 #include <vector> // vector
5326 
5327 // #include <nlohmann/detail/exceptions.hpp>
5328 
5329 // #include <nlohmann/detail/input/input_adapters.hpp>
5330 
5331 
5332 #include <array> // array
5333 #include <cstddef> // size_t
5334 #include <cstring> // strlen
5335 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
5336 #include <memory> // shared_ptr, make_shared, addressof
5337 #include <numeric> // accumulate
5338 #include <string> // string, char_traits
5339 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
5340 #include <utility> // pair, declval
5341 
5342 #ifndef JSON_NO_IO
5343  #include <cstdio> // FILE *
5344  #include <istream> // istream
5345 #endif // JSON_NO_IO
5346 
5347 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
5348 
5349 // #include <nlohmann/detail/macro_scope.hpp>
5350 
5351 
5352 namespace nlohmann
5353 {
5354 namespace detail
5355 {
5358 
5360 // input adapters //
5362 
5363 #ifndef JSON_NO_IO
5364 
5369 {
5370  public:
5371  using char_type = char;
5372 
5374  explicit file_input_adapter(std::FILE* f) noexcept
5375  : m_file(f)
5376  {}
5377 
5378  // make class move-only
5379  file_input_adapter(const file_input_adapter&) = delete;
5380  file_input_adapter(file_input_adapter&&) noexcept = default;
5381  file_input_adapter& operator=(const file_input_adapter&) = delete;
5382  file_input_adapter& operator=(file_input_adapter&&) = delete;
5383  ~file_input_adapter() = default;
5384 
5385  std::char_traits<char>::int_type get_character() noexcept
5386  {
5387  return std::fgetc(m_file);
5388  }
5389 
5390  private:
5392  std::FILE* m_file;
5393 };
5394 
5395 
5406 {
5407  public:
5408  using char_type = char;
5409 
5411  {
5412  // clear stream flags; we use underlying streambuf I/O, do not
5413  // maintain ifstream flags, except eof
5414  if (is != nullptr)
5415  {
5416  is->clear(is->rdstate() & std::ios::eofbit);
5417  }
5418  }
5419 
5420  explicit input_stream_adapter(std::istream& i)
5421  : is(&i), sb(i.rdbuf())
5422  {}
5423 
5424  // delete because of pointer members
5425  input_stream_adapter(const input_stream_adapter&) = delete;
5426  input_stream_adapter& operator=(input_stream_adapter&) = delete;
5427  input_stream_adapter& operator=(input_stream_adapter&&) = delete;
5428 
5430  : is(rhs.is), sb(rhs.sb)
5431  {
5432  rhs.is = nullptr;
5433  rhs.sb = nullptr;
5434  }
5435 
5436  // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
5437  // ensure that std::char_traits<char>::eof() and the character 0xFF do not
5438  // end up as the same value, eg. 0xFFFFFFFF.
5439  std::char_traits<char>::int_type get_character()
5440  {
5441  auto res = sb->sbumpc();
5442  // set eof manually, as we don't use the istream interface.
5443  if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
5444  {
5445  is->clear(is->rdstate() | std::ios::eofbit);
5446  }
5447  return res;
5448  }
5449 
5450  private:
5452  std::istream* is = nullptr;
5453  std::streambuf* sb = nullptr;
5454 };
5455 #endif // JSON_NO_IO
5456 
5457 // General-purpose iterator-based adapter. It might not be as fast as
5458 // theoretically possible for some containers, but it is extremely versatile.
5459 template<typename IteratorType>
5461 {
5462  public:
5463  using char_type = typename std::iterator_traits<IteratorType>::value_type;
5464 
5465  iterator_input_adapter(IteratorType first, IteratorType last)
5466  : current(std::move(first)), end(std::move(last))
5467  {}
5468 
5469  typename std::char_traits<char_type>::int_type get_character()
5470  {
5471  if (JSON_HEDLEY_LIKELY(current != end))
5472  {
5473  auto result = std::char_traits<char_type>::to_int_type(*current);
5474  std::advance(current, 1);
5475  return result;
5476  }
5477 
5478  return std::char_traits<char_type>::eof();
5479  }
5480 
5481  private:
5482  IteratorType current;
5483  IteratorType end;
5484 
5485  template<typename BaseInputAdapter, size_t T>
5487 
5488  bool empty() const
5489  {
5490  return current == end;
5491  }
5492 };
5493 
5494 
5495 template<typename BaseInputAdapter, size_t T>
5497 
5498 template<typename BaseInputAdapter>
5499 struct wide_string_input_helper<BaseInputAdapter, 4>
5500 {
5501  // UTF-32
5502  static void fill_buffer(BaseInputAdapter& input,
5503  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5504  size_t& utf8_bytes_index,
5505  size_t& utf8_bytes_filled)
5506  {
5507  utf8_bytes_index = 0;
5508 
5509  if (JSON_HEDLEY_UNLIKELY(input.empty()))
5510  {
5511  utf8_bytes[0] = std::char_traits<char>::eof();
5512  utf8_bytes_filled = 1;
5513  }
5514  else
5515  {
5516  // get the current character
5517  const auto wc = input.get_character();
5518 
5519  // UTF-32 to UTF-8 encoding
5520  if (wc < 0x80)
5521  {
5522  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5523  utf8_bytes_filled = 1;
5524  }
5525  else if (wc <= 0x7FF)
5526  {
5527  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
5528  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5529  utf8_bytes_filled = 2;
5530  }
5531  else if (wc <= 0xFFFF)
5532  {
5533  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
5534  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5535  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5536  utf8_bytes_filled = 3;
5537  }
5538  else if (wc <= 0x10FFFF)
5539  {
5540  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
5541  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
5542  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5543  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5544  utf8_bytes_filled = 4;
5545  }
5546  else
5547  {
5548  // unknown character
5549  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5550  utf8_bytes_filled = 1;
5551  }
5552  }
5553  }
5554 };
5555 
5556 template<typename BaseInputAdapter>
5557 struct wide_string_input_helper<BaseInputAdapter, 2>
5558 {
5559  // UTF-16
5560  static void fill_buffer(BaseInputAdapter& input,
5561  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5562  size_t& utf8_bytes_index,
5563  size_t& utf8_bytes_filled)
5564  {
5565  utf8_bytes_index = 0;
5566 
5567  if (JSON_HEDLEY_UNLIKELY(input.empty()))
5568  {
5569  utf8_bytes[0] = std::char_traits<char>::eof();
5570  utf8_bytes_filled = 1;
5571  }
5572  else
5573  {
5574  // get the current character
5575  const auto wc = input.get_character();
5576 
5577  // UTF-16 to UTF-8 encoding
5578  if (wc < 0x80)
5579  {
5580  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5581  utf8_bytes_filled = 1;
5582  }
5583  else if (wc <= 0x7FF)
5584  {
5585  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5586  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5587  utf8_bytes_filled = 2;
5588  }
5589  else if (0xD800 > wc || wc >= 0xE000)
5590  {
5591  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5592  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5593  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5594  utf8_bytes_filled = 3;
5595  }
5596  else
5597  {
5598  if (JSON_HEDLEY_UNLIKELY(!input.empty()))
5599  {
5600  const auto wc2 = static_cast<unsigned int>(input.get_character());
5601  const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
5602  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
5603  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
5604  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
5605  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
5606  utf8_bytes_filled = 4;
5607  }
5608  else
5609  {
5610  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5611  utf8_bytes_filled = 1;
5612  }
5613  }
5614  }
5615  }
5616 };
5617 
5618 // Wraps another input apdater to convert wide character types into individual bytes.
5619 template<typename BaseInputAdapter, typename WideCharType>
5621 {
5622  public:
5623  using char_type = char;
5624 
5625  wide_string_input_adapter(BaseInputAdapter base)
5626  : base_adapter(base) {}
5627 
5628  typename std::char_traits<char>::int_type get_character() noexcept
5629  {
5630  // check if buffer needs to be filled
5631  if (utf8_bytes_index == utf8_bytes_filled)
5632  {
5633  fill_buffer<sizeof(WideCharType)>();
5634 
5635  JSON_ASSERT(utf8_bytes_filled > 0);
5636  JSON_ASSERT(utf8_bytes_index == 0);
5637  }
5638 
5639  // use buffer
5640  JSON_ASSERT(utf8_bytes_filled > 0);
5641  JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
5642  return utf8_bytes[utf8_bytes_index++];
5643  }
5644 
5645  private:
5646  BaseInputAdapter base_adapter;
5647 
5648  template<size_t T>
5650  {
5651  wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
5652  }
5653 
5655  std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5656 
5658  std::size_t utf8_bytes_index = 0;
5660  std::size_t utf8_bytes_filled = 0;
5661 };
5662 
5663 
5664 template<typename IteratorType, typename Enable = void>
5666 {
5667  using iterator_type = IteratorType;
5668  using char_type = typename std::iterator_traits<iterator_type>::value_type;
5670 
5671  static adapter_type create(IteratorType first, IteratorType last)
5672  {
5673  return adapter_type(std::move(first), std::move(last));
5674  }
5675 };
5676 
5677 template<typename T>
5679 {
5680  using value_type = typename std::iterator_traits<T>::value_type;
5681  enum
5682  {
5683  value = sizeof(value_type) > 1
5684  };
5685 };
5686 
5687 template<typename IteratorType>
5689 {
5690  using iterator_type = IteratorType;
5691  using char_type = typename std::iterator_traits<iterator_type>::value_type;
5694 
5695  static adapter_type create(IteratorType first, IteratorType last)
5696  {
5697  return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5698  }
5699 };
5700 
5701 // General purpose iterator-based input
5702 template<typename IteratorType>
5703 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
5704 {
5705  using factory_type = iterator_input_adapter_factory<IteratorType>;
5706  return factory_type::create(first, last);
5707 }
5708 
5709 // Convenience shorthand from container to iterator
5710 // Enables ADL on begin(container) and end(container)
5711 // Encloses the using declarations in namespace for not to leak them to outside scope
5712 
5713 namespace container_input_adapter_factory_impl
5714 {
5715 
5716 using std::begin;
5717 using std::end;
5718 
5719 template<typename ContainerType, typename Enable = void>
5721 
5722 template<typename ContainerType>
5723 struct container_input_adapter_factory< ContainerType,
5724  void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
5725  {
5726  using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
5727 
5728  static adapter_type create(const ContainerType& container)
5729 {
5730  return input_adapter(begin(container), end(container));
5731 }
5732  };
5733 
5734 } // namespace container_input_adapter_factory_impl
5735 
5736 template<typename ContainerType>
5738 {
5740 }
5741 
5742 #ifndef JSON_NO_IO
5743 // Special cases with fast paths
5744 inline file_input_adapter input_adapter(std::FILE* file)
5745 {
5746  return file_input_adapter(file);
5747 }
5748 
5749 inline input_stream_adapter input_adapter(std::istream& stream)
5750 {
5751  return input_stream_adapter(stream);
5752 }
5753 
5754 inline input_stream_adapter input_adapter(std::istream&& stream)
5755 {
5756  return input_stream_adapter(stream);
5757 }
5758 #endif // JSON_NO_IO
5759 
5760 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5761 
5762 // Null-delimited strings, and the like.
5763 template < typename CharT,
5764  typename std::enable_if <
5765  std::is_pointer<CharT>::value&&
5766  !std::is_array<CharT>::value&&
5767  std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5768  sizeof(typename std::remove_pointer<CharT>::type) == 1,
5769  int >::type = 0 >
5771 {
5772  auto length = std::strlen(reinterpret_cast<const char*>(b));
5773  const auto* ptr = reinterpret_cast<const char*>(b);
5774  return input_adapter(ptr, ptr + length);
5775 }
5776 
5777 template<typename T, std::size_t N>
5778 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)
5779 {
5780  return input_adapter(array, array + N);
5781 }
5782 
5783 // This class only handles inputs of input_buffer_adapter type.
5784 // It's required so that expressions like {ptr, len} can be implicitely casted
5785 // to the correct adapter.
5787 {
5788  public:
5789  template < typename CharT,
5790  typename std::enable_if <
5791  std::is_pointer<CharT>::value&&
5792  std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5793  sizeof(typename std::remove_pointer<CharT>::type) == 1,
5794  int >::type = 0 >
5795  span_input_adapter(CharT b, std::size_t l)
5796  : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5797 
5798  template<class IteratorType,
5799  typename std::enable_if<
5800  std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5801  int>::type = 0>
5802  span_input_adapter(IteratorType first, IteratorType last)
5803  : ia(input_adapter(first, last)) {}
5804 
5806  {
5807  return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
5808  }
5809 
5810  private:
5812 };
5813 } // namespace detail
5814 } // namespace nlohmann
5815 
5816 // #include <nlohmann/detail/input/json_sax.hpp>
5817 
5818 
5819 #include <cstddef>
5820 #include <string> // string
5821 #include <utility> // move
5822 #include <vector> // vector
5823 
5824 // #include <nlohmann/detail/exceptions.hpp>
5825 
5826 // #include <nlohmann/detail/macro_scope.hpp>
5827 
5828 
5829 namespace nlohmann
5830 {
5831 
5840 template<typename BasicJsonType>
5841 struct json_sax
5842 {
5843  using number_integer_t = typename BasicJsonType::number_integer_t;
5844  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5845  using number_float_t = typename BasicJsonType::number_float_t;
5846  using string_t = typename BasicJsonType::string_t;
5847  using binary_t = typename BasicJsonType::binary_t;
5848 
5853  virtual bool null() = 0;
5854 
5860  virtual bool boolean(bool val) = 0;
5861 
5867  virtual bool number_integer(number_integer_t val) = 0;
5868 
5874  virtual bool number_unsigned(number_unsigned_t val) = 0;
5875 
5882  virtual bool number_float(number_float_t val, const string_t& s) = 0;
5883 
5890  virtual bool string(string_t& val) = 0;
5891 
5898  virtual bool binary(binary_t& val) = 0;
5899 
5906  virtual bool start_object(std::size_t elements) = 0;
5907 
5914  virtual bool key(string_t& val) = 0;
5915 
5920  virtual bool end_object() = 0;
5921 
5928  virtual bool start_array(std::size_t elements) = 0;
5929 
5934  virtual bool end_array() = 0;
5935 
5943  virtual bool parse_error(std::size_t position,
5944  const std::string& last_token,
5945  const detail::exception& ex) = 0;
5946 
5947  json_sax() = default;
5948  json_sax(const json_sax&) = default;
5949  json_sax(json_sax&&) noexcept = default;
5950  json_sax& operator=(const json_sax&) = default;
5951  json_sax& operator=(json_sax&&) noexcept = default;
5952  virtual ~json_sax() = default;
5953 };
5954 
5955 
5956 namespace detail
5957 {
5971 template<typename BasicJsonType>
5973 {
5974  public:
5975  using number_integer_t = typename BasicJsonType::number_integer_t;
5976  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5977  using number_float_t = typename BasicJsonType::number_float_t;
5978  using string_t = typename BasicJsonType::string_t;
5979  using binary_t = typename BasicJsonType::binary_t;
5980 
5986  explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
5987  : root(r), allow_exceptions(allow_exceptions_)
5988  {}
5989 
5990  // make class move-only
5991  json_sax_dom_parser(const json_sax_dom_parser&) = delete;
5992  json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
5993  json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
5994  json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
5995  ~json_sax_dom_parser() = default;
5996 
5997  bool null()
5998  {
5999  handle_value(nullptr);
6000  return true;
6001  }
6002 
6003  bool boolean(bool val)
6004  {
6005  handle_value(val);
6006  return true;
6007  }
6008 
6010  {
6011  handle_value(val);
6012  return true;
6013  }
6014 
6016  {
6017  handle_value(val);
6018  return true;
6019  }
6020 
6021  bool number_float(number_float_t val, const string_t& /*unused*/)
6022  {
6023  handle_value(val);
6024  return true;
6025  }
6026 
6027  bool string(string_t& val)
6028  {
6029  handle_value(val);
6030  return true;
6031  }
6032 
6033  bool binary(binary_t& val)
6034  {
6035  handle_value(std::move(val));
6036  return true;
6037  }
6038 
6039  bool start_object(std::size_t len)
6040  {
6041  ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6042 
6043  if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6044  {
6045  JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6046  }
6047 
6048  return true;
6049  }
6050 
6051  bool key(string_t& val)
6052  {
6053  // add null at given key and store the reference for later
6054  object_element = &(ref_stack.back()->m_value.object->operator[](val));
6055  return true;
6056  }
6057 
6058  bool end_object()
6059  {
6060  ref_stack.back()->set_parents();
6061  ref_stack.pop_back();
6062  return true;
6063  }
6064 
6065  bool start_array(std::size_t len)
6066  {
6067  ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6068 
6069  if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6070  {
6071  JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6072  }
6073 
6074  return true;
6075  }
6076 
6077  bool end_array()
6078  {
6079  ref_stack.back()->set_parents();
6080  ref_stack.pop_back();
6081  return true;
6082  }
6083 
6084  template<class Exception>
6085  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6086  const Exception& ex)
6087  {
6088  errored = true;
6089  static_cast<void>(ex);
6090  if (allow_exceptions)
6091  {
6092  JSON_THROW(ex);
6093  }
6094  return false;
6095  }
6096 
6097  constexpr bool is_errored() const
6098  {
6099  return errored;
6100  }
6101 
6102  private:
6109  template<typename Value>
6111  BasicJsonType* handle_value(Value&& v)
6112  {
6113  if (ref_stack.empty())
6114  {
6115  root = BasicJsonType(std::forward<Value>(v));
6116  return &root;
6117  }
6118 
6119  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6120 
6121  if (ref_stack.back()->is_array())
6122  {
6123  ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6124  return &(ref_stack.back()->m_value.array->back());
6125  }
6126 
6127  JSON_ASSERT(ref_stack.back()->is_object());
6128  JSON_ASSERT(object_element);
6129  *object_element = BasicJsonType(std::forward<Value>(v));
6130  return object_element;
6131  }
6132 
6134  BasicJsonType& root;
6136  std::vector<BasicJsonType*> ref_stack {};
6138  BasicJsonType* object_element = nullptr;
6140  bool errored = false;
6142  const bool allow_exceptions = true;
6143 };
6144 
6145 template<typename BasicJsonType>
6147 {
6148  public:
6149  using number_integer_t = typename BasicJsonType::number_integer_t;
6150  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6151  using number_float_t = typename BasicJsonType::number_float_t;
6152  using string_t = typename BasicJsonType::string_t;
6153  using binary_t = typename BasicJsonType::binary_t;
6156 
6158  const parser_callback_t cb,
6159  const bool allow_exceptions_ = true)
6160  : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6161  {
6162  keep_stack.push_back(true);
6163  }
6164 
6165  // make class move-only
6167  json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6168  json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
6169  json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6170  ~json_sax_dom_callback_parser() = default;
6171 
6172  bool null()
6173  {
6174  handle_value(nullptr);
6175  return true;
6176  }
6177 
6178  bool boolean(bool val)
6179  {
6180  handle_value(val);
6181  return true;
6182  }
6183 
6185  {
6186  handle_value(val);
6187  return true;
6188  }
6189 
6191  {
6192  handle_value(val);
6193  return true;
6194  }
6195 
6196  bool number_float(number_float_t val, const string_t& /*unused*/)
6197  {
6198  handle_value(val);
6199  return true;
6200  }
6201 
6202  bool string(string_t& val)
6203  {
6204  handle_value(val);
6205  return true;
6206  }
6207 
6208  bool binary(binary_t& val)
6209  {
6210  handle_value(std::move(val));
6211  return true;
6212  }
6213 
6214  bool start_object(std::size_t len)
6215  {
6216  // check callback for object start
6217  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6218  keep_stack.push_back(keep);
6219 
6220  auto val = handle_value(BasicJsonType::value_t::object, true);
6221  ref_stack.push_back(val.second);
6222 
6223  // check object limit
6224  if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6225  {
6226  JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6227  }
6228 
6229  return true;
6230  }
6231 
6232  bool key(string_t& val)
6233  {
6234  BasicJsonType k = BasicJsonType(val);
6235 
6236  // check callback for key
6237  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
6238  key_keep_stack.push_back(keep);
6239 
6240  // add discarded value at given key and store the reference for later
6241  if (keep && ref_stack.back())
6242  {
6243  object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
6244  }
6245 
6246  return true;
6247  }
6248 
6249  bool end_object()
6250  {
6251  if (ref_stack.back())
6252  {
6253  if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
6254  {
6255  // discard object
6256  *ref_stack.back() = discarded;
6257  }
6258  else
6259  {
6260  ref_stack.back()->set_parents();
6261  }
6262  }
6263 
6264  JSON_ASSERT(!ref_stack.empty());
6265  JSON_ASSERT(!keep_stack.empty());
6266  ref_stack.pop_back();
6267  keep_stack.pop_back();
6268 
6269  if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
6270  {
6271  // remove discarded value
6272  for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
6273  {
6274  if (it->is_discarded())
6275  {
6276  ref_stack.back()->erase(it);
6277  break;
6278  }
6279  }
6280  }
6281 
6282  return true;
6283  }
6284 
6285  bool start_array(std::size_t len)
6286  {
6287  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
6288  keep_stack.push_back(keep);
6289 
6290  auto val = handle_value(BasicJsonType::value_t::array, true);
6291  ref_stack.push_back(val.second);
6292 
6293  // check array limit
6294  if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6295  {
6296  JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6297  }
6298 
6299  return true;
6300  }
6301 
6302  bool end_array()
6303  {
6304  bool keep = true;
6305 
6306  if (ref_stack.back())
6307  {
6308  keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
6309  if (keep)
6310  {
6311  ref_stack.back()->set_parents();
6312  }
6313  else
6314  {
6315  // discard array
6316  *ref_stack.back() = discarded;
6317  }
6318  }
6319 
6320  JSON_ASSERT(!ref_stack.empty());
6321  JSON_ASSERT(!keep_stack.empty());
6322  ref_stack.pop_back();
6323  keep_stack.pop_back();
6324 
6325  // remove discarded value
6326  if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
6327  {
6328  ref_stack.back()->m_value.array->pop_back();
6329  }
6330 
6331  return true;
6332  }
6333 
6334  template<class Exception>
6335  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6336  const Exception& ex)
6337  {
6338  errored = true;
6339  static_cast<void>(ex);
6340  if (allow_exceptions)
6341  {
6342  JSON_THROW(ex);
6343  }
6344  return false;
6345  }
6346 
6347  constexpr bool is_errored() const
6348  {
6349  return errored;
6350  }
6351 
6352  private:
6368  template<typename Value>
6369  std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
6370  {
6371  JSON_ASSERT(!keep_stack.empty());
6372 
6373  // do not handle this value if we know it would be added to a discarded
6374  // container
6375  if (!keep_stack.back())
6376  {
6377  return {false, nullptr};
6378  }
6379 
6380  // create value
6381  auto value = BasicJsonType(std::forward<Value>(v));
6382 
6383  // check callback
6384  const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
6385 
6386  // do not handle this value if we just learnt it shall be discarded
6387  if (!keep)
6388  {
6389  return {false, nullptr};
6390  }
6391 
6392  if (ref_stack.empty())
6393  {
6394  root = std::move(value);
6395  return {true, &root};
6396  }
6397 
6398  // skip this value if we already decided to skip the parent
6399  // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
6400  if (!ref_stack.back())
6401  {
6402  return {false, nullptr};
6403  }
6404 
6405  // we now only expect arrays and objects
6406  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6407 
6408  // array
6409  if (ref_stack.back()->is_array())
6410  {
6411  ref_stack.back()->m_value.array->emplace_back(std::move(value));
6412  return {true, &(ref_stack.back()->m_value.array->back())};
6413  }
6414 
6415  // object
6416  JSON_ASSERT(ref_stack.back()->is_object());
6417  // check if we should store an element for the current key
6418  JSON_ASSERT(!key_keep_stack.empty());
6419  const bool store_element = key_keep_stack.back();
6420  key_keep_stack.pop_back();
6421 
6422  if (!store_element)
6423  {
6424  return {false, nullptr};
6425  }
6426 
6427  JSON_ASSERT(object_element);
6428  *object_element = std::move(value);
6429  return {true, object_element};
6430  }
6431 
6433  BasicJsonType& root;
6435  std::vector<BasicJsonType*> ref_stack {};
6437  std::vector<bool> keep_stack {};
6439  std::vector<bool> key_keep_stack {};
6441  BasicJsonType* object_element = nullptr;
6443  bool errored = false;
6445  const parser_callback_t callback = nullptr;
6447  const bool allow_exceptions = true;
6449  BasicJsonType discarded = BasicJsonType::value_t::discarded;
6450 };
6451 
6452 template<typename BasicJsonType>
6454 {
6455  public:
6456  using number_integer_t = typename BasicJsonType::number_integer_t;
6457  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6458  using number_float_t = typename BasicJsonType::number_float_t;
6459  using string_t = typename BasicJsonType::string_t;
6460  using binary_t = typename BasicJsonType::binary_t;
6461 
6462  bool null()
6463  {
6464  return true;
6465  }
6466 
6467  bool boolean(bool /*unused*/)
6468  {
6469  return true;
6470  }
6471 
6473  {
6474  return true;
6475  }
6476 
6478  {
6479  return true;
6480  }
6481 
6482  bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
6483  {
6484  return true;
6485  }
6486 
6487  bool string(string_t& /*unused*/)
6488  {
6489  return true;
6490  }
6491 
6492  bool binary(binary_t& /*unused*/)
6493  {
6494  return true;
6495  }
6496 
6497  bool start_object(std::size_t /*unused*/ = std::size_t(-1))
6498  {
6499  return true;
6500  }
6501 
6502  bool key(string_t& /*unused*/)
6503  {
6504  return true;
6505  }
6506 
6507  bool end_object()
6508  {
6509  return true;
6510  }
6511 
6512  bool start_array(std::size_t /*unused*/ = std::size_t(-1))
6513  {
6514  return true;
6515  }
6516 
6517  bool end_array()
6518  {
6519  return true;
6520  }
6521 
6522  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
6523  {
6524  return false;
6525  }
6526 };
6527 } // namespace detail
6528 
6529 } // namespace nlohmann
6530 
6531 // #include <nlohmann/detail/input/lexer.hpp>
6532 
6533 
6534 #include <array> // array
6535 #include <clocale> // localeconv
6536 #include <cstddef> // size_t
6537 #include <cstdio> // snprintf
6538 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
6539 #include <initializer_list> // initializer_list
6540 #include <string> // char_traits, string
6541 #include <utility> // move
6542 #include <vector> // vector
6543 
6544 // #include <nlohmann/detail/input/input_adapters.hpp>
6545 
6546 // #include <nlohmann/detail/input/position_t.hpp>
6547 
6548 // #include <nlohmann/detail/macro_scope.hpp>
6549 
6550 
6551 namespace nlohmann
6552 {
6553 namespace detail
6554 {
6556 // lexer //
6558 
6559 template<typename BasicJsonType>
6561 {
6562  public:
6564  enum class token_type
6565  {
6566  uninitialized,
6567  literal_true,
6568  literal_false,
6569  literal_null,
6570  value_string,
6571  value_unsigned,
6572  value_integer,
6573  value_float,
6574  begin_array,
6575  begin_object,
6576  end_array,
6577  end_object,
6578  name_separator,
6579  value_separator,
6580  parse_error,
6581  end_of_input,
6582  literal_or_value
6583  };
6584 
6588  static const char* token_type_name(const token_type t) noexcept
6589  {
6590  switch (t)
6591  {
6592  case token_type::uninitialized:
6593  return "<uninitialized>";
6594  case token_type::literal_true:
6595  return "true literal";
6596  case token_type::literal_false:
6597  return "false literal";
6598  case token_type::literal_null:
6599  return "null literal";
6600  case token_type::value_string:
6601  return "string literal";
6602  case token_type::value_unsigned:
6603  case token_type::value_integer:
6604  case token_type::value_float:
6605  return "number literal";
6606  case token_type::begin_array:
6607  return "'['";
6608  case token_type::begin_object:
6609  return "'{'";
6610  case token_type::end_array:
6611  return "']'";
6612  case token_type::end_object:
6613  return "'}'";
6614  case token_type::name_separator:
6615  return "':'";
6616  case token_type::value_separator:
6617  return "','";
6618  case token_type::parse_error:
6619  return "<parse error>";
6620  case token_type::end_of_input:
6621  return "end of input";
6622  case token_type::literal_or_value:
6623  return "'[', '{', or a literal";
6624  // LCOV_EXCL_START
6625  default: // catch non-enum values
6626  return "unknown token";
6627  // LCOV_EXCL_STOP
6628  }
6629  }
6630 };
6636 template<typename BasicJsonType, typename InputAdapterType>
6637 class lexer : public lexer_base<BasicJsonType>
6638 {
6639  using number_integer_t = typename BasicJsonType::number_integer_t;
6640  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6641  using number_float_t = typename BasicJsonType::number_float_t;
6642  using string_t = typename BasicJsonType::string_t;
6643  using char_type = typename InputAdapterType::char_type;
6644  using char_int_type = typename std::char_traits<char_type>::int_type;
6645 
6646  public:
6648 
6649  explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
6650  : ia(std::move(adapter))
6651  , ignore_comments(ignore_comments_)
6652  , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
6653  {}
6654 
6655  // delete because of pointer members
6656  lexer(const lexer&) = delete;
6657  lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6658  lexer& operator=(lexer&) = delete;
6659  lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6660  ~lexer() = default;
6661 
6662  private:
6664  // locales
6666 
6669  static char get_decimal_point() noexcept
6670  {
6671  const auto* loc = localeconv();
6672  JSON_ASSERT(loc != nullptr);
6673  return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6674  }
6675 
6677  // scan functions
6679 
6696  {
6697  // this function only makes sense after reading `\u`
6698  JSON_ASSERT(current == 'u');
6699  int codepoint = 0;
6700 
6701  const auto factors = { 12u, 8u, 4u, 0u };
6702  for (const auto factor : factors)
6703  {
6704  get();
6705 
6706  if (current >= '0' && current <= '9')
6707  {
6708  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6709  }
6710  else if (current >= 'A' && current <= 'F')
6711  {
6712  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6713  }
6714  else if (current >= 'a' && current <= 'f')
6715  {
6716  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6717  }
6718  else
6719  {
6720  return -1;
6721  }
6722  }
6723 
6724  JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6725  return codepoint;
6726  }
6727 
6743  bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6744  {
6745  JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6746  add(current);
6747 
6748  for (auto range = ranges.begin(); range != ranges.end(); ++range)
6749  {
6750  get();
6751  if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6752  {
6753  add(current);
6754  }
6755  else
6756  {
6757  error_message = "invalid string: ill-formed UTF-8 byte";
6758  return false;
6759  }
6760  }
6761 
6762  return true;
6763  }
6764 
6781  {
6782  // reset token_buffer (ignore opening quote)
6783  reset();
6784 
6785  // we entered the function by reading an open quote
6786  JSON_ASSERT(current == '\"');
6787 
6788  while (true)
6789  {
6790  // get next character
6791  switch (get())
6792  {
6793  // end of file while parsing string
6794  case std::char_traits<char_type>::eof():
6795  {
6796  error_message = "invalid string: missing closing quote";
6797  return token_type::parse_error;
6798  }
6799 
6800  // closing quote
6801  case '\"':
6802  {
6803  return token_type::value_string;
6804  }
6805 
6806  // escapes
6807  case '\\':
6808  {
6809  switch (get())
6810  {
6811  // quotation mark
6812  case '\"':
6813  add('\"');
6814  break;
6815  // reverse solidus
6816  case '\\':
6817  add('\\');
6818  break;
6819  // solidus
6820  case '/':
6821  add('/');
6822  break;
6823  // backspace
6824  case 'b':
6825  add('\b');
6826  break;
6827  // form feed
6828  case 'f':
6829  add('\f');
6830  break;
6831  // line feed
6832  case 'n':
6833  add('\n');
6834  break;
6835  // carriage return
6836  case 'r':
6837  add('\r');
6838  break;
6839  // tab
6840  case 't':
6841  add('\t');
6842  break;
6843 
6844  // unicode escapes
6845  case 'u':
6846  {
6847  const int codepoint1 = get_codepoint();
6848  int codepoint = codepoint1; // start with codepoint1
6849 
6850  if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
6851  {
6852  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6853  return token_type::parse_error;
6854  }
6855 
6856  // check if code point is a high surrogate
6857  if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6858  {
6859  // expect next \uxxxx entry
6860  if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6861  {
6862  const int codepoint2 = get_codepoint();
6863 
6864  if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
6865  {
6866  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6867  return token_type::parse_error;
6868  }
6869 
6870  // check if codepoint2 is a low surrogate
6871  if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6872  {
6873  // overwrite codepoint
6874  codepoint = static_cast<int>(
6875  // high surrogate occupies the most significant 22 bits
6876  (static_cast<unsigned int>(codepoint1) << 10u)
6877  // low surrogate occupies the least significant 15 bits
6878  + static_cast<unsigned int>(codepoint2)
6879  // there is still the 0xD800, 0xDC00 and 0x10000 noise
6880  // in the result so we have to subtract with:
6881  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6882  - 0x35FDC00u);
6883  }
6884  else
6885  {
6886  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6887  return token_type::parse_error;
6888  }
6889  }
6890  else
6891  {
6892  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6893  return token_type::parse_error;
6894  }
6895  }
6896  else
6897  {
6898  if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6899  {
6900  error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6901  return token_type::parse_error;
6902  }
6903  }
6904 
6905  // result of the above calculation yields a proper codepoint
6906  JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
6907 
6908  // translate codepoint into bytes
6909  if (codepoint < 0x80)
6910  {
6911  // 1-byte characters: 0xxxxxxx (ASCII)
6912  add(static_cast<char_int_type>(codepoint));
6913  }
6914  else if (codepoint <= 0x7FF)
6915  {
6916  // 2-byte characters: 110xxxxx 10xxxxxx
6917  add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
6918  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6919  }
6920  else if (codepoint <= 0xFFFF)
6921  {
6922  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
6923  add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
6924  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6925  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6926  }
6927  else
6928  {
6929  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
6930  add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
6931  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
6932  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6933  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6934  }
6935 
6936  break;
6937  }
6938 
6939  // other characters after escape
6940  default:
6941  error_message = "invalid string: forbidden character after backslash";
6942  return token_type::parse_error;
6943  }
6944 
6945  break;
6946  }
6947 
6948  // invalid control characters
6949  case 0x00:
6950  {
6951  error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
6952  return token_type::parse_error;
6953  }
6954 
6955  case 0x01:
6956  {
6957  error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
6958  return token_type::parse_error;
6959  }
6960 
6961  case 0x02:
6962  {
6963  error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
6964  return token_type::parse_error;
6965  }
6966 
6967  case 0x03:
6968  {
6969  error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
6970  return token_type::parse_error;
6971  }
6972 
6973  case 0x04:
6974  {
6975  error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
6976  return token_type::parse_error;
6977  }
6978 
6979  case 0x05:
6980  {
6981  error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
6982  return token_type::parse_error;
6983  }
6984 
6985  case 0x06:
6986  {
6987  error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
6988  return token_type::parse_error;
6989  }
6990 
6991  case 0x07:
6992  {
6993  error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
6994  return token_type::parse_error;
6995  }
6996 
6997  case 0x08:
6998  {
6999  error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7000  return token_type::parse_error;
7001  }
7002 
7003  case 0x09:
7004  {
7005  error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7006  return token_type::parse_error;
7007  }
7008 
7009  case 0x0A:
7010  {
7011  error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7012  return token_type::parse_error;
7013  }
7014 
7015  case 0x0B:
7016  {
7017  error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7018  return token_type::parse_error;
7019  }
7020 
7021  case 0x0C:
7022  {
7023  error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7024  return token_type::parse_error;
7025  }
7026 
7027  case 0x0D:
7028  {
7029  error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7030  return token_type::parse_error;
7031  }
7032 
7033  case 0x0E:
7034  {
7035  error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7036  return token_type::parse_error;
7037  }
7038 
7039  case 0x0F:
7040  {
7041  error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7042  return token_type::parse_error;
7043  }
7044 
7045  case 0x10:
7046  {
7047  error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7048  return token_type::parse_error;
7049  }
7050 
7051  case 0x11:
7052  {
7053  error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7054  return token_type::parse_error;
7055  }
7056 
7057  case 0x12:
7058  {
7059  error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7060  return token_type::parse_error;
7061  }
7062 
7063  case 0x13:
7064  {
7065  error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7066  return token_type::parse_error;
7067  }
7068 
7069  case 0x14:
7070  {
7071  error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7072  return token_type::parse_error;
7073  }
7074 
7075  case 0x15:
7076  {
7077  error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7078  return token_type::parse_error;
7079  }
7080 
7081  case 0x16:
7082  {
7083  error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7084  return token_type::parse_error;
7085  }
7086 
7087  case 0x17:
7088  {
7089  error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7090  return token_type::parse_error;
7091  }
7092 
7093  case 0x18:
7094  {
7095  error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7096  return token_type::parse_error;
7097  }
7098 
7099  case 0x19:
7100  {
7101  error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7102  return token_type::parse_error;
7103  }
7104 
7105  case 0x1A:
7106  {
7107  error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7108  return token_type::parse_error;
7109  }
7110 
7111  case 0x1B:
7112  {
7113  error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7114  return token_type::parse_error;
7115  }
7116 
7117  case 0x1C:
7118  {
7119  error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7120  return token_type::parse_error;
7121  }
7122 
7123  case 0x1D:
7124  {
7125  error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7126  return token_type::parse_error;
7127  }
7128 
7129  case 0x1E:
7130  {
7131  error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7132  return token_type::parse_error;
7133  }
7134 
7135  case 0x1F:
7136  {
7137  error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7138  return token_type::parse_error;
7139  }
7140 
7141  // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7142  case 0x20:
7143  case 0x21:
7144  case 0x23:
7145  case 0x24:
7146  case 0x25:
7147  case 0x26:
7148  case 0x27:
7149  case 0x28:
7150  case 0x29:
7151  case 0x2A:
7152  case 0x2B:
7153  case 0x2C:
7154  case 0x2D:
7155  case 0x2E:
7156  case 0x2F:
7157  case 0x30:
7158  case 0x31:
7159  case 0x32:
7160  case 0x33:
7161  case 0x34:
7162  case 0x35:
7163  case 0x36:
7164  case 0x37:
7165  case 0x38:
7166  case 0x39:
7167  case 0x3A:
7168  case 0x3B:
7169  case 0x3C:
7170  case 0x3D:
7171  case 0x3E:
7172  case 0x3F:
7173  case 0x40:
7174  case 0x41:
7175  case 0x42:
7176  case 0x43:
7177  case 0x44:
7178  case 0x45:
7179  case 0x46:
7180  case 0x47:
7181  case 0x48:
7182  case 0x49:
7183  case 0x4A:
7184  case 0x4B:
7185  case 0x4C:
7186  case 0x4D:
7187  case 0x4E:
7188  case 0x4F:
7189  case 0x50:
7190  case 0x51:
7191  case 0x52:
7192  case 0x53:
7193  case 0x54:
7194  case 0x55:
7195  case 0x56:
7196  case 0x57:
7197  case 0x58:
7198  case 0x59:
7199  case 0x5A:
7200  case 0x5B:
7201  case 0x5D:
7202  case 0x5E:
7203  case 0x5F:
7204  case 0x60:
7205  case 0x61:
7206  case 0x62:
7207  case 0x63:
7208  case 0x64:
7209  case 0x65:
7210  case 0x66:
7211  case 0x67:
7212  case 0x68:
7213  case 0x69:
7214  case 0x6A:
7215  case 0x6B:
7216  case 0x6C:
7217  case 0x6D:
7218  case 0x6E:
7219  case 0x6F:
7220  case 0x70:
7221  case 0x71:
7222  case 0x72:
7223  case 0x73:
7224  case 0x74:
7225  case 0x75:
7226  case 0x76:
7227  case 0x77:
7228  case 0x78:
7229  case 0x79:
7230  case 0x7A:
7231  case 0x7B:
7232  case 0x7C:
7233  case 0x7D:
7234  case 0x7E:
7235  case 0x7F:
7236  {
7237  add(current);
7238  break;
7239  }
7240 
7241  // U+0080..U+07FF: bytes C2..DF 80..BF
7242  case 0xC2:
7243  case 0xC3:
7244  case 0xC4:
7245  case 0xC5:
7246  case 0xC6:
7247  case 0xC7:
7248  case 0xC8:
7249  case 0xC9:
7250  case 0xCA:
7251  case 0xCB:
7252  case 0xCC:
7253  case 0xCD:
7254  case 0xCE:
7255  case 0xCF:
7256  case 0xD0:
7257  case 0xD1:
7258  case 0xD2:
7259  case 0xD3:
7260  case 0xD4:
7261  case 0xD5:
7262  case 0xD6:
7263  case 0xD7:
7264  case 0xD8:
7265  case 0xD9:
7266  case 0xDA:
7267  case 0xDB:
7268  case 0xDC:
7269  case 0xDD:
7270  case 0xDE:
7271  case 0xDF:
7272  {
7273  if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
7274  {
7275  return token_type::parse_error;
7276  }
7277  break;
7278  }
7279 
7280  // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7281  case 0xE0:
7282  {
7283  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7284  {
7285  return token_type::parse_error;
7286  }
7287  break;
7288  }
7289 
7290  // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7291  // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7292  case 0xE1:
7293  case 0xE2:
7294  case 0xE3:
7295  case 0xE4:
7296  case 0xE5:
7297  case 0xE6:
7298  case 0xE7:
7299  case 0xE8:
7300  case 0xE9:
7301  case 0xEA:
7302  case 0xEB:
7303  case 0xEC:
7304  case 0xEE:
7305  case 0xEF:
7306  {
7307  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
7308  {
7309  return token_type::parse_error;
7310  }
7311  break;
7312  }
7313 
7314  // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7315  case 0xED:
7316  {
7317  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
7318  {
7319  return token_type::parse_error;
7320  }
7321  break;
7322  }
7323 
7324  // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7325  case 0xF0:
7326  {
7327  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7328  {
7329  return token_type::parse_error;
7330  }
7331  break;
7332  }
7333 
7334  // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7335  case 0xF1:
7336  case 0xF2:
7337  case 0xF3:
7338  {
7339  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7340  {
7341  return token_type::parse_error;
7342  }
7343  break;
7344  }
7345 
7346  // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7347  case 0xF4:
7348  {
7349  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
7350  {
7351  return token_type::parse_error;
7352  }
7353  break;
7354  }
7355 
7356  // remaining bytes (80..C1 and F5..FF) are ill-formed
7357  default:
7358  {
7359  error_message = "invalid string: ill-formed UTF-8 byte";
7360  return token_type::parse_error;
7361  }
7362  }
7363  }
7364  }
7365 
7371  {
7372  switch (get())
7373  {
7374  // single-line comments skip input until a newline or EOF is read
7375  case '/':
7376  {
7377  while (true)
7378  {
7379  switch (get())
7380  {
7381  case '\n':
7382  case '\r':
7383  case std::char_traits<char_type>::eof():
7384  case '\0':
7385  return true;
7386 
7387  default:
7388  break;
7389  }
7390  }
7391  }
7392 
7393  // multi-line comments skip input until */ is read
7394  case '*':
7395  {
7396  while (true)
7397  {
7398  switch (get())
7399  {
7400  case std::char_traits<char_type>::eof():
7401  case '\0':
7402  {
7403  error_message = "invalid comment; missing closing '*/'";
7404  return false;
7405  }
7406 
7407  case '*':
7408  {
7409  switch (get())
7410  {
7411  case '/':
7412  return true;
7413 
7414  default:
7415  {
7416  unget();
7417  continue;
7418  }
7419  }
7420  }
7421 
7422  default:
7423  continue;
7424  }
7425  }
7426  }
7427 
7428  // unexpected character after reading '/'
7429  default:
7430  {
7431  error_message = "invalid comment; expecting '/' or '*' after '/'";
7432  return false;
7433  }
7434  }
7435  }
7436 
7438  static void strtof(float& f, const char* str, char** endptr) noexcept
7439  {
7440  f = std::strtof(str, endptr);
7441  }
7442 
7444  static void strtof(double& f, const char* str, char** endptr) noexcept
7445  {
7446  f = std::strtod(str, endptr);
7447  }
7448 
7450  static void strtof(long double& f, const char* str, char** endptr) noexcept
7451  {
7452  f = std::strtold(str, endptr);
7453  }
7454 
7495  token_type scan_number() // lgtm [cpp/use-of-goto]
7496  {
7497  // reset token_buffer to store the number's bytes
7498  reset();
7499 
7500  // the type of the parsed number; initially set to unsigned; will be
7501  // changed if minus sign, decimal point or exponent is read
7502  token_type number_type = token_type::value_unsigned;
7503 
7504  // state (init): we just found out we need to scan a number
7505  switch (current)
7506  {
7507  case '-':
7508  {
7509  add(current);
7510  goto scan_number_minus;
7511  }
7512 
7513  case '0':
7514  {
7515  add(current);
7516  goto scan_number_zero;
7517  }
7518 
7519  case '1':
7520  case '2':
7521  case '3':
7522  case '4':
7523  case '5':
7524  case '6':
7525  case '7':
7526  case '8':
7527  case '9':
7528  {
7529  add(current);
7530  goto scan_number_any1;
7531  }
7532 
7533  // all other characters are rejected outside scan_number()
7534  default: // LCOV_EXCL_LINE
7535  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
7536  }
7537 
7538 scan_number_minus:
7539  // state: we just parsed a leading minus sign
7540  number_type = token_type::value_integer;
7541  switch (get())
7542  {
7543  case '0':
7544  {
7545  add(current);
7546  goto scan_number_zero;
7547  }
7548 
7549  case '1':
7550  case '2':
7551  case '3':
7552  case '4':
7553  case '5':
7554  case '6':
7555  case '7':
7556  case '8':
7557  case '9':
7558  {
7559  add(current);
7560  goto scan_number_any1;
7561  }
7562 
7563  default:
7564  {
7565  error_message = "invalid number; expected digit after '-'";
7566  return token_type::parse_error;
7567  }
7568  }
7569 
7570 scan_number_zero:
7571  // state: we just parse a zero (maybe with a leading minus sign)
7572  switch (get())
7573  {
7574  case '.':
7575  {
7576  add(decimal_point_char);
7577  goto scan_number_decimal1;
7578  }
7579 
7580  case 'e':
7581  case 'E':
7582  {
7583  add(current);
7584  goto scan_number_exponent;
7585  }
7586 
7587  default:
7588  goto scan_number_done;
7589  }
7590 
7591 scan_number_any1:
7592  // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7593  switch (get())
7594  {
7595  case '0':
7596  case '1':
7597  case '2':
7598  case '3':
7599  case '4':
7600  case '5':
7601  case '6':
7602  case '7':
7603  case '8':
7604  case '9':
7605  {
7606  add(current);
7607  goto scan_number_any1;
7608  }
7609 
7610  case '.':
7611  {
7612  add(decimal_point_char);
7613  goto scan_number_decimal1;
7614  }
7615 
7616  case 'e':
7617  case 'E':
7618  {
7619  add(current);
7620  goto scan_number_exponent;
7621  }
7622 
7623  default:
7624  goto scan_number_done;
7625  }
7626 
7627 scan_number_decimal1:
7628  // state: we just parsed a decimal point
7629  number_type = token_type::value_float;
7630  switch (get())
7631  {
7632  case '0':
7633  case '1':
7634  case '2':
7635  case '3':
7636  case '4':
7637  case '5':
7638  case '6':
7639  case '7':
7640  case '8':
7641  case '9':
7642  {
7643  add(current);
7644  goto scan_number_decimal2;
7645  }
7646 
7647  default:
7648  {
7649  error_message = "invalid number; expected digit after '.'";
7650  return token_type::parse_error;
7651  }
7652  }
7653 
7654 scan_number_decimal2:
7655  // we just parsed at least one number after a decimal point
7656  switch (get())
7657  {
7658  case '0':
7659  case '1':
7660  case '2':
7661  case '3':
7662  case '4':
7663  case '5':
7664  case '6':
7665  case '7':
7666  case '8':
7667  case '9':
7668  {
7669  add(current);
7670  goto scan_number_decimal2;
7671  }
7672 
7673  case 'e':
7674  case 'E':
7675  {
7676  add(current);
7677  goto scan_number_exponent;
7678  }
7679 
7680  default:
7681  goto scan_number_done;
7682  }
7683 
7684 scan_number_exponent:
7685  // we just parsed an exponent
7686  number_type = token_type::value_float;
7687  switch (get())
7688  {
7689  case '+':
7690  case '-':
7691  {
7692  add(current);
7693  goto scan_number_sign;
7694  }
7695 
7696  case '0':
7697  case '1':
7698  case '2':
7699  case '3':
7700  case '4':
7701  case '5':
7702  case '6':
7703  case '7':
7704  case '8':
7705  case '9':
7706  {
7707  add(current);
7708  goto scan_number_any2;
7709  }
7710 
7711  default:
7712  {
7713  error_message =
7714  "invalid number; expected '+', '-', or digit after exponent";
7715  return token_type::parse_error;
7716  }
7717  }
7718 
7719 scan_number_sign:
7720  // we just parsed an exponent sign
7721  switch (get())
7722  {
7723  case '0':
7724  case '1':
7725  case '2':
7726  case '3':
7727  case '4':
7728  case '5':
7729  case '6':
7730  case '7':
7731  case '8':
7732  case '9':
7733  {
7734  add(current);
7735  goto scan_number_any2;
7736  }
7737 
7738  default:
7739  {
7740  error_message = "invalid number; expected digit after exponent sign";
7741  return token_type::parse_error;
7742  }
7743  }
7744 
7745 scan_number_any2:
7746  // we just parsed a number after the exponent or exponent sign
7747  switch (get())
7748  {
7749  case '0':
7750  case '1':
7751  case '2':
7752  case '3':
7753  case '4':
7754  case '5':
7755  case '6':
7756  case '7':
7757  case '8':
7758  case '9':
7759  {
7760  add(current);
7761  goto scan_number_any2;
7762  }
7763 
7764  default:
7765  goto scan_number_done;
7766  }
7767 
7768 scan_number_done:
7769  // unget the character after the number (we only read it to know that
7770  // we are done scanning a number)
7771  unget();
7772 
7773  char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7774  errno = 0;
7775 
7776  // try to parse integers first and fall back to floats
7777  if (number_type == token_type::value_unsigned)
7778  {
7779  const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7780 
7781  // we checked the number format before
7782  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7783 
7784  if (errno == 0)
7785  {
7786  value_unsigned = static_cast<number_unsigned_t>(x);
7787  if (value_unsigned == x)
7788  {
7789  return token_type::value_unsigned;
7790  }
7791  }
7792  }
7793  else if (number_type == token_type::value_integer)
7794  {
7795  const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7796 
7797  // we checked the number format before
7798  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7799 
7800  if (errno == 0)
7801  {
7802  value_integer = static_cast<number_integer_t>(x);
7803  if (value_integer == x)
7804  {
7805  return token_type::value_integer;
7806  }
7807  }
7808  }
7809 
7810  // this code is reached if we parse a floating-point number or if an
7811  // integer conversion above failed
7812  strtof(value_float, token_buffer.data(), &endptr);
7813 
7814  // we checked the number format before
7815  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7816 
7817  return token_type::value_float;
7818  }
7819 
7826  token_type scan_literal(const char_type* literal_text, const std::size_t length,
7827  token_type return_type)
7828  {
7829  JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
7830  for (std::size_t i = 1; i < length; ++i)
7831  {
7832  if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
7833  {
7834  error_message = "invalid literal";
7835  return token_type::parse_error;
7836  }
7837  }
7838  return return_type;
7839  }
7840 
7842  // input management
7844 
7846  void reset() noexcept
7847  {
7848  token_buffer.clear();
7849  token_string.clear();
7850  token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7851  }
7852 
7853  /*
7854  @brief get next character from the input
7855 
7856  This function provides the interface to the used input adapter. It does
7857  not throw in case the input reached EOF, but returns a
7858  `std::char_traits<char>::eof()` in that case. Stores the scanned characters
7859  for use in error messages.
7860 
7861  @return character read from the input
7862  */
7864  {
7865  ++position.chars_read_total;
7866  ++position.chars_read_current_line;
7867 
7868  if (next_unget)
7869  {
7870  // just reset the next_unget variable and work with current
7871  next_unget = false;
7872  }
7873  else
7874  {
7875  current = ia.get_character();
7876  }
7877 
7878  if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7879  {
7880  token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7881  }
7882 
7883  if (current == '\n')
7884  {
7885  ++position.lines_read;
7886  position.chars_read_current_line = 0;
7887  }
7888 
7889  return current;
7890  }
7891 
7900  void unget()
7901  {
7902  next_unget = true;
7903 
7904  --position.chars_read_total;
7905 
7906  // in case we "unget" a newline, we have to also decrement the lines_read
7907  if (position.chars_read_current_line == 0)
7908  {
7909  if (position.lines_read > 0)
7910  {
7911  --position.lines_read;
7912  }
7913  }
7914  else
7915  {
7916  --position.chars_read_current_line;
7917  }
7918 
7919  if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7920  {
7921  JSON_ASSERT(!token_string.empty());
7922  token_string.pop_back();
7923  }
7924  }
7925 
7928  {
7929  token_buffer.push_back(static_cast<typename string_t::value_type>(c));
7930  }
7931 
7932  public:
7934  // value getters
7936 
7938  constexpr number_integer_t get_number_integer() const noexcept
7939  {
7940  return value_integer;
7941  }
7942 
7944  constexpr number_unsigned_t get_number_unsigned() const noexcept
7945  {
7946  return value_unsigned;
7947  }
7948 
7950  constexpr number_float_t get_number_float() const noexcept
7951  {
7952  return value_float;
7953  }
7954 
7957  {
7958  return token_buffer;
7959  }
7960 
7962  // diagnostics
7964 
7966  constexpr position_t get_position() const noexcept
7967  {
7968  return position;
7969  }
7970 
7974  std::string get_token_string() const
7975  {
7976  // escape control characters
7977  std::string result;
7978  for (const auto c : token_string)
7979  {
7980  if (static_cast<unsigned char>(c) <= '\x1F')
7981  {
7982  // escape control characters
7983  std::array<char, 9> cs{{}};
7984  (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7985  result += cs.data();
7986  }
7987  else
7988  {
7989  // add character as is
7990  result.push_back(static_cast<std::string::value_type>(c));
7991  }
7992  }
7993 
7994  return result;
7995  }
7996 
7999  constexpr const char* get_error_message() const noexcept
8000  {
8001  return error_message;
8002  }
8003 
8005  // actual scanner
8007 
8012  bool skip_bom()
8013  {
8014  if (get() == 0xEF)
8015  {
8016  // check if we completely parse the BOM
8017  return get() == 0xBB && get() == 0xBF;
8018  }
8019 
8020  // the first character is not the beginning of the BOM; unget it to
8021  // process is later
8022  unget();
8023  return true;
8024  }
8025 
8027  {
8028  do
8029  {
8030  get();
8031  }
8032  while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8033  }
8034 
8036  {
8037  // initially, skip the BOM
8038  if (position.chars_read_total == 0 && !skip_bom())
8039  {
8040  error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8041  return token_type::parse_error;
8042  }
8043 
8044  // read next character and ignore whitespace
8045  skip_whitespace();
8046 
8047  // ignore comments
8048  while (ignore_comments && current == '/')
8049  {
8050  if (!scan_comment())
8051  {
8052  return token_type::parse_error;
8053  }
8054 
8055  // skip following whitespace
8056  skip_whitespace();
8057  }
8058 
8059  switch (current)
8060  {
8061  // structural characters
8062  case '[':
8063  return token_type::begin_array;
8064  case ']':
8065  return token_type::end_array;
8066  case '{':
8067  return token_type::begin_object;
8068  case '}':
8069  return token_type::end_object;
8070  case ':':
8071  return token_type::name_separator;
8072  case ',':
8073  return token_type::value_separator;
8074 
8075  // literals
8076  case 't':
8077  {
8078  std::array<char_type, 4> true_literal = {{char_type('t'), char_type('r'), char_type('u'), char_type('e')}};
8079  return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8080  }
8081  case 'f':
8082  {
8083  std::array<char_type, 5> false_literal = {{char_type('f'), char_type('a'), char_type('l'), char_type('s'), char_type('e')}};
8084  return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8085  }
8086  case 'n':
8087  {
8088  std::array<char_type, 4> null_literal = {{char_type('n'), char_type('u'), char_type('l'), char_type('l')}};
8089  return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8090  }
8091 
8092  // string
8093  case '\"':
8094  return scan_string();
8095 
8096  // number
8097  case '-':
8098  case '0':
8099  case '1':
8100  case '2':
8101  case '3':
8102  case '4':
8103  case '5':
8104  case '6':
8105  case '7':
8106  case '8':
8107  case '9':
8108  return scan_number();
8109 
8110  // end of input (the null byte is needed when parsing from
8111  // string literals)
8112  case '\0':
8113  case std::char_traits<char_type>::eof():
8114  return token_type::end_of_input;
8115 
8116  // error
8117  default:
8118  error_message = "invalid literal";
8119  return token_type::parse_error;
8120  }
8121  }
8122 
8123  private:
8125  InputAdapterType ia;
8126 
8128  const bool ignore_comments = false;
8129 
8131  char_int_type current = std::char_traits<char_type>::eof();
8132 
8134  bool next_unget = false;
8135 
8137  position_t position {};
8138 
8140  std::vector<char_type> token_string {};
8141 
8143  string_t token_buffer {};
8144 
8146  const char* error_message = "";
8147 
8148  // number values
8149  number_integer_t value_integer = 0;
8150  number_unsigned_t value_unsigned = 0;
8151  number_float_t value_float = 0;
8152 
8154  const char_int_type decimal_point_char = '.';
8155 };
8156 } // namespace detail
8157 } // namespace nlohmann
8158 
8159 // #include <nlohmann/detail/macro_scope.hpp>
8160 
8161 // #include <nlohmann/detail/meta/is_sax.hpp>
8162 
8163 
8164 #include <cstdint> // size_t
8165 #include <utility> // declval
8166 #include <string> // string
8167 
8168 // #include <nlohmann/detail/meta/detected.hpp>
8169 
8170 // #include <nlohmann/detail/meta/type_traits.hpp>
8171 
8172 
8173 namespace nlohmann
8174 {
8175 namespace detail
8176 {
8177 template<typename T>
8178 using null_function_t = decltype(std::declval<T&>().null());
8179 
8180 template<typename T>
8181 using boolean_function_t =
8182  decltype(std::declval<T&>().boolean(std::declval<bool>()));
8183 
8184 template<typename T, typename Integer>
8186  decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8187 
8188 template<typename T, typename Unsigned>
8190  decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8191 
8192 template<typename T, typename Float, typename String>
8193 using number_float_function_t = decltype(std::declval<T&>().number_float(
8194  std::declval<Float>(), std::declval<const String&>()));
8195 
8196 template<typename T, typename String>
8197 using string_function_t =
8198  decltype(std::declval<T&>().string(std::declval<String&>()));
8199 
8200 template<typename T, typename Binary>
8201 using binary_function_t =
8202  decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8203 
8204 template<typename T>
8206  decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8207 
8208 template<typename T, typename String>
8209 using key_function_t =
8210  decltype(std::declval<T&>().key(std::declval<String&>()));
8211 
8212 template<typename T>
8213 using end_object_function_t = decltype(std::declval<T&>().end_object());
8214 
8215 template<typename T>
8216 using start_array_function_t =
8217  decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
8218 
8219 template<typename T>
8220 using end_array_function_t = decltype(std::declval<T&>().end_array());
8221 
8222 template<typename T, typename Exception>
8223 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
8224  std::declval<std::size_t>(), std::declval<const std::string&>(),
8225  std::declval<const Exception&>()));
8226 
8227 template<typename SAX, typename BasicJsonType>
8228 struct is_sax
8229 {
8230  private:
8232  "BasicJsonType must be of type basic_json<...>");
8233 
8234  using number_integer_t = typename BasicJsonType::number_integer_t;
8235  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8236  using number_float_t = typename BasicJsonType::number_float_t;
8237  using string_t = typename BasicJsonType::string_t;
8238  using binary_t = typename BasicJsonType::binary_t;
8239  using exception_t = typename BasicJsonType::exception;
8240 
8241  public:
8242  static constexpr bool value =
8256 };
8257 
8258 template<typename SAX, typename BasicJsonType>
8260 {
8261  private:
8263  "BasicJsonType must be of type basic_json<...>");
8264 
8265  using number_integer_t = typename BasicJsonType::number_integer_t;
8266  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8267  using number_float_t = typename BasicJsonType::number_float_t;
8268  using string_t = typename BasicJsonType::string_t;
8269  using binary_t = typename BasicJsonType::binary_t;
8270  using exception_t = typename BasicJsonType::exception;
8271 
8272  public:
8274  "Missing/invalid function: bool null()");
8276  "Missing/invalid function: bool boolean(bool)");
8278  "Missing/invalid function: bool boolean(bool)");
8279  static_assert(
8281  number_integer_t>::value,
8282  "Missing/invalid function: bool number_integer(number_integer_t)");
8283  static_assert(
8285  number_unsigned_t>::value,
8286  "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
8287  static_assert(is_detected_exact<bool, number_float_function_t, SAX,
8288  number_float_t, string_t>::value,
8289  "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
8290  static_assert(
8292  "Missing/invalid function: bool string(string_t&)");
8293  static_assert(
8295  "Missing/invalid function: bool binary(binary_t&)");
8297  "Missing/invalid function: bool start_object(std::size_t)");
8299  "Missing/invalid function: bool key(string_t&)");
8301  "Missing/invalid function: bool end_object()");
8303  "Missing/invalid function: bool start_array(std::size_t)");
8305  "Missing/invalid function: bool end_array()");
8306  static_assert(
8308  "Missing/invalid function: bool parse_error(std::size_t, const "
8309  "std::string&, const exception&)");
8310 };
8311 } // namespace detail
8312 } // namespace nlohmann
8313 
8314 // #include <nlohmann/detail/meta/type_traits.hpp>
8315 
8316 // #include <nlohmann/detail/value_t.hpp>
8317 
8318 
8319 namespace nlohmann
8320 {
8321 namespace detail
8322 {
8323 
8326 {
8327  error,
8328  ignore,
8329  store
8330 };
8331 
8339 static inline bool little_endianess(int num = 1) noexcept
8340 {
8341  return *reinterpret_cast<char*>(&num) == 1;
8342 }
8343 
8344 
8346 // binary reader //
8348 
8352 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
8354 {
8355  using number_integer_t = typename BasicJsonType::number_integer_t;
8356  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8357  using number_float_t = typename BasicJsonType::number_float_t;
8358  using string_t = typename BasicJsonType::string_t;
8359  using binary_t = typename BasicJsonType::binary_t;
8360  using json_sax_t = SAX;
8361  using char_type = typename InputAdapterType::char_type;
8362  using char_int_type = typename std::char_traits<char_type>::int_type;
8363 
8364  public:
8370  explicit binary_reader(InputAdapterType&& adapter) noexcept : ia(std::move(adapter))
8371  {
8373  }
8374 
8375  // make class move-only
8376  binary_reader(const binary_reader&) = delete;
8377  binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8378  binary_reader& operator=(const binary_reader&) = delete;
8379  binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8380  ~binary_reader() = default;
8381 
8391  bool sax_parse(const input_format_t format,
8392  json_sax_t* sax_,
8393  const bool strict = true,
8394  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
8395  {
8396  sax = sax_;
8397  bool result = false;
8398 
8399  switch (format)
8400  {
8401  case input_format_t::bson:
8402  result = parse_bson_internal();
8403  break;
8404 
8405  case input_format_t::cbor:
8406  result = parse_cbor_internal(true, tag_handler);
8407  break;
8408 
8409  case input_format_t::msgpack:
8410  result = parse_msgpack_internal();
8411  break;
8412 
8413  case input_format_t::ubjson:
8414  result = parse_ubjson_internal();
8415  break;
8416 
8417  case input_format_t::json: // LCOV_EXCL_LINE
8418  default: // LCOV_EXCL_LINE
8419  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8420  }
8421 
8422  // strict mode: next byte must be EOF
8423  if (result && strict)
8424  {
8425  if (format == input_format_t::ubjson)
8426  {
8427  get_ignore_noop();
8428  }
8429  else
8430  {
8431  get();
8432  }
8433 
8434  if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
8435  {
8436  return sax->parse_error(chars_read, get_token_string(),
8437  parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value"), BasicJsonType()));
8438  }
8439  }
8440 
8441  return result;
8442  }
8443 
8444  private:
8446  // BSON //
8448 
8454  {
8455  std::int32_t document_size{};
8456  get_number<std::int32_t, true>(input_format_t::bson, document_size);
8457 
8458  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
8459  {
8460  return false;
8461  }
8462 
8463  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
8464  {
8465  return false;
8466  }
8467 
8468  return sax->end_object();
8469  }
8470 
8478  bool get_bson_cstr(string_t& result)
8479  {
8480  auto out = std::back_inserter(result);
8481  while (true)
8482  {
8483  get();
8484  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
8485  {
8486  return false;
8487  }
8488  if (current == 0x00)
8489  {
8490  return true;
8491  }
8492  *out++ = static_cast<typename string_t::value_type>(current);
8493  }
8494  }
8495 
8507  template<typename NumberType>
8508  bool get_bson_string(const NumberType len, string_t& result)
8509  {
8510  if (JSON_HEDLEY_UNLIKELY(len < 1))
8511  {
8512  auto last_token = get_token_string();
8513  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string"), BasicJsonType()));
8514  }
8515 
8516  return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
8517  }
8518 
8528  template<typename NumberType>
8529  bool get_bson_binary(const NumberType len, binary_t& result)
8530  {
8531  if (JSON_HEDLEY_UNLIKELY(len < 0))
8532  {
8533  auto last_token = get_token_string();
8534  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary"), BasicJsonType()));
8535  }
8536 
8537  // All BSON binary values have a subtype
8538  std::uint8_t subtype{};
8539  get_number<std::uint8_t>(input_format_t::bson, subtype);
8540  result.set_subtype(subtype);
8541 
8542  return get_binary(input_format_t::bson, len, result);
8543  }
8544 
8556  const std::size_t element_type_parse_position)
8557  {
8558  switch (element_type)
8559  {
8560  case 0x01: // double
8561  {
8562  double number{};
8563  return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
8564  }
8565 
8566  case 0x02: // string
8567  {
8568  std::int32_t len{};
8569  string_t value;
8570  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
8571  }
8572 
8573  case 0x03: // object
8574  {
8575  return parse_bson_internal();
8576  }
8577 
8578  case 0x04: // array
8579  {
8580  return parse_bson_array();
8581  }
8582 
8583  case 0x05: // binary
8584  {
8585  std::int32_t len{};
8586  binary_t value;
8587  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
8588  }
8589 
8590  case 0x08: // boolean
8591  {
8592  return sax->boolean(get() != 0);
8593  }
8594 
8595  case 0x0A: // null
8596  {
8597  return sax->null();
8598  }
8599 
8600  case 0x10: // int32
8601  {
8602  std::int32_t value{};
8603  return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8604  }
8605 
8606  case 0x12: // int64
8607  {
8608  std::int64_t value{};
8609  return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8610  }
8611 
8612  default: // anything else not supported (yet)
8613  {
8614  std::array<char, 3> cr{{}};
8615  (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8616  return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data()), BasicJsonType()));
8617  }
8618  }
8619  }
8620 
8633  bool parse_bson_element_list(const bool is_array)
8634  {
8635  string_t key;
8636 
8637  while (auto element_type = get())
8638  {
8639  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
8640  {
8641  return false;
8642  }
8643 
8644  const std::size_t element_type_parse_position = chars_read;
8645  if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
8646  {
8647  return false;
8648  }
8649 
8650  if (!is_array && !sax->key(key))
8651  {
8652  return false;
8653  }
8654 
8655  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
8656  {
8657  return false;
8658  }
8659 
8660  // get_bson_cstr only appends
8661  key.clear();
8662  }
8663 
8664  return true;
8665  }
8666 
8672  {
8673  std::int32_t document_size{};
8674  get_number<std::int32_t, true>(input_format_t::bson, document_size);
8675 
8676  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
8677  {
8678  return false;
8679  }
8680 
8681  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8682  {
8683  return false;
8684  }
8685 
8686  return sax->end_array();
8687  }
8688 
8690  // CBOR //
8692 
8701  bool parse_cbor_internal(const bool get_char,
8702  const cbor_tag_handler_t tag_handler)
8703  {
8704  switch (get_char ? get() : current)
8705  {
8706  // EOF
8707  case std::char_traits<char_type>::eof():
8708  return unexpect_eof(input_format_t::cbor, "value");
8709 
8710  // Integer 0x00..0x17 (0..23)
8711  case 0x00:
8712  case 0x01:
8713  case 0x02:
8714  case 0x03:
8715  case 0x04:
8716  case 0x05:
8717  case 0x06:
8718  case 0x07:
8719  case 0x08:
8720  case 0x09:
8721  case 0x0A:
8722  case 0x0B:
8723  case 0x0C:
8724  case 0x0D:
8725  case 0x0E:
8726  case 0x0F:
8727  case 0x10:
8728  case 0x11:
8729  case 0x12:
8730  case 0x13:
8731  case 0x14:
8732  case 0x15:
8733  case 0x16:
8734  case 0x17:
8735  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8736 
8737  case 0x18: // Unsigned integer (one-byte uint8_t follows)
8738  {
8739  std::uint8_t number{};
8740  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8741  }
8742 
8743  case 0x19: // Unsigned integer (two-byte uint16_t follows)
8744  {
8745  std::uint16_t number{};
8746  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8747  }
8748 
8749  case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8750  {
8751  std::uint32_t number{};
8752  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8753  }
8754 
8755  case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8756  {
8757  std::uint64_t number{};
8758  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8759  }
8760 
8761  // Negative integer -1-0x00..-1-0x17 (-1..-24)
8762  case 0x20:
8763  case 0x21:
8764  case 0x22:
8765  case 0x23:
8766  case 0x24:
8767  case 0x25:
8768  case 0x26:
8769  case 0x27:
8770  case 0x28:
8771  case 0x29:
8772  case 0x2A:
8773  case 0x2B:
8774  case 0x2C:
8775  case 0x2D:
8776  case 0x2E:
8777  case 0x2F:
8778  case 0x30:
8779  case 0x31:
8780  case 0x32:
8781  case 0x33:
8782  case 0x34:
8783  case 0x35:
8784  case 0x36:
8785  case 0x37:
8786  return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8787 
8788  case 0x38: // Negative integer (one-byte uint8_t follows)
8789  {
8790  std::uint8_t number{};
8791  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8792  }
8793 
8794  case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8795  {
8796  std::uint16_t number{};
8797  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8798  }
8799 
8800  case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8801  {
8802  std::uint32_t number{};
8803  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8804  }
8805 
8806  case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8807  {
8808  std::uint64_t number{};
8809  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8810  - static_cast<number_integer_t>(number));
8811  }
8812 
8813  // Binary data (0x00..0x17 bytes follow)
8814  case 0x40:
8815  case 0x41:
8816  case 0x42:
8817  case 0x43:
8818  case 0x44:
8819  case 0x45:
8820  case 0x46:
8821  case 0x47:
8822  case 0x48:
8823  case 0x49:
8824  case 0x4A:
8825  case 0x4B:
8826  case 0x4C:
8827  case 0x4D:
8828  case 0x4E:
8829  case 0x4F:
8830  case 0x50:
8831  case 0x51:
8832  case 0x52:
8833  case 0x53:
8834  case 0x54:
8835  case 0x55:
8836  case 0x56:
8837  case 0x57:
8838  case 0x58: // Binary data (one-byte uint8_t for n follows)
8839  case 0x59: // Binary data (two-byte uint16_t for n follow)
8840  case 0x5A: // Binary data (four-byte uint32_t for n follow)
8841  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8842  case 0x5F: // Binary data (indefinite length)
8843  {
8844  binary_t b;
8845  return get_cbor_binary(b) && sax->binary(b);
8846  }
8847 
8848  // UTF-8 string (0x00..0x17 bytes follow)
8849  case 0x60:
8850  case 0x61:
8851  case 0x62:
8852  case 0x63:
8853  case 0x64:
8854  case 0x65:
8855  case 0x66:
8856  case 0x67:
8857  case 0x68:
8858  case 0x69:
8859  case 0x6A:
8860  case 0x6B:
8861  case 0x6C:
8862  case 0x6D:
8863  case 0x6E:
8864  case 0x6F:
8865  case 0x70:
8866  case 0x71:
8867  case 0x72:
8868  case 0x73:
8869  case 0x74:
8870  case 0x75:
8871  case 0x76:
8872  case 0x77:
8873  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8874  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8875  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8876  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8877  case 0x7F: // UTF-8 string (indefinite length)
8878  {
8879  string_t s;
8880  return get_cbor_string(s) && sax->string(s);
8881  }
8882 
8883  // array (0x00..0x17 data items follow)
8884  case 0x80:
8885  case 0x81:
8886  case 0x82:
8887  case 0x83:
8888  case 0x84:
8889  case 0x85:
8890  case 0x86:
8891  case 0x87:
8892  case 0x88:
8893  case 0x89:
8894  case 0x8A:
8895  case 0x8B:
8896  case 0x8C:
8897  case 0x8D:
8898  case 0x8E:
8899  case 0x8F:
8900  case 0x90:
8901  case 0x91:
8902  case 0x92:
8903  case 0x93:
8904  case 0x94:
8905  case 0x95:
8906  case 0x96:
8907  case 0x97:
8908  return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8909 
8910  case 0x98: // array (one-byte uint8_t for n follows)
8911  {
8912  std::uint8_t len{};
8913  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8914  }
8915 
8916  case 0x99: // array (two-byte uint16_t for n follow)
8917  {
8918  std::uint16_t len{};
8919  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8920  }
8921 
8922  case 0x9A: // array (four-byte uint32_t for n follow)
8923  {
8924  std::uint32_t len{};
8925  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8926  }
8927 
8928  case 0x9B: // array (eight-byte uint64_t for n follow)
8929  {
8930  std::uint64_t len{};
8931  return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast<std::size_t>(len), tag_handler);
8932  }
8933 
8934  case 0x9F: // array (indefinite length)
8935  return get_cbor_array(std::size_t(-1), tag_handler);
8936 
8937  // map (0x00..0x17 pairs of data items follow)
8938  case 0xA0:
8939  case 0xA1:
8940  case 0xA2:
8941  case 0xA3:
8942  case 0xA4:
8943  case 0xA5:
8944  case 0xA6:
8945  case 0xA7:
8946  case 0xA8:
8947  case 0xA9:
8948  case 0xAA:
8949  case 0xAB:
8950  case 0xAC:
8951  case 0xAD:
8952  case 0xAE:
8953  case 0xAF:
8954  case 0xB0:
8955  case 0xB1:
8956  case 0xB2:
8957  case 0xB3:
8958  case 0xB4:
8959  case 0xB5:
8960  case 0xB6:
8961  case 0xB7:
8962  return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8963 
8964  case 0xB8: // map (one-byte uint8_t for n follows)
8965  {
8966  std::uint8_t len{};
8967  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8968  }
8969 
8970  case 0xB9: // map (two-byte uint16_t for n follow)
8971  {
8972  std::uint16_t len{};
8973  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8974  }
8975 
8976  case 0xBA: // map (four-byte uint32_t for n follow)
8977  {
8978  std::uint32_t len{};
8979  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8980  }
8981 
8982  case 0xBB: // map (eight-byte uint64_t for n follow)
8983  {
8984  std::uint64_t len{};
8985  return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast<std::size_t>(len), tag_handler);
8986  }
8987 
8988  case 0xBF: // map (indefinite length)
8989  return get_cbor_object(std::size_t(-1), tag_handler);
8990 
8991  case 0xC6: // tagged item
8992  case 0xC7:
8993  case 0xC8:
8994  case 0xC9:
8995  case 0xCA:
8996  case 0xCB:
8997  case 0xCC:
8998  case 0xCD:
8999  case 0xCE:
9000  case 0xCF:
9001  case 0xD0:
9002  case 0xD1:
9003  case 0xD2:
9004  case 0xD3:
9005  case 0xD4:
9006  case 0xD8: // tagged item (1 bytes follow)
9007  case 0xD9: // tagged item (2 bytes follow)
9008  case 0xDA: // tagged item (4 bytes follow)
9009  case 0xDB: // tagged item (8 bytes follow)
9010  {
9011  switch (tag_handler)
9012  {
9013  case cbor_tag_handler_t::error:
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  case cbor_tag_handler_t::ignore:
9020  {
9021  // ignore binary subtype
9022  switch (current)
9023  {
9024  case 0xD8:
9025  {
9026  std::uint8_t subtype_to_ignore{};
9027  get_number(input_format_t::cbor, subtype_to_ignore);
9028  break;
9029  }
9030  case 0xD9:
9031  {
9032  std::uint16_t subtype_to_ignore{};
9033  get_number(input_format_t::cbor, subtype_to_ignore);
9034  break;
9035  }
9036  case 0xDA:
9037  {
9038  std::uint32_t subtype_to_ignore{};
9039  get_number(input_format_t::cbor, subtype_to_ignore);
9040  break;
9041  }
9042  case 0xDB:
9043  {
9044  std::uint64_t subtype_to_ignore{};
9045  get_number(input_format_t::cbor, subtype_to_ignore);
9046  break;
9047  }
9048  default:
9049  break;
9050  }
9051  return parse_cbor_internal(true, tag_handler);
9052  }
9053 
9054  case cbor_tag_handler_t::store:
9055  {
9056  binary_t b;
9057  // use binary subtype and store in binary container
9058  switch (current)
9059  {
9060  case 0xD8:
9061  {
9062  std::uint8_t subtype{};
9063  get_number(input_format_t::cbor, subtype);
9064  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9065  break;
9066  }
9067  case 0xD9:
9068  {
9069  std::uint16_t subtype{};
9070  get_number(input_format_t::cbor, subtype);
9071  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9072  break;
9073  }
9074  case 0xDA:
9075  {
9076  std::uint32_t subtype{};
9077  get_number(input_format_t::cbor, subtype);
9078  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9079  break;
9080  }
9081  case 0xDB:
9082  {
9083  std::uint64_t subtype{};
9084  get_number(input_format_t::cbor, subtype);
9085  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9086  break;
9087  }
9088  default:
9089  return parse_cbor_internal(true, tag_handler);
9090  }
9091  get();
9092  return get_cbor_binary(b) && sax->binary(b);
9093  }
9094 
9095  default: // LCOV_EXCL_LINE
9096  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9097  return false; // LCOV_EXCL_LINE
9098  }
9099  }
9100 
9101  case 0xF4: // false
9102  return sax->boolean(false);
9103 
9104  case 0xF5: // true
9105  return sax->boolean(true);
9106 
9107  case 0xF6: // null
9108  return sax->null();
9109 
9110  case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9111  {
9112  const auto byte1_raw = get();
9113  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9114  {
9115  return false;
9116  }
9117  const auto byte2_raw = get();
9118  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9119  {
9120  return false;
9121  }
9122 
9123  const auto byte1 = static_cast<unsigned char>(byte1_raw);
9124  const auto byte2 = static_cast<unsigned char>(byte2_raw);
9125 
9126  // code from RFC 7049, Appendix D, Figure 3:
9127  // As half-precision floating-point numbers were only added
9128  // to IEEE 754 in 2008, today's programming platforms often
9129  // still only have limited support for them. It is very
9130  // easy to include at least decoding support for them even
9131  // without such support. An example of a small decoder for
9132  // half-precision floating-point numbers in the C language
9133  // is shown in Fig. 3.
9134  const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
9135  const double val = [&half]
9136  {
9137  const int exp = (half >> 10u) & 0x1Fu;
9138  const unsigned int mant = half & 0x3FFu;
9139  JSON_ASSERT(0 <= exp&& exp <= 32);
9140  JSON_ASSERT(mant <= 1024);
9141  switch (exp)
9142  {
9143  case 0:
9144  return std::ldexp(mant, -24);
9145  case 31:
9146  return (mant == 0)
9147  ? std::numeric_limits<double>::infinity()
9148  : std::numeric_limits<double>::quiet_NaN();
9149  default:
9150  return std::ldexp(mant + 1024, exp - 25);
9151  }
9152  }();
9153  return sax->number_float((half & 0x8000u) != 0
9154  ? static_cast<number_float_t>(-val)
9155  : static_cast<number_float_t>(val), "");
9156  }
9157 
9158  case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9159  {
9160  float number{};
9161  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9162  }
9163 
9164  case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9165  {
9166  double number{};
9167  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9168  }
9169 
9170  default: // anything else (0xFF is handled inside the other types)
9171  {
9172  auto last_token = get_token_string();
9173  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
9174  }
9175  }
9176  }
9177 
9190  {
9191  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
9192  {
9193  return false;
9194  }
9195 
9196  switch (current)
9197  {
9198  // UTF-8 string (0x00..0x17 bytes follow)
9199  case 0x60:
9200  case 0x61:
9201  case 0x62:
9202  case 0x63:
9203  case 0x64:
9204  case 0x65:
9205  case 0x66:
9206  case 0x67:
9207  case 0x68:
9208  case 0x69:
9209  case 0x6A:
9210  case 0x6B:
9211  case 0x6C:
9212  case 0x6D:
9213  case 0x6E:
9214  case 0x6F:
9215  case 0x70:
9216  case 0x71:
9217  case 0x72:
9218  case 0x73:
9219  case 0x74:
9220  case 0x75:
9221  case 0x76:
9222  case 0x77:
9223  {
9224  return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9225  }
9226 
9227  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9228  {
9229  std::uint8_t len{};
9230  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9231  }
9232 
9233  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9234  {
9235  std::uint16_t len{};
9236  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9237  }
9238 
9239  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9240  {
9241  std::uint32_t len{};
9242  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9243  }
9244 
9245  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9246  {
9247  std::uint64_t len{};
9248  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9249  }
9250 
9251  case 0x7F: // UTF-8 string (indefinite length)
9252  {
9253  while (get() != 0xFF)
9254  {
9255  string_t chunk;
9256  if (!get_cbor_string(chunk))
9257  {
9258  return false;
9259  }
9260  result.append(chunk);
9261  }
9262  return true;
9263  }
9264 
9265  default:
9266  {
9267  auto last_token = get_token_string();
9268  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string"), BasicJsonType()));
9269  }
9270  }
9271  }
9272 
9285  {
9286  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
9287  {
9288  return false;
9289  }
9290 
9291  switch (current)
9292  {
9293  // Binary data (0x00..0x17 bytes follow)
9294  case 0x40:
9295  case 0x41:
9296  case 0x42:
9297  case 0x43:
9298  case 0x44:
9299  case 0x45:
9300  case 0x46:
9301  case 0x47:
9302  case 0x48:
9303  case 0x49:
9304  case 0x4A:
9305  case 0x4B:
9306  case 0x4C:
9307  case 0x4D:
9308  case 0x4E:
9309  case 0x4F:
9310  case 0x50:
9311  case 0x51:
9312  case 0x52:
9313  case 0x53:
9314  case 0x54:
9315  case 0x55:
9316  case 0x56:
9317  case 0x57:
9318  {
9319  return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9320  }
9321 
9322  case 0x58: // Binary data (one-byte uint8_t for n follows)
9323  {
9324  std::uint8_t len{};
9325  return get_number(input_format_t::cbor, len) &&
9326  get_binary(input_format_t::cbor, len, result);
9327  }
9328 
9329  case 0x59: // Binary data (two-byte uint16_t for n follow)
9330  {
9331  std::uint16_t len{};
9332  return get_number(input_format_t::cbor, len) &&
9333  get_binary(input_format_t::cbor, len, result);
9334  }
9335 
9336  case 0x5A: // Binary data (four-byte uint32_t for n follow)
9337  {
9338  std::uint32_t len{};
9339  return get_number(input_format_t::cbor, len) &&
9340  get_binary(input_format_t::cbor, len, result);
9341  }
9342 
9343  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9344  {
9345  std::uint64_t len{};
9346  return get_number(input_format_t::cbor, len) &&
9347  get_binary(input_format_t::cbor, len, result);
9348  }
9349 
9350  case 0x5F: // Binary data (indefinite length)
9351  {
9352  while (get() != 0xFF)
9353  {
9354  binary_t chunk;
9355  if (!get_cbor_binary(chunk))
9356  {
9357  return false;
9358  }
9359  result.insert(result.end(), chunk.begin(), chunk.end());
9360  }
9361  return true;
9362  }
9363 
9364  default:
9365  {
9366  auto last_token = get_token_string();
9367  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token, "binary"), BasicJsonType()));
9368  }
9369  }
9370  }
9371 
9378  bool get_cbor_array(const std::size_t len,
9379  const cbor_tag_handler_t tag_handler)
9380  {
9381  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9382  {
9383  return false;
9384  }
9385 
9386  if (len != std::size_t(-1))
9387  {
9388  for (std::size_t i = 0; i < len; ++i)
9389  {
9390  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9391  {
9392  return false;
9393  }
9394  }
9395  }
9396  else
9397  {
9398  while (get() != 0xFF)
9399  {
9400  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
9401  {
9402  return false;
9403  }
9404  }
9405  }
9406 
9407  return sax->end_array();
9408  }
9409 
9416  bool get_cbor_object(const std::size_t len,
9417  const cbor_tag_handler_t tag_handler)
9418  {
9419  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9420  {
9421  return false;
9422  }
9423 
9424  if (len != 0)
9425  {
9426  string_t key;
9427  if (len != std::size_t(-1))
9428  {
9429  for (std::size_t i = 0; i < len; ++i)
9430  {
9431  get();
9432  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9433  {
9434  return false;
9435  }
9436 
9437  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9438  {
9439  return false;
9440  }
9441  key.clear();
9442  }
9443  }
9444  else
9445  {
9446  while (get() != 0xFF)
9447  {
9448  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9449  {
9450  return false;
9451  }
9452 
9453  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9454  {
9455  return false;
9456  }
9457  key.clear();
9458  }
9459  }
9460  }
9461 
9462  return sax->end_object();
9463  }
9464 
9466  // MsgPack //
9468 
9473  {
9474  switch (get())
9475  {
9476  // EOF
9477  case std::char_traits<char_type>::eof():
9478  return unexpect_eof(input_format_t::msgpack, "value");
9479 
9480  // positive fixint
9481  case 0x00:
9482  case 0x01:
9483  case 0x02:
9484  case 0x03:
9485  case 0x04:
9486  case 0x05:
9487  case 0x06:
9488  case 0x07:
9489  case 0x08:
9490  case 0x09:
9491  case 0x0A:
9492  case 0x0B:
9493  case 0x0C:
9494  case 0x0D:
9495  case 0x0E:
9496  case 0x0F:
9497  case 0x10:
9498  case 0x11:
9499  case 0x12:
9500  case 0x13:
9501  case 0x14:
9502  case 0x15:
9503  case 0x16:
9504  case 0x17:
9505  case 0x18:
9506  case 0x19:
9507  case 0x1A:
9508  case 0x1B:
9509  case 0x1C:
9510  case 0x1D:
9511  case 0x1E:
9512  case 0x1F:
9513  case 0x20:
9514  case 0x21:
9515  case 0x22:
9516  case 0x23:
9517  case 0x24:
9518  case 0x25:
9519  case 0x26:
9520  case 0x27:
9521  case 0x28:
9522  case 0x29:
9523  case 0x2A:
9524  case 0x2B:
9525  case 0x2C:
9526  case 0x2D:
9527  case 0x2E:
9528  case 0x2F:
9529  case 0x30:
9530  case 0x31:
9531  case 0x32:
9532  case 0x33:
9533  case 0x34:
9534  case 0x35:
9535  case 0x36:
9536  case 0x37:
9537  case 0x38:
9538  case 0x39:
9539  case 0x3A:
9540  case 0x3B:
9541  case 0x3C:
9542  case 0x3D:
9543  case 0x3E:
9544  case 0x3F:
9545  case 0x40:
9546  case 0x41:
9547  case 0x42:
9548  case 0x43:
9549  case 0x44:
9550  case 0x45:
9551  case 0x46:
9552  case 0x47:
9553  case 0x48:
9554  case 0x49:
9555  case 0x4A:
9556  case 0x4B:
9557  case 0x4C:
9558  case 0x4D:
9559  case 0x4E:
9560  case 0x4F:
9561  case 0x50:
9562  case 0x51:
9563  case 0x52:
9564  case 0x53:
9565  case 0x54:
9566  case 0x55:
9567  case 0x56:
9568  case 0x57:
9569  case 0x58:
9570  case 0x59:
9571  case 0x5A:
9572  case 0x5B:
9573  case 0x5C:
9574  case 0x5D:
9575  case 0x5E:
9576  case 0x5F:
9577  case 0x60:
9578  case 0x61:
9579  case 0x62:
9580  case 0x63:
9581  case 0x64:
9582  case 0x65:
9583  case 0x66:
9584  case 0x67:
9585  case 0x68:
9586  case 0x69:
9587  case 0x6A:
9588  case 0x6B:
9589  case 0x6C:
9590  case 0x6D:
9591  case 0x6E:
9592  case 0x6F:
9593  case 0x70:
9594  case 0x71:
9595  case 0x72:
9596  case 0x73:
9597  case 0x74:
9598  case 0x75:
9599  case 0x76:
9600  case 0x77:
9601  case 0x78:
9602  case 0x79:
9603  case 0x7A:
9604  case 0x7B:
9605  case 0x7C:
9606  case 0x7D:
9607  case 0x7E:
9608  case 0x7F:
9609  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9610 
9611  // fixmap
9612  case 0x80:
9613  case 0x81:
9614  case 0x82:
9615  case 0x83:
9616  case 0x84:
9617  case 0x85:
9618  case 0x86:
9619  case 0x87:
9620  case 0x88:
9621  case 0x89:
9622  case 0x8A:
9623  case 0x8B:
9624  case 0x8C:
9625  case 0x8D:
9626  case 0x8E:
9627  case 0x8F:
9628  return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9629 
9630  // fixarray
9631  case 0x90:
9632  case 0x91:
9633  case 0x92:
9634  case 0x93:
9635  case 0x94:
9636  case 0x95:
9637  case 0x96:
9638  case 0x97:
9639  case 0x98:
9640  case 0x99:
9641  case 0x9A:
9642  case 0x9B:
9643  case 0x9C:
9644  case 0x9D:
9645  case 0x9E:
9646  case 0x9F:
9647  return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9648 
9649  // fixstr
9650  case 0xA0:
9651  case 0xA1:
9652  case 0xA2:
9653  case 0xA3:
9654  case 0xA4:
9655  case 0xA5:
9656  case 0xA6:
9657  case 0xA7:
9658  case 0xA8:
9659  case 0xA9:
9660  case 0xAA:
9661  case 0xAB:
9662  case 0xAC:
9663  case 0xAD:
9664  case 0xAE:
9665  case 0xAF:
9666  case 0xB0:
9667  case 0xB1:
9668  case 0xB2:
9669  case 0xB3:
9670  case 0xB4:
9671  case 0xB5:
9672  case 0xB6:
9673  case 0xB7:
9674  case 0xB8:
9675  case 0xB9:
9676  case 0xBA:
9677  case 0xBB:
9678  case 0xBC:
9679  case 0xBD:
9680  case 0xBE:
9681  case 0xBF:
9682  case 0xD9: // str 8
9683  case 0xDA: // str 16
9684  case 0xDB: // str 32
9685  {
9686  string_t s;
9687  return get_msgpack_string(s) && sax->string(s);
9688  }
9689 
9690  case 0xC0: // nil
9691  return sax->null();
9692 
9693  case 0xC2: // false
9694  return sax->boolean(false);
9695 
9696  case 0xC3: // true
9697  return sax->boolean(true);
9698 
9699  case 0xC4: // bin 8
9700  case 0xC5: // bin 16
9701  case 0xC6: // bin 32
9702  case 0xC7: // ext 8
9703  case 0xC8: // ext 16
9704  case 0xC9: // ext 32
9705  case 0xD4: // fixext 1
9706  case 0xD5: // fixext 2
9707  case 0xD6: // fixext 4
9708  case 0xD7: // fixext 8
9709  case 0xD8: // fixext 16
9710  {
9711  binary_t b;
9712  return get_msgpack_binary(b) && sax->binary(b);
9713  }
9714 
9715  case 0xCA: // float 32
9716  {
9717  float number{};
9718  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9719  }
9720 
9721  case 0xCB: // float 64
9722  {
9723  double number{};
9724  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9725  }
9726 
9727  case 0xCC: // uint 8
9728  {
9729  std::uint8_t number{};
9730  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9731  }
9732 
9733  case 0xCD: // uint 16
9734  {
9735  std::uint16_t number{};
9736  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9737  }
9738 
9739  case 0xCE: // uint 32
9740  {
9741  std::uint32_t number{};
9742  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9743  }
9744 
9745  case 0xCF: // uint 64
9746  {
9747  std::uint64_t number{};
9748  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9749  }
9750 
9751  case 0xD0: // int 8
9752  {
9753  std::int8_t number{};
9754  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9755  }
9756 
9757  case 0xD1: // int 16
9758  {
9759  std::int16_t number{};
9760  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9761  }
9762 
9763  case 0xD2: // int 32
9764  {
9765  std::int32_t number{};
9766  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9767  }
9768 
9769  case 0xD3: // int 64
9770  {
9771  std::int64_t number{};
9772  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9773  }
9774 
9775  case 0xDC: // array 16
9776  {
9777  std::uint16_t len{};
9778  return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9779  }
9780 
9781  case 0xDD: // array 32
9782  {
9783  std::uint32_t len{};
9784  return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9785  }
9786 
9787  case 0xDE: // map 16
9788  {
9789  std::uint16_t len{};
9790  return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9791  }
9792 
9793  case 0xDF: // map 32
9794  {
9795  std::uint32_t len{};
9796  return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9797  }
9798 
9799  // negative fixint
9800  case 0xE0:
9801  case 0xE1:
9802  case 0xE2:
9803  case 0xE3:
9804  case 0xE4:
9805  case 0xE5:
9806  case 0xE6:
9807  case 0xE7:
9808  case 0xE8:
9809  case 0xE9:
9810  case 0xEA:
9811  case 0xEB:
9812  case 0xEC:
9813  case 0xED:
9814  case 0xEE:
9815  case 0xEF:
9816  case 0xF0:
9817  case 0xF1:
9818  case 0xF2:
9819  case 0xF3:
9820  case 0xF4:
9821  case 0xF5:
9822  case 0xF6:
9823  case 0xF7:
9824  case 0xF8:
9825  case 0xF9:
9826  case 0xFA:
9827  case 0xFB:
9828  case 0xFC:
9829  case 0xFD:
9830  case 0xFE:
9831  case 0xFF:
9832  return sax->number_integer(static_cast<std::int8_t>(current));
9833 
9834  default: // anything else
9835  {
9836  auto last_token = get_token_string();
9837  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
9838  }
9839  }
9840  }
9841 
9853  {
9854  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
9855  {
9856  return false;
9857  }
9858 
9859  switch (current)
9860  {
9861  // fixstr
9862  case 0xA0:
9863  case 0xA1:
9864  case 0xA2:
9865  case 0xA3:
9866  case 0xA4:
9867  case 0xA5:
9868  case 0xA6:
9869  case 0xA7:
9870  case 0xA8:
9871  case 0xA9:
9872  case 0xAA:
9873  case 0xAB:
9874  case 0xAC:
9875  case 0xAD:
9876  case 0xAE:
9877  case 0xAF:
9878  case 0xB0:
9879  case 0xB1:
9880  case 0xB2:
9881  case 0xB3:
9882  case 0xB4:
9883  case 0xB5:
9884  case 0xB6:
9885  case 0xB7:
9886  case 0xB8:
9887  case 0xB9:
9888  case 0xBA:
9889  case 0xBB:
9890  case 0xBC:
9891  case 0xBD:
9892  case 0xBE:
9893  case 0xBF:
9894  {
9895  return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
9896  }
9897 
9898  case 0xD9: // str 8
9899  {
9900  std::uint8_t len{};
9901  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9902  }
9903 
9904  case 0xDA: // str 16
9905  {
9906  std::uint16_t len{};
9907  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9908  }
9909 
9910  case 0xDB: // str 32
9911  {
9912  std::uint32_t len{};
9913  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9914  }
9915 
9916  default:
9917  {
9918  auto last_token = get_token_string();
9919  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string"), BasicJsonType()));
9920  }
9921  }
9922  }
9923 
9935  {
9936  // helper function to set the subtype
9937  auto assign_and_return_true = [&result](std::int8_t subtype)
9938  {
9939  result.set_subtype(static_cast<std::uint8_t>(subtype));
9940  return true;
9941  };
9942 
9943  switch (current)
9944  {
9945  case 0xC4: // bin 8
9946  {
9947  std::uint8_t len{};
9948  return get_number(input_format_t::msgpack, len) &&
9949  get_binary(input_format_t::msgpack, len, result);
9950  }
9951 
9952  case 0xC5: // bin 16
9953  {
9954  std::uint16_t len{};
9955  return get_number(input_format_t::msgpack, len) &&
9956  get_binary(input_format_t::msgpack, len, result);
9957  }
9958 
9959  case 0xC6: // bin 32
9960  {
9961  std::uint32_t len{};
9962  return get_number(input_format_t::msgpack, len) &&
9963  get_binary(input_format_t::msgpack, len, result);
9964  }
9965 
9966  case 0xC7: // ext 8
9967  {
9968  std::uint8_t len{};
9969  std::int8_t subtype{};
9970  return get_number(input_format_t::msgpack, len) &&
9971  get_number(input_format_t::msgpack, subtype) &&
9972  get_binary(input_format_t::msgpack, len, result) &&
9973  assign_and_return_true(subtype);
9974  }
9975 
9976  case 0xC8: // ext 16
9977  {
9978  std::uint16_t len{};
9979  std::int8_t subtype{};
9980  return get_number(input_format_t::msgpack, len) &&
9981  get_number(input_format_t::msgpack, subtype) &&
9982  get_binary(input_format_t::msgpack, len, result) &&
9983  assign_and_return_true(subtype);
9984  }
9985 
9986  case 0xC9: // ext 32
9987  {
9988  std::uint32_t len{};
9989  std::int8_t subtype{};
9990  return get_number(input_format_t::msgpack, len) &&
9991  get_number(input_format_t::msgpack, subtype) &&
9992  get_binary(input_format_t::msgpack, len, result) &&
9993  assign_and_return_true(subtype);
9994  }
9995 
9996  case 0xD4: // fixext 1
9997  {
9998  std::int8_t subtype{};
9999  return get_number(input_format_t::msgpack, subtype) &&
10000  get_binary(input_format_t::msgpack, 1, result) &&
10001  assign_and_return_true(subtype);
10002  }
10003 
10004  case 0xD5: // fixext 2
10005  {
10006  std::int8_t subtype{};
10007  return get_number(input_format_t::msgpack, subtype) &&
10008  get_binary(input_format_t::msgpack, 2, result) &&
10009  assign_and_return_true(subtype);
10010  }
10011 
10012  case 0xD6: // fixext 4
10013  {
10014  std::int8_t subtype{};
10015  return get_number(input_format_t::msgpack, subtype) &&
10016  get_binary(input_format_t::msgpack, 4, result) &&
10017  assign_and_return_true(subtype);
10018  }
10019 
10020  case 0xD7: // fixext 8
10021  {
10022  std::int8_t subtype{};
10023  return get_number(input_format_t::msgpack, subtype) &&
10024  get_binary(input_format_t::msgpack, 8, result) &&
10025  assign_and_return_true(subtype);
10026  }
10027 
10028  case 0xD8: // fixext 16
10029  {
10030  std::int8_t subtype{};
10031  return get_number(input_format_t::msgpack, subtype) &&
10032  get_binary(input_format_t::msgpack, 16, result) &&
10033  assign_and_return_true(subtype);
10034  }
10035 
10036  default: // LCOV_EXCL_LINE
10037  return false; // LCOV_EXCL_LINE
10038  }
10039  }
10040 
10045  bool get_msgpack_array(const std::size_t len)
10046  {
10047  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10048  {
10049  return false;
10050  }
10051 
10052  for (std::size_t i = 0; i < len; ++i)
10053  {
10054  if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10055  {
10056  return false;
10057  }
10058  }
10059 
10060  return sax->end_array();
10061  }
10062 
10067  bool get_msgpack_object(const std::size_t len)
10068  {
10069  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10070  {
10071  return false;
10072  }
10073 
10074  string_t key;
10075  for (std::size_t i = 0; i < len; ++i)
10076  {
10077  get();
10078  if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
10079  {
10080  return false;
10081  }
10082 
10083  if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10084  {
10085  return false;
10086  }
10087  key.clear();
10088  }
10089 
10090  return sax->end_object();
10091  }
10092 
10094  // UBJSON //
10096 
10104  bool parse_ubjson_internal(const bool get_char = true)
10105  {
10106  return get_ubjson_value(get_char ? get_ignore_noop() : current);
10107  }
10108 
10123  bool get_ubjson_string(string_t& result, const bool get_char = true)
10124  {
10125  if (get_char)
10126  {
10127  get(); // TODO(niels): may we ignore N here?
10128  }
10129 
10130  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
10131  {
10132  return false;
10133  }
10134 
10135  switch (current)
10136  {
10137  case 'U':
10138  {
10139  std::uint8_t len{};
10140  return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10141  }
10142 
10143  case 'i':
10144  {
10145  std::int8_t len{};
10146  return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10147  }
10148 
10149  case 'I':
10150  {
10151  std::int16_t len{};
10152  return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10153  }
10154 
10155  case 'l':
10156  {
10157  std::int32_t len{};
10158  return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10159  }
10160 
10161  case 'L':
10162  {
10163  std::int64_t len{};
10164  return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10165  }
10166 
10167  default:
10168  auto last_token = get_token_string();
10169  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string"), BasicJsonType()));
10170  }
10171  }
10172 
10177  bool get_ubjson_size_value(std::size_t& result)
10178  {
10179  switch (get_ignore_noop())
10180  {
10181  case 'U':
10182  {
10183  std::uint8_t number{};
10184  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10185  {
10186  return false;
10187  }
10188  result = static_cast<std::size_t>(number);
10189  return true;
10190  }
10191 
10192  case 'i':
10193  {
10194  std::int8_t number{};
10195  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10196  {
10197  return false;
10198  }
10199  result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
10200  return true;
10201  }
10202 
10203  case 'I':
10204  {
10205  std::int16_t number{};
10206  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10207  {
10208  return false;
10209  }
10210  result = static_cast<std::size_t>(number);
10211  return true;
10212  }
10213 
10214  case 'l':
10215  {
10216  std::int32_t number{};
10217  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10218  {
10219  return false;
10220  }
10221  result = static_cast<std::size_t>(number);
10222  return true;
10223  }
10224 
10225  case 'L':
10226  {
10227  std::int64_t number{};
10228  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10229  {
10230  return false;
10231  }
10232  result = static_cast<std::size_t>(number);
10233  return true;
10234  }
10235 
10236  default:
10237  {
10238  auto last_token = get_token_string();
10239  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size"), BasicJsonType()));
10240  }
10241  }
10242  }
10243 
10254  bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
10255  {
10256  result.first = string_t::npos; // size
10257  result.second = 0; // type
10258 
10259  get_ignore_noop();
10260 
10261  if (current == '$')
10262  {
10263  result.second = get(); // must not ignore 'N', because 'N' maybe the type
10264  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type")))
10265  {
10266  return false;
10267  }
10268 
10269  get_ignore_noop();
10270  if (JSON_HEDLEY_UNLIKELY(current != '#'))
10271  {
10272  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
10273  {
10274  return false;
10275  }
10276  auto last_token = get_token_string();
10277  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size"), BasicJsonType()));
10278  }
10279 
10280  return get_ubjson_size_value(result.first);
10281  }
10282 
10283  if (current == '#')
10284  {
10285  return get_ubjson_size_value(result.first);
10286  }
10287 
10288  return true;
10289  }
10290 
10295  bool get_ubjson_value(const char_int_type prefix)
10296  {
10297  switch (prefix)
10298  {
10299  case std::char_traits<char_type>::eof(): // EOF
10300  return unexpect_eof(input_format_t::ubjson, "value");
10301 
10302  case 'T': // true
10303  return sax->boolean(true);
10304  case 'F': // false
10305  return sax->boolean(false);
10306 
10307  case 'Z': // null
10308  return sax->null();
10309 
10310  case 'U':
10311  {
10312  std::uint8_t number{};
10313  return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
10314  }
10315 
10316  case 'i':
10317  {
10318  std::int8_t number{};
10319  return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10320  }
10321 
10322  case 'I':
10323  {
10324  std::int16_t number{};
10325  return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10326  }
10327 
10328  case 'l':
10329  {
10330  std::int32_t number{};
10331  return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10332  }
10333 
10334  case 'L':
10335  {
10336  std::int64_t number{};
10337  return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10338  }
10339 
10340  case 'd':
10341  {
10342  float number{};
10343  return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10344  }
10345 
10346  case 'D':
10347  {
10348  double number{};
10349  return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10350  }
10351 
10352  case 'H':
10353  {
10354  return get_ubjson_high_precision_number();
10355  }
10356 
10357  case 'C': // char
10358  {
10359  get();
10360  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char")))
10361  {
10362  return false;
10363  }
10364  if (JSON_HEDLEY_UNLIKELY(current > 127))
10365  {
10366  auto last_token = get_token_string();
10367  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char"), BasicJsonType()));
10368  }
10369  string_t s(1, static_cast<typename string_t::value_type>(current));
10370  return sax->string(s);
10371  }
10372 
10373  case 'S': // string
10374  {
10375  string_t s;
10376  return get_ubjson_string(s) && sax->string(s);
10377  }
10378 
10379  case '[': // array
10380  return get_ubjson_array();
10381 
10382  case '{': // object
10383  return get_ubjson_object();
10384 
10385  default: // anything else
10386  {
10387  auto last_token = get_token_string();
10388  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
10389  }
10390  }
10391  }
10392 
10397  {
10398  std::pair<std::size_t, char_int_type> size_and_type;
10399  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10400  {
10401  return false;
10402  }
10403 
10404  if (size_and_type.first != string_t::npos)
10405  {
10406  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
10407  {
10408  return false;
10409  }
10410 
10411  if (size_and_type.second != 0)
10412  {
10413  if (size_and_type.second != 'N')
10414  {
10415  for (std::size_t i = 0; i < size_and_type.first; ++i)
10416  {
10417  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10418  {
10419  return false;
10420  }
10421  }
10422  }
10423  }
10424  else
10425  {
10426  for (std::size_t i = 0; i < size_and_type.first; ++i)
10427  {
10428  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10429  {
10430  return false;
10431  }
10432  }
10433  }
10434  }
10435  else
10436  {
10437  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10438  {
10439  return false;
10440  }
10441 
10442  while (current != ']')
10443  {
10444  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
10445  {
10446  return false;
10447  }
10448  get_ignore_noop();
10449  }
10450  }
10451 
10452  return sax->end_array();
10453  }
10454 
10459  {
10460  std::pair<std::size_t, char_int_type> size_and_type;
10461  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10462  {
10463  return false;
10464  }
10465 
10466  string_t key;
10467  if (size_and_type.first != string_t::npos)
10468  {
10469  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
10470  {
10471  return false;
10472  }
10473 
10474  if (size_and_type.second != 0)
10475  {
10476  for (std::size_t i = 0; i < size_and_type.first; ++i)
10477  {
10478  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10479  {
10480  return false;
10481  }
10482  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10483  {
10484  return false;
10485  }
10486  key.clear();
10487  }
10488  }
10489  else
10490  {
10491  for (std::size_t i = 0; i < size_and_type.first; ++i)
10492  {
10493  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10494  {
10495  return false;
10496  }
10497  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10498  {
10499  return false;
10500  }
10501  key.clear();
10502  }
10503  }
10504  }
10505  else
10506  {
10507  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10508  {
10509  return false;
10510  }
10511 
10512  while (current != '}')
10513  {
10514  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
10515  {
10516  return false;
10517  }
10518  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10519  {
10520  return false;
10521  }
10522  get_ignore_noop();
10523  key.clear();
10524  }
10525  }
10526 
10527  return sax->end_object();
10528  }
10529 
10530  // Note, no reader for UBJSON binary types is implemented because they do
10531  // not exist
10532 
10534  {
10535  // get size of following number string
10536  std::size_t size{};
10537  auto res = get_ubjson_size_value(size);
10538  if (JSON_HEDLEY_UNLIKELY(!res))
10539  {
10540  return res;
10541  }
10542 
10543  // get number string
10544  std::vector<char> number_vector;
10545  for (std::size_t i = 0; i < size; ++i)
10546  {
10547  get();
10548  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number")))
10549  {
10550  return false;
10551  }
10552  number_vector.push_back(static_cast<char>(current));
10553  }
10554 
10555  // parse number string
10556  using ia_type = decltype(detail::input_adapter(number_vector));
10557  auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
10558  const auto result_number = number_lexer.scan();
10559  const auto number_string = number_lexer.get_token_string();
10560  const auto result_remainder = number_lexer.scan();
10561 
10562  using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
10563 
10564  if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
10565  {
10566  return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType()));
10567  }
10568 
10569  switch (result_number)
10570  {
10571  case token_type::value_integer:
10572  return sax->number_integer(number_lexer.get_number_integer());
10573  case token_type::value_unsigned:
10574  return sax->number_unsigned(number_lexer.get_number_unsigned());
10575  case token_type::value_float:
10576  return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
10577  case token_type::uninitialized:
10578  case token_type::literal_true:
10579  case token_type::literal_false:
10580  case token_type::literal_null:
10581  case token_type::value_string:
10582  case token_type::begin_array:
10583  case token_type::begin_object:
10584  case token_type::end_array:
10585  case token_type::end_object:
10586  case token_type::name_separator:
10587  case token_type::value_separator:
10588  case token_type::parse_error:
10589  case token_type::end_of_input:
10590  case token_type::literal_or_value:
10591  default:
10592  return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType()));
10593  }
10594  }
10595 
10597  // Utility functions //
10599 
10610  {
10611  ++chars_read;
10612  return current = ia.get_character();
10613  }
10614 
10619  {
10620  do
10621  {
10622  get();
10623  }
10624  while (current == 'N');
10625 
10626  return current;
10627  }
10628 
10629  /*
10630  @brief read a number from the input
10631 
10632  @tparam NumberType the type of the number
10633  @param[in] format the current format (for diagnostics)
10634  @param[out] result number of type @a NumberType
10635 
10636  @return whether conversion completed
10637 
10638  @note This function needs to respect the system's endianess, because
10639  bytes in CBOR, MessagePack, and UBJSON are stored in network order
10640  (big endian) and therefore need reordering on little endian systems.
10641  */
10642  template<typename NumberType, bool InputIsLittleEndian = false>
10643  bool get_number(const input_format_t format, NumberType& result)
10644  {
10645  // step 1: read input into array with system's byte order
10646  std::array<std::uint8_t, sizeof(NumberType)> vec{};
10647  for (std::size_t i = 0; i < sizeof(NumberType); ++i)
10648  {
10649  get();
10650  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
10651  {
10652  return false;
10653  }
10654 
10655  // reverse byte order prior to conversion if necessary
10656  if (is_little_endian != InputIsLittleEndian)
10657  {
10658  vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
10659  }
10660  else
10661  {
10662  vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
10663  }
10664  }
10665 
10666  // step 2: convert array into number of type T and return
10667  std::memcpy(&result, vec.data(), sizeof(NumberType));
10668  return true;
10669  }
10670 
10685  template<typename NumberType>
10686  bool get_string(const input_format_t format,
10687  const NumberType len,
10688  string_t& result)
10689  {
10690  bool success = true;
10691  for (NumberType i = 0; i < len; i++)
10692  {
10693  get();
10694  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
10695  {
10696  success = false;
10697  break;
10698  }
10699  result.push_back(static_cast<typename string_t::value_type>(current));
10700  }
10701  return success;
10702  }
10703 
10718  template<typename NumberType>
10719  bool get_binary(const input_format_t format,
10720  const NumberType len,
10721  binary_t& result)
10722  {
10723  bool success = true;
10724  for (NumberType i = 0; i < len; i++)
10725  {
10726  get();
10727  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10728  {
10729  success = false;
10730  break;
10731  }
10732  result.push_back(static_cast<std::uint8_t>(current));
10733  }
10734  return success;
10735  }
10736 
10743  bool unexpect_eof(const input_format_t format, const char* context) const
10744  {
10745  if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
10746  {
10747  return sax->parse_error(chars_read, "<end of file>",
10748  parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), BasicJsonType()));
10749  }
10750  return true;
10751  }
10752 
10756  std::string get_token_string() const
10757  {
10758  std::array<char, 3> cr{{}};
10759  (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
10760  return std::string{cr.data()};
10761  }
10762 
10769  std::string exception_message(const input_format_t format,
10770  const std::string& detail,
10771  const std::string& context) const
10772  {
10773  std::string error_msg = "syntax error while parsing ";
10774 
10775  switch (format)
10776  {
10777  case input_format_t::cbor:
10778  error_msg += "CBOR";
10779  break;
10780 
10781  case input_format_t::msgpack:
10782  error_msg += "MessagePack";
10783  break;
10784 
10785  case input_format_t::ubjson:
10786  error_msg += "UBJSON";
10787  break;
10788 
10789  case input_format_t::bson:
10790  error_msg += "BSON";
10791  break;
10792 
10793  case input_format_t::json: // LCOV_EXCL_LINE
10794  default: // LCOV_EXCL_LINE
10795  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
10796  }
10797 
10798  return error_msg + " " + context + ": " + detail;
10799  }
10800 
10801  private:
10803  InputAdapterType ia;
10804 
10806  char_int_type current = std::char_traits<char_type>::eof();
10807 
10809  std::size_t chars_read = 0;
10810 
10812  const bool is_little_endian = little_endianess();
10813 
10815  json_sax_t* sax = nullptr;
10816 };
10817 } // namespace detail
10818 } // namespace nlohmann
10819 
10820 // #include <nlohmann/detail/input/input_adapters.hpp>
10821 
10822 // #include <nlohmann/detail/input/lexer.hpp>
10823 
10824 // #include <nlohmann/detail/input/parser.hpp>
10825 
10826 
10827 #include <cmath> // isfinite
10828 #include <cstdint> // uint8_t
10829 #include <functional> // function
10830 #include <string> // string
10831 #include <utility> // move
10832 #include <vector> // vector
10833 
10834 // #include <nlohmann/detail/exceptions.hpp>
10835 
10836 // #include <nlohmann/detail/input/input_adapters.hpp>
10837 
10838 // #include <nlohmann/detail/input/json_sax.hpp>
10839 
10840 // #include <nlohmann/detail/input/lexer.hpp>
10841 
10842 // #include <nlohmann/detail/macro_scope.hpp>
10843 
10844 // #include <nlohmann/detail/meta/is_sax.hpp>
10845 
10846 // #include <nlohmann/detail/value_t.hpp>
10847 
10848 
10849 namespace nlohmann
10850 {
10851 namespace detail
10852 {
10854 // parser //
10856 
10857 enum class parse_event_t : std::uint8_t
10858 {
10860  object_start,
10862  object_end,
10864  array_start,
10866  array_end,
10868  key,
10870  value
10871 };
10872 
10873 template<typename BasicJsonType>
10874 using parser_callback_t =
10875  std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
10876 
10882 template<typename BasicJsonType, typename InputAdapterType>
10883 class parser
10884 {
10885  using number_integer_t = typename BasicJsonType::number_integer_t;
10886  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10887  using number_float_t = typename BasicJsonType::number_float_t;
10888  using string_t = typename BasicJsonType::string_t;
10891 
10892  public:
10894  explicit parser(InputAdapterType&& adapter,
10895  const parser_callback_t<BasicJsonType> cb = nullptr,
10896  const bool allow_exceptions_ = true,
10897  const bool skip_comments = false)
10898  : callback(cb)
10899  , m_lexer(std::move(adapter), skip_comments)
10900  , allow_exceptions(allow_exceptions_)
10901  {
10902  // read first token
10903  get_token();
10904  }
10905 
10916  void parse(const bool strict, BasicJsonType& result)
10917  {
10918  if (callback)
10919  {
10920  json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
10921  sax_parse_internal(&sdp);
10922 
10923  // in strict mode, input must be completely read
10924  if (strict && (get_token() != token_type::end_of_input))
10925  {
10926  sdp.parse_error(m_lexer.get_position(),
10927  m_lexer.get_token_string(),
10928  parse_error::create(101, m_lexer.get_position(),
10929  exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10930  }
10931 
10932  // in case of an error, return discarded value
10933  if (sdp.is_errored())
10934  {
10935  result = value_t::discarded;
10936  return;
10937  }
10938 
10939  // set top-level value to null if it was discarded by the callback
10940  // function
10941  if (result.is_discarded())
10942  {
10943  result = nullptr;
10944  }
10945  }
10946  else
10947  {
10948  json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
10949  sax_parse_internal(&sdp);
10950 
10951  // in strict mode, input must be completely read
10952  if (strict && (get_token() != token_type::end_of_input))
10953  {
10954  sdp.parse_error(m_lexer.get_position(),
10955  m_lexer.get_token_string(),
10956  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10957  }
10958 
10959  // in case of an error, return discarded value
10960  if (sdp.is_errored())
10961  {
10962  result = value_t::discarded;
10963  return;
10964  }
10965  }
10966 
10967  result.assert_invariant();
10968  }
10969 
10976  bool accept(const bool strict = true)
10977  {
10978  json_sax_acceptor<BasicJsonType> sax_acceptor;
10979  return sax_parse(&sax_acceptor, strict);
10980  }
10981 
10982  template<typename SAX>
10984  bool sax_parse(SAX* sax, const bool strict = true)
10985  {
10987  const bool result = sax_parse_internal(sax);
10988 
10989  // strict mode: next byte must be EOF
10990  if (result && strict && (get_token() != token_type::end_of_input))
10991  {
10992  return sax->parse_error(m_lexer.get_position(),
10993  m_lexer.get_token_string(),
10994  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10995  }
10996 
10997  return result;
10998  }
10999 
11000  private:
11001  template<typename SAX>
11003  bool sax_parse_internal(SAX* sax)
11004  {
11005  // stack to remember the hierarchy of structured values we are parsing
11006  // true = array; false = object
11007  std::vector<bool> states;
11008  // value to avoid a goto (see comment where set to true)
11009  bool skip_to_state_evaluation = false;
11010 
11011  while (true)
11012  {
11013  if (!skip_to_state_evaluation)
11014  {
11015  // invariant: get_token() was called before each iteration
11016  switch (last_token)
11017  {
11018  case token_type::begin_object:
11019  {
11020  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
11021  {
11022  return false;
11023  }
11024 
11025  // closing } -> we are done
11026  if (get_token() == token_type::end_object)
11027  {
11028  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11029  {
11030  return false;
11031  }
11032  break;
11033  }
11034 
11035  // parse key
11036  if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
11037  {
11038  return sax->parse_error(m_lexer.get_position(),
11039  m_lexer.get_token_string(),
11040  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11041  }
11042  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11043  {
11044  return false;
11045  }
11046 
11047  // parse separator (:)
11048  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11049  {
11050  return sax->parse_error(m_lexer.get_position(),
11051  m_lexer.get_token_string(),
11052  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11053  }
11054 
11055  // remember we are now inside an object
11056  states.push_back(false);
11057 
11058  // parse values
11059  get_token();
11060  continue;
11061  }
11062 
11063  case token_type::begin_array:
11064  {
11065  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
11066  {
11067  return false;
11068  }
11069 
11070  // closing ] -> we are done
11071  if (get_token() == token_type::end_array)
11072  {
11073  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11074  {
11075  return false;
11076  }
11077  break;
11078  }
11079 
11080  // remember we are now inside an array
11081  states.push_back(true);
11082 
11083  // parse values (no need to call get_token)
11084  continue;
11085  }
11086 
11087  case token_type::value_float:
11088  {
11089  const auto res = m_lexer.get_number_float();
11090 
11091  if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
11092  {
11093  return sax->parse_error(m_lexer.get_position(),
11094  m_lexer.get_token_string(),
11095  out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType()));
11096  }
11097 
11098  if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
11099  {
11100  return false;
11101  }
11102 
11103  break;
11104  }
11105 
11106  case token_type::literal_false:
11107  {
11108  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
11109  {
11110  return false;
11111  }
11112  break;
11113  }
11114 
11115  case token_type::literal_null:
11116  {
11117  if (JSON_HEDLEY_UNLIKELY(!sax->null()))
11118  {
11119  return false;
11120  }
11121  break;
11122  }
11123 
11124  case token_type::literal_true:
11125  {
11126  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
11127  {
11128  return false;
11129  }
11130  break;
11131  }
11132 
11133  case token_type::value_integer:
11134  {
11135  if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
11136  {
11137  return false;
11138  }
11139  break;
11140  }
11141 
11142  case token_type::value_string:
11143  {
11144  if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
11145  {
11146  return false;
11147  }
11148  break;
11149  }
11150 
11151  case token_type::value_unsigned:
11152  {
11153  if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
11154  {
11155  return false;
11156  }
11157  break;
11158  }
11159 
11160  case token_type::parse_error:
11161  {
11162  // using "uninitialized" to avoid "expected" message
11163  return sax->parse_error(m_lexer.get_position(),
11164  m_lexer.get_token_string(),
11165  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType()));
11166  }
11167 
11168  case token_type::uninitialized:
11169  case token_type::end_array:
11170  case token_type::end_object:
11171  case token_type::name_separator:
11172  case token_type::value_separator:
11173  case token_type::end_of_input:
11174  case token_type::literal_or_value:
11175  default: // the last token was unexpected
11176  {
11177  return sax->parse_error(m_lexer.get_position(),
11178  m_lexer.get_token_string(),
11179  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), BasicJsonType()));
11180  }
11181  }
11182  }
11183  else
11184  {
11185  skip_to_state_evaluation = false;
11186  }
11187 
11188  // we reached this line after we successfully parsed a value
11189  if (states.empty())
11190  {
11191  // empty stack: we reached the end of the hierarchy: done
11192  return true;
11193  }
11194 
11195  if (states.back()) // array
11196  {
11197  // comma -> next value
11198  if (get_token() == token_type::value_separator)
11199  {
11200  // parse a new value
11201  get_token();
11202  continue;
11203  }
11204 
11205  // closing ]
11206  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
11207  {
11208  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11209  {
11210  return false;
11211  }
11212 
11213  // We are done with this array. Before we can parse a
11214  // new value, we need to evaluate the new state first.
11215  // By setting skip_to_state_evaluation to false, we
11216  // are effectively jumping to the beginning of this if.
11217  JSON_ASSERT(!states.empty());
11218  states.pop_back();
11219  skip_to_state_evaluation = true;
11220  continue;
11221  }
11222 
11223  return sax->parse_error(m_lexer.get_position(),
11224  m_lexer.get_token_string(),
11225  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), BasicJsonType()));
11226  }
11227 
11228  // states.back() is false -> object
11229 
11230  // comma -> next value
11231  if (get_token() == token_type::value_separator)
11232  {
11233  // parse key
11234  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
11235  {
11236  return sax->parse_error(m_lexer.get_position(),
11237  m_lexer.get_token_string(),
11238  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11239  }
11240 
11241  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11242  {
11243  return false;
11244  }
11245 
11246  // parse separator (:)
11247  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11248  {
11249  return sax->parse_error(m_lexer.get_position(),
11250  m_lexer.get_token_string(),
11251  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11252  }
11253 
11254  // parse values
11255  get_token();
11256  continue;
11257  }
11258 
11259  // closing }
11260  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
11261  {
11262  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11263  {
11264  return false;
11265  }
11266 
11267  // We are done with this object. Before we can parse a
11268  // new value, we need to evaluate the new state first.
11269  // By setting skip_to_state_evaluation to false, we
11270  // are effectively jumping to the beginning of this if.
11271  JSON_ASSERT(!states.empty());
11272  states.pop_back();
11273  skip_to_state_evaluation = true;
11274  continue;
11275  }
11276 
11277  return sax->parse_error(m_lexer.get_position(),
11278  m_lexer.get_token_string(),
11279  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), BasicJsonType()));
11280  }
11281  }
11282 
11285  {
11286  return last_token = m_lexer.scan();
11287  }
11288 
11289  std::string exception_message(const token_type expected, const std::string& context)
11290  {
11291  std::string error_msg = "syntax error ";
11292 
11293  if (!context.empty())
11294  {
11295  error_msg += "while parsing " + context + " ";
11296  }
11297 
11298  error_msg += "- ";
11299 
11300  if (last_token == token_type::parse_error)
11301  {
11302  error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
11303  m_lexer.get_token_string() + "'";
11304  }
11305  else
11306  {
11307  error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
11308  }
11309 
11310  if (expected != token_type::uninitialized)
11311  {
11312  error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
11313  }
11314 
11315  return error_msg;
11316  }
11317 
11318  private:
11320  const parser_callback_t<BasicJsonType> callback = nullptr;
11322  token_type last_token = token_type::uninitialized;
11326  const bool allow_exceptions = true;
11327 };
11328 
11329 } // namespace detail
11330 } // namespace nlohmann
11331 
11332 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
11333 
11334 
11335 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11336 
11337 
11338 #include <cstddef> // ptrdiff_t
11339 #include <limits> // numeric_limits
11340 
11341 // #include <nlohmann/detail/macro_scope.hpp>
11342 
11343 
11344 namespace nlohmann
11345 {
11346 namespace detail
11347 {
11348 /*
11349 @brief an iterator for primitive JSON types
11350 
11351 This class models an iterator for primitive JSON types (boolean, number,
11352 string). It's only purpose is to allow the iterator/const_iterator classes
11353 to "iterate" over primitive values. Internally, the iterator is modeled by
11354 a `difference_type` variable. Value begin_value (`0`) models the begin,
11355 end_value (`1`) models past the end.
11356 */
11358 {
11359  private:
11360  using difference_type = std::ptrdiff_t;
11361  static constexpr difference_type begin_value = 0;
11362  static constexpr difference_type end_value = begin_value + 1;
11363 
11366  difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
11367 
11368  public:
11369  constexpr difference_type get_value() const noexcept
11370  {
11371  return m_it;
11372  }
11373 
11375  void set_begin() noexcept
11376  {
11377  m_it = begin_value;
11378  }
11379 
11381  void set_end() noexcept
11382  {
11383  m_it = end_value;
11384  }
11385 
11387  constexpr bool is_begin() const noexcept
11388  {
11389  return m_it == begin_value;
11390  }
11391 
11393  constexpr bool is_end() const noexcept
11394  {
11395  return m_it == end_value;
11396  }
11397 
11398  friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11399  {
11400  return lhs.m_it == rhs.m_it;
11401  }
11402 
11403  friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11404  {
11405  return lhs.m_it < rhs.m_it;
11406  }
11407 
11409  {
11410  auto result = *this;
11411  result += n;
11412  return result;
11413  }
11414 
11416  {
11417  return lhs.m_it - rhs.m_it;
11418  }
11419 
11421  {
11422  ++m_it;
11423  return *this;
11424  }
11425 
11426  primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)
11427  {
11428  auto result = *this;
11429  ++m_it;
11430  return result;
11431  }
11432 
11434  {
11435  --m_it;
11436  return *this;
11437  }
11438 
11439  primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)
11440  {
11441  auto result = *this;
11442  --m_it;
11443  return result;
11444  }
11445 
11447  {
11448  m_it += n;
11449  return *this;
11450  }
11451 
11453  {
11454  m_it -= n;
11455  return *this;
11456  }
11457 };
11458 } // namespace detail
11459 } // namespace nlohmann
11460 
11461 
11462 namespace nlohmann
11463 {
11464 namespace detail
11465 {
11472 template<typename BasicJsonType> struct internal_iterator
11473 {
11475  typename BasicJsonType::object_t::iterator object_iterator {};
11477  typename BasicJsonType::array_t::iterator array_iterator {};
11479  primitive_iterator_t primitive_iterator {};
11480 };
11481 } // namespace detail
11482 } // namespace nlohmann
11483 
11484 // #include <nlohmann/detail/iterators/iter_impl.hpp>
11485 
11486 
11487 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
11488 #include <type_traits> // conditional, is_const, remove_const
11489 
11490 // #include <nlohmann/detail/exceptions.hpp>
11491 
11492 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
11493 
11494 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11495 
11496 // #include <nlohmann/detail/macro_scope.hpp>
11497 
11498 // #include <nlohmann/detail/meta/cpp_future.hpp>
11499 
11500 // #include <nlohmann/detail/meta/type_traits.hpp>
11501 
11502 // #include <nlohmann/detail/value_t.hpp>
11503 
11504 
11505 namespace nlohmann
11506 {
11507 namespace detail
11508 {
11509 // forward declare, to be able to friend it later on
11510 template<typename IteratorType> class iteration_proxy;
11511 template<typename IteratorType> class iteration_proxy_value;
11512 
11529 template<typename BasicJsonType>
11531 {
11533  using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
11539 
11540  using object_t = typename BasicJsonType::object_t;
11541  using array_t = typename BasicJsonType::array_t;
11542  // make sure BasicJsonType is basic_json or const basic_json
11543  static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
11544  "iter_impl only accepts (const) basic_json");
11545 
11546  public:
11547 
11553  using iterator_category = std::bidirectional_iterator_tag;
11554 
11556  using value_type = typename BasicJsonType::value_type;
11558  using difference_type = typename BasicJsonType::difference_type;
11560  using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
11561  typename BasicJsonType::const_pointer,
11562  typename BasicJsonType::pointer>::type;
11564  using reference =
11565  typename std::conditional<std::is_const<BasicJsonType>::value,
11566  typename BasicJsonType::const_reference,
11567  typename BasicJsonType::reference>::type;
11568 
11569  iter_impl() = default;
11570  ~iter_impl() = default;
11571  iter_impl(iter_impl&&) noexcept = default;
11572  iter_impl& operator=(iter_impl&&) noexcept = default;
11573 
11580  explicit iter_impl(pointer object) noexcept : m_object(object)
11581  {
11582  JSON_ASSERT(m_object != nullptr);
11583 
11584  switch (m_object->m_type)
11585  {
11586  case value_t::object:
11587  {
11588  m_it.object_iterator = typename object_t::iterator();
11589  break;
11590  }
11591 
11592  case value_t::array:
11593  {
11594  m_it.array_iterator = typename array_t::iterator();
11595  break;
11596  }
11597 
11598  case value_t::null:
11599  case value_t::string:
11600  case value_t::boolean:
11601  case value_t::number_integer:
11602  case value_t::number_unsigned:
11603  case value_t::number_float:
11604  case value_t::binary:
11605  case value_t::discarded:
11606  default:
11607  {
11608  m_it.primitive_iterator = primitive_iterator_t();
11609  break;
11610  }
11611  }
11612  }
11613 
11631  : m_object(other.m_object), m_it(other.m_it)
11632  {}
11633 
11641  {
11642  if (&other != this)
11643  {
11644  m_object = other.m_object;
11645  m_it = other.m_it;
11646  }
11647  return *this;
11648  }
11649 
11655  iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
11656  : m_object(other.m_object), m_it(other.m_it)
11657  {}
11658 
11665  iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
11666  {
11667  m_object = other.m_object;
11668  m_it = other.m_it;
11669  return *this;
11670  }
11671 
11677  void set_begin() noexcept
11678  {
11679  JSON_ASSERT(m_object != nullptr);
11680 
11681  switch (m_object->m_type)
11682  {
11683  case value_t::object:
11684  {
11685  m_it.object_iterator = m_object->m_value.object->begin();
11686  break;
11687  }
11688 
11689  case value_t::array:
11690  {
11691  m_it.array_iterator = m_object->m_value.array->begin();
11692  break;
11693  }
11694 
11695  case value_t::null:
11696  {
11697  // set to end so begin()==end() is true: null is empty
11698  m_it.primitive_iterator.set_end();
11699  break;
11700  }
11701 
11702  case value_t::string:
11703  case value_t::boolean:
11704  case value_t::number_integer:
11705  case value_t::number_unsigned:
11706  case value_t::number_float:
11707  case value_t::binary:
11708  case value_t::discarded:
11709  default:
11710  {
11711  m_it.primitive_iterator.set_begin();
11712  break;
11713  }
11714  }
11715  }
11716 
11721  void set_end() noexcept
11722  {
11723  JSON_ASSERT(m_object != nullptr);
11724 
11725  switch (m_object->m_type)
11726  {
11727  case value_t::object:
11728  {
11729  m_it.object_iterator = m_object->m_value.object->end();
11730  break;
11731  }
11732 
11733  case value_t::array:
11734  {
11735  m_it.array_iterator = m_object->m_value.array->end();
11736  break;
11737  }
11738 
11739  case value_t::null:
11740  case value_t::string:
11741  case value_t::boolean:
11742  case value_t::number_integer:
11743  case value_t::number_unsigned:
11744  case value_t::number_float:
11745  case value_t::binary:
11746  case value_t::discarded:
11747  default:
11748  {
11749  m_it.primitive_iterator.set_end();
11750  break;
11751  }
11752  }
11753  }
11754 
11755  public:
11761  {
11762  JSON_ASSERT(m_object != nullptr);
11763 
11764  switch (m_object->m_type)
11765  {
11766  case value_t::object:
11767  {
11768  JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11769  return m_it.object_iterator->second;
11770  }
11771 
11772  case value_t::array:
11773  {
11774  JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11775  return *m_it.array_iterator;
11776  }
11777 
11778  case value_t::null:
11779  JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11780 
11781  case value_t::string:
11782  case value_t::boolean:
11783  case value_t::number_integer:
11784  case value_t::number_unsigned:
11785  case value_t::number_float:
11786  case value_t::binary:
11787  case value_t::discarded:
11788  default:
11789  {
11790  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11791  {
11792  return *m_object;
11793  }
11794 
11795  JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11796  }
11797  }
11798  }
11799 
11805  {
11806  JSON_ASSERT(m_object != nullptr);
11807 
11808  switch (m_object->m_type)
11809  {
11810  case value_t::object:
11811  {
11812  JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11813  return &(m_it.object_iterator->second);
11814  }
11815 
11816  case value_t::array:
11817  {
11818  JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11819  return &*m_it.array_iterator;
11820  }
11821 
11822  case value_t::null:
11823  case value_t::string:
11824  case value_t::boolean:
11825  case value_t::number_integer:
11826  case value_t::number_unsigned:
11827  case value_t::number_float:
11828  case value_t::binary:
11829  case value_t::discarded:
11830  default:
11831  {
11832  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11833  {
11834  return m_object;
11835  }
11836 
11837  JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11838  }
11839  }
11840  }
11841 
11846  iter_impl const operator++(int) // NOLINT(readability-const-return-type)
11847  {
11848  auto result = *this;
11849  ++(*this);
11850  return result;
11851  }
11852 
11858  {
11859  JSON_ASSERT(m_object != nullptr);
11860 
11861  switch (m_object->m_type)
11862  {
11863  case value_t::object:
11864  {
11865  std::advance(m_it.object_iterator, 1);
11866  break;
11867  }
11868 
11869  case value_t::array:
11870  {
11871  std::advance(m_it.array_iterator, 1);
11872  break;
11873  }
11874 
11875  case value_t::null:
11876  case value_t::string:
11877  case value_t::boolean:
11878  case value_t::number_integer:
11879  case value_t::number_unsigned:
11880  case value_t::number_float:
11881  case value_t::binary:
11882  case value_t::discarded:
11883  default:
11884  {
11885  ++m_it.primitive_iterator;
11886  break;
11887  }
11888  }
11889 
11890  return *this;
11891  }
11892 
11897  iter_impl const operator--(int) // NOLINT(readability-const-return-type)
11898  {
11899  auto result = *this;
11900  --(*this);
11901  return result;
11902  }
11903 
11909  {
11910  JSON_ASSERT(m_object != nullptr);
11911 
11912  switch (m_object->m_type)
11913  {
11914  case value_t::object:
11915  {
11916  std::advance(m_it.object_iterator, -1);
11917  break;
11918  }
11919 
11920  case value_t::array:
11921  {
11922  std::advance(m_it.array_iterator, -1);
11923  break;
11924  }
11925 
11926  case value_t::null:
11927  case value_t::string:
11928  case value_t::boolean:
11929  case value_t::number_integer:
11930  case value_t::number_unsigned:
11931  case value_t::number_float:
11932  case value_t::binary:
11933  case value_t::discarded:
11934  default:
11935  {
11936  --m_it.primitive_iterator;
11937  break;
11938  }
11939  }
11940 
11941  return *this;
11942  }
11943 
11948  template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
11949  bool operator==(const IterImpl& other) const
11950  {
11951  // if objects are not the same, the comparison is undefined
11952  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11953  {
11954  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
11955  }
11956 
11957  JSON_ASSERT(m_object != nullptr);
11958 
11959  switch (m_object->m_type)
11960  {
11961  case value_t::object:
11962  return (m_it.object_iterator == other.m_it.object_iterator);
11963 
11964  case value_t::array:
11965  return (m_it.array_iterator == other.m_it.array_iterator);
11966 
11967  case value_t::null:
11968  case value_t::string:
11969  case value_t::boolean:
11970  case value_t::number_integer:
11971  case value_t::number_unsigned:
11972  case value_t::number_float:
11973  case value_t::binary:
11974  case value_t::discarded:
11975  default:
11976  return (m_it.primitive_iterator == other.m_it.primitive_iterator);
11977  }
11978  }
11979 
11984  template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
11985  bool operator!=(const IterImpl& other) const
11986  {
11987  return !operator==(other);
11988  }
11989 
11994  bool operator<(const iter_impl& other) const
11995  {
11996  // if objects are not the same, the comparison is undefined
11997  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11998  {
11999  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
12000  }
12001 
12002  JSON_ASSERT(m_object != nullptr);
12003 
12004  switch (m_object->m_type)
12005  {
12006  case value_t::object:
12007  JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", *m_object));
12008 
12009  case value_t::array:
12010  return (m_it.array_iterator < other.m_it.array_iterator);
12011 
12012  case value_t::null:
12013  case value_t::string:
12014  case value_t::boolean:
12015  case value_t::number_integer:
12016  case value_t::number_unsigned:
12017  case value_t::number_float:
12018  case value_t::binary:
12019  case value_t::discarded:
12020  default:
12021  return (m_it.primitive_iterator < other.m_it.primitive_iterator);
12022  }
12023  }
12024 
12029  bool operator<=(const iter_impl& other) const
12030  {
12031  return !other.operator < (*this);
12032  }
12033 
12038  bool operator>(const iter_impl& other) const
12039  {
12040  return !operator<=(other);
12041  }
12042 
12047  bool operator>=(const iter_impl& other) const
12048  {
12049  return !operator<(other);
12050  }
12051 
12057  {
12058  JSON_ASSERT(m_object != nullptr);
12059 
12060  switch (m_object->m_type)
12061  {
12062  case value_t::object:
12063  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12064 
12065  case value_t::array:
12066  {
12067  std::advance(m_it.array_iterator, i);
12068  break;
12069  }
12070 
12071  case value_t::null:
12072  case value_t::string:
12073  case value_t::boolean:
12074  case value_t::number_integer:
12075  case value_t::number_unsigned:
12076  case value_t::number_float:
12077  case value_t::binary:
12078  case value_t::discarded:
12079  default:
12080  {
12081  m_it.primitive_iterator += i;
12082  break;
12083  }
12084  }
12085 
12086  return *this;
12087  }
12088 
12094  {
12095  return operator+=(-i);
12096  }
12097 
12103  {
12104  auto result = *this;
12105  result += i;
12106  return result;
12107  }
12108 
12114  {
12115  auto result = it;
12116  result += i;
12117  return result;
12118  }
12119 
12125  {
12126  auto result = *this;
12127  result -= i;
12128  return result;
12129  }
12130 
12136  {
12137  JSON_ASSERT(m_object != nullptr);
12138 
12139  switch (m_object->m_type)
12140  {
12141  case value_t::object:
12142  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12143 
12144  case value_t::array:
12145  return m_it.array_iterator - other.m_it.array_iterator;
12146 
12147  case value_t::null:
12148  case value_t::string:
12149  case value_t::boolean:
12150  case value_t::number_integer:
12151  case value_t::number_unsigned:
12152  case value_t::number_float:
12153  case value_t::binary:
12154  case value_t::discarded:
12155  default:
12156  return m_it.primitive_iterator - other.m_it.primitive_iterator;
12157  }
12158  }
12159 
12165  {
12166  JSON_ASSERT(m_object != nullptr);
12167 
12168  switch (m_object->m_type)
12169  {
12170  case value_t::object:
12171  JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", *m_object));
12172 
12173  case value_t::array:
12174  return *std::next(m_it.array_iterator, n);
12175 
12176  case value_t::null:
12177  JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12178 
12179  case value_t::string:
12180  case value_t::boolean:
12181  case value_t::number_integer:
12182  case value_t::number_unsigned:
12183  case value_t::number_float:
12184  case value_t::binary:
12185  case value_t::discarded:
12186  default:
12187  {
12188  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
12189  {
12190  return *m_object;
12191  }
12192 
12193  JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12194  }
12195  }
12196  }
12197 
12202  const typename object_t::key_type& key() const
12203  {
12204  JSON_ASSERT(m_object != nullptr);
12205 
12206  if (JSON_HEDLEY_LIKELY(m_object->is_object()))
12207  {
12208  return m_it.object_iterator->first;
12209  }
12210 
12211  JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", *m_object));
12212  }
12213 
12219  {
12220  return operator*();
12221  }
12222 
12225  pointer m_object = nullptr;
12228 };
12229 } // namespace detail
12230 } // namespace nlohmann
12231 
12232 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
12233 
12234 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
12235 
12236 
12237 #include <cstddef> // ptrdiff_t
12238 #include <iterator> // reverse_iterator
12239 #include <utility> // declval
12240 
12241 namespace nlohmann
12242 {
12243 namespace detail
12244 {
12246 // reverse_iterator //
12248 
12267 template<typename Base>
12268 class json_reverse_iterator : public std::reverse_iterator<Base>
12269 {
12270  public:
12271  using difference_type = std::ptrdiff_t;
12273  using base_iterator = std::reverse_iterator<Base>;
12275  using reference = typename Base::reference;
12276 
12278  explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
12279  : base_iterator(it) {}
12280 
12282  explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
12283 
12285  json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)
12286  {
12287  return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
12288  }
12289 
12292  {
12293  return static_cast<json_reverse_iterator&>(base_iterator::operator++());
12294  }
12295 
12297  json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)
12298  {
12299  return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
12300  }
12301 
12304  {
12305  return static_cast<json_reverse_iterator&>(base_iterator::operator--());
12306  }
12307 
12310  {
12311  return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
12312  }
12313 
12316  {
12317  return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
12318  }
12319 
12322  {
12323  return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
12324  }
12325 
12328  {
12329  return base_iterator(*this) - base_iterator(other);
12330  }
12331 
12334  {
12335  return *(this->operator+(n));
12336  }
12337 
12339  auto key() const -> decltype(std::declval<Base>().key())
12340  {
12341  auto it = --this->base();
12342  return it.key();
12343  }
12344 
12347  {
12348  auto it = --this->base();
12349  return it.operator * ();
12350  }
12351 };
12352 } // namespace detail
12353 } // namespace nlohmann
12354 
12355 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12356 
12357 // #include <nlohmann/detail/json_pointer.hpp>
12358 
12359 
12360 #include <algorithm> // all_of
12361 #include <cctype> // isdigit
12362 #include <limits> // max
12363 #include <numeric> // accumulate
12364 #include <string> // string
12365 #include <utility> // move
12366 #include <vector> // vector
12367 
12368 // #include <nlohmann/detail/exceptions.hpp>
12369 
12370 // #include <nlohmann/detail/macro_scope.hpp>
12371 
12372 // #include <nlohmann/detail/string_escape.hpp>
12373 
12374 // #include <nlohmann/detail/value_t.hpp>
12375 
12376 
12377 namespace nlohmann
12378 {
12379 template<typename BasicJsonType>
12380 class json_pointer
12381 {
12382  // allow basic_json to access private members
12384  friend class basic_json;
12385 
12386  public:
12408  explicit json_pointer(const std::string& s = "")
12409  : reference_tokens(split(s))
12410  {}
12411 
12426  std::string to_string() const
12427  {
12428  return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
12429  std::string{},
12430  [](const std::string & a, const std::string & b)
12431  {
12432  return a + "/" + detail::escape(b);
12433  });
12434  }
12435 
12437  operator std::string() const
12438  {
12439  return to_string();
12440  }
12441 
12459  {
12460  reference_tokens.insert(reference_tokens.end(),
12461  ptr.reference_tokens.begin(),
12462  ptr.reference_tokens.end());
12463  return *this;
12464  }
12465 
12482  json_pointer& operator/=(std::string token)
12483  {
12484  push_back(std::move(token));
12485  return *this;
12486  }
12487 
12504  json_pointer& operator/=(std::size_t array_idx)
12505  {
12506  return *this /= std::to_string(array_idx);
12507  }
12508 
12525  const json_pointer& rhs)
12526  {
12527  return json_pointer(lhs) /= rhs;
12528  }
12529 
12545  friend json_pointer operator/(const json_pointer& ptr, std::string token) // NOLINT(performance-unnecessary-value-param)
12546  {
12547  return json_pointer(ptr) /= std::move(token);
12548  }
12549 
12565  friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
12566  {
12567  return json_pointer(ptr) /= array_idx;
12568  }
12569 
12584  {
12585  if (empty())
12586  {
12587  return *this;
12588  }
12589 
12590  json_pointer res = *this;
12591  res.pop_back();
12592  return res;
12593  }
12594 
12608  void pop_back()
12609  {
12610  if (JSON_HEDLEY_UNLIKELY(empty()))
12611  {
12612  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12613  }
12614 
12615  reference_tokens.pop_back();
12616  }
12617 
12632  const std::string& back() const
12633  {
12634  if (JSON_HEDLEY_UNLIKELY(empty()))
12635  {
12636  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12637  }
12638 
12639  return reference_tokens.back();
12640  }
12641 
12654  void push_back(const std::string& token)
12655  {
12656  reference_tokens.push_back(token);
12657  }
12658 
12660  void push_back(std::string&& token)
12661  {
12662  reference_tokens.push_back(std::move(token));
12663  }
12664 
12679  bool empty() const noexcept
12680  {
12681  return reference_tokens.empty();
12682  }
12683 
12684  private:
12695  static typename BasicJsonType::size_type array_index(const std::string& s)
12696  {
12697  using size_type = typename BasicJsonType::size_type;
12698 
12699  // error condition (cf. RFC 6901, Sect. 4)
12700  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
12701  {
12702  JSON_THROW(detail::parse_error::create(106, 0, "array index '" + s + "' must not begin with '0'", BasicJsonType()));
12703  }
12704 
12705  // error condition (cf. RFC 6901, Sect. 4)
12706  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
12707  {
12708  JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number", BasicJsonType()));
12709  }
12710 
12711  std::size_t processed_chars = 0;
12712  unsigned long long res = 0; // NOLINT(runtime/int)
12713  JSON_TRY
12714  {
12715  res = std::stoull(s, &processed_chars);
12716  }
12717  JSON_CATCH(std::out_of_range&)
12718  {
12719  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12720  }
12721 
12722  // check if the string was completely read
12723  if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
12724  {
12725  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12726  }
12727 
12728  // only triggered on special platforms (like 32bit), see also
12729  // https://github.com/nlohmann/json/pull/2203
12730  if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
12731  {
12732  JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type", BasicJsonType())); // LCOV_EXCL_LINE
12733  }
12734 
12735  return static_cast<size_type>(res);
12736  }
12737 
12739  json_pointer top() const
12740  {
12741  if (JSON_HEDLEY_UNLIKELY(empty()))
12742  {
12743  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12744  }
12745 
12746  json_pointer result = *this;
12747  result.reference_tokens = {reference_tokens[0]};
12748  return result;
12749  }
12750 
12751  private:
12760  BasicJsonType& get_and_create(BasicJsonType& j) const
12761  {
12762  auto* result = &j;
12763 
12764  // in case no reference tokens exist, return a reference to the JSON value
12765  // j which will be overwritten by a primitive value
12766  for (const auto& reference_token : reference_tokens)
12767  {
12768  switch (result->type())
12769  {
12770  case detail::value_t::null:
12771  {
12772  if (reference_token == "0")
12773  {
12774  // start a new array if reference token is 0
12775  result = &result->operator[](0);
12776  }
12777  else
12778  {
12779  // start a new object otherwise
12780  result = &result->operator[](reference_token);
12781  }
12782  break;
12783  }
12784 
12786  {
12787  // create an entry in the object
12788  result = &result->operator[](reference_token);
12789  break;
12790  }
12791 
12793  {
12794  // create an entry in the array
12795  result = &result->operator[](array_index(reference_token));
12796  break;
12797  }
12798 
12799  /*
12800  The following code is only reached if there exists a reference
12801  token _and_ the current value is primitive. In this case, we have
12802  an error situation, because primitive values may only occur as
12803  single value; that is, with an empty list of reference tokens.
12804  */
12812  default:
12813  JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j));
12814  }
12815  }
12816 
12817  return *result;
12818  }
12819 
12839  BasicJsonType& get_unchecked(BasicJsonType* ptr) const
12840  {
12841  for (const auto& reference_token : reference_tokens)
12842  {
12843  // convert null values to arrays or objects before continuing
12844  if (ptr->is_null())
12845  {
12846  // check if reference token is a number
12847  const bool nums =
12848  std::all_of(reference_token.begin(), reference_token.end(),
12849  [](const unsigned char x)
12850  {
12851  return std::isdigit(x);
12852  });
12853 
12854  // change value to array for numbers or "-" or to object otherwise
12855  *ptr = (nums || reference_token == "-")
12858  }
12859 
12860  switch (ptr->type())
12861  {
12863  {
12864  // use unchecked object access
12865  ptr = &ptr->operator[](reference_token);
12866  break;
12867  }
12868 
12870  {
12871  if (reference_token == "-")
12872  {
12873  // explicitly treat "-" as index beyond the end
12874  ptr = &ptr->operator[](ptr->m_value.array->size());
12875  }
12876  else
12877  {
12878  // convert array index to number; unchecked access
12879  ptr = &ptr->operator[](array_index(reference_token));
12880  }
12881  break;
12882  }
12883 
12884  case detail::value_t::null:
12892  default:
12893  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12894  }
12895  }
12896 
12897  return *ptr;
12898  }
12899 
12906  BasicJsonType& get_checked(BasicJsonType* ptr) const
12907  {
12908  for (const auto& reference_token : reference_tokens)
12909  {
12910  switch (ptr->type())
12911  {
12913  {
12914  // note: at performs range check
12915  ptr = &ptr->at(reference_token);
12916  break;
12917  }
12918 
12920  {
12921  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12922  {
12923  // "-" always fails the range check
12925  "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12926  ") is out of range", *ptr));
12927  }
12928 
12929  // note: at performs range check
12930  ptr = &ptr->at(array_index(reference_token));
12931  break;
12932  }
12933 
12934  case detail::value_t::null:
12942  default:
12943  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12944  }
12945  }
12946 
12947  return *ptr;
12948  }
12949 
12963  const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
12964  {
12965  for (const auto& reference_token : reference_tokens)
12966  {
12967  switch (ptr->type())
12968  {
12970  {
12971  // use unchecked object access
12972  ptr = &ptr->operator[](reference_token);
12973  break;
12974  }
12975 
12977  {
12978  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12979  {
12980  // "-" cannot be used for const access
12981  JSON_THROW(detail::out_of_range::create(402, "array index '-' (" + std::to_string(ptr->m_value.array->size()) + ") is out of range", *ptr));
12982  }
12983 
12984  // use unchecked array access
12985  ptr = &ptr->operator[](array_index(reference_token));
12986  break;
12987  }
12988 
12989  case detail::value_t::null:
12997  default:
12998  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12999  }
13000  }
13001 
13002  return *ptr;
13003  }
13004 
13011  const BasicJsonType& get_checked(const BasicJsonType* ptr) const
13012  {
13013  for (const auto& reference_token : reference_tokens)
13014  {
13015  switch (ptr->type())
13016  {
13018  {
13019  // note: at performs range check
13020  ptr = &ptr->at(reference_token);
13021  break;
13022  }
13023 
13025  {
13026  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13027  {
13028  // "-" always fails the range check
13030  "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13031  ") is out of range", *ptr));
13032  }
13033 
13034  // note: at performs range check
13035  ptr = &ptr->at(array_index(reference_token));
13036  break;
13037  }
13038 
13039  case detail::value_t::null:
13047  default:
13048  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13049  }
13050  }
13051 
13052  return *ptr;
13053  }
13054 
13059  bool contains(const BasicJsonType* ptr) const
13060  {
13061  for (const auto& reference_token : reference_tokens)
13062  {
13063  switch (ptr->type())
13064  {
13066  {
13067  if (!ptr->contains(reference_token))
13068  {
13069  // we did not find the key in the object
13070  return false;
13071  }
13072 
13073  ptr = &ptr->operator[](reference_token);
13074  break;
13075  }
13076 
13078  {
13079  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13080  {
13081  // "-" always fails the range check
13082  return false;
13083  }
13084  if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
13085  {
13086  // invalid char
13087  return false;
13088  }
13089  if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
13090  {
13091  if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
13092  {
13093  // first char should be between '1' and '9'
13094  return false;
13095  }
13096  for (std::size_t i = 1; i < reference_token.size(); i++)
13097  {
13098  if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
13099  {
13100  // other char should be between '0' and '9'
13101  return false;
13102  }
13103  }
13104  }
13105 
13106  const auto idx = array_index(reference_token);
13107  if (idx >= ptr->size())
13108  {
13109  // index out of range
13110  return false;
13111  }
13112 
13113  ptr = &ptr->operator[](idx);
13114  break;
13115  }
13116 
13117  case detail::value_t::null:
13125  default:
13126  {
13127  // we do not expect primitive values if there is still a
13128  // reference token to process
13129  return false;
13130  }
13131  }
13132  }
13133 
13134  // no reference token left means we found a primitive value
13135  return true;
13136  }
13137 
13147  static std::vector<std::string> split(const std::string& reference_string)
13148  {
13149  std::vector<std::string> result;
13150 
13151  // special case: empty reference string -> no reference tokens
13152  if (reference_string.empty())
13153  {
13154  return result;
13155  }
13156 
13157  // check if nonempty reference string begins with slash
13158  if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
13159  {
13160  JSON_THROW(detail::parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'", BasicJsonType()));
13161  }
13162 
13163  // extract the reference tokens:
13164  // - slash: position of the last read slash (or end of string)
13165  // - start: position after the previous slash
13166  for (
13167  // search for the first slash after the first character
13168  std::size_t slash = reference_string.find_first_of('/', 1),
13169  // set the beginning of the first reference token
13170  start = 1;
13171  // we can stop if start == 0 (if slash == std::string::npos)
13172  start != 0;
13173  // set the beginning of the next reference token
13174  // (will eventually be 0 if slash == std::string::npos)
13175  start = (slash == std::string::npos) ? 0 : slash + 1,
13176  // find next slash
13177  slash = reference_string.find_first_of('/', start))
13178  {
13179  // use the text between the beginning of the reference token
13180  // (start) and the last slash (slash).
13181  auto reference_token = reference_string.substr(start, slash - start);
13182 
13183  // check reference tokens are properly escaped
13184  for (std::size_t pos = reference_token.find_first_of('~');
13185  pos != std::string::npos;
13186  pos = reference_token.find_first_of('~', pos + 1))
13187  {
13188  JSON_ASSERT(reference_token[pos] == '~');
13189 
13190  // ~ must be followed by 0 or 1
13191  if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
13192  (reference_token[pos + 1] != '0' &&
13193  reference_token[pos + 1] != '1')))
13194  {
13195  JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", BasicJsonType()));
13196  }
13197  }
13198 
13199  // finally, store the reference token
13200  detail::unescape(reference_token);
13201  result.push_back(reference_token);
13202  }
13203 
13204  return result;
13205  }
13206 
13207  private:
13215  static void flatten(const std::string& reference_string,
13216  const BasicJsonType& value,
13217  BasicJsonType& result)
13218  {
13219  switch (value.type())
13220  {
13222  {
13223  if (value.m_value.array->empty())
13224  {
13225  // flatten empty array as null
13226  result[reference_string] = nullptr;
13227  }
13228  else
13229  {
13230  // iterate array and use index as reference string
13231  for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
13232  {
13233  flatten(reference_string + "/" + std::to_string(i),
13234  value.m_value.array->operator[](i), result);
13235  }
13236  }
13237  break;
13238  }
13239 
13241  {
13242  if (value.m_value.object->empty())
13243  {
13244  // flatten empty object as null
13245  result[reference_string] = nullptr;
13246  }
13247  else
13248  {
13249  // iterate object and use keys as reference string
13250  for (const auto& element : *value.m_value.object)
13251  {
13252  flatten(reference_string + "/" + detail::escape(element.first), element.second, result);
13253  }
13254  }
13255  break;
13256  }
13257 
13258  case detail::value_t::null:
13266  default:
13267  {
13268  // add primitive value with its reference string
13269  result[reference_string] = value;
13270  break;
13271  }
13272  }
13273  }
13274 
13285  static BasicJsonType
13286  unflatten(const BasicJsonType& value)
13287  {
13288  if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
13289  {
13290  JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", value));
13291  }
13292 
13293  BasicJsonType result;
13294 
13295  // iterate the JSON object values
13296  for (const auto& element : *value.m_value.object)
13297  {
13298  if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
13299  {
13300  JSON_THROW(detail::type_error::create(315, "values in object must be primitive", element.second));
13301  }
13302 
13303  // assign value to reference pointed to by JSON pointer; Note that if
13304  // the JSON pointer is "" (i.e., points to the whole value), function
13305  // get_and_create returns a reference to result itself. An assignment
13306  // will then create a primitive value.
13307  json_pointer(element.first).get_and_create(result) = element.second;
13308  }
13309 
13310  return result;
13311  }
13312 
13324  friend bool operator==(json_pointer const& lhs,
13325  json_pointer const& rhs) noexcept
13326  {
13327  return lhs.reference_tokens == rhs.reference_tokens;
13328  }
13329 
13341  friend bool operator!=(json_pointer const& lhs,
13342  json_pointer const& rhs) noexcept
13343  {
13344  return !(lhs == rhs);
13345  }
13346 
13348  std::vector<std::string> reference_tokens;
13349 };
13350 } // namespace nlohmann
13351 
13352 // #include <nlohmann/detail/json_ref.hpp>
13353 
13354 
13355 #include <initializer_list>
13356 #include <utility>
13357 
13358 // #include <nlohmann/detail/meta/type_traits.hpp>
13359 
13360 
13361 namespace nlohmann
13362 {
13363 namespace detail
13364 {
13365 template<typename BasicJsonType>
13366 class json_ref
13367 {
13368  public:
13369  using value_type = BasicJsonType;
13370 
13372  : owned_value(std::move(value))
13373  {}
13374 
13375  json_ref(const value_type& value)
13376  : value_ref(&value)
13377  {}
13378 
13379  json_ref(std::initializer_list<json_ref> init)
13380  : owned_value(init)
13381  {}
13382 
13383  template <
13384  class... Args,
13385  enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
13386  json_ref(Args && ... args)
13387  : owned_value(std::forward<Args>(args)...)
13388  {}
13389 
13390  // class should be movable only
13391  json_ref(json_ref&&) noexcept = default;
13392  json_ref(const json_ref&) = delete;
13393  json_ref& operator=(const json_ref&) = delete;
13394  json_ref& operator=(json_ref&&) = delete;
13395  ~json_ref() = default;
13396 
13397  value_type moved_or_copied() const
13398  {
13399  if (value_ref == nullptr)
13400  {
13401  return std::move(owned_value);
13402  }
13403  return *value_ref;
13404  }
13405 
13406  value_type const& operator*() const
13407  {
13408  return value_ref ? *value_ref : owned_value;
13409  }
13410 
13411  value_type const* operator->() const
13412  {
13413  return &** this;
13414  }
13415 
13416  private:
13417  mutable value_type owned_value = nullptr;
13418  value_type const* value_ref = nullptr;
13419 };
13420 } // namespace detail
13421 } // namespace nlohmann
13422 
13423 // #include <nlohmann/detail/macro_scope.hpp>
13424 
13425 // #include <nlohmann/detail/string_escape.hpp>
13426 
13427 // #include <nlohmann/detail/meta/cpp_future.hpp>
13428 
13429 // #include <nlohmann/detail/meta/type_traits.hpp>
13430 
13431 // #include <nlohmann/detail/output/binary_writer.hpp>
13432 
13433 
13434 #include <algorithm> // reverse
13435 #include <array> // array
13436 #include <cmath> // isnan, isinf
13437 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
13438 #include <cstring> // memcpy
13439 #include <limits> // numeric_limits
13440 #include <string> // string
13441 #include <utility> // move
13442 
13443 // #include <nlohmann/detail/input/binary_reader.hpp>
13444 
13445 // #include <nlohmann/detail/macro_scope.hpp>
13446 
13447 // #include <nlohmann/detail/output/output_adapters.hpp>
13448 
13449 
13450 #include <algorithm> // copy
13451 #include <cstddef> // size_t
13452 #include <iterator> // back_inserter
13453 #include <memory> // shared_ptr, make_shared
13454 #include <string> // basic_string
13455 #include <vector> // vector
13456 
13457 #ifndef JSON_NO_IO
13458  #include <ios> // streamsize
13459  #include <ostream> // basic_ostream
13460 #endif // JSON_NO_IO
13461 
13462 // #include <nlohmann/detail/macro_scope.hpp>
13463 
13464 
13465 namespace nlohmann
13466 {
13467 namespace detail
13468 {
13470 template<typename CharType> struct output_adapter_protocol
13471 {
13472  virtual void write_character(CharType c) = 0;
13473  virtual void write_characters(const CharType* s, std::size_t length) = 0;
13474  virtual ~output_adapter_protocol() = default;
13475 
13476  output_adapter_protocol() = default;
13478  output_adapter_protocol(output_adapter_protocol&&) noexcept = default;
13479  output_adapter_protocol& operator=(const output_adapter_protocol&) = default;
13480  output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
13481 };
13482 
13484 template<typename CharType>
13485 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
13486 
13488 template<typename CharType>
13490 {
13491  public:
13492  explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
13493  : v(vec)
13494  {}
13495 
13496  void write_character(CharType c) override
13497  {
13498  v.push_back(c);
13499  }
13500 
13502  void write_characters(const CharType* s, std::size_t length) override
13503  {
13504  std::copy(s, s + length, std::back_inserter(v));
13505  }
13506 
13507  private:
13508  std::vector<CharType>& v;
13509 };
13510 
13511 #ifndef JSON_NO_IO
13512 template<typename CharType>
13515 {
13516  public:
13517  explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
13518  : stream(s)
13519  {}
13520 
13521  void write_character(CharType c) override
13522  {
13523  stream.put(c);
13524  }
13525 
13527  void write_characters(const CharType* s, std::size_t length) override
13528  {
13529  stream.write(s, static_cast<std::streamsize>(length));
13530  }
13531 
13532  private:
13533  std::basic_ostream<CharType>& stream;
13534 };
13535 #endif // JSON_NO_IO
13536 
13538 template<typename CharType, typename StringType = std::basic_string<CharType>>
13540 {
13541  public:
13542  explicit output_string_adapter(StringType& s) noexcept
13543  : str(s)
13544  {}
13545 
13546  void write_character(CharType c) override
13547  {
13548  str.push_back(c);
13549  }
13550 
13552  void write_characters(const CharType* s, std::size_t length) override
13553  {
13554  str.append(s, length);
13555  }
13556 
13557  private:
13558  StringType& str;
13559 };
13560 
13561 template<typename CharType, typename StringType = std::basic_string<CharType>>
13563 {
13564  public:
13565  output_adapter(std::vector<CharType>& vec)
13566  : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
13567 
13568 #ifndef JSON_NO_IO
13569  output_adapter(std::basic_ostream<CharType>& s)
13570  : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
13571 #endif // JSON_NO_IO
13572 
13573  output_adapter(StringType& s)
13574  : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
13575 
13577  {
13578  return oa;
13579  }
13580 
13581  private:
13583 };
13584 } // namespace detail
13585 } // namespace nlohmann
13586 
13587 
13588 namespace nlohmann
13589 {
13590 namespace detail
13591 {
13593 // binary writer //
13595 
13599 template<typename BasicJsonType, typename CharType>
13601 {
13602  using string_t = typename BasicJsonType::string_t;
13603  using binary_t = typename BasicJsonType::binary_t;
13604  using number_float_t = typename BasicJsonType::number_float_t;
13605 
13606  public:
13612  explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
13613  {
13614  JSON_ASSERT(oa);
13615  }
13616 
13621  void write_bson(const BasicJsonType& j)
13622  {
13623  switch (j.type())
13624  {
13625  case value_t::object:
13626  {
13627  write_bson_object(*j.m_value.object);
13628  break;
13629  }
13630 
13631  case value_t::null:
13632  case value_t::array:
13633  case value_t::string:
13634  case value_t::boolean:
13635  case value_t::number_integer:
13636  case value_t::number_unsigned:
13637  case value_t::number_float:
13638  case value_t::binary:
13639  case value_t::discarded:
13640  default:
13641  {
13642  JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));
13643  }
13644  }
13645  }
13646 
13650  void write_cbor(const BasicJsonType& j)
13651  {
13652  switch (j.type())
13653  {
13654  case value_t::null:
13655  {
13656  oa->write_character(to_char_type(0xF6));
13657  break;
13658  }
13659 
13660  case value_t::boolean:
13661  {
13662  oa->write_character(j.m_value.boolean
13663  ? to_char_type(0xF5)
13664  : to_char_type(0xF4));
13665  break;
13666  }
13667 
13668  case value_t::number_integer:
13669  {
13670  if (j.m_value.number_integer >= 0)
13671  {
13672  // CBOR does not differentiate between positive signed
13673  // integers and unsigned integers. Therefore, we used the
13674  // code from the value_t::number_unsigned case here.
13675  if (j.m_value.number_integer <= 0x17)
13676  {
13677  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13678  }
13679  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
13680  {
13681  oa->write_character(to_char_type(0x18));
13682  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13683  }
13684  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
13685  {
13686  oa->write_character(to_char_type(0x19));
13687  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13688  }
13689  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
13690  {
13691  oa->write_character(to_char_type(0x1A));
13692  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13693  }
13694  else
13695  {
13696  oa->write_character(to_char_type(0x1B));
13697  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13698  }
13699  }
13700  else
13701  {
13702  // The conversions below encode the sign in the first
13703  // byte, and the value is converted to a positive number.
13704  const auto positive_number = -1 - j.m_value.number_integer;
13705  if (j.m_value.number_integer >= -24)
13706  {
13707  write_number(static_cast<std::uint8_t>(0x20 + positive_number));
13708  }
13709  else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
13710  {
13711  oa->write_character(to_char_type(0x38));
13712  write_number(static_cast<std::uint8_t>(positive_number));
13713  }
13714  else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
13715  {
13716  oa->write_character(to_char_type(0x39));
13717  write_number(static_cast<std::uint16_t>(positive_number));
13718  }
13719  else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
13720  {
13721  oa->write_character(to_char_type(0x3A));
13722  write_number(static_cast<std::uint32_t>(positive_number));
13723  }
13724  else
13725  {
13726  oa->write_character(to_char_type(0x3B));
13727  write_number(static_cast<std::uint64_t>(positive_number));
13728  }
13729  }
13730  break;
13731  }
13732 
13733  case value_t::number_unsigned:
13734  {
13735  if (j.m_value.number_unsigned <= 0x17)
13736  {
13737  write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13738  }
13739  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13740  {
13741  oa->write_character(to_char_type(0x18));
13742  write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13743  }
13744  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13745  {
13746  oa->write_character(to_char_type(0x19));
13747  write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
13748  }
13749  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13750  {
13751  oa->write_character(to_char_type(0x1A));
13752  write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
13753  }
13754  else
13755  {
13756  oa->write_character(to_char_type(0x1B));
13757  write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
13758  }
13759  break;
13760  }
13761 
13762  case value_t::number_float:
13763  {
13764  if (std::isnan(j.m_value.number_float))
13765  {
13766  // NaN is 0xf97e00 in CBOR
13767  oa->write_character(to_char_type(0xF9));
13768  oa->write_character(to_char_type(0x7E));
13769  oa->write_character(to_char_type(0x00));
13770  }
13771  else if (std::isinf(j.m_value.number_float))
13772  {
13773  // Infinity is 0xf97c00, -Infinity is 0xf9fc00
13774  oa->write_character(to_char_type(0xf9));
13775  oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
13776  oa->write_character(to_char_type(0x00));
13777  }
13778  else
13779  {
13780  write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
13781  }
13782  break;
13783  }
13784 
13785  case value_t::string:
13786  {
13787  // step 1: write control byte and the string length
13788  const auto N = j.m_value.string->size();
13789  if (N <= 0x17)
13790  {
13791  write_number(static_cast<std::uint8_t>(0x60 + N));
13792  }
13793  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13794  {
13795  oa->write_character(to_char_type(0x78));
13796  write_number(static_cast<std::uint8_t>(N));
13797  }
13798  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13799  {
13800  oa->write_character(to_char_type(0x79));
13801  write_number(static_cast<std::uint16_t>(N));
13802  }
13803  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13804  {
13805  oa->write_character(to_char_type(0x7A));
13806  write_number(static_cast<std::uint32_t>(N));
13807  }
13808  // LCOV_EXCL_START
13809  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13810  {
13811  oa->write_character(to_char_type(0x7B));
13812  write_number(static_cast<std::uint64_t>(N));
13813  }
13814  // LCOV_EXCL_STOP
13815 
13816  // step 2: write the string
13817  oa->write_characters(
13818  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13819  j.m_value.string->size());
13820  break;
13821  }
13822 
13823  case value_t::array:
13824  {
13825  // step 1: write control byte and the array size
13826  const auto N = j.m_value.array->size();
13827  if (N <= 0x17)
13828  {
13829  write_number(static_cast<std::uint8_t>(0x80 + N));
13830  }
13831  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13832  {
13833  oa->write_character(to_char_type(0x98));
13834  write_number(static_cast<std::uint8_t>(N));
13835  }
13836  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13837  {
13838  oa->write_character(to_char_type(0x99));
13839  write_number(static_cast<std::uint16_t>(N));
13840  }
13841  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13842  {
13843  oa->write_character(to_char_type(0x9A));
13844  write_number(static_cast<std::uint32_t>(N));
13845  }
13846  // LCOV_EXCL_START
13847  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13848  {
13849  oa->write_character(to_char_type(0x9B));
13850  write_number(static_cast<std::uint64_t>(N));
13851  }
13852  // LCOV_EXCL_STOP
13853 
13854  // step 2: write each element
13855  for (const auto& el : *j.m_value.array)
13856  {
13857  write_cbor(el);
13858  }
13859  break;
13860  }
13861 
13862  case value_t::binary:
13863  {
13864  if (j.m_value.binary->has_subtype())
13865  {
13866  if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
13867  {
13868  write_number(static_cast<std::uint8_t>(0xd8));
13869  write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
13870  }
13871  else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
13872  {
13873  write_number(static_cast<std::uint8_t>(0xd9));
13874  write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
13875  }
13876  else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
13877  {
13878  write_number(static_cast<std::uint8_t>(0xda));
13879  write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
13880  }
13881  else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
13882  {
13883  write_number(static_cast<std::uint8_t>(0xdb));
13884  write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
13885  }
13886  }
13887 
13888  // step 1: write control byte and the binary array size
13889  const auto N = j.m_value.binary->size();
13890  if (N <= 0x17)
13891  {
13892  write_number(static_cast<std::uint8_t>(0x40 + N));
13893  }
13894  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13895  {
13896  oa->write_character(to_char_type(0x58));
13897  write_number(static_cast<std::uint8_t>(N));
13898  }
13899  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13900  {
13901  oa->write_character(to_char_type(0x59));
13902  write_number(static_cast<std::uint16_t>(N));
13903  }
13904  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13905  {
13906  oa->write_character(to_char_type(0x5A));
13907  write_number(static_cast<std::uint32_t>(N));
13908  }
13909  // LCOV_EXCL_START
13910  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13911  {
13912  oa->write_character(to_char_type(0x5B));
13913  write_number(static_cast<std::uint64_t>(N));
13914  }
13915  // LCOV_EXCL_STOP
13916 
13917  // step 2: write each element
13918  oa->write_characters(
13919  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13920  N);
13921 
13922  break;
13923  }
13924 
13925  case value_t::object:
13926  {
13927  // step 1: write control byte and the object size
13928  const auto N = j.m_value.object->size();
13929  if (N <= 0x17)
13930  {
13931  write_number(static_cast<std::uint8_t>(0xA0 + N));
13932  }
13933  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13934  {
13935  oa->write_character(to_char_type(0xB8));
13936  write_number(static_cast<std::uint8_t>(N));
13937  }
13938  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13939  {
13940  oa->write_character(to_char_type(0xB9));
13941  write_number(static_cast<std::uint16_t>(N));
13942  }
13943  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13944  {
13945  oa->write_character(to_char_type(0xBA));
13946  write_number(static_cast<std::uint32_t>(N));
13947  }
13948  // LCOV_EXCL_START
13949  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13950  {
13951  oa->write_character(to_char_type(0xBB));
13952  write_number(static_cast<std::uint64_t>(N));
13953  }
13954  // LCOV_EXCL_STOP
13955 
13956  // step 2: write each element
13957  for (const auto& el : *j.m_value.object)
13958  {
13959  write_cbor(el.first);
13960  write_cbor(el.second);
13961  }
13962  break;
13963  }
13964 
13965  case value_t::discarded:
13966  default:
13967  break;
13968  }
13969  }
13970 
13974  void write_msgpack(const BasicJsonType& j)
13975  {
13976  switch (j.type())
13977  {
13978  case value_t::null: // nil
13979  {
13980  oa->write_character(to_char_type(0xC0));
13981  break;
13982  }
13983 
13984  case value_t::boolean: // true and false
13985  {
13986  oa->write_character(j.m_value.boolean
13987  ? to_char_type(0xC3)
13988  : to_char_type(0xC2));
13989  break;
13990  }
13991 
13992  case value_t::number_integer:
13993  {
13994  if (j.m_value.number_integer >= 0)
13995  {
13996  // MessagePack does not differentiate between positive
13997  // signed integers and unsigned integers. Therefore, we used
13998  // the code from the value_t::number_unsigned case here.
13999  if (j.m_value.number_unsigned < 128)
14000  {
14001  // positive fixnum
14002  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14003  }
14004  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14005  {
14006  // uint 8
14007  oa->write_character(to_char_type(0xCC));
14008  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14009  }
14010  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14011  {
14012  // uint 16
14013  oa->write_character(to_char_type(0xCD));
14014  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14015  }
14016  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14017  {
14018  // uint 32
14019  oa->write_character(to_char_type(0xCE));
14020  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14021  }
14022  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14023  {
14024  // uint 64
14025  oa->write_character(to_char_type(0xCF));
14026  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14027  }
14028  }
14029  else
14030  {
14031  if (j.m_value.number_integer >= -32)
14032  {
14033  // negative fixnum
14034  write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14035  }
14036  else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
14037  j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
14038  {
14039  // int 8
14040  oa->write_character(to_char_type(0xD0));
14041  write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14042  }
14043  else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
14044  j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
14045  {
14046  // int 16
14047  oa->write_character(to_char_type(0xD1));
14048  write_number(static_cast<std::int16_t>(j.m_value.number_integer));
14049  }
14050  else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
14051  j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
14052  {
14053  // int 32
14054  oa->write_character(to_char_type(0xD2));
14055  write_number(static_cast<std::int32_t>(j.m_value.number_integer));
14056  }
14057  else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
14058  j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
14059  {
14060  // int 64
14061  oa->write_character(to_char_type(0xD3));
14062  write_number(static_cast<std::int64_t>(j.m_value.number_integer));
14063  }
14064  }
14065  break;
14066  }
14067 
14068  case value_t::number_unsigned:
14069  {
14070  if (j.m_value.number_unsigned < 128)
14071  {
14072  // positive fixnum
14073  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14074  }
14075  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14076  {
14077  // uint 8
14078  oa->write_character(to_char_type(0xCC));
14079  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14080  }
14081  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14082  {
14083  // uint 16
14084  oa->write_character(to_char_type(0xCD));
14085  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14086  }
14087  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14088  {
14089  // uint 32
14090  oa->write_character(to_char_type(0xCE));
14091  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14092  }
14093  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14094  {
14095  // uint 64
14096  oa->write_character(to_char_type(0xCF));
14097  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14098  }
14099  break;
14100  }
14101 
14102  case value_t::number_float:
14103  {
14104  write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
14105  break;
14106  }
14107 
14108  case value_t::string:
14109  {
14110  // step 1: write control byte and the string length
14111  const auto N = j.m_value.string->size();
14112  if (N <= 31)
14113  {
14114  // fixstr
14115  write_number(static_cast<std::uint8_t>(0xA0 | N));
14116  }
14117  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14118  {
14119  // str 8
14120  oa->write_character(to_char_type(0xD9));
14121  write_number(static_cast<std::uint8_t>(N));
14122  }
14123  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14124  {
14125  // str 16
14126  oa->write_character(to_char_type(0xDA));
14127  write_number(static_cast<std::uint16_t>(N));
14128  }
14129  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14130  {
14131  // str 32
14132  oa->write_character(to_char_type(0xDB));
14133  write_number(static_cast<std::uint32_t>(N));
14134  }
14135 
14136  // step 2: write the string
14137  oa->write_characters(
14138  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14139  j.m_value.string->size());
14140  break;
14141  }
14142 
14143  case value_t::array:
14144  {
14145  // step 1: write control byte and the array size
14146  const auto N = j.m_value.array->size();
14147  if (N <= 15)
14148  {
14149  // fixarray
14150  write_number(static_cast<std::uint8_t>(0x90 | N));
14151  }
14152  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14153  {
14154  // array 16
14155  oa->write_character(to_char_type(0xDC));
14156  write_number(static_cast<std::uint16_t>(N));
14157  }
14158  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14159  {
14160  // array 32
14161  oa->write_character(to_char_type(0xDD));
14162  write_number(static_cast<std::uint32_t>(N));
14163  }
14164 
14165  // step 2: write each element
14166  for (const auto& el : *j.m_value.array)
14167  {
14168  write_msgpack(el);
14169  }
14170  break;
14171  }
14172 
14173  case value_t::binary:
14174  {
14175  // step 0: determine if the binary type has a set subtype to
14176  // determine whether or not to use the ext or fixext types
14177  const bool use_ext = j.m_value.binary->has_subtype();
14178 
14179  // step 1: write control byte and the byte string length
14180  const auto N = j.m_value.binary->size();
14181  if (N <= (std::numeric_limits<std::uint8_t>::max)())
14182  {
14183  std::uint8_t output_type{};
14184  bool fixed = true;
14185  if (use_ext)
14186  {
14187  switch (N)
14188  {
14189  case 1:
14190  output_type = 0xD4; // fixext 1
14191  break;
14192  case 2:
14193  output_type = 0xD5; // fixext 2
14194  break;
14195  case 4:
14196  output_type = 0xD6; // fixext 4
14197  break;
14198  case 8:
14199  output_type = 0xD7; // fixext 8
14200  break;
14201  case 16:
14202  output_type = 0xD8; // fixext 16
14203  break;
14204  default:
14205  output_type = 0xC7; // ext 8
14206  fixed = false;
14207  break;
14208  }
14209 
14210  }
14211  else
14212  {
14213  output_type = 0xC4; // bin 8
14214  fixed = false;
14215  }
14216 
14217  oa->write_character(to_char_type(output_type));
14218  if (!fixed)
14219  {
14220  write_number(static_cast<std::uint8_t>(N));
14221  }
14222  }
14223  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14224  {
14225  std::uint8_t output_type = use_ext
14226  ? 0xC8 // ext 16
14227  : 0xC5; // bin 16
14228 
14229  oa->write_character(to_char_type(output_type));
14230  write_number(static_cast<std::uint16_t>(N));
14231  }
14232  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14233  {
14234  std::uint8_t output_type = use_ext
14235  ? 0xC9 // ext 32
14236  : 0xC6; // bin 32
14237 
14238  oa->write_character(to_char_type(output_type));
14239  write_number(static_cast<std::uint32_t>(N));
14240  }
14241 
14242  // step 1.5: if this is an ext type, write the subtype
14243  if (use_ext)
14244  {
14245  write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
14246  }
14247 
14248  // step 2: write the byte string
14249  oa->write_characters(
14250  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14251  N);
14252 
14253  break;
14254  }
14255 
14256  case value_t::object:
14257  {
14258  // step 1: write control byte and the object size
14259  const auto N = j.m_value.object->size();
14260  if (N <= 15)
14261  {
14262  // fixmap
14263  write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
14264  }
14265  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14266  {
14267  // map 16
14268  oa->write_character(to_char_type(0xDE));
14269  write_number(static_cast<std::uint16_t>(N));
14270  }
14271  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14272  {
14273  // map 32
14274  oa->write_character(to_char_type(0xDF));
14275  write_number(static_cast<std::uint32_t>(N));
14276  }
14277 
14278  // step 2: write each element
14279  for (const auto& el : *j.m_value.object)
14280  {
14281  write_msgpack(el.first);
14282  write_msgpack(el.second);
14283  }
14284  break;
14285  }
14286 
14287  case value_t::discarded:
14288  default:
14289  break;
14290  }
14291  }
14292 
14299  void write_ubjson(const BasicJsonType& j, const bool use_count,
14300  const bool use_type, const bool add_prefix = true)
14301  {
14302  switch (j.type())
14303  {
14304  case value_t::null:
14305  {
14306  if (add_prefix)
14307  {
14308  oa->write_character(to_char_type('Z'));
14309  }
14310  break;
14311  }
14312 
14313  case value_t::boolean:
14314  {
14315  if (add_prefix)
14316  {
14317  oa->write_character(j.m_value.boolean
14318  ? to_char_type('T')
14319  : to_char_type('F'));
14320  }
14321  break;
14322  }
14323 
14324  case value_t::number_integer:
14325  {
14326  write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
14327  break;
14328  }
14329 
14330  case value_t::number_unsigned:
14331  {
14332  write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
14333  break;
14334  }
14335 
14336  case value_t::number_float:
14337  {
14338  write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
14339  break;
14340  }
14341 
14342  case value_t::string:
14343  {
14344  if (add_prefix)
14345  {
14346  oa->write_character(to_char_type('S'));
14347  }
14348  write_number_with_ubjson_prefix(j.m_value.string->size(), true);
14349  oa->write_characters(
14350  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14351  j.m_value.string->size());
14352  break;
14353  }
14354 
14355  case value_t::array:
14356  {
14357  if (add_prefix)
14358  {
14359  oa->write_character(to_char_type('['));
14360  }
14361 
14362  bool prefix_required = true;
14363  if (use_type && !j.m_value.array->empty())
14364  {
14365  JSON_ASSERT(use_count);
14366  const CharType first_prefix = ubjson_prefix(j.front());
14367  const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
14368  [this, first_prefix](const BasicJsonType & v)
14369  {
14370  return ubjson_prefix(v) == first_prefix;
14371  });
14372 
14373  if (same_prefix)
14374  {
14375  prefix_required = false;
14376  oa->write_character(to_char_type('$'));
14377  oa->write_character(first_prefix);
14378  }
14379  }
14380 
14381  if (use_count)
14382  {
14383  oa->write_character(to_char_type('#'));
14384  write_number_with_ubjson_prefix(j.m_value.array->size(), true);
14385  }
14386 
14387  for (const auto& el : *j.m_value.array)
14388  {
14389  write_ubjson(el, use_count, use_type, prefix_required);
14390  }
14391 
14392  if (!use_count)
14393  {
14394  oa->write_character(to_char_type(']'));
14395  }
14396 
14397  break;
14398  }
14399 
14400  case value_t::binary:
14401  {
14402  if (add_prefix)
14403  {
14404  oa->write_character(to_char_type('['));
14405  }
14406 
14407  if (use_type && !j.m_value.binary->empty())
14408  {
14409  JSON_ASSERT(use_count);
14410  oa->write_character(to_char_type('$'));
14411  oa->write_character('U');
14412  }
14413 
14414  if (use_count)
14415  {
14416  oa->write_character(to_char_type('#'));
14417  write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
14418  }
14419 
14420  if (use_type)
14421  {
14422  oa->write_characters(
14423  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14424  j.m_value.binary->size());
14425  }
14426  else
14427  {
14428  for (size_t i = 0; i < j.m_value.binary->size(); ++i)
14429  {
14430  oa->write_character(to_char_type('U'));
14431  oa->write_character(j.m_value.binary->data()[i]);
14432  }
14433  }
14434 
14435  if (!use_count)
14436  {
14437  oa->write_character(to_char_type(']'));
14438  }
14439 
14440  break;
14441  }
14442 
14443  case value_t::object:
14444  {
14445  if (add_prefix)
14446  {
14447  oa->write_character(to_char_type('{'));
14448  }
14449 
14450  bool prefix_required = true;
14451  if (use_type && !j.m_value.object->empty())
14452  {
14453  JSON_ASSERT(use_count);
14454  const CharType first_prefix = ubjson_prefix(j.front());
14455  const bool same_prefix = std::all_of(j.begin(), j.end(),
14456  [this, first_prefix](const BasicJsonType & v)
14457  {
14458  return ubjson_prefix(v) == first_prefix;
14459  });
14460 
14461  if (same_prefix)
14462  {
14463  prefix_required = false;
14464  oa->write_character(to_char_type('$'));
14465  oa->write_character(first_prefix);
14466  }
14467  }
14468 
14469  if (use_count)
14470  {
14471  oa->write_character(to_char_type('#'));
14472  write_number_with_ubjson_prefix(j.m_value.object->size(), true);
14473  }
14474 
14475  for (const auto& el : *j.m_value.object)
14476  {
14477  write_number_with_ubjson_prefix(el.first.size(), true);
14478  oa->write_characters(
14479  reinterpret_cast<const CharType*>(el.first.c_str()),
14480  el.first.size());
14481  write_ubjson(el.second, use_count, use_type, prefix_required);
14482  }
14483 
14484  if (!use_count)
14485  {
14486  oa->write_character(to_char_type('}'));
14487  }
14488 
14489  break;
14490  }
14491 
14492  case value_t::discarded:
14493  default:
14494  break;
14495  }
14496  }
14497 
14498  private:
14500  // BSON //
14502 
14507  static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
14508  {
14509  const auto it = name.find(static_cast<typename string_t::value_type>(0));
14510  if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
14511  {
14512  JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j));
14513  static_cast<void>(j);
14514  }
14515 
14516  return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
14517  }
14518 
14523  const std::uint8_t element_type)
14524  {
14525  oa->write_character(to_char_type(element_type)); // boolean
14526  oa->write_characters(
14527  reinterpret_cast<const CharType*>(name.c_str()),
14528  name.size() + 1u);
14529  }
14530 
14534  void write_bson_boolean(const string_t& name,
14535  const bool value)
14536  {
14537  write_bson_entry_header(name, 0x08);
14538  oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
14539  }
14540 
14544  void write_bson_double(const string_t& name,
14545  const double value)
14546  {
14547  write_bson_entry_header(name, 0x01);
14548  write_number<double, true>(value);
14549  }
14550 
14554  static std::size_t calc_bson_string_size(const string_t& value)
14555  {
14556  return sizeof(std::int32_t) + value.size() + 1ul;
14557  }
14558 
14562  void write_bson_string(const string_t& name,
14563  const string_t& value)
14564  {
14565  write_bson_entry_header(name, 0x02);
14566 
14567  write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
14568  oa->write_characters(
14569  reinterpret_cast<const CharType*>(value.c_str()),
14570  value.size() + 1);
14571  }
14572 
14576  void write_bson_null(const string_t& name)
14577  {
14578  write_bson_entry_header(name, 0x0A);
14579  }
14580 
14584  static std::size_t calc_bson_integer_size(const std::int64_t value)
14585  {
14586  return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
14587  ? sizeof(std::int32_t)
14588  : sizeof(std::int64_t);
14589  }
14590 
14594  void write_bson_integer(const string_t& name,
14595  const std::int64_t value)
14596  {
14597  if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
14598  {
14599  write_bson_entry_header(name, 0x10); // int32
14600  write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
14601  }
14602  else
14603  {
14604  write_bson_entry_header(name, 0x12); // int64
14605  write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
14606  }
14607  }
14608 
14612  static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
14613  {
14614  return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14615  ? sizeof(std::int32_t)
14616  : sizeof(std::int64_t);
14617  }
14618 
14622  void write_bson_unsigned(const string_t& name,
14623  const BasicJsonType& j)
14624  {
14625  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14626  {
14627  write_bson_entry_header(name, 0x10 /* int32 */);
14628  write_number<std::int32_t, true>(static_cast<std::int32_t>(j.m_value.number_unsigned));
14629  }
14630  else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14631  {
14632  write_bson_entry_header(name, 0x12 /* int64 */);
14633  write_number<std::int64_t, true>(static_cast<std::int64_t>(j.m_value.number_unsigned));
14634  }
14635  else
14636  {
14637  JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(j.m_value.number_unsigned) + " cannot be represented by BSON as it does not fit int64", j));
14638  }
14639  }
14640 
14645  const typename BasicJsonType::object_t& value)
14646  {
14647  write_bson_entry_header(name, 0x03); // object
14648  write_bson_object(value);
14649  }
14650 
14654  static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
14655  {
14656  std::size_t array_index = 0ul;
14657 
14658  const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
14659  {
14660  return result + calc_bson_element_size(std::to_string(array_index++), el);
14661  });
14662 
14663  return sizeof(std::int32_t) + embedded_document_size + 1ul;
14664  }
14665 
14669  static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
14670  {
14671  return sizeof(std::int32_t) + value.size() + 1ul;
14672  }
14673 
14677  void write_bson_array(const string_t& name,
14678  const typename BasicJsonType::array_t& value)
14679  {
14680  write_bson_entry_header(name, 0x04); // array
14681  write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
14682 
14683  std::size_t array_index = 0ul;
14684 
14685  for (const auto& el : value)
14686  {
14687  write_bson_element(std::to_string(array_index++), el);
14688  }
14689 
14690  oa->write_character(to_char_type(0x00));
14691  }
14692 
14696  void write_bson_binary(const string_t& name,
14697  const binary_t& value)
14698  {
14699  write_bson_entry_header(name, 0x05);
14700 
14701  write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
14702  write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : std::uint8_t(0x00));
14703 
14704  oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
14705  }
14706 
14711  static std::size_t calc_bson_element_size(const string_t& name,
14712  const BasicJsonType& j)
14713  {
14714  const auto header_size = calc_bson_entry_header_size(name, j);
14715  switch (j.type())
14716  {
14717  case value_t::object:
14718  return header_size + calc_bson_object_size(*j.m_value.object);
14719 
14720  case value_t::array:
14721  return header_size + calc_bson_array_size(*j.m_value.array);
14722 
14723  case value_t::binary:
14724  return header_size + calc_bson_binary_size(*j.m_value.binary);
14725 
14726  case value_t::boolean:
14727  return header_size + 1ul;
14728 
14729  case value_t::number_float:
14730  return header_size + 8ul;
14731 
14732  case value_t::number_integer:
14733  return header_size + calc_bson_integer_size(j.m_value.number_integer);
14734 
14735  case value_t::number_unsigned:
14736  return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
14737 
14738  case value_t::string:
14739  return header_size + calc_bson_string_size(*j.m_value.string);
14740 
14741  case value_t::null:
14742  return header_size + 0ul;
14743 
14744  // LCOV_EXCL_START
14745  case value_t::discarded:
14746  default:
14747  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14748  return 0ul;
14749  // LCOV_EXCL_STOP
14750  }
14751  }
14752 
14759  void write_bson_element(const string_t& name,
14760  const BasicJsonType& j)
14761  {
14762  switch (j.type())
14763  {
14764  case value_t::object:
14765  return write_bson_object_entry(name, *j.m_value.object);
14766 
14767  case value_t::array:
14768  return write_bson_array(name, *j.m_value.array);
14769 
14770  case value_t::binary:
14771  return write_bson_binary(name, *j.m_value.binary);
14772 
14773  case value_t::boolean:
14774  return write_bson_boolean(name, j.m_value.boolean);
14775 
14776  case value_t::number_float:
14777  return write_bson_double(name, j.m_value.number_float);
14778 
14779  case value_t::number_integer:
14780  return write_bson_integer(name, j.m_value.number_integer);
14781 
14782  case value_t::number_unsigned:
14783  return write_bson_unsigned(name, j);
14784 
14785  case value_t::string:
14786  return write_bson_string(name, *j.m_value.string);
14787 
14788  case value_t::null:
14789  return write_bson_null(name);
14790 
14791  // LCOV_EXCL_START
14792  case value_t::discarded:
14793  default:
14794  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14795  return;
14796  // LCOV_EXCL_STOP
14797  }
14798  }
14799 
14806  static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
14807  {
14808  std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
14809  [](size_t result, const typename BasicJsonType::object_t::value_type & el)
14810  {
14811  return result += calc_bson_element_size(el.first, el.second);
14812  });
14813 
14814  return sizeof(std::int32_t) + document_size + 1ul;
14815  }
14816 
14821  void write_bson_object(const typename BasicJsonType::object_t& value)
14822  {
14823  write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
14824 
14825  for (const auto& el : value)
14826  {
14827  write_bson_element(el.first, el.second);
14828  }
14829 
14830  oa->write_character(to_char_type(0x00));
14831  }
14832 
14834  // CBOR //
14836 
14837  static constexpr CharType get_cbor_float_prefix(float /*unused*/)
14838  {
14839  return to_char_type(0xFA); // Single-Precision Float
14840  }
14841 
14842  static constexpr CharType get_cbor_float_prefix(double /*unused*/)
14843  {
14844  return to_char_type(0xFB); // Double-Precision Float
14845  }
14846 
14848  // MsgPack //
14850 
14851  static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
14852  {
14853  return to_char_type(0xCA); // float 32
14854  }
14855 
14856  static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
14857  {
14858  return to_char_type(0xCB); // float 64
14859  }
14860 
14862  // UBJSON //
14864 
14865  // UBJSON: write number (floating point)
14866  template<typename NumberType, typename std::enable_if<
14867  std::is_floating_point<NumberType>::value, int>::type = 0>
14868  void write_number_with_ubjson_prefix(const NumberType n,
14869  const bool add_prefix)
14870  {
14871  if (add_prefix)
14872  {
14873  oa->write_character(get_ubjson_float_prefix(n));
14874  }
14875  write_number(n);
14876  }
14877 
14878  // UBJSON: write number (unsigned integer)
14879  template<typename NumberType, typename std::enable_if<
14880  std::is_unsigned<NumberType>::value, int>::type = 0>
14881  void write_number_with_ubjson_prefix(const NumberType n,
14882  const bool add_prefix)
14883  {
14884  if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14885  {
14886  if (add_prefix)
14887  {
14888  oa->write_character(to_char_type('i')); // int8
14889  }
14890  write_number(static_cast<std::uint8_t>(n));
14891  }
14892  else if (n <= (std::numeric_limits<std::uint8_t>::max)())
14893  {
14894  if (add_prefix)
14895  {
14896  oa->write_character(to_char_type('U')); // uint8
14897  }
14898  write_number(static_cast<std::uint8_t>(n));
14899  }
14900  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14901  {
14902  if (add_prefix)
14903  {
14904  oa->write_character(to_char_type('I')); // int16
14905  }
14906  write_number(static_cast<std::int16_t>(n));
14907  }
14908  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14909  {
14910  if (add_prefix)
14911  {
14912  oa->write_character(to_char_type('l')); // int32
14913  }
14914  write_number(static_cast<std::int32_t>(n));
14915  }
14916  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14917  {
14918  if (add_prefix)
14919  {
14920  oa->write_character(to_char_type('L')); // int64
14921  }
14922  write_number(static_cast<std::int64_t>(n));
14923  }
14924  else
14925  {
14926  if (add_prefix)
14927  {
14928  oa->write_character(to_char_type('H')); // high-precision number
14929  }
14930 
14931  const auto number = BasicJsonType(n).dump();
14932  write_number_with_ubjson_prefix(number.size(), true);
14933  for (std::size_t i = 0; i < number.size(); ++i)
14934  {
14935  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14936  }
14937  }
14938  }
14939 
14940  // UBJSON: write number (signed integer)
14941  template < typename NumberType, typename std::enable_if <
14942  std::is_signed<NumberType>::value&&
14943  !std::is_floating_point<NumberType>::value, int >::type = 0 >
14944  void write_number_with_ubjson_prefix(const NumberType n,
14945  const bool add_prefix)
14946  {
14947  if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
14948  {
14949  if (add_prefix)
14950  {
14951  oa->write_character(to_char_type('i')); // int8
14952  }
14953  write_number(static_cast<std::int8_t>(n));
14954  }
14955  else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
14956  {
14957  if (add_prefix)
14958  {
14959  oa->write_character(to_char_type('U')); // uint8
14960  }
14961  write_number(static_cast<std::uint8_t>(n));
14962  }
14963  else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
14964  {
14965  if (add_prefix)
14966  {
14967  oa->write_character(to_char_type('I')); // int16
14968  }
14969  write_number(static_cast<std::int16_t>(n));
14970  }
14971  else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
14972  {
14973  if (add_prefix)
14974  {
14975  oa->write_character(to_char_type('l')); // int32
14976  }
14977  write_number(static_cast<std::int32_t>(n));
14978  }
14979  else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
14980  {
14981  if (add_prefix)
14982  {
14983  oa->write_character(to_char_type('L')); // int64
14984  }
14985  write_number(static_cast<std::int64_t>(n));
14986  }
14987  // LCOV_EXCL_START
14988  else
14989  {
14990  if (add_prefix)
14991  {
14992  oa->write_character(to_char_type('H')); // high-precision number
14993  }
14994 
14995  const auto number = BasicJsonType(n).dump();
14996  write_number_with_ubjson_prefix(number.size(), true);
14997  for (std::size_t i = 0; i < number.size(); ++i)
14998  {
14999  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15000  }
15001  }
15002  // LCOV_EXCL_STOP
15003  }
15004 
15008  CharType ubjson_prefix(const BasicJsonType& j) const noexcept
15009  {
15010  switch (j.type())
15011  {
15012  case value_t::null:
15013  return 'Z';
15014 
15015  case value_t::boolean:
15016  return j.m_value.boolean ? 'T' : 'F';
15017 
15018  case value_t::number_integer:
15019  {
15020  if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
15021  {
15022  return 'i';
15023  }
15024  if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
15025  {
15026  return 'U';
15027  }
15028  if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
15029  {
15030  return 'I';
15031  }
15032  if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
15033  {
15034  return 'l';
15035  }
15036  if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
15037  {
15038  return 'L';
15039  }
15040  // anything else is treated as high-precision number
15041  return 'H'; // LCOV_EXCL_LINE
15042  }
15043 
15044  case value_t::number_unsigned:
15045  {
15046  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
15047  {
15048  return 'i';
15049  }
15050  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
15051  {
15052  return 'U';
15053  }
15054  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
15055  {
15056  return 'I';
15057  }
15058  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15059  {
15060  return 'l';
15061  }
15062  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15063  {
15064  return 'L';
15065  }
15066  // anything else is treated as high-precision number
15067  return 'H'; // LCOV_EXCL_LINE
15068  }
15069 
15070  case value_t::number_float:
15071  return get_ubjson_float_prefix(j.m_value.number_float);
15072 
15073  case value_t::string:
15074  return 'S';
15075 
15076  case value_t::array: // fallthrough
15077  case value_t::binary:
15078  return '[';
15079 
15080  case value_t::object:
15081  return '{';
15082 
15083  case value_t::discarded:
15084  default: // discarded values
15085  return 'N';
15086  }
15087  }
15088 
15089  static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
15090  {
15091  return 'd'; // float 32
15092  }
15093 
15094  static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
15095  {
15096  return 'D'; // float 64
15097  }
15098 
15100  // Utility functions //
15102 
15103  /*
15104  @brief write a number to output input
15105  @param[in] n number of type @a NumberType
15106  @tparam NumberType the type of the number
15107  @tparam OutputIsLittleEndian Set to true if output data is
15108  required to be little endian
15109 
15110  @note This function needs to respect the system's endianess, because bytes
15111  in CBOR, MessagePack, and UBJSON are stored in network order (big
15112  endian) and therefore need reordering on little endian systems.
15113  */
15114  template<typename NumberType, bool OutputIsLittleEndian = false>
15115  void write_number(const NumberType n)
15116  {
15117  // step 1: write number to array of length NumberType
15118  std::array<CharType, sizeof(NumberType)> vec{};
15119  std::memcpy(vec.data(), &n, sizeof(NumberType));
15120 
15121  // step 2: write array to output (with possible reordering)
15122  if (is_little_endian != OutputIsLittleEndian)
15123  {
15124  // reverse byte order prior to conversion if necessary
15125  std::reverse(vec.begin(), vec.end());
15126  }
15127 
15128  oa->write_characters(vec.data(), sizeof(NumberType));
15129  }
15130 
15132  {
15133 #ifdef __GNUC__
15134 #pragma GCC diagnostic push
15135 #pragma GCC diagnostic ignored "-Wfloat-equal"
15136 #endif
15137  if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
15138  static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
15139  static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
15140  {
15141  oa->write_character(format == detail::input_format_t::cbor
15142  ? get_cbor_float_prefix(static_cast<float>(n))
15143  : get_msgpack_float_prefix(static_cast<float>(n)));
15144  write_number(static_cast<float>(n));
15145  }
15146  else
15147  {
15148  oa->write_character(format == detail::input_format_t::cbor
15149  ? get_cbor_float_prefix(n)
15150  : get_msgpack_float_prefix(n));
15151  write_number(n);
15152  }
15153 #ifdef __GNUC__
15154 #pragma GCC diagnostic pop
15155 #endif
15156  }
15157 
15158  public:
15159  // The following to_char_type functions are implement the conversion
15160  // between uint8_t and CharType. In case CharType is not unsigned,
15161  // such a conversion is required to allow values greater than 128.
15162  // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
15163  template < typename C = CharType,
15164  enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
15165  static constexpr CharType to_char_type(std::uint8_t x) noexcept
15166  {
15167  return *reinterpret_cast<char*>(&x);
15168  }
15169 
15170  template < typename C = CharType,
15171  enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
15172  static CharType to_char_type(std::uint8_t x) noexcept
15173  {
15174  static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
15175  static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
15176  CharType result;
15177  std::memcpy(&result, &x, sizeof(x));
15178  return result;
15179  }
15180 
15181  template<typename C = CharType,
15183  static constexpr CharType to_char_type(std::uint8_t x) noexcept
15184  {
15185  return x;
15186  }
15187 
15188  template < typename InputCharType, typename C = CharType,
15189  enable_if_t <
15190  std::is_signed<C>::value &&
15191  std::is_signed<char>::value &&
15192  std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
15193  > * = nullptr >
15194  static constexpr CharType to_char_type(InputCharType x) noexcept
15195  {
15196  return x;
15197  }
15198 
15199  private:
15201  const bool is_little_endian = little_endianess();
15202 
15205 };
15206 } // namespace detail
15207 } // namespace nlohmann
15208 
15209 // #include <nlohmann/detail/output/output_adapters.hpp>
15210 
15211 // #include <nlohmann/detail/output/serializer.hpp>
15212 
15213 
15214 #include <algorithm> // reverse, remove, fill, find, none_of
15215 #include <array> // array
15216 #include <clocale> // localeconv, lconv
15217 #include <cmath> // labs, isfinite, isnan, signbit
15218 #include <cstddef> // size_t, ptrdiff_t
15219 #include <cstdint> // uint8_t
15220 #include <cstdio> // snprintf
15221 #include <limits> // numeric_limits
15222 #include <string> // string, char_traits
15223 #include <type_traits> // is_same
15224 #include <utility> // move
15225 
15226 // #include <nlohmann/detail/conversions/to_chars.hpp>
15227 
15228 
15229 #include <array> // array
15230 #include <cmath> // signbit, isfinite
15231 #include <cstdint> // intN_t, uintN_t
15232 #include <cstring> // memcpy, memmove
15233 #include <limits> // numeric_limits
15234 #include <type_traits> // conditional
15235 
15236 // #include <nlohmann/detail/macro_scope.hpp>
15237 
15238 
15239 namespace nlohmann
15240 {
15241 namespace detail
15242 {
15243 
15263 namespace dtoa_impl
15264 {
15265 
15266 template<typename Target, typename Source>
15267 Target reinterpret_bits(const Source source)
15268 {
15269  static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
15270 
15271  Target target;
15272  std::memcpy(&target, &source, sizeof(Source));
15273  return target;
15274 }
15275 
15276 struct diyfp // f * 2^e
15277 {
15278  static constexpr int kPrecision = 64; // = q
15279 
15280  std::uint64_t f = 0;
15281  int e = 0;
15282 
15283  constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
15284 
15289  static diyfp sub(const diyfp& x, const diyfp& y) noexcept
15290  {
15291  JSON_ASSERT(x.e == y.e);
15292  JSON_ASSERT(x.f >= y.f);
15293 
15294  return {x.f - y.f, x.e};
15295  }
15296 
15301  static diyfp mul(const diyfp& x, const diyfp& y) noexcept
15302  {
15303  static_assert(kPrecision == 64, "internal error");
15304 
15305  // Computes:
15306  // f = round((x.f * y.f) / 2^q)
15307  // e = x.e + y.e + q
15308 
15309  // Emulate the 64-bit * 64-bit multiplication:
15310  //
15311  // p = u * v
15312  // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
15313  // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
15314  // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
15315  // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
15316  // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
15317  // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
15318  // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
15319  //
15320  // (Since Q might be larger than 2^32 - 1)
15321  //
15322  // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
15323  //
15324  // (Q_hi + H does not overflow a 64-bit int)
15325  //
15326  // = p_lo + 2^64 p_hi
15327 
15328  const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
15329  const std::uint64_t u_hi = x.f >> 32u;
15330  const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
15331  const std::uint64_t v_hi = y.f >> 32u;
15332 
15333  const std::uint64_t p0 = u_lo * v_lo;
15334  const std::uint64_t p1 = u_lo * v_hi;
15335  const std::uint64_t p2 = u_hi * v_lo;
15336  const std::uint64_t p3 = u_hi * v_hi;
15337 
15338  const std::uint64_t p0_hi = p0 >> 32u;
15339  const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
15340  const std::uint64_t p1_hi = p1 >> 32u;
15341  const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
15342  const std::uint64_t p2_hi = p2 >> 32u;
15343 
15344  std::uint64_t Q = p0_hi + p1_lo + p2_lo;
15345 
15346  // The full product might now be computed as
15347  //
15348  // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
15349  // p_lo = p0_lo + (Q << 32)
15350  //
15351  // But in this particular case here, the full p_lo is not required.
15352  // Effectively we only need to add the highest bit in p_lo to p_hi (and
15353  // Q_hi + 1 does not overflow).
15354 
15355  Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
15356 
15357  const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
15358 
15359  return {h, x.e + y.e + 64};
15360  }
15361 
15366  static diyfp normalize(diyfp x) noexcept
15367  {
15368  JSON_ASSERT(x.f != 0);
15369 
15370  while ((x.f >> 63u) == 0)
15371  {
15372  x.f <<= 1u;
15373  x.e--;
15374  }
15375 
15376  return x;
15377  }
15378 
15383  static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
15384  {
15385  const int delta = x.e - target_exponent;
15386 
15387  JSON_ASSERT(delta >= 0);
15388  JSON_ASSERT(((x.f << delta) >> delta) == x.f);
15389 
15390  return {x.f << delta, target_exponent};
15391  }
15392 };
15393 
15395 {
15399 };
15400 
15407 template<typename FloatType>
15409 {
15410  JSON_ASSERT(std::isfinite(value));
15411  JSON_ASSERT(value > 0);
15412 
15413  // Convert the IEEE representation into a diyfp.
15414  //
15415  // If v is denormal:
15416  // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
15417  // If v is normalized:
15418  // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
15419 
15420  static_assert(std::numeric_limits<FloatType>::is_iec559,
15421  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
15422 
15423  constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
15424  constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
15425  constexpr int kMinExp = 1 - kBias;
15426  constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
15427 
15428  using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
15429 
15430  const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
15431  const std::uint64_t E = bits >> (kPrecision - 1);
15432  const std::uint64_t F = bits & (kHiddenBit - 1);
15433 
15434  const bool is_denormal = E == 0;
15435  const diyfp v = is_denormal
15436  ? diyfp(F, kMinExp)
15437  : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
15438 
15439  // Compute the boundaries m- and m+ of the floating-point value
15440  // v = f * 2^e.
15441  //
15442  // Determine v- and v+, the floating-point predecessor and successor if v,
15443  // respectively.
15444  //
15445  // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
15446  // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
15447  //
15448  // v+ = v + 2^e
15449  //
15450  // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
15451  // between m- and m+ round to v, regardless of how the input rounding
15452  // algorithm breaks ties.
15453  //
15454  // ---+-------------+-------------+-------------+-------------+--- (A)
15455  // v- m- v m+ v+
15456  //
15457  // -----------------+------+------+-------------+-------------+--- (B)
15458  // v- m- v m+ v+
15459 
15460  const bool lower_boundary_is_closer = F == 0 && E > 1;
15461  const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
15462  const diyfp m_minus = lower_boundary_is_closer
15463  ? diyfp(4 * v.f - 1, v.e - 2) // (B)
15464  : diyfp(2 * v.f - 1, v.e - 1); // (A)
15465 
15466  // Determine the normalized w+ = m+.
15467  const diyfp w_plus = diyfp::normalize(m_plus);
15468 
15469  // Determine w- = m- such that e_(w-) = e_(w+).
15470  const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
15471 
15472  return {diyfp::normalize(v), w_minus, w_plus};
15473 }
15474 
15475 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
15476 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
15477 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
15478 //
15479 // alpha <= e = e_c + e_w + q <= gamma
15480 //
15481 // or
15482 //
15483 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
15484 // <= f_c * f_w * 2^gamma
15485 //
15486 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
15487 //
15488 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
15489 //
15490 // or
15491 //
15492 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
15493 //
15494 // The choice of (alpha,gamma) determines the size of the table and the form of
15495 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
15496 // in practice:
15497 //
15498 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
15499 // processed independently: An integral part p1, and a fractional part p2:
15500 //
15501 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
15502 // = (f div 2^-e) + (f mod 2^-e) * 2^e
15503 // = p1 + p2 * 2^e
15504 //
15505 // The conversion of p1 into decimal form requires a series of divisions and
15506 // modulos by (a power of) 10. These operations are faster for 32-bit than for
15507 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
15508 // achieved by choosing
15509 //
15510 // -e >= 32 or e <= -32 := gamma
15511 //
15512 // In order to convert the fractional part
15513 //
15514 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
15515 //
15516 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
15517 // d[-i] are extracted in order:
15518 //
15519 // (10 * p2) div 2^-e = d[-1]
15520 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
15521 //
15522 // The multiplication by 10 must not overflow. It is sufficient to choose
15523 //
15524 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
15525 //
15526 // Since p2 = f mod 2^-e < 2^-e,
15527 //
15528 // -e <= 60 or e >= -60 := alpha
15529 
15530 constexpr int kAlpha = -60;
15531 constexpr int kGamma = -32;
15532 
15533 struct cached_power // c = f * 2^e ~= 10^k
15534 {
15535  std::uint64_t f;
15536  int e;
15537  int k;
15538 };
15539 
15548 {
15549  // Now
15550  //
15551  // alpha <= e_c + e + q <= gamma (1)
15552  // ==> f_c * 2^alpha <= c * 2^e * 2^q
15553  //
15554  // and since the c's are normalized, 2^(q-1) <= f_c,
15555  //
15556  // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
15557  // ==> 2^(alpha - e - 1) <= c
15558  //
15559  // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
15560  //
15561  // k = ceil( log_10( 2^(alpha - e - 1) ) )
15562  // = ceil( (alpha - e - 1) * log_10(2) )
15563  //
15564  // From the paper:
15565  // "In theory the result of the procedure could be wrong since c is rounded,
15566  // and the computation itself is approximated [...]. In practice, however,
15567  // this simple function is sufficient."
15568  //
15569  // For IEEE double precision floating-point numbers converted into
15570  // normalized diyfp's w = f * 2^e, with q = 64,
15571  //
15572  // e >= -1022 (min IEEE exponent)
15573  // -52 (p - 1)
15574  // -52 (p - 1, possibly normalize denormal IEEE numbers)
15575  // -11 (normalize the diyfp)
15576  // = -1137
15577  //
15578  // and
15579  //
15580  // e <= +1023 (max IEEE exponent)
15581  // -52 (p - 1)
15582  // -11 (normalize the diyfp)
15583  // = 960
15584  //
15585  // This binary exponent range [-1137,960] results in a decimal exponent
15586  // range [-307,324]. One does not need to store a cached power for each
15587  // k in this range. For each such k it suffices to find a cached power
15588  // such that the exponent of the product lies in [alpha,gamma].
15589  // This implies that the difference of the decimal exponents of adjacent
15590  // table entries must be less than or equal to
15591  //
15592  // floor( (gamma - alpha) * log_10(2) ) = 8.
15593  //
15594  // (A smaller distance gamma-alpha would require a larger table.)
15595 
15596  // NB:
15597  // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
15598 
15599  constexpr int kCachedPowersMinDecExp = -300;
15600  constexpr int kCachedPowersDecStep = 8;
15601 
15602  static constexpr std::array<cached_power, 79> kCachedPowers =
15603  {
15604  {
15605  { 0xAB70FE17C79AC6CA, -1060, -300 },
15606  { 0xFF77B1FCBEBCDC4F, -1034, -292 },
15607  { 0xBE5691EF416BD60C, -1007, -284 },
15608  { 0x8DD01FAD907FFC3C, -980, -276 },
15609  { 0xD3515C2831559A83, -954, -268 },
15610  { 0x9D71AC8FADA6C9B5, -927, -260 },
15611  { 0xEA9C227723EE8BCB, -901, -252 },
15612  { 0xAECC49914078536D, -874, -244 },
15613  { 0x823C12795DB6CE57, -847, -236 },
15614  { 0xC21094364DFB5637, -821, -228 },
15615  { 0x9096EA6F3848984F, -794, -220 },
15616  { 0xD77485CB25823AC7, -768, -212 },
15617  { 0xA086CFCD97BF97F4, -741, -204 },
15618  { 0xEF340A98172AACE5, -715, -196 },
15619  { 0xB23867FB2A35B28E, -688, -188 },
15620  { 0x84C8D4DFD2C63F3B, -661, -180 },
15621  { 0xC5DD44271AD3CDBA, -635, -172 },
15622  { 0x936B9FCEBB25C996, -608, -164 },
15623  { 0xDBAC6C247D62A584, -582, -156 },
15624  { 0xA3AB66580D5FDAF6, -555, -148 },
15625  { 0xF3E2F893DEC3F126, -529, -140 },
15626  { 0xB5B5ADA8AAFF80B8, -502, -132 },
15627  { 0x87625F056C7C4A8B, -475, -124 },
15628  { 0xC9BCFF6034C13053, -449, -116 },
15629  { 0x964E858C91BA2655, -422, -108 },
15630  { 0xDFF9772470297EBD, -396, -100 },
15631  { 0xA6DFBD9FB8E5B88F, -369, -92 },
15632  { 0xF8A95FCF88747D94, -343, -84 },
15633  { 0xB94470938FA89BCF, -316, -76 },
15634  { 0x8A08F0F8BF0F156B, -289, -68 },
15635  { 0xCDB02555653131B6, -263, -60 },
15636  { 0x993FE2C6D07B7FAC, -236, -52 },
15637  { 0xE45C10C42A2B3B06, -210, -44 },
15638  { 0xAA242499697392D3, -183, -36 },
15639  { 0xFD87B5F28300CA0E, -157, -28 },
15640  { 0xBCE5086492111AEB, -130, -20 },
15641  { 0x8CBCCC096F5088CC, -103, -12 },
15642  { 0xD1B71758E219652C, -77, -4 },
15643  { 0x9C40000000000000, -50, 4 },
15644  { 0xE8D4A51000000000, -24, 12 },
15645  { 0xAD78EBC5AC620000, 3, 20 },
15646  { 0x813F3978F8940984, 30, 28 },
15647  { 0xC097CE7BC90715B3, 56, 36 },
15648  { 0x8F7E32CE7BEA5C70, 83, 44 },
15649  { 0xD5D238A4ABE98068, 109, 52 },
15650  { 0x9F4F2726179A2245, 136, 60 },
15651  { 0xED63A231D4C4FB27, 162, 68 },
15652  { 0xB0DE65388CC8ADA8, 189, 76 },
15653  { 0x83C7088E1AAB65DB, 216, 84 },
15654  { 0xC45D1DF942711D9A, 242, 92 },
15655  { 0x924D692CA61BE758, 269, 100 },
15656  { 0xDA01EE641A708DEA, 295, 108 },
15657  { 0xA26DA3999AEF774A, 322, 116 },
15658  { 0xF209787BB47D6B85, 348, 124 },
15659  { 0xB454E4A179DD1877, 375, 132 },
15660  { 0x865B86925B9BC5C2, 402, 140 },
15661  { 0xC83553C5C8965D3D, 428, 148 },
15662  { 0x952AB45CFA97A0B3, 455, 156 },
15663  { 0xDE469FBD99A05FE3, 481, 164 },
15664  { 0xA59BC234DB398C25, 508, 172 },
15665  { 0xF6C69A72A3989F5C, 534, 180 },
15666  { 0xB7DCBF5354E9BECE, 561, 188 },
15667  { 0x88FCF317F22241E2, 588, 196 },
15668  { 0xCC20CE9BD35C78A5, 614, 204 },
15669  { 0x98165AF37B2153DF, 641, 212 },
15670  { 0xE2A0B5DC971F303A, 667, 220 },
15671  { 0xA8D9D1535CE3B396, 694, 228 },
15672  { 0xFB9B7CD9A4A7443C, 720, 236 },
15673  { 0xBB764C4CA7A44410, 747, 244 },
15674  { 0x8BAB8EEFB6409C1A, 774, 252 },
15675  { 0xD01FEF10A657842C, 800, 260 },
15676  { 0x9B10A4E5E9913129, 827, 268 },
15677  { 0xE7109BFBA19C0C9D, 853, 276 },
15678  { 0xAC2820D9623BF429, 880, 284 },
15679  { 0x80444B5E7AA7CF85, 907, 292 },
15680  { 0xBF21E44003ACDD2D, 933, 300 },
15681  { 0x8E679C2F5E44FF8F, 960, 308 },
15682  { 0xD433179D9C8CB841, 986, 316 },
15683  { 0x9E19DB92B4E31BA9, 1013, 324 },
15684  }
15685  };
15686 
15687  // This computation gives exactly the same results for k as
15688  // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
15689  // for |e| <= 1500, but doesn't require floating-point operations.
15690  // NB: log_10(2) ~= 78913 / 2^18
15691  JSON_ASSERT(e >= -1500);
15692  JSON_ASSERT(e <= 1500);
15693  const int f = kAlpha - e - 1;
15694  const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
15695 
15696  const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
15697  JSON_ASSERT(index >= 0);
15698  JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
15699 
15700  const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
15701  JSON_ASSERT(kAlpha <= cached.e + e + 64);
15702  JSON_ASSERT(kGamma >= cached.e + e + 64);
15703 
15704  return cached;
15705 }
15706 
15711 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
15712 {
15713  // LCOV_EXCL_START
15714  if (n >= 1000000000)
15715  {
15716  pow10 = 1000000000;
15717  return 10;
15718  }
15719  // LCOV_EXCL_STOP
15720  if (n >= 100000000)
15721  {
15722  pow10 = 100000000;
15723  return 9;
15724  }
15725  if (n >= 10000000)
15726  {
15727  pow10 = 10000000;
15728  return 8;
15729  }
15730  if (n >= 1000000)
15731  {
15732  pow10 = 1000000;
15733  return 7;
15734  }
15735  if (n >= 100000)
15736  {
15737  pow10 = 100000;
15738  return 6;
15739  }
15740  if (n >= 10000)
15741  {
15742  pow10 = 10000;
15743  return 5;
15744  }
15745  if (n >= 1000)
15746  {
15747  pow10 = 1000;
15748  return 4;
15749  }
15750  if (n >= 100)
15751  {
15752  pow10 = 100;
15753  return 3;
15754  }
15755  if (n >= 10)
15756  {
15757  pow10 = 10;
15758  return 2;
15759  }
15760 
15761  pow10 = 1;
15762  return 1;
15763 }
15764 
15765 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
15766  std::uint64_t rest, std::uint64_t ten_k)
15767 {
15768  JSON_ASSERT(len >= 1);
15769  JSON_ASSERT(dist <= delta);
15770  JSON_ASSERT(rest <= delta);
15771  JSON_ASSERT(ten_k > 0);
15772 
15773  // <--------------------------- delta ---->
15774  // <---- dist --------->
15775  // --------------[------------------+-------------------]--------------
15776  // M- w M+
15777  //
15778  // ten_k
15779  // <------>
15780  // <---- rest ---->
15781  // --------------[------------------+----+--------------]--------------
15782  // w V
15783  // = buf * 10^k
15784  //
15785  // ten_k represents a unit-in-the-last-place in the decimal representation
15786  // stored in buf.
15787  // Decrement buf by ten_k while this takes buf closer to w.
15788 
15789  // The tests are written in this order to avoid overflow in unsigned
15790  // integer arithmetic.
15791 
15792  while (rest < dist
15793  && delta - rest >= ten_k
15794  && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
15795  {
15796  JSON_ASSERT(buf[len - 1] != '0');
15797  buf[len - 1]--;
15798  rest += ten_k;
15799  }
15800 }
15801 
15806 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
15807  diyfp M_minus, diyfp w, diyfp M_plus)
15808 {
15809  static_assert(kAlpha >= -60, "internal error");
15810  static_assert(kGamma <= -32, "internal error");
15811 
15812  // Generates the digits (and the exponent) of a decimal floating-point
15813  // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
15814  // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
15815  //
15816  // <--------------------------- delta ---->
15817  // <---- dist --------->
15818  // --------------[------------------+-------------------]--------------
15819  // M- w M+
15820  //
15821  // Grisu2 generates the digits of M+ from left to right and stops as soon as
15822  // V is in [M-,M+].
15823 
15824  JSON_ASSERT(M_plus.e >= kAlpha);
15825  JSON_ASSERT(M_plus.e <= kGamma);
15826 
15827  std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
15828  std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
15829 
15830  // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
15831  //
15832  // M+ = f * 2^e
15833  // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
15834  // = ((p1 ) * 2^-e + (p2 )) * 2^e
15835  // = p1 + p2 * 2^e
15836 
15837  const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
15838 
15839  auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
15840  std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
15841 
15842  // 1)
15843  //
15844  // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
15845 
15846  JSON_ASSERT(p1 > 0);
15847 
15848  std::uint32_t pow10{};
15849  const int k = find_largest_pow10(p1, pow10);
15850 
15851  // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
15852  //
15853  // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
15854  // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
15855  //
15856  // M+ = p1 + p2 * 2^e
15857  // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
15858  // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
15859  // = d[k-1] * 10^(k-1) + ( rest) * 2^e
15860  //
15861  // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
15862  //
15863  // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
15864  //
15865  // but stop as soon as
15866  //
15867  // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
15868 
15869  int n = k;
15870  while (n > 0)
15871  {
15872  // Invariants:
15873  // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
15874  // pow10 = 10^(n-1) <= p1 < 10^n
15875  //
15876  const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
15877  const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
15878  //
15879  // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
15880  // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
15881  //
15882  JSON_ASSERT(d <= 9);
15883  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15884  //
15885  // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
15886  //
15887  p1 = r;
15888  n--;
15889  //
15890  // M+ = buffer * 10^n + (p1 + p2 * 2^e)
15891  // pow10 = 10^n
15892  //
15893 
15894  // Now check if enough digits have been generated.
15895  // Compute
15896  //
15897  // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
15898  //
15899  // Note:
15900  // Since rest and delta share the same exponent e, it suffices to
15901  // compare the significands.
15902  const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
15903  if (rest <= delta)
15904  {
15905  // V = buffer * 10^n, with M- <= V <= M+.
15906 
15907  decimal_exponent += n;
15908 
15909  // We may now just stop. But instead look if the buffer could be
15910  // decremented to bring V closer to w.
15911  //
15912  // pow10 = 10^n is now 1 ulp in the decimal representation V.
15913  // The rounding procedure works with diyfp's with an implicit
15914  // exponent of e.
15915  //
15916  // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
15917  //
15918  const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
15919  grisu2_round(buffer, length, dist, delta, rest, ten_n);
15920 
15921  return;
15922  }
15923 
15924  pow10 /= 10;
15925  //
15926  // pow10 = 10^(n-1) <= p1 < 10^n
15927  // Invariants restored.
15928  }
15929 
15930  // 2)
15931  //
15932  // The digits of the integral part have been generated:
15933  //
15934  // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
15935  // = buffer + p2 * 2^e
15936  //
15937  // Now generate the digits of the fractional part p2 * 2^e.
15938  //
15939  // Note:
15940  // No decimal point is generated: the exponent is adjusted instead.
15941  //
15942  // p2 actually represents the fraction
15943  //
15944  // p2 * 2^e
15945  // = p2 / 2^-e
15946  // = d[-1] / 10^1 + d[-2] / 10^2 + ...
15947  //
15948  // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
15949  //
15950  // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
15951  // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
15952  //
15953  // using
15954  //
15955  // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
15956  // = ( d) * 2^-e + ( r)
15957  //
15958  // or
15959  // 10^m * p2 * 2^e = d + r * 2^e
15960  //
15961  // i.e.
15962  //
15963  // M+ = buffer + p2 * 2^e
15964  // = buffer + 10^-m * (d + r * 2^e)
15965  // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
15966  //
15967  // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
15968 
15969  JSON_ASSERT(p2 > delta);
15970 
15971  int m = 0;
15972  for (;;)
15973  {
15974  // Invariant:
15975  // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
15976  // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
15977  // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
15978  // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
15979  //
15980  JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
15981  p2 *= 10;
15982  const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
15983  const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
15984  //
15985  // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
15986  // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
15987  // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
15988  //
15989  JSON_ASSERT(d <= 9);
15990  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15991  //
15992  // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
15993  //
15994  p2 = r;
15995  m++;
15996  //
15997  // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
15998  // Invariant restored.
15999 
16000  // Check if enough digits have been generated.
16001  //
16002  // 10^-m * p2 * 2^e <= delta * 2^e
16003  // p2 * 2^e <= 10^m * delta * 2^e
16004  // p2 <= 10^m * delta
16005  delta *= 10;
16006  dist *= 10;
16007  if (p2 <= delta)
16008  {
16009  break;
16010  }
16011  }
16012 
16013  // V = buffer * 10^-m, with M- <= V <= M+.
16014 
16015  decimal_exponent -= m;
16016 
16017  // 1 ulp in the decimal representation is now 10^-m.
16018  // Since delta and dist are now scaled by 10^m, we need to do the
16019  // same with ulp in order to keep the units in sync.
16020  //
16021  // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
16022  //
16023  const std::uint64_t ten_m = one.f;
16024  grisu2_round(buffer, length, dist, delta, p2, ten_m);
16025 
16026  // By construction this algorithm generates the shortest possible decimal
16027  // number (Loitsch, Theorem 6.2) which rounds back to w.
16028  // For an input number of precision p, at least
16029  //
16030  // N = 1 + ceil(p * log_10(2))
16031  //
16032  // decimal digits are sufficient to identify all binary floating-point
16033  // numbers (Matula, "In-and-Out conversions").
16034  // This implies that the algorithm does not produce more than N decimal
16035  // digits.
16036  //
16037  // N = 17 for p = 53 (IEEE double precision)
16038  // N = 9 for p = 24 (IEEE single precision)
16039 }
16040 
16047 inline void grisu2(char* buf, int& len, int& decimal_exponent,
16048  diyfp m_minus, diyfp v, diyfp m_plus)
16049 {
16050  JSON_ASSERT(m_plus.e == m_minus.e);
16051  JSON_ASSERT(m_plus.e == v.e);
16052 
16053  // --------(-----------------------+-----------------------)-------- (A)
16054  // m- v m+
16055  //
16056  // --------------------(-----------+-----------------------)-------- (B)
16057  // m- v m+
16058  //
16059  // First scale v (and m- and m+) such that the exponent is in the range
16060  // [alpha, gamma].
16061 
16062  const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
16063 
16064  const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
16065 
16066  // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
16067  const diyfp w = diyfp::mul(v, c_minus_k);
16068  const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
16069  const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
16070 
16071  // ----(---+---)---------------(---+---)---------------(---+---)----
16072  // w- w w+
16073  // = c*m- = c*v = c*m+
16074  //
16075  // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
16076  // w+ are now off by a small amount.
16077  // In fact:
16078  //
16079  // w - v * 10^k < 1 ulp
16080  //
16081  // To account for this inaccuracy, add resp. subtract 1 ulp.
16082  //
16083  // --------+---[---------------(---+---)---------------]---+--------
16084  // w- M- w M+ w+
16085  //
16086  // Now any number in [M-, M+] (bounds included) will round to w when input,
16087  // regardless of how the input rounding algorithm breaks ties.
16088  //
16089  // And digit_gen generates the shortest possible such number in [M-, M+].
16090  // Note that this does not mean that Grisu2 always generates the shortest
16091  // possible number in the interval (m-, m+).
16092  const diyfp M_minus(w_minus.f + 1, w_minus.e);
16093  const diyfp M_plus (w_plus.f - 1, w_plus.e );
16094 
16095  decimal_exponent = -cached.k; // = -(-k) = k
16096 
16097  grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
16098 }
16099 
16105 template<typename FloatType>
16107 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
16108 {
16109  static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
16110  "internal error: not enough precision");
16111 
16112  JSON_ASSERT(std::isfinite(value));
16113  JSON_ASSERT(value > 0);
16114 
16115  // If the neighbors (and boundaries) of 'value' are always computed for double-precision
16116  // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
16117  // decimal representations are not exactly "short".
16118  //
16119  // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
16120  // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
16121  // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
16122  // does.
16123  // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
16124  // representation using the corresponding std::from_chars function recovers value exactly". That
16125  // indicates that single precision floating-point numbers should be recovered using
16126  // 'std::strtof'.
16127  //
16128  // NB: If the neighbors are computed for single-precision numbers, there is a single float
16129  // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
16130  // value is off by 1 ulp.
16131 #if 0
16132  const boundaries w = compute_boundaries(static_cast<double>(value));
16133 #else
16134  const boundaries w = compute_boundaries(value);
16135 #endif
16136 
16137  grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
16138 }
16139 
16147 inline char* append_exponent(char* buf, int e)
16148 {
16149  JSON_ASSERT(e > -1000);
16150  JSON_ASSERT(e < 1000);
16151 
16152  if (e < 0)
16153  {
16154  e = -e;
16155  *buf++ = '-';
16156  }
16157  else
16158  {
16159  *buf++ = '+';
16160  }
16161 
16162  auto k = static_cast<std::uint32_t>(e);
16163  if (k < 10)
16164  {
16165  // Always print at least two digits in the exponent.
16166  // This is for compatibility with printf("%g").
16167  *buf++ = '0';
16168  *buf++ = static_cast<char>('0' + k);
16169  }
16170  else if (k < 100)
16171  {
16172  *buf++ = static_cast<char>('0' + k / 10);
16173  k %= 10;
16174  *buf++ = static_cast<char>('0' + k);
16175  }
16176  else
16177  {
16178  *buf++ = static_cast<char>('0' + k / 100);
16179  k %= 100;
16180  *buf++ = static_cast<char>('0' + k / 10);
16181  k %= 10;
16182  *buf++ = static_cast<char>('0' + k);
16183  }
16184 
16185  return buf;
16186 }
16187 
16199 inline char* format_buffer(char* buf, int len, int decimal_exponent,
16200  int min_exp, int max_exp)
16201 {
16202  JSON_ASSERT(min_exp < 0);
16203  JSON_ASSERT(max_exp > 0);
16204 
16205  const int k = len;
16206  const int n = len + decimal_exponent;
16207 
16208  // v = buf * 10^(n-k)
16209  // k is the length of the buffer (number of decimal digits)
16210  // n is the position of the decimal point relative to the start of the buffer.
16211 
16212  if (k <= n && n <= max_exp)
16213  {
16214  // digits[000]
16215  // len <= max_exp + 2
16216 
16217  std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
16218  // Make it look like a floating-point number (#362, #378)
16219  buf[n + 0] = '.';
16220  buf[n + 1] = '0';
16221  return buf + (static_cast<size_t>(n) + 2);
16222  }
16223 
16224  if (0 < n && n <= max_exp)
16225  {
16226  // dig.its
16227  // len <= max_digits10 + 1
16228 
16229  JSON_ASSERT(k > n);
16230 
16231  std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
16232  buf[n] = '.';
16233  return buf + (static_cast<size_t>(k) + 1U);
16234  }
16235 
16236  if (min_exp < n && n <= 0)
16237  {
16238  // 0.[000]digits
16239  // len <= 2 + (-min_exp - 1) + max_digits10
16240 
16241  std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
16242  buf[0] = '0';
16243  buf[1] = '.';
16244  std::memset(buf + 2, '0', static_cast<size_t>(-n));
16245  return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
16246  }
16247 
16248  if (k == 1)
16249  {
16250  // dE+123
16251  // len <= 1 + 5
16252 
16253  buf += 1;
16254  }
16255  else
16256  {
16257  // d.igitsE+123
16258  // len <= max_digits10 + 1 + 5
16259 
16260  std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
16261  buf[1] = '.';
16262  buf += 1 + static_cast<size_t>(k);
16263  }
16264 
16265  *buf++ = 'e';
16266  return append_exponent(buf, n - 1);
16267 }
16268 
16269 } // namespace dtoa_impl
16270 
16281 template<typename FloatType>
16284 char* to_chars(char* first, const char* last, FloatType value)
16285 {
16286  static_cast<void>(last); // maybe unused - fix warning
16287  JSON_ASSERT(std::isfinite(value));
16288 
16289  // Use signbit(value) instead of (value < 0) since signbit works for -0.
16290  if (std::signbit(value))
16291  {
16292  value = -value;
16293  *first++ = '-';
16294  }
16295 
16296 #ifdef __GNUC__
16297 #pragma GCC diagnostic push
16298 #pragma GCC diagnostic ignored "-Wfloat-equal"
16299 #endif
16300  if (value == 0) // +-0
16301  {
16302  *first++ = '0';
16303  // Make it look like a floating-point number (#362, #378)
16304  *first++ = '.';
16305  *first++ = '0';
16306  return first;
16307  }
16308 #ifdef __GNUC__
16309 #pragma GCC diagnostic pop
16310 #endif
16311 
16312  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
16313 
16314  // Compute v = buffer * 10^decimal_exponent.
16315  // The decimal digits are stored in the buffer, which needs to be interpreted
16316  // as an unsigned decimal integer.
16317  // len is the length of the buffer, i.e. the number of decimal digits.
16318  int len = 0;
16319  int decimal_exponent = 0;
16320  dtoa_impl::grisu2(first, len, decimal_exponent, value);
16321 
16322  JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
16323 
16324  // Format the buffer like printf("%.*g", prec, value)
16325  constexpr int kMinExp = -4;
16326  // Use digits10 here to increase compatibility with version 2.
16327  constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
16328 
16329  JSON_ASSERT(last - first >= kMaxExp + 2);
16330  JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
16331  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
16332 
16333  return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
16334 }
16335 
16336 } // namespace detail
16337 } // namespace nlohmann
16338 
16339 // #include <nlohmann/detail/exceptions.hpp>
16340 
16341 // #include <nlohmann/detail/macro_scope.hpp>
16342 
16343 // #include <nlohmann/detail/meta/cpp_future.hpp>
16344 
16345 // #include <nlohmann/detail/output/binary_writer.hpp>
16346 
16347 // #include <nlohmann/detail/output/output_adapters.hpp>
16348 
16349 // #include <nlohmann/detail/value_t.hpp>
16350 
16351 
16352 namespace nlohmann
16353 {
16354 namespace detail
16355 {
16357 // serialization //
16359 
16362 {
16363  strict,
16364  replace,
16365  ignore
16366 };
16367 
16368 template<typename BasicJsonType>
16370 {
16371  using string_t = typename BasicJsonType::string_t;
16372  using number_float_t = typename BasicJsonType::number_float_t;
16373  using number_integer_t = typename BasicJsonType::number_integer_t;
16374  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
16375  using binary_char_t = typename BasicJsonType::binary_t::value_type;
16376  static constexpr std::uint8_t UTF8_ACCEPT = 0;
16377  static constexpr std::uint8_t UTF8_REJECT = 1;
16378 
16379  public:
16385  serializer(output_adapter_t<char> s, const char ichar,
16386  error_handler_t error_handler_ = error_handler_t::strict)
16387  : o(std::move(s))
16388  , loc(std::localeconv())
16389  , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
16390  , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
16391  , indent_char(ichar)
16392  , indent_string(512, indent_char)
16393  , error_handler(error_handler_)
16394  {}
16395 
16396  // delete because of pointer members
16397  serializer(const serializer&) = delete;
16398  serializer& operator=(const serializer&) = delete;
16399  serializer(serializer&&) = delete;
16400  serializer& operator=(serializer&&) = delete;
16401  ~serializer() = default;
16402 
16425  void dump(const BasicJsonType& val,
16426  const bool pretty_print,
16427  const bool ensure_ascii,
16428  const unsigned int indent_step,
16429  const unsigned int current_indent = 0)
16430  {
16431  switch (val.m_type)
16432  {
16433  case value_t::object:
16434  {
16435  if (val.m_value.object->empty())
16436  {
16437  o->write_characters("{}", 2);
16438  return;
16439  }
16440 
16441  if (pretty_print)
16442  {
16443  o->write_characters("{\n", 2);
16444 
16445  // variable to hold indentation for recursive calls
16446  const auto new_indent = current_indent + indent_step;
16447  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16448  {
16449  indent_string.resize(indent_string.size() * 2, ' ');
16450  }
16451 
16452  // first n-1 elements
16453  auto i = val.m_value.object->cbegin();
16454  for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16455  {
16456  o->write_characters(indent_string.c_str(), new_indent);
16457  o->write_character('\"');
16458  dump_escaped(i->first, ensure_ascii);
16459  o->write_characters("\": ", 3);
16460  dump(i->second, true, ensure_ascii, indent_step, new_indent);
16461  o->write_characters(",\n", 2);
16462  }
16463 
16464  // last element
16465  JSON_ASSERT(i != val.m_value.object->cend());
16466  JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16467  o->write_characters(indent_string.c_str(), new_indent);
16468  o->write_character('\"');
16469  dump_escaped(i->first, ensure_ascii);
16470  o->write_characters("\": ", 3);
16471  dump(i->second, true, ensure_ascii, indent_step, new_indent);
16472 
16473  o->write_character('\n');
16474  o->write_characters(indent_string.c_str(), current_indent);
16475  o->write_character('}');
16476  }
16477  else
16478  {
16479  o->write_character('{');
16480 
16481  // first n-1 elements
16482  auto i = val.m_value.object->cbegin();
16483  for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16484  {
16485  o->write_character('\"');
16486  dump_escaped(i->first, ensure_ascii);
16487  o->write_characters("\":", 2);
16488  dump(i->second, false, ensure_ascii, indent_step, current_indent);
16489  o->write_character(',');
16490  }
16491 
16492  // last element
16493  JSON_ASSERT(i != val.m_value.object->cend());
16494  JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16495  o->write_character('\"');
16496  dump_escaped(i->first, ensure_ascii);
16497  o->write_characters("\":", 2);
16498  dump(i->second, false, ensure_ascii, indent_step, current_indent);
16499 
16500  o->write_character('}');
16501  }
16502 
16503  return;
16504  }
16505 
16506  case value_t::array:
16507  {
16508  if (val.m_value.array->empty())
16509  {
16510  o->write_characters("[]", 2);
16511  return;
16512  }
16513 
16514  if (pretty_print)
16515  {
16516  o->write_characters("[\n", 2);
16517 
16518  // variable to hold indentation for recursive calls
16519  const auto new_indent = current_indent + indent_step;
16520  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16521  {
16522  indent_string.resize(indent_string.size() * 2, ' ');
16523  }
16524 
16525  // first n-1 elements
16526  for (auto i = val.m_value.array->cbegin();
16527  i != val.m_value.array->cend() - 1; ++i)
16528  {
16529  o->write_characters(indent_string.c_str(), new_indent);
16530  dump(*i, true, ensure_ascii, indent_step, new_indent);
16531  o->write_characters(",\n", 2);
16532  }
16533 
16534  // last element
16535  JSON_ASSERT(!val.m_value.array->empty());
16536  o->write_characters(indent_string.c_str(), new_indent);
16537  dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
16538 
16539  o->write_character('\n');
16540  o->write_characters(indent_string.c_str(), current_indent);
16541  o->write_character(']');
16542  }
16543  else
16544  {
16545  o->write_character('[');
16546 
16547  // first n-1 elements
16548  for (auto i = val.m_value.array->cbegin();
16549  i != val.m_value.array->cend() - 1; ++i)
16550  {
16551  dump(*i, false, ensure_ascii, indent_step, current_indent);
16552  o->write_character(',');
16553  }
16554 
16555  // last element
16556  JSON_ASSERT(!val.m_value.array->empty());
16557  dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
16558 
16559  o->write_character(']');
16560  }
16561 
16562  return;
16563  }
16564 
16565  case value_t::string:
16566  {
16567  o->write_character('\"');
16568  dump_escaped(*val.m_value.string, ensure_ascii);
16569  o->write_character('\"');
16570  return;
16571  }
16572 
16573  case value_t::binary:
16574  {
16575  if (pretty_print)
16576  {
16577  o->write_characters("{\n", 2);
16578 
16579  // variable to hold indentation for recursive calls
16580  const auto new_indent = current_indent + indent_step;
16581  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16582  {
16583  indent_string.resize(indent_string.size() * 2, ' ');
16584  }
16585 
16586  o->write_characters(indent_string.c_str(), new_indent);
16587 
16588  o->write_characters("\"bytes\": [", 10);
16589 
16590  if (!val.m_value.binary->empty())
16591  {
16592  for (auto i = val.m_value.binary->cbegin();
16593  i != val.m_value.binary->cend() - 1; ++i)
16594  {
16595  dump_integer(*i);
16596  o->write_characters(", ", 2);
16597  }
16598  dump_integer(val.m_value.binary->back());
16599  }
16600 
16601  o->write_characters("],\n", 3);
16602  o->write_characters(indent_string.c_str(), new_indent);
16603 
16604  o->write_characters("\"subtype\": ", 11);
16605  if (val.m_value.binary->has_subtype())
16606  {
16607  dump_integer(val.m_value.binary->subtype());
16608  }
16609  else
16610  {
16611  o->write_characters("null", 4);
16612  }
16613  o->write_character('\n');
16614  o->write_characters(indent_string.c_str(), current_indent);
16615  o->write_character('}');
16616  }
16617  else
16618  {
16619  o->write_characters("{\"bytes\":[", 10);
16620 
16621  if (!val.m_value.binary->empty())
16622  {
16623  for (auto i = val.m_value.binary->cbegin();
16624  i != val.m_value.binary->cend() - 1; ++i)
16625  {
16626  dump_integer(*i);
16627  o->write_character(',');
16628  }
16629  dump_integer(val.m_value.binary->back());
16630  }
16631 
16632  o->write_characters("],\"subtype\":", 12);
16633  if (val.m_value.binary->has_subtype())
16634  {
16635  dump_integer(val.m_value.binary->subtype());
16636  o->write_character('}');
16637  }
16638  else
16639  {
16640  o->write_characters("null}", 5);
16641  }
16642  }
16643  return;
16644  }
16645 
16646  case value_t::boolean:
16647  {
16648  if (val.m_value.boolean)
16649  {
16650  o->write_characters("true", 4);
16651  }
16652  else
16653  {
16654  o->write_characters("false", 5);
16655  }
16656  return;
16657  }
16658 
16659  case value_t::number_integer:
16660  {
16661  dump_integer(val.m_value.number_integer);
16662  return;
16663  }
16664 
16665  case value_t::number_unsigned:
16666  {
16667  dump_integer(val.m_value.number_unsigned);
16668  return;
16669  }
16670 
16671  case value_t::number_float:
16672  {
16673  dump_float(val.m_value.number_float);
16674  return;
16675  }
16676 
16677  case value_t::discarded:
16678  {
16679  o->write_characters("<discarded>", 11);
16680  return;
16681  }
16682 
16683  case value_t::null:
16684  {
16685  o->write_characters("null", 4);
16686  return;
16687  }
16688 
16689  default: // LCOV_EXCL_LINE
16690  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16691  }
16692  }
16693 
16709  void dump_escaped(const string_t& s, const bool ensure_ascii)
16710  {
16711  std::uint32_t codepoint{};
16712  std::uint8_t state = UTF8_ACCEPT;
16713  std::size_t bytes = 0; // number of bytes written to string_buffer
16714 
16715  // number of bytes written at the point of the last valid byte
16716  std::size_t bytes_after_last_accept = 0;
16717  std::size_t undumped_chars = 0;
16718 
16719  for (std::size_t i = 0; i < s.size(); ++i)
16720  {
16721  const auto byte = static_cast<std::uint8_t>(s[i]);
16722 
16723  switch (decode(state, codepoint, byte))
16724  {
16725  case UTF8_ACCEPT: // decode found a new code point
16726  {
16727  switch (codepoint)
16728  {
16729  case 0x08: // backspace
16730  {
16731  string_buffer[bytes++] = '\\';
16732  string_buffer[bytes++] = 'b';
16733  break;
16734  }
16735 
16736  case 0x09: // horizontal tab
16737  {
16738  string_buffer[bytes++] = '\\';
16739  string_buffer[bytes++] = 't';
16740  break;
16741  }
16742 
16743  case 0x0A: // newline
16744  {
16745  string_buffer[bytes++] = '\\';
16746  string_buffer[bytes++] = 'n';
16747  break;
16748  }
16749 
16750  case 0x0C: // formfeed
16751  {
16752  string_buffer[bytes++] = '\\';
16753  string_buffer[bytes++] = 'f';
16754  break;
16755  }
16756 
16757  case 0x0D: // carriage return
16758  {
16759  string_buffer[bytes++] = '\\';
16760  string_buffer[bytes++] = 'r';
16761  break;
16762  }
16763 
16764  case 0x22: // quotation mark
16765  {
16766  string_buffer[bytes++] = '\\';
16767  string_buffer[bytes++] = '\"';
16768  break;
16769  }
16770 
16771  case 0x5C: // reverse solidus
16772  {
16773  string_buffer[bytes++] = '\\';
16774  string_buffer[bytes++] = '\\';
16775  break;
16776  }
16777 
16778  default:
16779  {
16780  // escape control characters (0x00..0x1F) or, if
16781  // ensure_ascii parameter is used, non-ASCII characters
16782  if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
16783  {
16784  if (codepoint <= 0xFFFF)
16785  {
16786  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16787  (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
16788  static_cast<std::uint16_t>(codepoint));
16789  bytes += 6;
16790  }
16791  else
16792  {
16793  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16794  (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
16795  static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
16796  static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
16797  bytes += 12;
16798  }
16799  }
16800  else
16801  {
16802  // copy byte to buffer (all previous bytes
16803  // been copied have in default case above)
16804  string_buffer[bytes++] = s[i];
16805  }
16806  break;
16807  }
16808  }
16809 
16810  // write buffer and reset index; there must be 13 bytes
16811  // left, as this is the maximal number of bytes to be
16812  // written ("\uxxxx\uxxxx\0") for one code point
16813  if (string_buffer.size() - bytes < 13)
16814  {
16815  o->write_characters(string_buffer.data(), bytes);
16816  bytes = 0;
16817  }
16818 
16819  // remember the byte position of this accept
16820  bytes_after_last_accept = bytes;
16821  undumped_chars = 0;
16822  break;
16823  }
16824 
16825  case UTF8_REJECT: // decode found invalid UTF-8 byte
16826  {
16827  switch (error_handler)
16828  {
16829  case error_handler_t::strict:
16830  {
16831  std::string sn(9, '\0');
16832  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16833  (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
16834  JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn, BasicJsonType()));
16835  }
16836 
16837  case error_handler_t::ignore:
16838  case error_handler_t::replace:
16839  {
16840  // in case we saw this character the first time, we
16841  // would like to read it again, because the byte
16842  // may be OK for itself, but just not OK for the
16843  // previous sequence
16844  if (undumped_chars > 0)
16845  {
16846  --i;
16847  }
16848 
16849  // reset length buffer to the last accepted index;
16850  // thus removing/ignoring the invalid characters
16851  bytes = bytes_after_last_accept;
16852 
16853  if (error_handler == error_handler_t::replace)
16854  {
16855  // add a replacement character
16856  if (ensure_ascii)
16857  {
16858  string_buffer[bytes++] = '\\';
16859  string_buffer[bytes++] = 'u';
16860  string_buffer[bytes++] = 'f';
16861  string_buffer[bytes++] = 'f';
16862  string_buffer[bytes++] = 'f';
16863  string_buffer[bytes++] = 'd';
16864  }
16865  else
16866  {
16867  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
16868  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
16869  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
16870  }
16871 
16872  // write buffer and reset index; there must be 13 bytes
16873  // left, as this is the maximal number of bytes to be
16874  // written ("\uxxxx\uxxxx\0") for one code point
16875  if (string_buffer.size() - bytes < 13)
16876  {
16877  o->write_characters(string_buffer.data(), bytes);
16878  bytes = 0;
16879  }
16880 
16881  bytes_after_last_accept = bytes;
16882  }
16883 
16884  undumped_chars = 0;
16885 
16886  // continue processing the string
16887  state = UTF8_ACCEPT;
16888  break;
16889  }
16890 
16891  default: // LCOV_EXCL_LINE
16892  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16893  }
16894  break;
16895  }
16896 
16897  default: // decode found yet incomplete multi-byte code point
16898  {
16899  if (!ensure_ascii)
16900  {
16901  // code point will not be escaped - copy byte to buffer
16902  string_buffer[bytes++] = s[i];
16903  }
16904  ++undumped_chars;
16905  break;
16906  }
16907  }
16908  }
16909 
16910  // we finished processing the string
16911  if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
16912  {
16913  // write buffer
16914  if (bytes > 0)
16915  {
16916  o->write_characters(string_buffer.data(), bytes);
16917  }
16918  }
16919  else
16920  {
16921  // we finish reading, but do not accept: string was incomplete
16922  switch (error_handler)
16923  {
16924  case error_handler_t::strict:
16925  {
16926  std::string sn(9, '\0');
16927  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16928  (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
16929  JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn, BasicJsonType()));
16930  }
16931 
16932  case error_handler_t::ignore:
16933  {
16934  // write all accepted bytes
16935  o->write_characters(string_buffer.data(), bytes_after_last_accept);
16936  break;
16937  }
16938 
16939  case error_handler_t::replace:
16940  {
16941  // write all accepted bytes
16942  o->write_characters(string_buffer.data(), bytes_after_last_accept);
16943  // add a replacement character
16944  if (ensure_ascii)
16945  {
16946  o->write_characters("\\ufffd", 6);
16947  }
16948  else
16949  {
16950  o->write_characters("\xEF\xBF\xBD", 3);
16951  }
16952  break;
16953  }
16954 
16955  default: // LCOV_EXCL_LINE
16956  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16957  }
16958  }
16959  }
16960 
16961  private:
16970  inline unsigned int count_digits(number_unsigned_t x) noexcept
16971  {
16972  unsigned int n_digits = 1;
16973  for (;;)
16974  {
16975  if (x < 10)
16976  {
16977  return n_digits;
16978  }
16979  if (x < 100)
16980  {
16981  return n_digits + 1;
16982  }
16983  if (x < 1000)
16984  {
16985  return n_digits + 2;
16986  }
16987  if (x < 10000)
16988  {
16989  return n_digits + 3;
16990  }
16991  x = x / 10000u;
16992  n_digits += 4;
16993  }
16994  }
16995 
17005  template < typename NumberType, detail::enable_if_t <
17006  std::is_integral<NumberType>::value ||
17007  std::is_same<NumberType, number_unsigned_t>::value ||
17008  std::is_same<NumberType, number_integer_t>::value ||
17009  std::is_same<NumberType, binary_char_t>::value,
17010  int > = 0 >
17011  void dump_integer(NumberType x)
17012  {
17013  static constexpr std::array<std::array<char, 2>, 100> digits_to_99
17014  {
17015  {
17016  {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
17017  {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
17018  {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
17019  {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
17020  {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
17021  {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
17022  {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
17023  {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
17024  {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
17025  {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
17026  }
17027  };
17028 
17029  // special case for "0"
17030  if (x == 0)
17031  {
17032  o->write_character('0');
17033  return;
17034  }
17035 
17036  // use a pointer to fill the buffer
17037  auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17038 
17039  const bool is_negative = std::is_signed<NumberType>::value && !(x >= 0); // see issue #755
17040  number_unsigned_t abs_value;
17041 
17042  unsigned int n_chars{};
17043 
17044  if (is_negative)
17045  {
17046  *buffer_ptr = '-';
17047  abs_value = remove_sign(static_cast<number_integer_t>(x));
17048 
17049  // account one more byte for the minus sign
17050  n_chars = 1 + count_digits(abs_value);
17051  }
17052  else
17053  {
17054  abs_value = static_cast<number_unsigned_t>(x);
17055  n_chars = count_digits(abs_value);
17056  }
17057 
17058  // spare 1 byte for '\0'
17059  JSON_ASSERT(n_chars < number_buffer.size() - 1);
17060 
17061  // jump to the end to generate the string from backward
17062  // so we later avoid reversing the result
17063  buffer_ptr += n_chars;
17064 
17065  // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
17066  // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
17067  while (abs_value >= 100)
17068  {
17069  const auto digits_index = static_cast<unsigned>((abs_value % 100));
17070  abs_value /= 100;
17071  *(--buffer_ptr) = digits_to_99[digits_index][1];
17072  *(--buffer_ptr) = digits_to_99[digits_index][0];
17073  }
17074 
17075  if (abs_value >= 10)
17076  {
17077  const auto digits_index = static_cast<unsigned>(abs_value);
17078  *(--buffer_ptr) = digits_to_99[digits_index][1];
17079  *(--buffer_ptr) = digits_to_99[digits_index][0];
17080  }
17081  else
17082  {
17083  *(--buffer_ptr) = static_cast<char>('0' + abs_value);
17084  }
17085 
17086  o->write_characters(number_buffer.data(), n_chars);
17087  }
17088 
17097  void dump_float(number_float_t x)
17098  {
17099  // NaN / inf
17100  if (!std::isfinite(x))
17101  {
17102  o->write_characters("null", 4);
17103  return;
17104  }
17105 
17106  // If number_float_t is an IEEE-754 single or double precision number,
17107  // use the Grisu2 algorithm to produce short numbers which are
17108  // guaranteed to round-trip, using strtof and strtod, resp.
17109  //
17110  // NB: The test below works if <long double> == <double>.
17111  static constexpr bool is_ieee_single_or_double
17112  = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
17113  (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
17114 
17115  dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
17116  }
17117 
17118  void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
17119  {
17120  auto* begin = number_buffer.data();
17121  auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
17122 
17123  o->write_characters(begin, static_cast<size_t>(end - begin));
17124  }
17125 
17126  void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
17127  {
17128  // get number of digits for a float -> text -> float round-trip
17129  static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
17130 
17131  // the actual conversion
17132  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17133  std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
17134 
17135  // negative value indicates an error
17136  JSON_ASSERT(len > 0);
17137  // check if buffer was large enough
17138  JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
17139 
17140  // erase thousands separator
17141  if (thousands_sep != '\0')
17142  {
17143  auto* const end = std::remove(number_buffer.begin(),
17144  number_buffer.begin() + len, thousands_sep);
17145  std::fill(end, number_buffer.end(), '\0');
17146  JSON_ASSERT((end - number_buffer.begin()) <= len);
17147  len = (end - number_buffer.begin());
17148  }
17149 
17150  // convert decimal point to '.'
17151  if (decimal_point != '\0' && decimal_point != '.')
17152  {
17153  auto* const dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
17154  if (dec_pos != number_buffer.end())
17155  {
17156  *dec_pos = '.';
17157  }
17158  }
17159 
17160  o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
17161 
17162  // determine if need to append ".0"
17163  const bool value_is_int_like =
17164  std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
17165  [](char c)
17166  {
17167  return c == '.' || c == 'e';
17168  });
17169 
17170  if (value_is_int_like)
17171  {
17172  o->write_characters(".0", 2);
17173  }
17174  }
17175 
17197  static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
17198  {
17199  static const std::array<std::uint8_t, 400> utf8d =
17200  {
17201  {
17202  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
17203  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
17204  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
17205  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
17206  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
17207  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
17208  8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
17209  0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
17210  0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
17211  0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
17212  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
17213  1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
17214  1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
17215  1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
17216  }
17217  };
17218 
17219  JSON_ASSERT(byte < utf8d.size());
17220  const std::uint8_t type = utf8d[byte];
17221 
17222  codep = (state != UTF8_ACCEPT)
17223  ? (byte & 0x3fu) | (codep << 6u)
17224  : (0xFFu >> type) & (byte);
17225 
17226  std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
17227  JSON_ASSERT(index < 400);
17228  state = utf8d[index];
17229  return state;
17230  }
17231 
17232  /*
17233  * Overload to make the compiler happy while it is instantiating
17234  * dump_integer for number_unsigned_t.
17235  * Must never be called.
17236  */
17237  number_unsigned_t remove_sign(number_unsigned_t x)
17238  {
17239  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17240  return x; // LCOV_EXCL_LINE
17241  }
17242 
17243  /*
17244  * Helper function for dump_integer
17245  *
17246  * This function takes a negative signed integer and returns its absolute
17247  * value as unsigned integer. The plus/minus shuffling is necessary as we can
17248  * not directly remove the sign of an arbitrary signed integer as the
17249  * absolute values of INT_MIN and INT_MAX are usually not the same. See
17250  * #1708 for details.
17251  */
17252  inline number_unsigned_t remove_sign(number_integer_t x) noexcept
17253  {
17254  JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
17255  return static_cast<number_unsigned_t>(-(x + 1)) + 1;
17256  }
17257 
17258  private:
17260  output_adapter_t<char> o = nullptr;
17261 
17263  std::array<char, 64> number_buffer{{}};
17264 
17266  const std::lconv* loc = nullptr;
17268  const char thousands_sep = '\0';
17270  const char decimal_point = '\0';
17271 
17273  std::array<char, 512> string_buffer{{}};
17274 
17276  const char indent_char;
17279 
17282 };
17283 } // namespace detail
17284 } // namespace nlohmann
17285 
17286 // #include <nlohmann/detail/value_t.hpp>
17287 
17288 // #include <nlohmann/json_fwd.hpp>
17289 
17290 // #include <nlohmann/ordered_map.hpp>
17291 
17292 
17293 #include <functional> // less
17294 #include <initializer_list> // initializer_list
17295 #include <iterator> // input_iterator_tag, iterator_traits
17296 #include <memory> // allocator
17297 #include <stdexcept> // for out_of_range
17298 #include <type_traits> // enable_if, is_convertible
17299 #include <utility> // pair
17300 #include <vector> // vector
17301 
17302 // #include <nlohmann/detail/macro_scope.hpp>
17303 
17304 
17305 namespace nlohmann
17306 {
17307 
17310 template <class Key, class T, class IgnoredLess = std::less<Key>,
17311  class Allocator = std::allocator<std::pair<const Key, T>>>
17312  struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
17313 {
17314  using key_type = Key;
17315  using mapped_type = T;
17316  using Container = std::vector<std::pair<const Key, T>, Allocator>;
17317  using typename Container::iterator;
17318  using typename Container::const_iterator;
17319  using typename Container::size_type;
17320  using typename Container::value_type;
17321 
17322  // Explicit constructors instead of `using Container::Container`
17323  // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
17324  ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
17325  template <class It>
17326  ordered_map(It first, It last, const Allocator& alloc = Allocator())
17327  : Container{first, last, alloc} {}
17328  ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
17329  : Container{init, alloc} {}
17330 
17331  std::pair<iterator, bool> emplace(const key_type& key, T&& t)
17332  {
17333  for (auto it = this->begin(); it != this->end(); ++it)
17334  {
17335  if (it->first == key)
17336  {
17337  return {it, false};
17338  }
17339  }
17340  Container::emplace_back(key, t);
17341  return {--this->end(), true};
17342  }
17343 
17344  T& operator[](const Key& key)
17345  {
17346  return emplace(key, T{}).first->second;
17347  }
17348 
17349  const T& operator[](const Key& key) const
17350  {
17351  return at(key);
17352  }
17353 
17354  T& at(const Key& key)
17355  {
17356  for (auto it = this->begin(); it != this->end(); ++it)
17357  {
17358  if (it->first == key)
17359  {
17360  return it->second;
17361  }
17362  }
17363 
17364  JSON_THROW(std::out_of_range("key not found"));
17365  }
17366 
17367  const T& at(const Key& key) const
17368  {
17369  for (auto it = this->begin(); it != this->end(); ++it)
17370  {
17371  if (it->first == key)
17372  {
17373  return it->second;
17374  }
17375  }
17376 
17377  JSON_THROW(std::out_of_range("key not found"));
17378  }
17379 
17380  size_type erase(const Key& key)
17381  {
17382  for (auto it = this->begin(); it != this->end(); ++it)
17383  {
17384  if (it->first == key)
17385  {
17386  // Since we cannot move const Keys, re-construct them in place
17387  for (auto next = it; ++next != this->end(); ++it)
17388  {
17389  it->~value_type(); // Destroy but keep allocation
17390  new (&*it) value_type{std::move(*next)};
17391  }
17392  Container::pop_back();
17393  return 1;
17394  }
17395  }
17396  return 0;
17397  }
17398 
17399  iterator erase(iterator pos)
17400  {
17401  auto it = pos;
17402 
17403  // Since we cannot move const Keys, re-construct them in place
17404  for (auto next = it; ++next != this->end(); ++it)
17405  {
17406  it->~value_type(); // Destroy but keep allocation
17407  new (&*it) value_type{std::move(*next)};
17408  }
17409  Container::pop_back();
17410  return pos;
17411  }
17412 
17413  size_type count(const Key& key) const
17414  {
17415  for (auto it = this->begin(); it != this->end(); ++it)
17416  {
17417  if (it->first == key)
17418  {
17419  return 1;
17420  }
17421  }
17422  return 0;
17423  }
17424 
17425  iterator find(const Key& key)
17426  {
17427  for (auto it = this->begin(); it != this->end(); ++it)
17428  {
17429  if (it->first == key)
17430  {
17431  return it;
17432  }
17433  }
17434  return Container::end();
17435  }
17436 
17437  const_iterator find(const Key& key) const
17438  {
17439  for (auto it = this->begin(); it != this->end(); ++it)
17440  {
17441  if (it->first == key)
17442  {
17443  return it;
17444  }
17445  }
17446  return Container::end();
17447  }
17448 
17449  std::pair<iterator, bool> insert( value_type&& value )
17450  {
17451  return emplace(value.first, std::move(value.second));
17452  }
17453 
17454  std::pair<iterator, bool> insert( const value_type& value )
17455  {
17456  for (auto it = this->begin(); it != this->end(); ++it)
17457  {
17458  if (it->first == value.first)
17459  {
17460  return {it, false};
17461  }
17462  }
17463  Container::push_back(value);
17464  return {--this->end(), true};
17465  }
17466 
17467  template<typename InputIt>
17468  using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
17469  std::input_iterator_tag>::value>::type;
17470 
17471  template<typename InputIt, typename = require_input_iter<InputIt>>
17472  void insert(InputIt first, InputIt last)
17473  {
17474  for (auto it = first; it != last; ++it)
17475  {
17476  insert(*it);
17477  }
17478  }
17479 };
17480 
17481 } // namespace nlohmann
17482 
17483 
17484 #if defined(JSON_HAS_CPP_17)
17485  #include <string_view>
17486 #endif
17487 
17493 namespace nlohmann
17494 {
17495 
17581 class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
17582 {
17583  private:
17584  template<detail::value_t> friend struct detail::external_constructor;
17585  friend ::nlohmann::json_pointer<basic_json>;
17586 
17587  template<typename BasicJsonType, typename InputType>
17588  friend class ::nlohmann::detail::parser;
17589  friend ::nlohmann::detail::serializer<basic_json>;
17590  template<typename BasicJsonType>
17591  friend class ::nlohmann::detail::iter_impl;
17592  template<typename BasicJsonType, typename CharType>
17593  friend class ::nlohmann::detail::binary_writer;
17594  template<typename BasicJsonType, typename InputType, typename SAX>
17595  friend class ::nlohmann::detail::binary_reader;
17596  template<typename BasicJsonType>
17597  friend class ::nlohmann::detail::json_sax_dom_parser;
17598  template<typename BasicJsonType>
17599  friend class ::nlohmann::detail::json_sax_dom_callback_parser;
17600  friend class ::nlohmann::detail::exception;
17601 
17604 
17606  // convenience aliases for types residing in namespace detail;
17608 
17609  template<typename InputAdapterType>
17610  static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
17611  InputAdapterType adapter,
17613  const bool allow_exceptions = true,
17614  const bool ignore_comments = false
17615  )
17616  {
17617  return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
17618  std::move(cb), allow_exceptions, ignore_comments);
17619  }
17620 
17621  private:
17623  template<typename BasicJsonType>
17625  template<typename BasicJsonType>
17627  template<typename Iterator>
17630 
17631  template<typename CharType>
17633 
17634  template<typename InputType>
17637 
17640 
17641  public:
17645  template<typename T, typename SFINAE>
17646  using json_serializer = JSONSerializer<T, SFINAE>;
17652  using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
17653 
17657 
17659  // exceptions //
17661 
17665 
17678 
17680 
17681 
17683  // container types //
17685 
17690 
17693 
17697  using const_reference = const value_type&;
17698 
17700  using difference_type = std::ptrdiff_t;
17702  using size_type = std::size_t;
17703 
17705  using allocator_type = AllocatorType<basic_json>;
17706 
17708  using pointer = typename std::allocator_traits<allocator_type>::pointer;
17710  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
17711 
17720 
17722 
17723 
17728  {
17729  return allocator_type();
17730  }
17731 
17759  static basic_json meta()
17760  {
17761  basic_json result;
17762 
17763  result["copyright"] = "(C) 2013-2021 Niels Lohmann";
17764  result["name"] = "JSON for Modern C++";
17765  result["url"] = "https://github.com/nlohmann/json";
17766  result["version"]["string"] =
17770  result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
17771  result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
17772  result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
17773 
17774 #ifdef _WIN32
17775  result["platform"] = "win32";
17776 #elif defined __linux__
17777  result["platform"] = "linux";
17778 #elif defined __APPLE__
17779  result["platform"] = "apple";
17780 #elif defined __unix__
17781  result["platform"] = "unix";
17782 #else
17783  result["platform"] = "unknown";
17784 #endif
17785 
17786 #if defined(__ICC) || defined(__INTEL_COMPILER)
17787  result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
17788 #elif defined(__clang__)
17789  result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
17790 #elif defined(__GNUC__) || defined(__GNUG__)
17791  result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
17792 #elif defined(__HP_cc) || defined(__HP_aCC)
17793  result["compiler"] = "hp"
17794 #elif defined(__IBMCPP__)
17795  result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
17796 #elif defined(_MSC_VER)
17797  result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
17798 #elif defined(__PGI)
17799  result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
17800 #elif defined(__SUNPRO_CC)
17801  result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
17802 #else
17803  result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
17804 #endif
17805 
17806 #ifdef __cplusplus
17807  result["compiler"]["c++"] = std::to_string(__cplusplus);
17808 #else
17809  result["compiler"]["c++"] = "unknown";
17810 #endif
17811  return result;
17812  }
17813 
17814 
17816  // JSON value data types //
17818 
17823 
17824 #if defined(JSON_HAS_CPP_14)
17825  // Use transparent comparator if possible, combined with perfect forwarding
17826  // on find() and count() calls prevents unnecessary string construction.
17827  using object_comparator_t = std::less<>;
17828 #else
17829  using object_comparator_t = std::less<StringType>;
17830 #endif
17831 
17915  using object_t = ObjectType<StringType,
17916  basic_json,
17918  AllocatorType<std::pair<const StringType,
17920 
17965  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
17966 
18018  using string_t = StringType;
18019 
18044  using boolean_t = BooleanType;
18045 
18116  using number_integer_t = NumberIntegerType;
18117 
18187  using number_unsigned_t = NumberUnsignedType;
18188 
18255  using number_float_t = NumberFloatType;
18256 
18328 
18329  private:
18330 
18332  template<typename T, typename... Args>
18334  static T* create(Args&& ... args)
18335  {
18336  AllocatorType<T> alloc;
18337  using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
18338 
18339  auto deleter = [&](T * obj)
18340  {
18341  AllocatorTraits::deallocate(alloc, obj, 1);
18342  };
18343  std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
18344  AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
18345  JSON_ASSERT(obj != nullptr);
18346  return obj.release();
18347  }
18348 
18350  // JSON value storage //
18352 
18379  union json_value
18380  {
18382  object_t* object;
18397 
18399  json_value() = default;
18401  json_value(boolean_t v) noexcept : boolean(v) {}
18403  json_value(number_integer_t v) noexcept : number_integer(v) {}
18405  json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
18407  json_value(number_float_t v) noexcept : number_float(v) {}
18410  {
18411  switch (t)
18412  {
18413  case value_t::object:
18414  {
18415  object = create<object_t>();
18416  break;
18417  }
18418 
18419  case value_t::array:
18420  {
18421  array = create<array_t>();
18422  break;
18423  }
18424 
18425  case value_t::string:
18426  {
18427  string = create<string_t>("");
18428  break;
18429  }
18430 
18431  case value_t::binary:
18432  {
18433  binary = create<binary_t>();
18434  break;
18435  }
18436 
18437  case value_t::boolean:
18438  {
18439  boolean = boolean_t(false);
18440  break;
18441  }
18442 
18443  case value_t::number_integer:
18444  {
18445  number_integer = number_integer_t(0);
18446  break;
18447  }
18448 
18449  case value_t::number_unsigned:
18450  {
18451  number_unsigned = number_unsigned_t(0);
18452  break;
18453  }
18454 
18455  case value_t::number_float:
18456  {
18457  number_float = number_float_t(0.0);
18458  break;
18459  }
18460 
18461  case value_t::null:
18462  {
18463  object = nullptr; // silence warning, see #821
18464  break;
18465  }
18466 
18467  case value_t::discarded:
18468  default:
18469  {
18470  object = nullptr; // silence warning, see #821
18471  if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
18472  {
18473  JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.2", basic_json())); // LCOV_EXCL_LINE
18474  }
18475  break;
18476  }
18477  }
18478  }
18479 
18481  json_value(const string_t& value)
18482  {
18483  string = create<string_t>(value);
18484  }
18485 
18488  {
18489  string = create<string_t>(std::move(value));
18490  }
18491 
18493  json_value(const object_t& value)
18494  {
18495  object = create<object_t>(value);
18496  }
18497 
18500  {
18501  object = create<object_t>(std::move(value));
18502  }
18503 
18505  json_value(const array_t& value)
18506  {
18507  array = create<array_t>(value);
18508  }
18509 
18512  {
18513  array = create<array_t>(std::move(value));
18514  }
18515 
18517  json_value(const typename binary_t::container_type& value)
18518  {
18519  binary = create<binary_t>(value);
18520  }
18521 
18524  {
18525  binary = create<binary_t>(std::move(value));
18526  }
18527 
18529  json_value(const binary_t& value)
18530  {
18531  binary = create<binary_t>(value);
18532  }
18533 
18536  {
18537  binary = create<binary_t>(std::move(value));
18538  }
18539 
18541  {
18542  if (t == value_t::array || t == value_t::object)
18543  {
18544  // flatten the current json_value to a heap-allocated stack
18545  std::vector<basic_json> stack;
18546 
18547  // move the top-level items to stack
18548  if (t == value_t::array)
18549  {
18550  stack.reserve(array->size());
18551  std::move(array->begin(), array->end(), std::back_inserter(stack));
18552  }
18553  else
18554  {
18555  stack.reserve(object->size());
18556  for (auto&& it : *object)
18557  {
18558  stack.push_back(std::move(it.second));
18559  }
18560  }
18561 
18562  while (!stack.empty())
18563  {
18564  // move the last item to local variable to be processed
18565  basic_json current_item(std::move(stack.back()));
18566  stack.pop_back();
18567 
18568  // if current_item is array/object, move
18569  // its children to the stack to be processed later
18570  if (current_item.is_array())
18571  {
18572  std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
18573 
18574  current_item.m_value.array->clear();
18575  }
18576  else if (current_item.is_object())
18577  {
18578  for (auto&& it : *current_item.m_value.object)
18579  {
18580  stack.push_back(std::move(it.second));
18581  }
18582 
18583  current_item.m_value.object->clear();
18584  }
18585 
18586  // it's now safe that current_item get destructed
18587  // since it doesn't have any children
18588  }
18589  }
18590 
18591  switch (t)
18592  {
18593  case value_t::object:
18594  {
18595  AllocatorType<object_t> alloc;
18596  std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
18597  std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
18598  break;
18599  }
18600 
18601  case value_t::array:
18602  {
18603  AllocatorType<array_t> alloc;
18604  std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
18605  std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
18606  break;
18607  }
18608 
18609  case value_t::string:
18610  {
18611  AllocatorType<string_t> alloc;
18612  std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
18613  std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
18614  break;
18615  }
18616 
18617  case value_t::binary:
18618  {
18619  AllocatorType<binary_t> alloc;
18620  std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
18621  std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
18622  break;
18623  }
18624 
18625  case value_t::null:
18626  case value_t::boolean:
18627  case value_t::number_integer:
18628  case value_t::number_unsigned:
18629  case value_t::number_float:
18630  case value_t::discarded:
18631  default:
18632  {
18633  break;
18634  }
18635  }
18636  }
18637  };
18638 
18639  private:
18658  void assert_invariant(bool check_parents = true) const noexcept
18659  {
18660  JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
18661  JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
18662  JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
18663  JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
18664 
18665 #if JSON_DIAGNOSTICS
18666  JSON_TRY
18667  {
18668  // cppcheck-suppress assertWithSideEffect
18669  JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
18670  {
18671  return j.m_parent == this;
18672  }));
18673  }
18674  JSON_CATCH(...) {} // LCOV_EXCL_LINE
18675 #endif
18676  static_cast<void>(check_parents);
18677  }
18678 
18680  {
18681 #if JSON_DIAGNOSTICS
18682  switch (m_type)
18683  {
18684  case value_t::array:
18685  {
18686  for (auto& element : *m_value.array)
18687  {
18688  element.m_parent = this;
18689  }
18690  break;
18691  }
18692 
18693  case value_t::object:
18694  {
18695  for (auto& element : *m_value.object)
18696  {
18697  element.second.m_parent = this;
18698  }
18699  break;
18700  }
18701 
18702  case value_t::null:
18703  case value_t::string:
18704  case value_t::boolean:
18705  case value_t::number_integer:
18706  case value_t::number_unsigned:
18707  case value_t::number_float:
18708  case value_t::binary:
18709  case value_t::discarded:
18710  default:
18711  break;
18712  }
18713 #endif
18714  }
18715 
18717  {
18718 #if JSON_DIAGNOSTICS
18719  for (typename iterator::difference_type i = 0; i < count; ++i)
18720  {
18721  (it + i)->m_parent = this;
18722  }
18723 #else
18724  static_cast<void>(count);
18725 #endif
18726  return it;
18727  }
18728 
18729  reference set_parent(reference j, std::size_t old_capacity = std::size_t(-1))
18730  {
18731 #if JSON_DIAGNOSTICS
18732  if (old_capacity != std::size_t(-1))
18733  {
18734  // see https://github.com/nlohmann/json/issues/2838
18735  JSON_ASSERT(type() == value_t::array);
18736  if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
18737  {
18738  // capacity has changed: update all parents
18739  set_parents();
18740  return j;
18741  }
18742  }
18743 
18744  // ordered_json uses a vector internally, so pointers could have
18745  // been invalidated; see https://github.com/nlohmann/json/issues/2962
18746 #ifdef JSON_HEDLEY_MSVC_VERSION
18747 #pragma warning(push )
18748 #pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
18749 #endif
18751  {
18752  set_parents();
18753  return j;
18754  }
18755 #ifdef JSON_HEDLEY_MSVC_VERSION
18756 #pragma warning( pop )
18757 #endif
18758 
18759  j.m_parent = this;
18760 #else
18761  static_cast<void>(j);
18762  static_cast<void>(old_capacity);
18763 #endif
18764  return j;
18765  }
18766 
18767  public:
18769  // JSON parser callback //
18771 
18788 
18839 
18841  // constructors //
18843 
18848 
18880  : m_type(v), m_value(v)
18881  {
18882  assert_invariant();
18883  }
18884 
18903  basic_json(std::nullptr_t = nullptr) noexcept
18904  : basic_json(value_t::null)
18905  {
18906  assert_invariant();
18907  }
18908 
18971  template < typename CompatibleType,
18972  typename U = detail::uncvref_t<CompatibleType>,
18975  basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
18976  JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
18977  std::forward<CompatibleType>(val))))
18978  {
18979  JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
18980  set_parents();
18981  assert_invariant();
18982  }
18983 
19010  template < typename BasicJsonType,
19012  detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
19013  basic_json(const BasicJsonType& val)
19014  {
19015  using other_boolean_t = typename BasicJsonType::boolean_t;
19016  using other_number_float_t = typename BasicJsonType::number_float_t;
19017  using other_number_integer_t = typename BasicJsonType::number_integer_t;
19018  using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
19019  using other_string_t = typename BasicJsonType::string_t;
19020  using other_object_t = typename BasicJsonType::object_t;
19021  using other_array_t = typename BasicJsonType::array_t;
19022  using other_binary_t = typename BasicJsonType::binary_t;
19023 
19024  switch (val.type())
19025  {
19026  case value_t::boolean:
19027  JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
19028  break;
19029  case value_t::number_float:
19030  JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
19031  break;
19032  case value_t::number_integer:
19033  JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
19034  break;
19035  case value_t::number_unsigned:
19036  JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
19037  break;
19038  case value_t::string:
19039  JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
19040  break;
19041  case value_t::object:
19042  JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
19043  break;
19044  case value_t::array:
19045  JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
19046  break;
19047  case value_t::binary:
19048  JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
19049  break;
19050  case value_t::null:
19051  *this = nullptr;
19052  break;
19053  case value_t::discarded:
19054  m_type = value_t::discarded;
19055  break;
19056  default: // LCOV_EXCL_LINE
19057  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19058  }
19059  set_parents();
19060  assert_invariant();
19061  }
19062 
19138  bool type_deduction = true,
19139  value_t manual_type = value_t::array)
19140  {
19141  // check if each element is an array with two elements whose first
19142  // element is a string
19143  bool is_an_object = std::all_of(init.begin(), init.end(),
19144  [](const detail::json_ref<basic_json>& element_ref)
19145  {
19146  return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
19147  });
19148 
19149  // adjust type if type deduction is not wanted
19150  if (!type_deduction)
19151  {
19152  // if array is wanted, do not create an object though possible
19153  if (manual_type == value_t::array)
19154  {
19155  is_an_object = false;
19156  }
19157 
19158  // if object is wanted but impossible, throw an exception
19159  if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
19160  {
19161  JSON_THROW(type_error::create(301, "cannot create object from initializer list", basic_json()));
19162  }
19163  }
19164 
19165  if (is_an_object)
19166  {
19167  // the initializer list is a list of pairs -> create object
19168  m_type = value_t::object;
19169  m_value = value_t::object;
19170 
19171  for (auto& element_ref : init)
19172  {
19173  auto element = element_ref.moved_or_copied();
19174  m_value.object->emplace(
19175  std::move(*((*element.m_value.array)[0].m_value.string)),
19176  std::move((*element.m_value.array)[1]));
19177  }
19178  }
19179  else
19180  {
19181  // the initializer list describes an array -> create array
19182  m_type = value_t::array;
19183  m_value.array = create<array_t>(init.begin(), init.end());
19184  }
19185 
19186  set_parents();
19187  assert_invariant();
19188  }
19189 
19218  static basic_json binary(const typename binary_t::container_type& init)
19219  {
19220  auto res = basic_json();
19221  res.m_type = value_t::binary;
19222  res.m_value = init;
19223  return res;
19224  }
19225 
19255  static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
19256  {
19257  auto res = basic_json();
19258  res.m_type = value_t::binary;
19259  res.m_value = binary_t(init, subtype);
19260  return res;
19261  }
19262 
19266  {
19267  auto res = basic_json();
19268  res.m_type = value_t::binary;
19269  res.m_value = std::move(init);
19270  return res;
19271  }
19272 
19275  static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
19276  {
19277  auto res = basic_json();
19278  res.m_type = value_t::binary;
19279  res.m_value = binary_t(std::move(init), subtype);
19280  return res;
19281  }
19282 
19322  {
19323  return basic_json(init, false, value_t::array);
19324  }
19325 
19366  {
19367  return basic_json(init, false, value_t::object);
19368  }
19369 
19393  : m_type(value_t::array)
19394  {
19395  m_value.array = create<array_t>(cnt, val);
19396  set_parents();
19397  assert_invariant();
19398  }
19399 
19455  template < class InputIT, typename std::enable_if <
19456  std::is_same<InputIT, typename basic_json_t::iterator>::value ||
19457  std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
19458  basic_json(InputIT first, InputIT last)
19459  {
19460  JSON_ASSERT(first.m_object != nullptr);
19461  JSON_ASSERT(last.m_object != nullptr);
19462 
19463  // make sure iterator fits the current value
19464  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19465  {
19466  JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", basic_json()));
19467  }
19468 
19469  // copy type from first iterator
19470  m_type = first.m_object->m_type;
19471 
19472  // check if iterator range is complete for primitive values
19473  switch (m_type)
19474  {
19475  case value_t::boolean:
19476  case value_t::number_float:
19477  case value_t::number_integer:
19478  case value_t::number_unsigned:
19479  case value_t::string:
19480  {
19481  if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
19482  || !last.m_it.primitive_iterator.is_end()))
19483  {
19484  JSON_THROW(invalid_iterator::create(204, "iterators out of range", *first.m_object));
19485  }
19486  break;
19487  }
19488 
19489  case value_t::null:
19490  case value_t::object:
19491  case value_t::array:
19492  case value_t::binary:
19493  case value_t::discarded:
19494  default:
19495  break;
19496  }
19497 
19498  switch (m_type)
19499  {
19500  case value_t::number_integer:
19501  {
19502  m_value.number_integer = first.m_object->m_value.number_integer;
19503  break;
19504  }
19505 
19506  case value_t::number_unsigned:
19507  {
19508  m_value.number_unsigned = first.m_object->m_value.number_unsigned;
19509  break;
19510  }
19511 
19512  case value_t::number_float:
19513  {
19514  m_value.number_float = first.m_object->m_value.number_float;
19515  break;
19516  }
19517 
19518  case value_t::boolean:
19519  {
19520  m_value.boolean = first.m_object->m_value.boolean;
19521  break;
19522  }
19523 
19524  case value_t::string:
19525  {
19526  m_value = *first.m_object->m_value.string;
19527  break;
19528  }
19529 
19530  case value_t::object:
19531  {
19532  m_value.object = create<object_t>(first.m_it.object_iterator,
19533  last.m_it.object_iterator);
19534  break;
19535  }
19536 
19537  case value_t::array:
19538  {
19539  m_value.array = create<array_t>(first.m_it.array_iterator,
19540  last.m_it.array_iterator);
19541  break;
19542  }
19543 
19544  case value_t::binary:
19545  {
19546  m_value = *first.m_object->m_value.binary;
19547  break;
19548  }
19549 
19550  case value_t::null:
19551  case value_t::discarded:
19552  default:
19553  JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object));
19554  }
19555 
19556  set_parents();
19557  assert_invariant();
19558  }
19559 
19560 
19562  // other constructors and destructor //
19564 
19565  template<typename JsonRef,
19567  std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
19568  basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
19569 
19595  basic_json(const basic_json& other)
19596  : m_type(other.m_type)
19597  {
19598  // check of passed value is valid
19599  other.assert_invariant();
19600 
19601  switch (m_type)
19602  {
19603  case value_t::object:
19604  {
19605  m_value = *other.m_value.object;
19606  break;
19607  }
19608 
19609  case value_t::array:
19610  {
19611  m_value = *other.m_value.array;
19612  break;
19613  }
19614 
19615  case value_t::string:
19616  {
19617  m_value = *other.m_value.string;
19618  break;
19619  }
19620 
19621  case value_t::boolean:
19622  {
19623  m_value = other.m_value.boolean;
19624  break;
19625  }
19626 
19627  case value_t::number_integer:
19628  {
19629  m_value = other.m_value.number_integer;
19630  break;
19631  }
19632 
19633  case value_t::number_unsigned:
19634  {
19635  m_value = other.m_value.number_unsigned;
19636  break;
19637  }
19638 
19639  case value_t::number_float:
19640  {
19641  m_value = other.m_value.number_float;
19642  break;
19643  }
19644 
19645  case value_t::binary:
19646  {
19647  m_value = *other.m_value.binary;
19648  break;
19649  }
19650 
19651  case value_t::null:
19652  case value_t::discarded:
19653  default:
19654  break;
19655  }
19656 
19657  set_parents();
19658  assert_invariant();
19659  }
19660 
19687  basic_json(basic_json&& other) noexcept
19688  : m_type(std::move(other.m_type)),
19689  m_value(std::move(other.m_value))
19690  {
19691  // check that passed value is valid
19692  other.assert_invariant(false);
19693 
19694  // invalidate payload
19695  other.m_type = value_t::null;
19696  other.m_value = {};
19697 
19698  set_parents();
19699  assert_invariant();
19700  }
19701 
19725  basic_json& operator=(basic_json other) noexcept (
19726  std::is_nothrow_move_constructible<value_t>::value&&
19727  std::is_nothrow_move_assignable<value_t>::value&&
19728  std::is_nothrow_move_constructible<json_value>::value&&
19729  std::is_nothrow_move_assignable<json_value>::value
19730  )
19731  {
19732  // check that passed value is valid
19733  other.assert_invariant();
19734 
19735  using std::swap;
19736  swap(m_type, other.m_type);
19737  swap(m_value, other.m_value);
19738 
19739  set_parents();
19740  assert_invariant();
19741  return *this;
19742  }
19743 
19759  ~basic_json() noexcept
19760  {
19761  assert_invariant(false);
19762  m_value.destroy(m_type);
19763  }
19764 
19766 
19767  public:
19769  // object inspection //
19771 
19775 
19823  string_t dump(const int indent = -1,
19824  const char indent_char = ' ',
19825  const bool ensure_ascii = false,
19826  const error_handler_t error_handler = error_handler_t::strict) const
19827  {
19828  string_t result;
19829  serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
19830 
19831  if (indent >= 0)
19832  {
19833  s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
19834  }
19835  else
19836  {
19837  s.dump(*this, false, ensure_ascii, 0);
19838  }
19839 
19840  return result;
19841  }
19842 
19876  constexpr value_t type() const noexcept
19877  {
19878  return m_type;
19879  }
19880 
19907  constexpr bool is_primitive() const noexcept
19908  {
19909  return is_null() || is_string() || is_boolean() || is_number() || is_binary();
19910  }
19911 
19934  constexpr bool is_structured() const noexcept
19935  {
19936  return is_array() || is_object();
19937  }
19938 
19956  constexpr bool is_null() const noexcept
19957  {
19958  return m_type == value_t::null;
19959  }
19960 
19978  constexpr bool is_boolean() const noexcept
19979  {
19980  return m_type == value_t::boolean;
19981  }
19982 
20008  constexpr bool is_number() const noexcept
20009  {
20010  return is_number_integer() || is_number_float();
20011  }
20012 
20037  constexpr bool is_number_integer() const noexcept
20038  {
20039  return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
20040  }
20041 
20065  constexpr bool is_number_unsigned() const noexcept
20066  {
20067  return m_type == value_t::number_unsigned;
20068  }
20069 
20093  constexpr bool is_number_float() const noexcept
20094  {
20095  return m_type == value_t::number_float;
20096  }
20097 
20115  constexpr bool is_object() const noexcept
20116  {
20117  return m_type == value_t::object;
20118  }
20119 
20137  constexpr bool is_array() const noexcept
20138  {
20139  return m_type == value_t::array;
20140  }
20141 
20159  constexpr bool is_string() const noexcept
20160  {
20161  return m_type == value_t::string;
20162  }
20163 
20181  constexpr bool is_binary() const noexcept
20182  {
20183  return m_type == value_t::binary;
20184  }
20185 
20208  constexpr bool is_discarded() const noexcept
20209  {
20210  return m_type == value_t::discarded;
20211  }
20212 
20234  constexpr operator value_t() const noexcept
20235  {
20236  return m_type;
20237  }
20238 
20240 
20241  private:
20243  // value access //
20245 
20247  boolean_t get_impl(boolean_t* /*unused*/) const
20248  {
20249  if (JSON_HEDLEY_LIKELY(is_boolean()))
20250  {
20251  return m_value.boolean;
20252  }
20253 
20254  JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()), *this));
20255  }
20256 
20258  object_t* get_impl_ptr(object_t* /*unused*/) noexcept
20259  {
20260  return is_object() ? m_value.object : nullptr;
20261  }
20262 
20264  constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
20265  {
20266  return is_object() ? m_value.object : nullptr;
20267  }
20268 
20270  array_t* get_impl_ptr(array_t* /*unused*/) noexcept
20271  {
20272  return is_array() ? m_value.array : nullptr;
20273  }
20274 
20276  constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
20277  {
20278  return is_array() ? m_value.array : nullptr;
20279  }
20280 
20282  string_t* get_impl_ptr(string_t* /*unused*/) noexcept
20283  {
20284  return is_string() ? m_value.string : nullptr;
20285  }
20286 
20288  constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
20289  {
20290  return is_string() ? m_value.string : nullptr;
20291  }
20292 
20294  boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
20295  {
20296  return is_boolean() ? &m_value.boolean : nullptr;
20297  }
20298 
20300  constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
20301  {
20302  return is_boolean() ? &m_value.boolean : nullptr;
20303  }
20304 
20307  {
20308  return is_number_integer() ? &m_value.number_integer : nullptr;
20309  }
20310 
20312  constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
20313  {
20314  return is_number_integer() ? &m_value.number_integer : nullptr;
20315  }
20316 
20319  {
20320  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20321  }
20322 
20324  constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
20325  {
20326  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20327  }
20328 
20331  {
20332  return is_number_float() ? &m_value.number_float : nullptr;
20333  }
20334 
20336  constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
20337  {
20338  return is_number_float() ? &m_value.number_float : nullptr;
20339  }
20340 
20342  binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
20343  {
20344  return is_binary() ? m_value.binary : nullptr;
20345  }
20346 
20348  constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
20349  {
20350  return is_binary() ? m_value.binary : nullptr;
20351  }
20352 
20364  template<typename ReferenceType, typename ThisType>
20365  static ReferenceType get_ref_impl(ThisType& obj)
20366  {
20367  // delegate the call to get_ptr<>()
20368  auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
20369 
20370  if (JSON_HEDLEY_LIKELY(ptr != nullptr))
20371  {
20372  return *ptr;
20373  }
20374 
20375  JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()), obj));
20376  }
20377 
20378  public:
20382 
20409  template<typename PointerType, typename std::enable_if<
20410  std::is_pointer<PointerType>::value, int>::type = 0>
20411  auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20412  {
20413  // delegate the call to get_impl_ptr<>()
20414  return get_impl_ptr(static_cast<PointerType>(nullptr));
20415  }
20416 
20421  template < typename PointerType, typename std::enable_if <
20422  std::is_pointer<PointerType>::value&&
20423  std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
20424  constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20425  {
20426  // delegate the call to get_impl_ptr<>() const
20427  return get_impl_ptr(static_cast<PointerType>(nullptr));
20428  }
20429 
20430  private:
20469  template < typename ValueType,
20473  int > = 0 >
20474  ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20475  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20476  {
20477  ValueType ret{};
20479  return ret;
20480  }
20481 
20512  template < typename ValueType,
20515  int > = 0 >
20516  ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20517  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20518  {
20520  }
20521 
20537  template < typename BasicJsonType,
20540  int > = 0 >
20541  BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20542  {
20543  return *this;
20544  }
20545 
20560  template<typename BasicJsonType,
20562  std::is_same<BasicJsonType, basic_json_t>::value,
20563  int> = 0>
20565  {
20566  return *this;
20567  }
20568 
20573  template<typename PointerType,
20575  std::is_pointer<PointerType>::value,
20576  int> = 0>
20577  constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
20578  -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
20579  {
20580  // delegate the call to get_ptr
20581  return get_ptr<PointerType>();
20582  }
20583 
20584  public:
20608  template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
20609 #if defined(JSON_HAS_CPP_14)
20610  constexpr
20611 #endif
20612  auto get() const noexcept(
20613  noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
20614  -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
20615  {
20616  // we cannot static_assert on ValueTypeCV being non-const, because
20617  // there is support for get<const basic_json_t>(), which is why we
20618  // still need the uncvref
20619  static_assert(!std::is_reference<ValueTypeCV>::value,
20620  "get() cannot be used with reference types, you might want to use get_ref()");
20621  return get_impl<ValueType>(detail::priority_tag<4> {});
20622  }
20623 
20651  template<typename PointerType, typename std::enable_if<
20652  std::is_pointer<PointerType>::value, int>::type = 0>
20653  auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
20654  {
20655  // delegate the call to get_ptr
20656  return get_ptr<PointerType>();
20657  }
20658 
20692  template < typename ValueType,
20696  int > = 0 >
20697  ValueType & get_to(ValueType& v) const noexcept(noexcept(
20698  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
20699  {
20701  return v;
20702  }
20703 
20704  // specialization to allow to call get_to with a basic_json value
20705  // see https://github.com/nlohmann/json/issues/2175
20706  template<typename ValueType,
20709  int> = 0>
20710  ValueType & get_to(ValueType& v) const
20711  {
20712  v = *this;
20713  return v;
20714  }
20715 
20716  template <
20717  typename T, std::size_t N,
20718  typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20721  Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20722  noexcept(noexcept(JSONSerializer<Array>::from_json(
20723  std::declval<const basic_json_t&>(), v)))
20724  {
20726  return v;
20727  }
20728 
20755  template<typename ReferenceType, typename std::enable_if<
20756  std::is_reference<ReferenceType>::value, int>::type = 0>
20757  ReferenceType get_ref()
20758  {
20759  // delegate call to get_ref_impl
20760  return get_ref_impl<ReferenceType>(*this);
20761  }
20762 
20767  template < typename ReferenceType, typename std::enable_if <
20768  std::is_reference<ReferenceType>::value&&
20769  std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
20770  ReferenceType get_ref() const
20771  {
20772  // delegate call to get_ref_impl
20773  return get_ref_impl<ReferenceType>(*this);
20774  }
20775 
20805  template < typename ValueType, typename std::enable_if <
20812 
20813 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
20815 #endif
20817  >::value, int >::type = 0 >
20818  JSON_EXPLICIT operator ValueType() const
20819  {
20820  // delegate the call to get<>() const
20821  return get<ValueType>();
20822  }
20823 
20834  {
20835  if (!is_binary())
20836  {
20837  JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20838  }
20839 
20840  return *get_ptr<binary_t*>();
20841  }
20842 
20844  const binary_t& get_binary() const
20845  {
20846  if (!is_binary())
20847  {
20848  JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20849  }
20850 
20851  return *get_ptr<const binary_t*>();
20852  }
20853 
20855 
20856 
20858  // element access //
20860 
20864 
20892  {
20893  // at only works for arrays
20894  if (JSON_HEDLEY_LIKELY(is_array()))
20895  {
20896  JSON_TRY
20897  {
20898  return set_parent(m_value.array->at(idx));
20899  }
20900  JSON_CATCH (std::out_of_range&)
20901  {
20902  // create better exception explanation
20903  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
20904  }
20905  }
20906  else
20907  {
20908  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
20909  }
20910  }
20911 
20939  {
20940  // at only works for arrays
20941  if (JSON_HEDLEY_LIKELY(is_array()))
20942  {
20943  JSON_TRY
20944  {
20945  return m_value.array->at(idx);
20946  }
20947  JSON_CATCH (std::out_of_range&)
20948  {
20949  // create better exception explanation
20950  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
20951  }
20952  }
20953  else
20954  {
20955  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
20956  }
20957  }
20958 
20989  reference at(const typename object_t::key_type& key)
20990  {
20991  // at only works for objects
20992  if (JSON_HEDLEY_LIKELY(is_object()))
20993  {
20994  JSON_TRY
20995  {
20996  return set_parent(m_value.object->at(key));
20997  }
20998  JSON_CATCH (std::out_of_range&)
20999  {
21000  // create better exception explanation
21001  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21002  }
21003  }
21004  else
21005  {
21006  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21007  }
21008  }
21009 
21040  const_reference at(const typename object_t::key_type& key) const
21041  {
21042  // at only works for objects
21043  if (JSON_HEDLEY_LIKELY(is_object()))
21044  {
21045  JSON_TRY
21046  {
21047  return m_value.object->at(key);
21048  }
21049  JSON_CATCH (std::out_of_range&)
21050  {
21051  // create better exception explanation
21052  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21053  }
21054  }
21055  else
21056  {
21057  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21058  }
21059  }
21060 
21087  {
21088  // implicitly convert null value to an empty array
21089  if (is_null())
21090  {
21091  m_type = value_t::array;
21092  m_value.array = create<array_t>();
21093  assert_invariant();
21094  }
21095 
21096  // operator[] only works for arrays
21097  if (JSON_HEDLEY_LIKELY(is_array()))
21098  {
21099  // fill up array with null values if given idx is outside range
21100  if (idx >= m_value.array->size())
21101  {
21102 #if JSON_DIAGNOSTICS
21103  // remember array size before resizing
21104  const auto previous_size = m_value.array->size();
21105 #endif
21106  m_value.array->resize(idx + 1);
21107 
21108 #if JSON_DIAGNOSTICS
21109  // set parent for values added above
21110  set_parents(begin() + static_cast<typename iterator::difference_type>(previous_size), static_cast<typename iterator::difference_type>(idx + 1 - previous_size));
21111 #endif
21112  }
21113 
21114  return m_value.array->operator[](idx);
21115  }
21116 
21117  JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21118  }
21119 
21140  {
21141  // const operator[] only works for arrays
21142  if (JSON_HEDLEY_LIKELY(is_array()))
21143  {
21144  return m_value.array->operator[](idx);
21145  }
21146 
21147  JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21148  }
21149 
21177  reference operator[](const typename object_t::key_type& key)
21178  {
21179  // implicitly convert null value to an empty object
21180  if (is_null())
21181  {
21182  m_type = value_t::object;
21183  m_value.object = create<object_t>();
21184  assert_invariant();
21185  }
21186 
21187  // operator[] only works for objects
21188  if (JSON_HEDLEY_LIKELY(is_object()))
21189  {
21190  return set_parent(m_value.object->operator[](key));
21191  }
21192 
21193  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21194  }
21195 
21226  const_reference operator[](const typename object_t::key_type& key) const
21227  {
21228  // const operator[] only works for objects
21229  if (JSON_HEDLEY_LIKELY(is_object()))
21230  {
21231  JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
21232  return m_value.object->find(key)->second;
21233  }
21234 
21235  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21236  }
21237 
21265  template<typename T>
21267  reference operator[](T* key)
21268  {
21269  // implicitly convert null to object
21270  if (is_null())
21271  {
21272  m_type = value_t::object;
21273  m_value = value_t::object;
21274  assert_invariant();
21275  }
21276 
21277  // at only works for objects
21278  if (JSON_HEDLEY_LIKELY(is_object()))
21279  {
21280  return set_parent(m_value.object->operator[](key));
21281  }
21282 
21283  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21284  }
21285 
21316  template<typename T>
21318  const_reference operator[](T* key) const
21319  {
21320  // at only works for objects
21321  if (JSON_HEDLEY_LIKELY(is_object()))
21322  {
21323  JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
21324  return m_value.object->find(key)->second;
21325  }
21326 
21327  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21328  }
21329 
21380  // using std::is_convertible in a std::enable_if will fail when using explicit conversions
21381  template < class ValueType, typename std::enable_if <
21383  && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
21384  ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
21385  {
21386  // at only works for objects
21387  if (JSON_HEDLEY_LIKELY(is_object()))
21388  {
21389  // if key is found, return value and given default value otherwise
21390  const auto it = find(key);
21391  if (it != end())
21392  {
21393  return it->template get<ValueType>();
21394  }
21395 
21396  return default_value;
21397  }
21398 
21399  JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21400  }
21401 
21406  string_t value(const typename object_t::key_type& key, const char* default_value) const
21407  {
21408  return value(key, string_t(default_value));
21409  }
21410 
21454  template<class ValueType, typename std::enable_if<
21456  ValueType value(const json_pointer& ptr, const ValueType& default_value) const
21457  {
21458  // at only works for objects
21459  if (JSON_HEDLEY_LIKELY(is_object()))
21460  {
21461  // if pointer resolves a value, return it or use default value
21462  JSON_TRY
21463  {
21464  return ptr.get_checked(this).template get<ValueType>();
21465  }
21467  {
21468  return default_value;
21469  }
21470  }
21471 
21472  JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21473  }
21474 
21480  string_t value(const json_pointer& ptr, const char* default_value) const
21481  {
21482  return value(ptr, string_t(default_value));
21483  }
21484 
21511  {
21512  return *begin();
21513  }
21514 
21519  {
21520  return *cbegin();
21521  }
21522 
21555  {
21556  auto tmp = end();
21557  --tmp;
21558  return *tmp;
21559  }
21560 
21565  {
21566  auto tmp = cend();
21567  --tmp;
21568  return *tmp;
21569  }
21570 
21617  template < class IteratorType, typename std::enable_if <
21618  std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21619  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21620  = 0 >
21621  IteratorType erase(IteratorType pos)
21622  {
21623  // make sure iterator fits the current value
21624  if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21625  {
21626  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
21627  }
21628 
21629  IteratorType result = end();
21630 
21631  switch (m_type)
21632  {
21633  case value_t::boolean:
21634  case value_t::number_float:
21635  case value_t::number_integer:
21636  case value_t::number_unsigned:
21637  case value_t::string:
21638  case value_t::binary:
21639  {
21640  if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
21641  {
21642  JSON_THROW(invalid_iterator::create(205, "iterator out of range", *this));
21643  }
21644 
21645  if (is_string())
21646  {
21647  AllocatorType<string_t> alloc;
21648  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21649  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21650  m_value.string = nullptr;
21651  }
21652  else if (is_binary())
21653  {
21654  AllocatorType<binary_t> alloc;
21655  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21656  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21657  m_value.binary = nullptr;
21658  }
21659 
21660  m_type = value_t::null;
21661  assert_invariant();
21662  break;
21663  }
21664 
21665  case value_t::object:
21666  {
21667  result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
21668  break;
21669  }
21670 
21671  case value_t::array:
21672  {
21673  result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
21674  break;
21675  }
21676 
21677  case value_t::null:
21678  case value_t::discarded:
21679  default:
21680  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21681  }
21682 
21683  return result;
21684  }
21685 
21732  template < class IteratorType, typename std::enable_if <
21733  std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21734  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21735  = 0 >
21736  IteratorType erase(IteratorType first, IteratorType last)
21737  {
21738  // make sure iterator fits the current value
21739  if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
21740  {
21741  JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", *this));
21742  }
21743 
21744  IteratorType result = end();
21745 
21746  switch (m_type)
21747  {
21748  case value_t::boolean:
21749  case value_t::number_float:
21750  case value_t::number_integer:
21751  case value_t::number_unsigned:
21752  case value_t::string:
21753  case value_t::binary:
21754  {
21755  if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
21756  || !last.m_it.primitive_iterator.is_end()))
21757  {
21758  JSON_THROW(invalid_iterator::create(204, "iterators out of range", *this));
21759  }
21760 
21761  if (is_string())
21762  {
21763  AllocatorType<string_t> alloc;
21764  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21765  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21766  m_value.string = nullptr;
21767  }
21768  else if (is_binary())
21769  {
21770  AllocatorType<binary_t> alloc;
21771  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21772  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21773  m_value.binary = nullptr;
21774  }
21775 
21776  m_type = value_t::null;
21777  assert_invariant();
21778  break;
21779  }
21780 
21781  case value_t::object:
21782  {
21783  result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
21784  last.m_it.object_iterator);
21785  break;
21786  }
21787 
21788  case value_t::array:
21789  {
21790  result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
21791  last.m_it.array_iterator);
21792  break;
21793  }
21794 
21795  case value_t::null:
21796  case value_t::discarded:
21797  default:
21798  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21799  }
21800 
21801  return result;
21802  }
21803 
21833  size_type erase(const typename object_t::key_type& key)
21834  {
21835  // this erase only works for objects
21836  if (JSON_HEDLEY_LIKELY(is_object()))
21837  {
21838  return m_value.object->erase(key);
21839  }
21840 
21841  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21842  }
21843 
21868  void erase(const size_type idx)
21869  {
21870  // this erase only works for arrays
21871  if (JSON_HEDLEY_LIKELY(is_array()))
21872  {
21873  if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21874  {
21875  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21876  }
21877 
21878  m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
21879  }
21880  else
21881  {
21882  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21883  }
21884  }
21885 
21887 
21888 
21890  // lookup //
21892 
21895 
21920  template<typename KeyT>
21921  iterator find(KeyT&& key)
21922  {
21923  auto result = end();
21924 
21925  if (is_object())
21926  {
21927  result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
21928  }
21929 
21930  return result;
21931  }
21932 
21937  template<typename KeyT>
21938  const_iterator find(KeyT&& key) const
21939  {
21940  auto result = cend();
21941 
21942  if (is_object())
21943  {
21944  result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
21945  }
21946 
21947  return result;
21948  }
21949 
21971  template<typename KeyT>
21972  size_type count(KeyT&& key) const
21973  {
21974  // return 0 for all nonobject types
21975  return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
21976  }
21977 
22003  template < typename KeyT, typename std::enable_if <
22004  !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
22005  bool contains(KeyT && key) const
22006  {
22007  return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
22008  }
22009 
22036  bool contains(const json_pointer& ptr) const
22037  {
22038  return ptr.contains(this);
22039  }
22040 
22042 
22043 
22045  // iterators //
22047 
22050 
22075  iterator begin() noexcept
22076  {
22077  iterator result(this);
22078  result.set_begin();
22079  return result;
22080  }
22081 
22085  const_iterator begin() const noexcept
22086  {
22087  return cbegin();
22088  }
22089 
22115  const_iterator cbegin() const noexcept
22116  {
22117  const_iterator result(this);
22118  result.set_begin();
22119  return result;
22120  }
22121 
22146  iterator end() noexcept
22147  {
22148  iterator result(this);
22149  result.set_end();
22150  return result;
22151  }
22152 
22156  const_iterator end() const noexcept
22157  {
22158  return cend();
22159  }
22160 
22186  const_iterator cend() const noexcept
22187  {
22188  const_iterator result(this);
22189  result.set_end();
22190  return result;
22191  }
22192 
22217  {
22218  return reverse_iterator(end());
22219  }
22220 
22225  {
22226  return crbegin();
22227  }
22228 
22254  {
22255  return reverse_iterator(begin());
22256  }
22257 
22261  const_reverse_iterator rend() const noexcept
22262  {
22263  return crend();
22264  }
22265 
22291  {
22292  return const_reverse_iterator(cend());
22293  }
22294 
22320  {
22321  return const_reverse_iterator(cbegin());
22322  }
22323 
22324  public:
22382  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22383  static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
22384  {
22385  return ref.items();
22386  }
22387 
22391  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22392  static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
22393  {
22394  return ref.items();
22395  }
22396 
22466  {
22467  return iteration_proxy<iterator>(*this);
22468  }
22469 
22474  {
22475  return iteration_proxy<const_iterator>(*this);
22476  }
22477 
22479 
22480 
22482  // capacity //
22484 
22487 
22530  bool empty() const noexcept
22531  {
22532  switch (m_type)
22533  {
22534  case value_t::null:
22535  {
22536  // null values are empty
22537  return true;
22538  }
22539 
22540  case value_t::array:
22541  {
22542  // delegate call to array_t::empty()
22543  return m_value.array->empty();
22544  }
22545 
22546  case value_t::object:
22547  {
22548  // delegate call to object_t::empty()
22549  return m_value.object->empty();
22550  }
22551 
22552  case value_t::string:
22553  case value_t::boolean:
22554  case value_t::number_integer:
22555  case value_t::number_unsigned:
22556  case value_t::number_float:
22557  case value_t::binary:
22558  case value_t::discarded:
22559  default:
22560  {
22561  // all other types are nonempty
22562  return false;
22563  }
22564  }
22565  }
22566 
22610  size_type size() const noexcept
22611  {
22612  switch (m_type)
22613  {
22614  case value_t::null:
22615  {
22616  // null values are empty
22617  return 0;
22618  }
22619 
22620  case value_t::array:
22621  {
22622  // delegate call to array_t::size()
22623  return m_value.array->size();
22624  }
22625 
22626  case value_t::object:
22627  {
22628  // delegate call to object_t::size()
22629  return m_value.object->size();
22630  }
22631 
22632  case value_t::string:
22633  case value_t::boolean:
22634  case value_t::number_integer:
22635  case value_t::number_unsigned:
22636  case value_t::number_float:
22637  case value_t::binary:
22638  case value_t::discarded:
22639  default:
22640  {
22641  // all other types have size 1
22642  return 1;
22643  }
22644  }
22645  }
22646 
22688  size_type max_size() const noexcept
22689  {
22690  switch (m_type)
22691  {
22692  case value_t::array:
22693  {
22694  // delegate call to array_t::max_size()
22695  return m_value.array->max_size();
22696  }
22697 
22698  case value_t::object:
22699  {
22700  // delegate call to object_t::max_size()
22701  return m_value.object->max_size();
22702  }
22703 
22704  case value_t::null:
22705  case value_t::string:
22706  case value_t::boolean:
22707  case value_t::number_integer:
22708  case value_t::number_unsigned:
22709  case value_t::number_float:
22710  case value_t::binary:
22711  case value_t::discarded:
22712  default:
22713  {
22714  // all other types have max_size() == size()
22715  return size();
22716  }
22717  }
22718  }
22719 
22721 
22722 
22724  // modifiers //
22726 
22729 
22767  void clear() noexcept
22768  {
22769  switch (m_type)
22770  {
22771  case value_t::number_integer:
22772  {
22773  m_value.number_integer = 0;
22774  break;
22775  }
22776 
22777  case value_t::number_unsigned:
22778  {
22779  m_value.number_unsigned = 0;
22780  break;
22781  }
22782 
22783  case value_t::number_float:
22784  {
22785  m_value.number_float = 0.0;
22786  break;
22787  }
22788 
22789  case value_t::boolean:
22790  {
22791  m_value.boolean = false;
22792  break;
22793  }
22794 
22795  case value_t::string:
22796  {
22797  m_value.string->clear();
22798  break;
22799  }
22800 
22801  case value_t::binary:
22802  {
22803  m_value.binary->clear();
22804  break;
22805  }
22806 
22807  case value_t::array:
22808  {
22809  m_value.array->clear();
22810  break;
22811  }
22812 
22813  case value_t::object:
22814  {
22815  m_value.object->clear();
22816  break;
22817  }
22818 
22819  case value_t::null:
22820  case value_t::discarded:
22821  default:
22822  break;
22823  }
22824  }
22825 
22846  void push_back(basic_json&& val)
22847  {
22848  // push_back only works for null objects or arrays
22849  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22850  {
22851  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22852  }
22853 
22854  // transform null object into an array
22855  if (is_null())
22856  {
22857  m_type = value_t::array;
22858  m_value = value_t::array;
22859  assert_invariant();
22860  }
22861 
22862  // add element to array (move semantics)
22863  const auto old_capacity = m_value.array->capacity();
22864  m_value.array->push_back(std::move(val));
22865  set_parent(m_value.array->back(), old_capacity);
22866  // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
22867  }
22868 
22874  {
22875  push_back(std::move(val));
22876  return *this;
22877  }
22878 
22883  void push_back(const basic_json& val)
22884  {
22885  // push_back only works for null objects or arrays
22886  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22887  {
22888  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22889  }
22890 
22891  // transform null object into an array
22892  if (is_null())
22893  {
22894  m_type = value_t::array;
22895  m_value = value_t::array;
22896  assert_invariant();
22897  }
22898 
22899  // add element to array
22900  const auto old_capacity = m_value.array->capacity();
22901  m_value.array->push_back(val);
22902  set_parent(m_value.array->back(), old_capacity);
22903  }
22904 
22910  {
22911  push_back(val);
22912  return *this;
22913  }
22914 
22935  void push_back(const typename object_t::value_type& val)
22936  {
22937  // push_back only works for null objects or objects
22938  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22939  {
22940  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22941  }
22942 
22943  // transform null object into an object
22944  if (is_null())
22945  {
22946  m_type = value_t::object;
22947  m_value = value_t::object;
22948  assert_invariant();
22949  }
22950 
22951  // add element to object
22952  auto res = m_value.object->insert(val);
22953  set_parent(res.first->second);
22954  }
22955 
22960  reference operator+=(const typename object_t::value_type& val)
22961  {
22962  push_back(val);
22963  return *this;
22964  }
22965 
22992  {
22993  if (is_object() && init.size() == 2 && (*init.begin())->is_string())
22994  {
22995  basic_json&& key = init.begin()->moved_or_copied();
22996  push_back(typename object_t::value_type(
22997  std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
22998  }
22999  else
23000  {
23001  push_back(basic_json(init));
23002  }
23003  }
23004 
23010  {
23011  push_back(init);
23012  return *this;
23013  }
23014 
23038  template<class... Args>
23039  reference emplace_back(Args&& ... args)
23040  {
23041  // emplace_back only works for null objects or arrays
23042  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23043  {
23044  JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()), *this));
23045  }
23046 
23047  // transform null object into an array
23048  if (is_null())
23049  {
23050  m_type = value_t::array;
23051  m_value = value_t::array;
23052  assert_invariant();
23053  }
23054 
23055  // add element to array (perfect forwarding)
23056  const auto old_capacity = m_value.array->capacity();
23057  m_value.array->emplace_back(std::forward<Args>(args)...);
23058  return set_parent(m_value.array->back(), old_capacity);
23059  }
23060 
23088  template<class... Args>
23089  std::pair<iterator, bool> emplace(Args&& ... args)
23090  {
23091  // emplace only works for null objects or arrays
23092  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23093  {
23094  JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()), *this));
23095  }
23096 
23097  // transform null object into an object
23098  if (is_null())
23099  {
23100  m_type = value_t::object;
23101  m_value = value_t::object;
23102  assert_invariant();
23103  }
23104 
23105  // add element to array (perfect forwarding)
23106  auto res = m_value.object->emplace(std::forward<Args>(args)...);
23107  set_parent(res.first->second);
23108 
23109  // create result iterator and set iterator to the result of emplace
23110  auto it = begin();
23111  it.m_it.object_iterator = res.first;
23112 
23113  // return pair of iterator and boolean
23114  return {it, res.second};
23115  }
23116 
23120  template<typename... Args>
23122  {
23123  iterator result(this);
23124  JSON_ASSERT(m_value.array != nullptr);
23125 
23126  auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
23127  m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
23128  result.m_it.array_iterator = m_value.array->begin() + insert_pos;
23129 
23130  // This could have been written as:
23131  // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
23132  // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
23133 
23134  set_parents();
23135  return result;
23136  }
23137 
23161  {
23162  // insert only works for arrays
23163  if (JSON_HEDLEY_LIKELY(is_array()))
23164  {
23165  // check if iterator pos fits to this JSON value
23166  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23167  {
23168  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23169  }
23170 
23171  // insert to array and return iterator
23172  return insert_iterator(pos, val);
23173  }
23174 
23175  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23176  }
23177 
23183  {
23184  return insert(pos, val);
23185  }
23186 
23212  {
23213  // insert only works for arrays
23214  if (JSON_HEDLEY_LIKELY(is_array()))
23215  {
23216  // check if iterator pos fits to this JSON value
23217  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23218  {
23219  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23220  }
23221 
23222  // insert to array and return iterator
23223  return insert_iterator(pos, cnt, val);
23224  }
23225 
23226  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23227  }
23228 
23260  {
23261  // insert only works for arrays
23262  if (JSON_HEDLEY_UNLIKELY(!is_array()))
23263  {
23264  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23265  }
23266 
23267  // check if iterator pos fits to this JSON value
23268  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23269  {
23270  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23271  }
23272 
23273  // check if range iterators belong to the same JSON object
23274  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23275  {
23276  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23277  }
23278 
23279  if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
23280  {
23281  JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", *this));
23282  }
23283 
23284  // insert to array and return iterator
23285  return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
23286  }
23287 
23313  {
23314  // insert only works for arrays
23315  if (JSON_HEDLEY_UNLIKELY(!is_array()))
23316  {
23317  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23318  }
23319 
23320  // check if iterator pos fits to this JSON value
23321  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23322  {
23323  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23324  }
23325 
23326  // insert to array and return iterator
23327  return insert_iterator(pos, ilist.begin(), ilist.end());
23328  }
23329 
23354  {
23355  // insert only works for objects
23356  if (JSON_HEDLEY_UNLIKELY(!is_object()))
23357  {
23358  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23359  }
23360 
23361  // check if range iterators belong to the same JSON object
23362  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23363  {
23364  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23365  }
23366 
23367  // passed iterators must belong to objects
23368  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
23369  {
23370  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23371  }
23372 
23373  m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
23374  }
23375 
23396  {
23397  // implicitly convert null value to an empty object
23398  if (is_null())
23399  {
23400  m_type = value_t::object;
23401  m_value.object = create<object_t>();
23402  assert_invariant();
23403  }
23404 
23405  if (JSON_HEDLEY_UNLIKELY(!is_object()))
23406  {
23407  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
23408  }
23409  if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
23410  {
23411  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()), *this));
23412  }
23413 
23414  for (auto it = j.cbegin(); it != j.cend(); ++it)
23415  {
23416  m_value.object->operator[](it.key()) = it.value();
23417  }
23418  }
23419 
23447  {
23448  // implicitly convert null value to an empty object
23449  if (is_null())
23450  {
23451  m_type = value_t::object;
23452  m_value.object = create<object_t>();
23453  assert_invariant();
23454  }
23455 
23456  if (JSON_HEDLEY_UNLIKELY(!is_object()))
23457  {
23458  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
23459  }
23460 
23461  // check if range iterators belong to the same JSON object
23462  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23463  {
23464  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23465  }
23466 
23467  // passed iterators must belong to objects
23468  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
23469  || !last.m_object->is_object()))
23470  {
23471  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23472  }
23473 
23474  for (auto it = first; it != last; ++it)
23475  {
23476  m_value.object->operator[](it.key()) = it.value();
23477  }
23478  }
23479 
23497  void swap(reference other) noexcept (
23498  std::is_nothrow_move_constructible<value_t>::value&&
23499  std::is_nothrow_move_assignable<value_t>::value&&
23500  std::is_nothrow_move_constructible<json_value>::value&&
23501  std::is_nothrow_move_assignable<json_value>::value
23502  )
23503  {
23504  std::swap(m_type, other.m_type);
23505  std::swap(m_value, other.m_value);
23506 
23507  set_parents();
23508  other.set_parents();
23509  assert_invariant();
23510  }
23511 
23530  friend void swap(reference left, reference right) noexcept (
23531  std::is_nothrow_move_constructible<value_t>::value&&
23532  std::is_nothrow_move_assignable<value_t>::value&&
23533  std::is_nothrow_move_constructible<json_value>::value&&
23534  std::is_nothrow_move_assignable<json_value>::value
23535  )
23536  {
23537  left.swap(right);
23538  }
23539 
23560  void swap(array_t& other) // NOLINT(bugprone-exception-escape)
23561  {
23562  // swap only works for arrays
23563  if (JSON_HEDLEY_LIKELY(is_array()))
23564  {
23565  std::swap(*(m_value.array), other);
23566  }
23567  else
23568  {
23569  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23570  }
23571  }
23572 
23593  void swap(object_t& other) // NOLINT(bugprone-exception-escape)
23594  {
23595  // swap only works for objects
23596  if (JSON_HEDLEY_LIKELY(is_object()))
23597  {
23598  std::swap(*(m_value.object), other);
23599  }
23600  else
23601  {
23602  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23603  }
23604  }
23605 
23626  void swap(string_t& other) // NOLINT(bugprone-exception-escape)
23627  {
23628  // swap only works for strings
23629  if (JSON_HEDLEY_LIKELY(is_string()))
23630  {
23631  std::swap(*(m_value.string), other);
23632  }
23633  else
23634  {
23635  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23636  }
23637  }
23638 
23659  void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
23660  {
23661  // swap only works for strings
23662  if (JSON_HEDLEY_LIKELY(is_binary()))
23663  {
23664  std::swap(*(m_value.binary), other);
23665  }
23666  else
23667  {
23668  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23669  }
23670  }
23671 
23673  void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
23674  {
23675  // swap only works for strings
23676  if (JSON_HEDLEY_LIKELY(is_binary()))
23677  {
23678  std::swap(*(m_value.binary), other);
23679  }
23680  else
23681  {
23682  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23683  }
23684  }
23685 
23687 
23688  public:
23690  // lexicographical comparison operators //
23692 
23695 
23751  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
23752  {
23753 #ifdef __GNUC__
23754 #pragma GCC diagnostic push
23755 #pragma GCC diagnostic ignored "-Wfloat-equal"
23756 #endif
23757  const auto lhs_type = lhs.type();
23758  const auto rhs_type = rhs.type();
23759 
23760  if (lhs_type == rhs_type)
23761  {
23762  switch (lhs_type)
23763  {
23764  case value_t::array:
23765  return *lhs.m_value.array == *rhs.m_value.array;
23766 
23767  case value_t::object:
23768  return *lhs.m_value.object == *rhs.m_value.object;
23769 
23770  case value_t::null:
23771  return true;
23772 
23773  case value_t::string:
23774  return *lhs.m_value.string == *rhs.m_value.string;
23775 
23776  case value_t::boolean:
23777  return lhs.m_value.boolean == rhs.m_value.boolean;
23778 
23779  case value_t::number_integer:
23780  return lhs.m_value.number_integer == rhs.m_value.number_integer;
23781 
23782  case value_t::number_unsigned:
23783  return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
23784 
23785  case value_t::number_float:
23786  return lhs.m_value.number_float == rhs.m_value.number_float;
23787 
23788  case value_t::binary:
23789  return *lhs.m_value.binary == *rhs.m_value.binary;
23790 
23791  case value_t::discarded:
23792  default:
23793  return false;
23794  }
23795  }
23796  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
23797  {
23798  return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
23799  }
23800  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
23801  {
23802  return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
23803  }
23804  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
23805  {
23806  return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
23807  }
23808  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
23809  {
23810  return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
23811  }
23812  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
23813  {
23814  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
23815  }
23816  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
23817  {
23818  return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
23819  }
23820 
23821  return false;
23822 #ifdef __GNUC__
23823 #pragma GCC diagnostic pop
23824 #endif
23825  }
23826 
23831  template<typename ScalarType, typename std::enable_if<
23832  std::is_scalar<ScalarType>::value, int>::type = 0>
23833  friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
23834  {
23835  return lhs == basic_json(rhs);
23836  }
23837 
23842  template<typename ScalarType, typename std::enable_if<
23843  std::is_scalar<ScalarType>::value, int>::type = 0>
23844  friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
23845  {
23846  return basic_json(lhs) == rhs;
23847  }
23848 
23867  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
23868  {
23869  return !(lhs == rhs);
23870  }
23871 
23876  template<typename ScalarType, typename std::enable_if<
23877  std::is_scalar<ScalarType>::value, int>::type = 0>
23878  friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23879  {
23880  return lhs != basic_json(rhs);
23881  }
23882 
23887  template<typename ScalarType, typename std::enable_if<
23888  std::is_scalar<ScalarType>::value, int>::type = 0>
23889  friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
23890  {
23891  return basic_json(lhs) != rhs;
23892  }
23893 
23920  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
23921  {
23922  const auto lhs_type = lhs.type();
23923  const auto rhs_type = rhs.type();
23924 
23925  if (lhs_type == rhs_type)
23926  {
23927  switch (lhs_type)
23928  {
23929  case value_t::array:
23930  // note parentheses are necessary, see
23931  // https://github.com/nlohmann/json/issues/1530
23932  return (*lhs.m_value.array) < (*rhs.m_value.array);
23933 
23934  case value_t::object:
23935  return (*lhs.m_value.object) < (*rhs.m_value.object);
23936 
23937  case value_t::null:
23938  return false;
23939 
23940  case value_t::string:
23941  return (*lhs.m_value.string) < (*rhs.m_value.string);
23942 
23943  case value_t::boolean:
23944  return (lhs.m_value.boolean) < (rhs.m_value.boolean);
23945 
23946  case value_t::number_integer:
23947  return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
23948 
23949  case value_t::number_unsigned:
23950  return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
23951 
23952  case value_t::number_float:
23953  return (lhs.m_value.number_float) < (rhs.m_value.number_float);
23954 
23955  case value_t::binary:
23956  return (*lhs.m_value.binary) < (*rhs.m_value.binary);
23957 
23958  case value_t::discarded:
23959  default:
23960  return false;
23961  }
23962  }
23963  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
23964  {
23965  return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
23966  }
23967  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
23968  {
23969  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
23970  }
23971  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
23972  {
23973  return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
23974  }
23975  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
23976  {
23977  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
23978  }
23979  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
23980  {
23981  return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
23982  }
23983  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
23984  {
23985  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
23986  }
23987 
23988  // We only reach this line if we cannot compare values. In that case,
23989  // we compare types. Note we have to call the operator explicitly,
23990  // because MSVC has problems otherwise.
23991  return operator<(lhs_type, rhs_type);
23992  }
23993 
23998  template<typename ScalarType, typename std::enable_if<
23999  std::is_scalar<ScalarType>::value, int>::type = 0>
24000  friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
24001  {
24002  return lhs < basic_json(rhs);
24003  }
24004 
24009  template<typename ScalarType, typename std::enable_if<
24010  std::is_scalar<ScalarType>::value, int>::type = 0>
24011  friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
24012  {
24013  return basic_json(lhs) < rhs;
24014  }
24015 
24035  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
24036  {
24037  return !(rhs < lhs);
24038  }
24039 
24044  template<typename ScalarType, typename std::enable_if<
24045  std::is_scalar<ScalarType>::value, int>::type = 0>
24046  friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
24047  {
24048  return lhs <= basic_json(rhs);
24049  }
24050 
24055  template<typename ScalarType, typename std::enable_if<
24056  std::is_scalar<ScalarType>::value, int>::type = 0>
24057  friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
24058  {
24059  return basic_json(lhs) <= rhs;
24060  }
24061 
24081  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
24082  {
24083  return !(lhs <= rhs);
24084  }
24085 
24090  template<typename ScalarType, typename std::enable_if<
24091  std::is_scalar<ScalarType>::value, int>::type = 0>
24092  friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
24093  {
24094  return lhs > basic_json(rhs);
24095  }
24096 
24101  template<typename ScalarType, typename std::enable_if<
24102  std::is_scalar<ScalarType>::value, int>::type = 0>
24103  friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
24104  {
24105  return basic_json(lhs) > rhs;
24106  }
24107 
24127  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
24128  {
24129  return !(lhs < rhs);
24130  }
24131 
24136  template<typename ScalarType, typename std::enable_if<
24137  std::is_scalar<ScalarType>::value, int>::type = 0>
24138  friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
24139  {
24140  return lhs >= basic_json(rhs);
24141  }
24142 
24147  template<typename ScalarType, typename std::enable_if<
24148  std::is_scalar<ScalarType>::value, int>::type = 0>
24149  friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
24150  {
24151  return basic_json(lhs) >= rhs;
24152  }
24153 
24155 
24157  // serialization //
24159 
24162 #ifndef JSON_NO_IO
24163 
24194  friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
24195  {
24196  // read width member and use it as indentation parameter if nonzero
24197  const bool pretty_print = o.width() > 0;
24198  const auto indentation = pretty_print ? o.width() : 0;
24199 
24200  // reset width to 0 for subsequent calls to this stream
24201  o.width(0);
24202 
24203  // do the actual serialization
24204  serializer s(detail::output_adapter<char>(o), o.fill());
24205  s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
24206  return o;
24207  }
24208 
24217  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
24218  friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
24219  {
24220  return o << j;
24221  }
24222 #endif // JSON_NO_IO
24223 
24225 
24227  // deserialization //
24229 
24232 
24284  template<typename InputType>
24286  static basic_json parse(InputType&& i,
24287  const parser_callback_t cb = nullptr,
24288  const bool allow_exceptions = true,
24289  const bool ignore_comments = false)
24290  {
24291  basic_json result;
24292  parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
24293  return result;
24294  }
24295 
24322  template<typename IteratorType>
24324  static basic_json parse(IteratorType first,
24325  IteratorType last,
24326  const parser_callback_t cb = nullptr,
24327  const bool allow_exceptions = true,
24328  const bool ignore_comments = false)
24329  {
24330  basic_json result;
24331  parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
24332  return result;
24333  }
24334 
24336  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
24337  static basic_json parse(detail::span_input_adapter&& i,
24338  const parser_callback_t cb = nullptr,
24339  const bool allow_exceptions = true,
24340  const bool ignore_comments = false)
24341  {
24342  basic_json result;
24343  parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
24344  return result;
24345  }
24346 
24377  template<typename InputType>
24378  static bool accept(InputType&& i,
24379  const bool ignore_comments = false)
24380  {
24381  return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
24382  }
24383 
24384  template<typename IteratorType>
24385  static bool accept(IteratorType first, IteratorType last,
24386  const bool ignore_comments = false)
24387  {
24388  return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
24389  }
24390 
24392  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
24393  static bool accept(detail::span_input_adapter&& i,
24394  const bool ignore_comments = false)
24395  {
24396  return parser(i.get(), nullptr, false, ignore_comments).accept(true);
24397  }
24398 
24439  template <typename InputType, typename SAX>
24441  static bool sax_parse(InputType&& i, SAX* sax,
24443  const bool strict = true,
24444  const bool ignore_comments = false)
24445  {
24446  auto ia = detail::input_adapter(std::forward<InputType>(i));
24447  return format == input_format_t::json
24448  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24449  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24450  }
24451 
24452  template<class IteratorType, class SAX>
24454  static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
24456  const bool strict = true,
24457  const bool ignore_comments = false)
24458  {
24459  auto ia = detail::input_adapter(std::move(first), std::move(last));
24460  return format == input_format_t::json
24461  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24462  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24463  }
24464 
24465  template <typename SAX>
24466  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
24468  static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
24470  const bool strict = true,
24471  const bool ignore_comments = false)
24472  {
24473  auto ia = i.get();
24474  return format == input_format_t::json
24475  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24476  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24477  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24478  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24479  }
24480 #ifndef JSON_NO_IO
24481 
24489  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
24490  friend std::istream& operator<<(basic_json& j, std::istream& i)
24491  {
24492  return operator>>(i, j);
24493  }
24494 
24520  friend std::istream& operator>>(std::istream& i, basic_json& j)
24521  {
24522  parser(detail::input_adapter(i)).parse(false, j);
24523  return i;
24524  }
24525 #endif // JSON_NO_IO
24526 
24529  // convenience functions //
24531 
24564  const char* type_name() const noexcept
24565  {
24566  {
24567  switch (m_type)
24568  {
24569  case value_t::null:
24570  return "null";
24571  case value_t::object:
24572  return "object";
24573  case value_t::array:
24574  return "array";
24575  case value_t::string:
24576  return "string";
24577  case value_t::boolean:
24578  return "boolean";
24579  case value_t::binary:
24580  return "binary";
24581  case value_t::discarded:
24582  return "discarded";
24583  case value_t::number_integer:
24584  case value_t::number_unsigned:
24585  case value_t::number_float:
24586  default:
24587  return "number";
24588  }
24589  }
24590  }
24591 
24592 
24595  // member variables //
24597 
24599  value_t m_type = value_t::null;
24600 
24602  json_value m_value = {};
24603 
24604 #if JSON_DIAGNOSTICS
24605  basic_json* m_parent = nullptr;
24607 #endif
24608 
24610  // binary serialization/deserialization //
24612 
24615 
24616  public:
24715  static std::vector<std::uint8_t> to_cbor(const basic_json& j)
24716  {
24717  std::vector<std::uint8_t> result;
24718  to_cbor(j, result);
24719  return result;
24720  }
24721 
24723  {
24724  binary_writer<std::uint8_t>(o).write_cbor(j);
24725  }
24726 
24728  {
24729  binary_writer<char>(o).write_cbor(j);
24730  }
24731 
24810  static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
24811  {
24812  std::vector<std::uint8_t> result;
24813  to_msgpack(j, result);
24814  return result;
24815  }
24816 
24818  {
24819  binary_writer<std::uint8_t>(o).write_msgpack(j);
24820  }
24821 
24823  {
24824  binary_writer<char>(o).write_msgpack(j);
24825  }
24826 
24913  static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
24914  const bool use_size = false,
24915  const bool use_type = false)
24916  {
24917  std::vector<std::uint8_t> result;
24918  to_ubjson(j, result, use_size, use_type);
24919  return result;
24920  }
24921 
24923  const bool use_size = false, const bool use_type = false)
24924  {
24925  binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
24926  }
24927 
24929  const bool use_size = false, const bool use_type = false)
24930  {
24931  binary_writer<char>(o).write_ubjson(j, use_size, use_type);
24932  }
24933 
24934 
24991  static std::vector<std::uint8_t> to_bson(const basic_json& j)
24992  {
24993  std::vector<std::uint8_t> result;
24994  to_bson(j, result);
24995  return result;
24996  }
24997 
25007  {
25008  binary_writer<std::uint8_t>(o).write_bson(j);
25009  }
25010 
25015  {
25016  binary_writer<char>(o).write_bson(j);
25017  }
25018 
25019 
25122  template<typename InputType>
25124  static basic_json from_cbor(InputType&& i,
25125  const bool strict = true,
25126  const bool allow_exceptions = true,
25127  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25128  {
25129  basic_json result;
25130  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25131  auto ia = detail::input_adapter(std::forward<InputType>(i));
25132  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25133  return res ? result : basic_json(value_t::discarded);
25134  }
25135 
25139  template<typename IteratorType>
25141  static basic_json from_cbor(IteratorType first, IteratorType last,
25142  const bool strict = true,
25143  const bool allow_exceptions = true,
25144  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25145  {
25146  basic_json result;
25147  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25148  auto ia = detail::input_adapter(std::move(first), std::move(last));
25149  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25150  return res ? result : basic_json(value_t::discarded);
25151  }
25152 
25153  template<typename T>
25155  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
25156  static basic_json from_cbor(const T* ptr, std::size_t len,
25157  const bool strict = true,
25158  const bool allow_exceptions = true,
25159  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25160  {
25161  return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
25162  }
25163 
25164 
25166  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
25167  static basic_json from_cbor(detail::span_input_adapter&& i,
25168  const bool strict = true,
25169  const bool allow_exceptions = true,
25170  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25171  {
25172  basic_json result;
25173  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25174  auto ia = i.get();
25175  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25176  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25177  return res ? result : basic_json(value_t::discarded);
25178  }
25179 
25266  template<typename InputType>
25268  static basic_json from_msgpack(InputType&& i,
25269  const bool strict = true,
25270  const bool allow_exceptions = true)
25271  {
25272  basic_json result;
25273  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25274  auto ia = detail::input_adapter(std::forward<InputType>(i));
25275  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25276  return res ? result : basic_json(value_t::discarded);
25277  }
25278 
25282  template<typename IteratorType>
25284  static basic_json from_msgpack(IteratorType first, IteratorType last,
25285  const bool strict = true,
25286  const bool allow_exceptions = true)
25287  {
25288  basic_json result;
25289  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25290  auto ia = detail::input_adapter(std::move(first), std::move(last));
25291  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25292  return res ? result : basic_json(value_t::discarded);
25293  }
25294 
25295 
25296  template<typename T>
25298  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
25299  static basic_json from_msgpack(const T* ptr, std::size_t len,
25300  const bool strict = true,
25301  const bool allow_exceptions = true)
25302  {
25303  return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
25304  }
25305 
25307  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
25308  static basic_json from_msgpack(detail::span_input_adapter&& i,
25309  const bool strict = true,
25310  const bool allow_exceptions = true)
25311  {
25312  basic_json result;
25313  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25314  auto ia = i.get();
25315  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25316  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25317  return res ? result : basic_json(value_t::discarded);
25318  }
25319 
25320 
25383  template<typename InputType>
25385  static basic_json from_ubjson(InputType&& i,
25386  const bool strict = true,
25387  const bool allow_exceptions = true)
25388  {
25389  basic_json result;
25390  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25391  auto ia = detail::input_adapter(std::forward<InputType>(i));
25392  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25393  return res ? result : basic_json(value_t::discarded);
25394  }
25395 
25399  template<typename IteratorType>
25401  static basic_json from_ubjson(IteratorType first, IteratorType last,
25402  const bool strict = true,
25403  const bool allow_exceptions = true)
25404  {
25405  basic_json result;
25406  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25407  auto ia = detail::input_adapter(std::move(first), std::move(last));
25408  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25409  return res ? result : basic_json(value_t::discarded);
25410  }
25411 
25412  template<typename T>
25414  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
25415  static basic_json from_ubjson(const T* ptr, std::size_t len,
25416  const bool strict = true,
25417  const bool allow_exceptions = true)
25418  {
25419  return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
25420  }
25421 
25423  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
25424  static basic_json from_ubjson(detail::span_input_adapter&& i,
25425  const bool strict = true,
25426  const bool allow_exceptions = true)
25427  {
25428  basic_json result;
25429  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25430  auto ia = i.get();
25431  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25432  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25433  return res ? result : basic_json(value_t::discarded);
25434  }
25435 
25436 
25497  template<typename InputType>
25499  static basic_json from_bson(InputType&& i,
25500  const bool strict = true,
25501  const bool allow_exceptions = true)
25502  {
25503  basic_json result;
25504  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25505  auto ia = detail::input_adapter(std::forward<InputType>(i));
25506  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25507  return res ? result : basic_json(value_t::discarded);
25508  }
25509 
25513  template<typename IteratorType>
25515  static basic_json from_bson(IteratorType first, IteratorType last,
25516  const bool strict = true,
25517  const bool allow_exceptions = true)
25518  {
25519  basic_json result;
25520  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25521  auto ia = detail::input_adapter(std::move(first), std::move(last));
25522  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25523  return res ? result : basic_json(value_t::discarded);
25524  }
25525 
25526  template<typename T>
25528  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25529  static basic_json from_bson(const T* ptr, std::size_t len,
25530  const bool strict = true,
25531  const bool allow_exceptions = true)
25532  {
25533  return from_bson(ptr, ptr + len, strict, allow_exceptions);
25534  }
25535 
25537  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25538  static basic_json from_bson(detail::span_input_adapter&& i,
25539  const bool strict = true,
25540  const bool allow_exceptions = true)
25541  {
25542  basic_json result;
25543  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25544  auto ia = i.get();
25545  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25546  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25547  return res ? result : basic_json(value_t::discarded);
25548  }
25550 
25552  // JSON Pointer support //
25554 
25557 
25592  {
25593  return ptr.get_unchecked(this);
25594  }
25595 
25620  {
25621  return ptr.get_unchecked(this);
25622  }
25623 
25663  {
25664  return ptr.get_checked(this);
25665  }
25666 
25705  const_reference at(const json_pointer& ptr) const
25706  {
25707  return ptr.get_checked(this);
25708  }
25709 
25733  {
25734  basic_json result(value_t::object);
25735  json_pointer::flatten("", *this, result);
25736  return result;
25737  }
25738 
25770  {
25771  return json_pointer::unflatten(*this);
25772  }
25773 
25775 
25777  // JSON Patch functions //
25779 
25782 
25830  basic_json patch(const basic_json& json_patch) const
25831  {
25832  // make a working copy to apply the patch to
25833  basic_json result = *this;
25834 
25835  // the valid JSON Patch operations
25836  enum class patch_operations {add, remove, replace, move, copy, test, invalid};
25837 
25838  const auto get_op = [](const std::string & op)
25839  {
25840  if (op == "add")
25841  {
25842  return patch_operations::add;
25843  }
25844  if (op == "remove")
25845  {
25846  return patch_operations::remove;
25847  }
25848  if (op == "replace")
25849  {
25850  return patch_operations::replace;
25851  }
25852  if (op == "move")
25853  {
25854  return patch_operations::move;
25855  }
25856  if (op == "copy")
25857  {
25858  return patch_operations::copy;
25859  }
25860  if (op == "test")
25861  {
25862  return patch_operations::test;
25863  }
25864 
25865  return patch_operations::invalid;
25866  };
25867 
25868  // wrapper for "add" operation; add value at ptr
25869  const auto operation_add = [&result](json_pointer & ptr, basic_json val)
25870  {
25871  // adding to the root of the target document means replacing it
25872  if (ptr.empty())
25873  {
25874  result = val;
25875  return;
25876  }
25877 
25878  // make sure the top element of the pointer exists
25879  json_pointer top_pointer = ptr.top();
25880  if (top_pointer != ptr)
25881  {
25882  result.at(top_pointer);
25883  }
25884 
25885  // get reference to parent of JSON pointer ptr
25886  const auto last_path = ptr.back();
25887  ptr.pop_back();
25888  basic_json& parent = result[ptr];
25889 
25890  switch (parent.m_type)
25891  {
25892  case value_t::null:
25893  case value_t::object:
25894  {
25895  // use operator[] to add value
25896  parent[last_path] = val;
25897  break;
25898  }
25899 
25900  case value_t::array:
25901  {
25902  if (last_path == "-")
25903  {
25904  // special case: append to back
25905  parent.push_back(val);
25906  }
25907  else
25908  {
25909  const auto idx = json_pointer::array_index(last_path);
25910  if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
25911  {
25912  // avoid undefined behavior
25913  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", parent));
25914  }
25915 
25916  // default case: insert add offset
25917  parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
25918  }
25919  break;
25920  }
25921 
25922  // if there exists a parent it cannot be primitive
25923  case value_t::string: // LCOV_EXCL_LINE
25924  case value_t::boolean: // LCOV_EXCL_LINE
25925  case value_t::number_integer: // LCOV_EXCL_LINE
25926  case value_t::number_unsigned: // LCOV_EXCL_LINE
25927  case value_t::number_float: // LCOV_EXCL_LINE
25928  case value_t::binary: // LCOV_EXCL_LINE
25929  case value_t::discarded: // LCOV_EXCL_LINE
25930  default: // LCOV_EXCL_LINE
25931  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
25932  }
25933  };
25934 
25935  // wrapper for "remove" operation; remove value at ptr
25936  const auto operation_remove = [this, &result](json_pointer & ptr)
25937  {
25938  // get reference to parent of JSON pointer ptr
25939  const auto last_path = ptr.back();
25940  ptr.pop_back();
25941  basic_json& parent = result.at(ptr);
25942 
25943  // remove child
25944  if (parent.is_object())
25945  {
25946  // perform range check
25947  auto it = parent.find(last_path);
25948  if (JSON_HEDLEY_LIKELY(it != parent.end()))
25949  {
25950  parent.erase(it);
25951  }
25952  else
25953  {
25954  JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found", *this));
25955  }
25956  }
25957  else if (parent.is_array())
25958  {
25959  // note erase performs range check
25960  parent.erase(json_pointer::array_index(last_path));
25961  }
25962  };
25963 
25964  // type check: top level value must be an array
25965  if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
25966  {
25967  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", json_patch));
25968  }
25969 
25970  // iterate and apply the operations
25971  for (const auto& val : json_patch)
25972  {
25973  // wrapper to get a value for an operation
25974  const auto get_value = [&val](const std::string & op,
25975  const std::string & member,
25976  bool string_type) -> basic_json &
25977  {
25978  // find value
25979  auto it = val.m_value.object->find(member);
25980 
25981  // context-sensitive error message
25982  const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
25983 
25984  // check if desired value is present
25985  if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
25986  {
25987  // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
25988  JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'", val));
25989  }
25990 
25991  // check if result is of type string
25992  if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
25993  {
25994  // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
25995  JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'", val));
25996  }
25997 
25998  // no error: return value
25999  return it->second;
26000  };
26001 
26002  // type check: every element of the array must be an object
26003  if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
26004  {
26005  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", val));
26006  }
26007 
26008  // collect mandatory members
26009  const auto op = get_value("op", "op", true).template get<std::string>();
26010  const auto path = get_value(op, "path", true).template get<std::string>();
26011  json_pointer ptr(path);
26012 
26013  switch (get_op(op))
26014  {
26015  case patch_operations::add:
26016  {
26017  operation_add(ptr, get_value("add", "value", false));
26018  break;
26019  }
26020 
26021  case patch_operations::remove:
26022  {
26023  operation_remove(ptr);
26024  break;
26025  }
26026 
26027  case patch_operations::replace:
26028  {
26029  // the "path" location must exist - use at()
26030  result.at(ptr) = get_value("replace", "value", false);
26031  break;
26032  }
26033 
26034  case patch_operations::move:
26035  {
26036  const auto from_path = get_value("move", "from", true).template get<std::string>();
26037  json_pointer from_ptr(from_path);
26038 
26039  // the "from" location must exist - use at()
26040  basic_json v = result.at(from_ptr);
26041 
26042  // The move operation is functionally identical to a
26043  // "remove" operation on the "from" location, followed
26044  // immediately by an "add" operation at the target
26045  // location with the value that was just removed.
26046  operation_remove(from_ptr);
26047  operation_add(ptr, v);
26048  break;
26049  }
26050 
26051  case patch_operations::copy:
26052  {
26053  const auto from_path = get_value("copy", "from", true).template get<std::string>();
26054  const json_pointer from_ptr(from_path);
26055 
26056  // the "from" location must exist - use at()
26057  basic_json v = result.at(from_ptr);
26058 
26059  // The copy is functionally identical to an "add"
26060  // operation at the target location using the value
26061  // specified in the "from" member.
26062  operation_add(ptr, v);
26063  break;
26064  }
26065 
26066  case patch_operations::test:
26067  {
26068  bool success = false;
26069  JSON_TRY
26070  {
26071  // check if "value" matches the one at "path"
26072  // the "path" location must exist - use at()
26073  success = (result.at(ptr) == get_value("test", "value", false));
26074  }
26076  {
26077  // ignore out of range errors: success remains false
26078  }
26079 
26080  // throw an exception if test fails
26081  if (JSON_HEDLEY_UNLIKELY(!success))
26082  {
26083  JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump(), val));
26084  }
26085 
26086  break;
26087  }
26088 
26089  case patch_operations::invalid:
26090  default:
26091  {
26092  // op must be "add", "remove", "replace", "move", "copy", or
26093  // "test"
26094  JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid", val));
26095  }
26096  }
26097  }
26098 
26099  return result;
26100  }
26101 
26136  static basic_json diff(const basic_json& source, const basic_json& target,
26137  const std::string& path = "")
26138  {
26139  // the patch
26140  basic_json result(value_t::array);
26141 
26142  // if the values are the same, return empty patch
26143  if (source == target)
26144  {
26145  return result;
26146  }
26147 
26148  if (source.type() != target.type())
26149  {
26150  // different types: replace value
26151  result.push_back(
26152  {
26153  {"op", "replace"}, {"path", path}, {"value", target}
26154  });
26155  return result;
26156  }
26157 
26158  switch (source.type())
26159  {
26160  case value_t::array:
26161  {
26162  // first pass: traverse common elements
26163  std::size_t i = 0;
26164  while (i < source.size() && i < target.size())
26165  {
26166  // recursive call to compare array values at index i
26167  auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
26168  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
26169  ++i;
26170  }
26171 
26172  // i now reached the end of at least one array
26173  // in a second pass, traverse the remaining elements
26174 
26175  // remove my remaining elements
26176  const auto end_index = static_cast<difference_type>(result.size());
26177  while (i < source.size())
26178  {
26179  // add operations in reverse order to avoid invalid
26180  // indices
26181  result.insert(result.begin() + end_index, object(
26182  {
26183  {"op", "remove"},
26184  {"path", path + "/" + std::to_string(i)}
26185  }));
26186  ++i;
26187  }
26188 
26189  // add other remaining elements
26190  while (i < target.size())
26191  {
26192  result.push_back(
26193  {
26194  {"op", "add"},
26195  {"path", path + "/-"},
26196  {"value", target[i]}
26197  });
26198  ++i;
26199  }
26200 
26201  break;
26202  }
26203 
26204  case value_t::object:
26205  {
26206  // first pass: traverse this object's elements
26207  for (auto it = source.cbegin(); it != source.cend(); ++it)
26208  {
26209  // escape the key name to be used in a JSON patch
26210  const auto path_key = path + "/" + detail::escape(it.key());
26211 
26212  if (target.find(it.key()) != target.end())
26213  {
26214  // recursive call to compare object values at key it
26215  auto temp_diff = diff(it.value(), target[it.key()], path_key);
26216  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
26217  }
26218  else
26219  {
26220  // found a key that is not in o -> remove it
26221  result.push_back(object(
26222  {
26223  {"op", "remove"}, {"path", path_key}
26224  }));
26225  }
26226  }
26227 
26228  // second pass: traverse other object's elements
26229  for (auto it = target.cbegin(); it != target.cend(); ++it)
26230  {
26231  if (source.find(it.key()) == source.end())
26232  {
26233  // found a key that is not in this -> add it
26234  const auto path_key = path + "/" + detail::escape(it.key());
26235  result.push_back(
26236  {
26237  {"op", "add"}, {"path", path_key},
26238  {"value", it.value()}
26239  });
26240  }
26241  }
26242 
26243  break;
26244  }
26245 
26246  case value_t::null:
26247  case value_t::string:
26248  case value_t::boolean:
26249  case value_t::number_integer:
26250  case value_t::number_unsigned:
26251  case value_t::number_float:
26252  case value_t::binary:
26253  case value_t::discarded:
26254  default:
26255  {
26256  // both primitive type: replace value
26257  result.push_back(
26258  {
26259  {"op", "replace"}, {"path", path}, {"value", target}
26260  });
26261  break;
26262  }
26263  }
26264 
26265  return result;
26266  }
26267 
26269 
26271  // JSON Merge Patch functions //
26273 
26276 
26319  void merge_patch(const basic_json& apply_patch)
26320  {
26321  if (apply_patch.is_object())
26322  {
26323  if (!is_object())
26324  {
26325  *this = object();
26326  }
26327  for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
26328  {
26329  if (it.value().is_null())
26330  {
26331  erase(it.key());
26332  }
26333  else
26334  {
26335  operator[](it.key()).merge_patch(it.value());
26336  }
26337  }
26338  }
26339  else
26340  {
26341  *this = apply_patch;
26342  }
26343  }
26344 
26346 };
26347 
26358 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
26359 {
26360  return j.dump();
26361 }
26362 } // namespace nlohmann
26363 
26365 // nonmember support //
26367 
26368 // specialization of std::swap, and std::hash
26369 namespace std
26370 {
26371 
26373 template<>
26374 struct hash<nlohmann::json>
26375 {
26381  std::size_t operator()(const nlohmann::json& j) const
26382  {
26383  return nlohmann::detail::hash(j);
26384  }
26385 };
26386 
26390 template<>
26392 {
26398  nlohmann::detail::value_t rhs) const noexcept
26399  {
26400  return nlohmann::detail::operator<(lhs, rhs);
26401  }
26402 };
26403 
26404 // C++20 prohibit function specialization in the std namespace.
26405 #ifndef JSON_HAS_CPP_20
26406 
26412 template<>
26413 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
26414  is_nothrow_move_constructible<nlohmann::json>::value&& // NOLINT(misc-redundant-expression)
26415  is_nothrow_move_assignable<nlohmann::json>::value
26416  )
26417 {
26418  j1.swap(j2);
26419 }
26420 
26421 #endif
26422 
26423 } // namespace std
26424 
26439 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
26440 {
26441  return nlohmann::json::parse(s, s + n);
26442 }
26443 
26458 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
26459 {
26460  return nlohmann::json::json_pointer(std::string(s, n));
26461 }
26462 
26463 // #include <nlohmann/detail/macro_unscope.hpp>
26464 
26465 
26466 // restore clang diagnostic settings
26467 #if defined(__clang__)
26468  #pragma clang diagnostic pop
26469 #endif
26470 
26471 // clean up
26472 #undef JSON_ASSERT
26473 #undef JSON_INTERNAL_CATCH
26474 #undef JSON_CATCH
26475 #undef JSON_THROW
26476 #undef JSON_TRY
26477 #undef JSON_PRIVATE_UNLESS_TESTED
26478 #undef JSON_HAS_CPP_11
26479 #undef JSON_HAS_CPP_14
26480 #undef JSON_HAS_CPP_17
26481 #undef JSON_HAS_CPP_20
26482 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
26483 #undef NLOHMANN_BASIC_JSON_TPL
26484 #undef JSON_EXPLICIT
26485 
26486 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
26487 
26488 
26489 #undef JSON_HEDLEY_ALWAYS_INLINE
26490 #undef JSON_HEDLEY_ARM_VERSION
26491 #undef JSON_HEDLEY_ARM_VERSION_CHECK
26492 #undef JSON_HEDLEY_ARRAY_PARAM
26493 #undef JSON_HEDLEY_ASSUME
26494 #undef JSON_HEDLEY_BEGIN_C_DECLS
26495 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
26496 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
26497 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
26498 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
26499 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
26500 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
26501 #undef JSON_HEDLEY_CLANG_HAS_WARNING
26502 #undef JSON_HEDLEY_COMPCERT_VERSION
26503 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
26504 #undef JSON_HEDLEY_CONCAT
26505 #undef JSON_HEDLEY_CONCAT3
26506 #undef JSON_HEDLEY_CONCAT3_EX
26507 #undef JSON_HEDLEY_CONCAT_EX
26508 #undef JSON_HEDLEY_CONST
26509 #undef JSON_HEDLEY_CONSTEXPR
26510 #undef JSON_HEDLEY_CONST_CAST
26511 #undef JSON_HEDLEY_CPP_CAST
26512 #undef JSON_HEDLEY_CRAY_VERSION
26513 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
26514 #undef JSON_HEDLEY_C_DECL
26515 #undef JSON_HEDLEY_DEPRECATED
26516 #undef JSON_HEDLEY_DEPRECATED_FOR
26517 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
26518 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
26519 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
26520 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
26521 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
26522 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
26523 #undef JSON_HEDLEY_DIAGNOSTIC_POP
26524 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
26525 #undef JSON_HEDLEY_DMC_VERSION
26526 #undef JSON_HEDLEY_DMC_VERSION_CHECK
26527 #undef JSON_HEDLEY_EMPTY_BASES
26528 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
26529 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
26530 #undef JSON_HEDLEY_END_C_DECLS
26531 #undef JSON_HEDLEY_FLAGS
26532 #undef JSON_HEDLEY_FLAGS_CAST
26533 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
26534 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
26535 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
26536 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
26537 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
26538 #undef JSON_HEDLEY_GCC_HAS_FEATURE
26539 #undef JSON_HEDLEY_GCC_HAS_WARNING
26540 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
26541 #undef JSON_HEDLEY_GCC_VERSION
26542 #undef JSON_HEDLEY_GCC_VERSION_CHECK
26543 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
26544 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
26545 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
26546 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
26547 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
26548 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
26549 #undef JSON_HEDLEY_GNUC_HAS_WARNING
26550 #undef JSON_HEDLEY_GNUC_VERSION
26551 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
26552 #undef JSON_HEDLEY_HAS_ATTRIBUTE
26553 #undef JSON_HEDLEY_HAS_BUILTIN
26554 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
26555 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
26556 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
26557 #undef JSON_HEDLEY_HAS_EXTENSION
26558 #undef JSON_HEDLEY_HAS_FEATURE
26559 #undef JSON_HEDLEY_HAS_WARNING
26560 #undef JSON_HEDLEY_IAR_VERSION
26561 #undef JSON_HEDLEY_IAR_VERSION_CHECK
26562 #undef JSON_HEDLEY_IBM_VERSION
26563 #undef JSON_HEDLEY_IBM_VERSION_CHECK
26564 #undef JSON_HEDLEY_IMPORT
26565 #undef JSON_HEDLEY_INLINE
26566 #undef JSON_HEDLEY_INTEL_CL_VERSION
26567 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
26568 #undef JSON_HEDLEY_INTEL_VERSION
26569 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
26570 #undef JSON_HEDLEY_IS_CONSTANT
26571 #undef JSON_HEDLEY_IS_CONSTEXPR_
26572 #undef JSON_HEDLEY_LIKELY
26573 #undef JSON_HEDLEY_MALLOC
26574 #undef JSON_HEDLEY_MCST_LCC_VERSION
26575 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
26576 #undef JSON_HEDLEY_MESSAGE
26577 #undef JSON_HEDLEY_MSVC_VERSION
26578 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
26579 #undef JSON_HEDLEY_NEVER_INLINE
26580 #undef JSON_HEDLEY_NON_NULL
26581 #undef JSON_HEDLEY_NO_ESCAPE
26582 #undef JSON_HEDLEY_NO_RETURN
26583 #undef JSON_HEDLEY_NO_THROW
26584 #undef JSON_HEDLEY_NULL
26585 #undef JSON_HEDLEY_PELLES_VERSION
26586 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
26587 #undef JSON_HEDLEY_PGI_VERSION
26588 #undef JSON_HEDLEY_PGI_VERSION_CHECK
26589 #undef JSON_HEDLEY_PREDICT
26590 #undef JSON_HEDLEY_PRINTF_FORMAT
26591 #undef JSON_HEDLEY_PRIVATE
26592 #undef JSON_HEDLEY_PUBLIC
26593 #undef JSON_HEDLEY_PURE
26594 #undef JSON_HEDLEY_REINTERPRET_CAST
26595 #undef JSON_HEDLEY_REQUIRE
26596 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
26597 #undef JSON_HEDLEY_REQUIRE_MSG
26598 #undef JSON_HEDLEY_RESTRICT
26599 #undef JSON_HEDLEY_RETURNS_NON_NULL
26600 #undef JSON_HEDLEY_SENTINEL
26601 #undef JSON_HEDLEY_STATIC_ASSERT
26602 #undef JSON_HEDLEY_STATIC_CAST
26603 #undef JSON_HEDLEY_STRINGIFY
26604 #undef JSON_HEDLEY_STRINGIFY_EX
26605 #undef JSON_HEDLEY_SUNPRO_VERSION
26606 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
26607 #undef JSON_HEDLEY_TINYC_VERSION
26608 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
26609 #undef JSON_HEDLEY_TI_ARMCL_VERSION
26610 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
26611 #undef JSON_HEDLEY_TI_CL2000_VERSION
26612 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
26613 #undef JSON_HEDLEY_TI_CL430_VERSION
26614 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
26615 #undef JSON_HEDLEY_TI_CL6X_VERSION
26616 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
26617 #undef JSON_HEDLEY_TI_CL7X_VERSION
26618 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
26619 #undef JSON_HEDLEY_TI_CLPRU_VERSION
26620 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
26621 #undef JSON_HEDLEY_TI_VERSION
26622 #undef JSON_HEDLEY_TI_VERSION_CHECK
26623 #undef JSON_HEDLEY_UNAVAILABLE
26624 #undef JSON_HEDLEY_UNLIKELY
26625 #undef JSON_HEDLEY_UNPREDICTABLE
26626 #undef JSON_HEDLEY_UNREACHABLE
26627 #undef JSON_HEDLEY_UNREACHABLE_RETURN
26628 #undef JSON_HEDLEY_VERSION
26629 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
26630 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
26631 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
26632 #undef JSON_HEDLEY_VERSION_ENCODE
26633 #undef JSON_HEDLEY_WARNING
26634 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
26635 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
26636 #undef JSON_HEDLEY_FALL_THROUGH
26637 
26638 
26639 
26640 #endif // INCLUDE_NLOHMANN_JSON_HPP_
BasicJsonType value_type
Definition: XrdOucJson.hh:13369
void write_number_with_ubjson_prefix(const NumberType n, const bool add_prefix)
Definition: XrdOucJson.hh:14868
static constexpr CharType get_ubjson_float_prefix(float)
Definition: XrdOucJson.hh:15089
std::string exception_message(const input_format_t format, const std::string &detail, const std::string &context) const
Definition: XrdOucJson.hh:10769
int e
Definition: XrdOucJson.hh:15536
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition: XrdOucJson.hh:11640
json_pointer & operator/=(std::string token)
append an unescaped reference token at the end of this JSON pointer
Definition: XrdOucJson.hh:12482
friend other_iter_impl
allow basic_json to access private members
Definition: XrdOucJson.hh:11535
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition: XrdOucJson.hh:6522
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
Definition: XrdOucJson.hh:8198
~input_stream_adapter()
Definition: XrdOucJson.hh:5410
std::random_access_iterator_tag iterator_category
Definition: XrdOucJson.hh:3269
#define JSON_THROW(exception)
Definition: XrdOucJson.hh:2266
reference value() const
return the value of an iterator
Definition: XrdOucJson.hh:12346
Definition: XrdOucJson.hh:15276
typename utility_internal::Gen< T, N >::type make_integer_sequence
Definition: XrdOucJson.hh:3151
bool boolean(bool)
Definition: XrdOucJson.hh:6467
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: XrdOucJson.hh:21456
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
Definition: XrdOucJson.hh:4049
#define JSON_TRY
Definition: XrdOucJson.hh:2267
bool empty() const
Definition: XrdOucJson.hh:5488
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: XrdOucJson.hh:17644
number_unsigned_t number_unsigned
number (unsigned integer)
Definition: XrdOucJson.hh:18394
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: XrdOucJson.hh:4697
bool get_cbor_binary(binary_t &result)
reads a CBOR byte array
Definition: XrdOucJson.hh:9284
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: XrdOucJson.hh:12124
typename BasicJsonType::number_float_t number_float_t
Definition: XrdOucJson.hh:6641
reference emplace_back(Args &&...args)
add an object to an array
Definition: XrdOucJson.hh:23039
typename T::pointer pointer_t
Definition: XrdOucJson.hh:3487
const int id
the id of the exception
Definition: XrdOucJson.hh:2659
friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
comparison: equal
Definition: XrdOucJson.hh:23833
binary_t * get_impl_ptr(binary_t *) noexcept
get a pointer to the value (binary)
Definition: XrdOucJson.hh:20342
std::uint64_t f
Definition: XrdOucJson.hh:15535
bool end_array()
Definition: XrdOucJson.hh:6517
static constexpr bool value
Definition: XrdOucJson.hh:3518
parse_error(int id_, std::size_t byte_, const char *what_arg)
Definition: XrdOucJson.hh:2825
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition: XrdOucJson.hh:4601
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: XrdOucJson.hh:21736
Definition: XrdOucJson.hh:3222
static bool little_endianess(int num=1) noexcept
determine system byte order
Definition: XrdOucJson.hh:8339
Definition: XrdOucJson.hh:4314
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: XrdOucJson.hh:19458
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition: XrdOucJson.hh:3894
static constexpr CharType get_cbor_float_prefix(float)
Definition: XrdOucJson.hh:14837
iterator begin() noexcept
returns an iterator to the first element
Definition: XrdOucJson.hh:22075
basic_json(CompatibleType &&val) noexcept(noexcept(//NOLINT(bugprone-forwarding-reference-overload, bugprone-exception-escape) JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value
Definition: XrdOucJson.hh:18975
Definition: XrdOucJson.hh:11357
array_t * array
array (stored with pointer to save storage)
Definition: XrdOucJson.hh:18384
typename BasicJsonType::binary_t binary_t
Definition: XrdOucJson.hh:8359
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
Definition: XrdOucJson.hh:18407
Definition: XrdOucJson.hh:3465
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: XrdOucJson.hh:23920
std::function< bool(int, parse_event_t, BasicJsonType &)> parser_callback_t
Definition: XrdOucJson.hh:10875
Definition: XrdOucJson.hh:3129
error_handler_t
how to treat decoding errors
Definition: XrdOucJson.hh:16361
typename std::char_traits< char_type >::int_type char_int_type
Definition: XrdOucJson.hh:6644
iteration_proxy_value(IteratorType it) noexcept
Definition: XrdOucJson.hh:4395
typename BasicJsonType::number_float_t number_float_t
Definition: XrdOucJson.hh:16372
static std::size_t calc_bson_string_size(const string_t &value)
Definition: XrdOucJson.hh:14554
Definition: XrdOucJson.hh:6560
wide_string_input_adapter(BaseInputAdapter base)
Definition: XrdOucJson.hh:5625
size_type size() const noexcept
returns the number of elements
Definition: XrdOucJson.hh:22610
void insert(InputIt first, InputIt last)
Definition: XrdOucJson.hh:17472
void unget()
unget current character (read it again on next get)
Definition: XrdOucJson.hh:7900
NLOHMANN_BASIC_JSON_TPL basic_json_t
workaround type for MSVC
Definition: XrdOucJson.hh:17603
JSON_HEDLEY_RETURNS_NON_NULL const char * type_name() const noexcept
return the type as string
Definition: XrdOucJson.hh:24564
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: XrdOucJson.hh:24810
typename BasicJsonType::string_t string_t
Definition: XrdOucJson.hh:6152
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: XrdOucJson.hh:26358
typename std::iterator_traits< IteratorType >::value_type char_type
Definition: XrdOucJson.hh:5463
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: XrdOucJson.hh:15289
decltype(input_adapter(std::declval< const char * >(), std::declval< const char * >())) contiguous_bytes_input_adapter
Definition: XrdOucJson.hh:5760
iter_impl & operator+=(difference_type i)
add to iterator
Definition: XrdOucJson.hh:12056
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
Definition: XrdOucJson.hh:8182
bool parse_cbor_internal(const bool get_char, const cbor_tag_handler_t tag_handler)
Definition: XrdOucJson.hh:8701
value_t
the JSON type enumeration
Definition: XrdOucJson.hh:120
binary_reader(InputAdapterType &&adapter) noexcept
create a binary reader
Definition: XrdOucJson.hh:8370
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition: XrdOucJson.hh:11446
iter_impl operator+(difference_type i) const
add to iterator
Definition: XrdOucJson.hh:12102
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: XrdOucJson.hh:15806
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: XrdOucJson.hh:12339
json_reverse_iterator const operator--(int)
post-decrement (it–)
Definition: XrdOucJson.hh:12297
void push_back(basic_json &&val)
add an object to an array
Definition: XrdOucJson.hh:22846
static BasicJsonType::size_type array_index(const std::string &s)
Definition: XrdOucJson.hh:12695
bool get_msgpack_object(const std::size_t len)
Definition: XrdOucJson.hh:10067
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: XrdOucJson.hh:4636
void write_bson_object(const typename BasicJsonType::object_t &value)
Definition: XrdOucJson.hh:14821
Definition: XrdOucJson.hh:16369
Definition: XrdOucJson.hh:13562
iterator end() noexcept
returns an iterator to one past the last element
Definition: XrdOucJson.hh:22146
Definition: XrdOucJson.hh:3238
void operator=(nonesuch const &)=delete
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
Definition: XrdOucJson.hh:20318
std::array< T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType &&j, identity_tag< std::array< T, sizeof...(Idx)>>, index_sequence< Idx...>)
Definition: XrdOucJson.hh:4132
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: XrdOucJson.hh:3049
static std::vector< std::uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: XrdOucJson.hh:24913
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: XrdOucJson.hh:22935
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition: XrdOucJson.hh:4685
bool start_array(std::size_t len)
Definition: XrdOucJson.hh:6065
static void unescape(std::string &s)
string unescaping as described in RFC 6901 (Sect. 4)
Definition: XrdOucJson.hh:2572
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
Definition: XrdOucJson.hh:23259
ArrayType< basic_json, AllocatorType< basic_json >> array_t
a type for an array
Definition: XrdOucJson.hh:17965
typename InputAdapterType::char_type char_type
Definition: XrdOucJson.hh:6643
typename BasicJsonType::string_t string_t
Definition: XrdOucJson.hh:5978
json_value(const string_t &value)
constructor for strings
Definition: XrdOucJson.hh:18481
primitive_iterator_t & operator++() noexcept
Definition: XrdOucJson.hh:11420
void push_back(const basic_json &val)
add an object to an array
Definition: XrdOucJson.hh:22883
throw a parse_error exception in case of a tag
bool number_integer(number_integer_t val)
Definition: XrdOucJson.hh:6009
byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition: XrdOucJson.hh:5058
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: XrdOucJson.hh:12273
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition: XrdOucJson.hh:4421
bool boolean(bool val)
Definition: XrdOucJson.hh:6003
Definition: XrdOucJson.hh:4562
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
Definition: XrdOucJson.hh:23211
constexpr int kAlpha
Definition: XrdOucJson.hh:15530
array (ordered collection of values)
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: XrdOucJson.hh:19725
void write_bson_double(const string_t &name, const double value)
Writes a BSON element with key name and double value value.
Definition: XrdOucJson.hh:14544
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: XrdOucJson.hh:18838
json_pointer(const std::string &s="")
create JSON pointer
Definition: XrdOucJson.hh:12408
InputAdapterType ia
input adapter
Definition: XrdOucJson.hh:8125
reference set_parent(reference j, std::size_t old_capacity=std::size_t(-1))
Definition: XrdOucJson.hh:18729
primitive_iterator_t operator+(difference_type n) noexcept
Definition: XrdOucJson.hh:11408
string_t dump(const int indent=-1, const char indent_char= ' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition: XrdOucJson.hh:19823
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: XrdOucJson.hh:19013
#define NLOHMANN_JSON_VERSION_MAJOR
Definition: XrdOucJson.hh:33
std::less< StringType > object_comparator_t
Definition: XrdOucJson.hh:17829
static void to_cbor(const basic_json &j, detail::output_adapter< std::uint8_t > o)
Definition: XrdOucJson.hh:24722
bool parse_msgpack_internal()
Definition: XrdOucJson.hh:9472
bool contains(const BasicJsonType *ptr) const
Definition: XrdOucJson.hh:13059
iter_impl & operator++()
pre-increment (++it)
Definition: XrdOucJson.hh:11857
char one
Definition: XrdOucJson.hh:3857
static constexpr CharType to_char_type(InputCharType x) noexcept
Definition: XrdOucJson.hh:15194
Definition: XrdOucJson.hh:3715
constexpr auto get_impl(detail::priority_tag< 4 >) const noexcept-> decltype(std::declval< const basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: XrdOucJson.hh:20577
reference back()
access the last element
Definition: XrdOucJson.hh:21554
a template for a reverse iterator class
Definition: XrdOucJson.hh:12268
bool start_object(std::size_t=std::size_t(-1))
Definition: XrdOucJson.hh:6497
const char indent_char
the indentation character
Definition: XrdOucJson.hh:17276
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: XrdOucJson.hh:11655
std::runtime_error m
an exception object as storage for error messages
Definition: XrdOucJson.hh:2736
a class to store JSON values
Definition: XrdOucJson.hh:3384
bool end_array()
Definition: XrdOucJson.hh:6302
constexpr int kGamma
Definition: XrdOucJson.hh:15531
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: XrdOucJson.hh:25284
void type
Definition: XrdOucJson.hh:3224
ObjectType< StringType, basic_json, object_comparator_t, AllocatorType< std::pair< const StringType, basic_json >>> object_t
a type for an object
Definition: XrdOucJson.hh:17919
static constexpr std::size_t size() noexcept
Definition: XrdOucJson.hh:3093
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
Definition: XrdOucJson.hh:20294
typename T::iterator iterator_t
Definition: XrdOucJson.hh:3496
subtype_type m_subtype
Definition: XrdOucJson.hh:5173
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: XrdOucJson.hh:25769
typename BasicJsonType::binary_t binary_t
Definition: XrdOucJson.hh:6153
static void to_bson(const basic_json &j, detail::output_adapter< std::uint8_t > o)
Serializes the given JSON object j to BSON and forwards the corresponding BSON-representation to the ...
Definition: XrdOucJson.hh:25006
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition: XrdOucJson.hh:13517
bool end_object()
Definition: XrdOucJson.hh:6507
friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: XrdOucJson.hh:24149
bool string(string_t &val)
Definition: XrdOucJson.hh:6027
byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
Definition: XrdOucJson.hh:5052
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
Definition: XrdOucJson.hh:20282
const std::string & back() const
return last reference token
Definition: XrdOucJson.hh:12632
basic_json flatten() const
return flattened JSON value
Definition: XrdOucJson.hh:25732
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
Definition: XrdOucJson.hh:20697
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: XrdOucJson.hh:17316
std::char_traits< char >::int_type get_character()
Definition: XrdOucJson.hh:5439
typename BasicJsonType::string_t string_t
Definition: XrdOucJson.hh:8237
default JSONSerializer template argument
Definition: XrdOucJson.hh:3371
std::shared_ptr< output_adapter_protocol< CharType >> output_adapter_t
a type to simplify interfaces
Definition: XrdOucJson.hh:13485
iter_impl const operator--(int)
post-decrement (it–)
Definition: XrdOucJson.hh:11897
std::ptrdiff_t difference_type
Definition: XrdOucJson.hh:12271
Definition: XrdOucJson.hh:5405
json_value(const array_t &value)
constructor for arrays
Definition: XrdOucJson.hh:18505
static JSON_HEDLEY_RETURNS_NON_NULL T * create(Args &&...args)
helper for exception-safe object creation
Definition: XrdOucJson.hh:18334
Definition: XrdOucJson.hh:3175
void write_compact_float(const number_float_t n, detail::input_format_t format)
Definition: XrdOucJson.hh:15131
#define JSON_HEDLEY_PURE
Definition: XrdOucJson.hh:1639
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: XrdOucJson.hh:24194
type_error(int id_, const char *what_arg)
Definition: XrdOucJson.hh:2939
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: XrdOucJson.hh:7950
json_value(string_t &&value)
constructor for rvalue strings
Definition: XrdOucJson.hh:18487
void write_bson_object_entry(const string_t &name, const typename BasicJsonType::object_t &value)
Writes a BSON element with key name and object value.
Definition: XrdOucJson.hh:14644
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: XrdOucJson.hh:22186
static bool accept(IteratorType first, IteratorType last, const bool ignore_comments=false)
Definition: XrdOucJson.hh:24385
Definition: XrdOucJson.hh:3843
void swap(binary_t &other)
exchanges the values
Definition: XrdOucJson.hh:23659
Definition: XrdOucJson.hh:3516
auto operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
Definition: XrdOucJson.hh:4922
::nlohmann::detail::output_adapter_t< CharType > output_adapter_t
Definition: XrdOucJson.hh:17632
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
Definition: XrdOucJson.hh:15383
BaseInputAdapter base_adapter
Definition: XrdOucJson.hh:5646
bool start_array(std::size_t len)
Definition: XrdOucJson.hh:6285
static std::string position_string(const position_t &pos)
Definition: XrdOucJson.hh:2828
number value (signed integer)
bool string(string_t &val)
Definition: XrdOucJson.hh:6202
void reset() noexcept
reset token_buffer; current character is beginning of token
Definition: XrdOucJson.hh:7846
Target reinterpret_bits(const Source source)
Definition: XrdOucJson.hh:15267
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: XrdOucJson.hh:17708
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: XrdOucJson.hh:18116
difference_type operator-(const iter_impl &other) const
return difference
Definition: XrdOucJson.hh:12135
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: XrdOucJson.hh:6640
output_adapter(StringType &s)
Definition: XrdOucJson.hh:13573
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: XrdOucJson.hh:4581
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: XrdOucJson.hh:12309
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: XrdOucJson.hh:12327
void grisu2_round(char *buf, int len, std::uint64_t dist, std::uint64_t delta, std::uint64_t rest, std::uint64_t ten_k)
Definition: XrdOucJson.hh:15765
bool key(string_t &val)
Definition: XrdOucJson.hh:6051
static constexpr CharType get_ubjson_float_prefix(double)
Definition: XrdOucJson.hh:15094
#define JSON_HEDLEY_LIKELY(expr)
Definition: XrdOucJson.hh:1565
Definition: XrdOucJson.hh:3855
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: XrdOucJson.hh:21040
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: XrdOucJson.hh:22319
BasicJsonType & get_and_create(BasicJsonType &j) const
create and return a reference to the pointed to value
Definition: XrdOucJson.hh:12760
void dump(const BasicJsonType &val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
Definition: XrdOucJson.hh:16425
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: XrdOucJson.hh:4478
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: XrdOucJson.hh:12093
void push_back(std::string &&token)
append an unescaped token at the end of the reference pointer
Definition: XrdOucJson.hh:12660
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: XrdOucJson.hh:25141
void set_end() noexcept
set the iterator past the last value
Definition: XrdOucJson.hh:11721
bool start_object(std::size_t len)
Definition: XrdOucJson.hh:6214
the parser read ] and finished processing a JSON array
pointer operator->() const
dereference the iterator
Definition: XrdOucJson.hh:11804
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition: XrdOucJson.hh:11530
typename InputAdapterType::char_type char_type
Definition: XrdOucJson.hh:8361
#define NLOHMANN_JSON_VERSION_MINOR
Definition: XrdOucJson.hh:34
bool string(string_t &)
Definition: XrdOucJson.hh:6487
bool parse_bson_element_list(const bool is_array)
Read a BSON element list (as specified in the BSON-spec)
Definition: XrdOucJson.hh:8633
Definition: XrdOucJson.hh:3326
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: XrdOucJson.hh:5221
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: XrdOucJson.hh:3908
bool get_ubjson_array()
Definition: XrdOucJson.hh:10396
std::size_t chars_read_current_line
the number of characters read in the current line
Definition: XrdOucJson.hh:2596
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition: XrdOucJson.hh:5093
std::bidirectional_iterator_tag iterator_category
Definition: XrdOucJson.hh:11553
friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
comparison: greater than
Definition: XrdOucJson.hh:24103
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition: XrdOucJson.hh:26136
output_adapter(std::basic_ostream< CharType > &s)
Definition: XrdOucJson.hh:13569
const_iterator begin() const noexcept
returns a const iterator to the first element
Definition: XrdOucJson.hh:22085
void write_character(CharType c) override
Definition: XrdOucJson.hh:13546
cached_power get_cached_power_for_binary_exponent(int e)
Definition: XrdOucJson.hh:15547
Definition: XrdOucJson.hh:8228
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
Definition: XrdOucJson.hh:8217
bool key(string_t &)
Definition: XrdOucJson.hh:6502
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
Definition: XrdOucJson.hh:21406
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: XrdOucJson.hh:12278
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition: XrdOucJson.hh:5048
typename BasicJsonType::binary_t binary_t
Definition: XrdOucJson.hh:8238
typename BasicJsonType::binary_t::value_type binary_char_t
Definition: XrdOucJson.hh:16375
json_ref(Args &&...args)
Definition: XrdOucJson.hh:13386
static std::vector< std::string > split(const std::string &reference_string)
split the string input to reference tokens
Definition: XrdOucJson.hh:13147
constexpr const number_integer_t * get_impl_ptr(const number_integer_t *) const noexcept
get a pointer to the value (integer number)
Definition: XrdOucJson.hh:20312
auto operator()(const BasicJsonType &j, T &&val) const noexcept(noexcept(from_json(j, std::forward< T >(val)))) -> decltype(from_json(j, std::forward< T >(val)))
Definition: XrdOucJson.hh:4317
lexical analysis
Definition: XrdOucJson.hh:6637
static auto from_json(BasicJsonType &&j, TargetType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), val), void())
convert a JSON value to any value type
Definition: XrdOucJson.hh:4962
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: XrdOucJson.hh:12315
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: XrdOucJson.hh:21833
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: XrdOucJson.hh:4649
void destroy(value_t t)
Definition: XrdOucJson.hh:18540
void write_bson(const BasicJsonType &j)
Definition: XrdOucJson.hh:13621
typename Extend< typename Gen< T, N/2 >::type, N/2, N%2 >::type type
Definition: XrdOucJson.hh:3132
reference operator[](difference_type n) const
access to successor
Definition: XrdOucJson.hh:12164
json_value(const binary_t &value)
constructor for binary arrays (internal type)
Definition: XrdOucJson.hh:18529
Definition: XrdOucJson.hh:3859
Definition: XrdOucJson.hh:3831
void set_end() noexcept
set iterator to a defined past the end
Definition: XrdOucJson.hh:11381
static out_of_range create(int id_, const std::string &what_arg, const BasicJsonType &context)
Definition: XrdOucJson.hh:2979
typename BasicJsonType::number_integer_t number_integer_t
Definition: XrdOucJson.hh:6456
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for equality
Definition: XrdOucJson.hh:13324
bool get_bson_binary(const NumberType len, binary_t &result)
Parses a byte array input of length len from the BSON input.
Definition: XrdOucJson.hh:8529
syntax analysis
Definition: XrdOucJson.hh:10883
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
Definition: XrdOucJson.hh:20264
serialization to CBOR and MessagePack values
Definition: XrdOucJson.hh:13600
diyfp minus
Definition: XrdOucJson.hh:15397
Definition: XrdOucJson.hh:3509
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: XrdOucJson.hh:25124
std::false_type value_t
Definition: XrdOucJson.hh:3311
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements
Definition: XrdOucJson.hh:23312
output adapter for byte vectors
Definition: XrdOucJson.hh:13489
JSON_HEDLEY_RETURNS_NON_NULL static JSON_HEDLEY_CONST const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
Definition: XrdOucJson.hh:6588
void skip_whitespace()
Definition: XrdOucJson.hh:8026
const std::size_t byte
byte index of the parse error
Definition: XrdOucJson.hh:2822
reference operator[](difference_type n) const
access to successor
Definition: XrdOucJson.hh:12333
bool get_cbor_array(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition: XrdOucJson.hh:9378
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: XrdOucJson.hh:5844
std::char_traits< char_type >::int_type get_character()
Definition: XrdOucJson.hh:5469
bool get_ubjson_value(const char_int_type prefix)
Definition: XrdOucJson.hh:10295
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition: XrdOucJson.hh:11475
void to_json(BasicJsonType &j, T b) noexcept
Definition: XrdOucJson.hh:4785
integer_sequence< size_t, Ints...> index_sequence
Definition: XrdOucJson.hh:3105
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: XrdOucJson.hh:12047
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: XrdOucJson.hh:5040
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
Definition: XrdOucJson.hh:20306
bool end_object()
Definition: XrdOucJson.hh:6249
Definition: XrdOucJson.hh:4372
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: XrdOucJson.hh:19978
throw a type_error exception in case of invalid UTF-8
bool accept(const bool strict=true)
public accept interface
Definition: XrdOucJson.hh:10976
T mapped_type
Definition: XrdOucJson.hh:17315
token_type scan()
Definition: XrdOucJson.hh:8035
bool skip_bom()
skip the UTF-8 byte order mark
Definition: XrdOucJson.hh:8012
bool number_float(number_float_t val, const string_t &)
Definition: XrdOucJson.hh:6021
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: XrdOucJson.hh:5668
exception indicating access out of the defined range
Definition: XrdOucJson.hh:2975
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition: XrdOucJson.hh:5044
json_ref(const value_type &value)
Definition: XrdOucJson.hh:13375
friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
Definition: XrdOucJson.hh:23889
#define JSON_EXPLICIT
Definition: XrdOucJson.hh:2512
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: XrdOucJson.hh:22253
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: XrdOucJson.hh:6150
Definition: XrdOucJson.hh:3174
JSON_HEDLEY_RETURNS_NON_NULL BasicJsonType * handle_value(Value &&v)
Definition: XrdOucJson.hh:6111
primitive_iterator_t & operator--() noexcept
Definition: XrdOucJson.hh:11433
binary array (ordered collection of bytes)
Definition: XrdOucJson.hh:3826
bool end_object()
Definition: XrdOucJson.hh:6058
void set_begin() noexcept
set iterator to a defined beginning
Definition: XrdOucJson.hh:11375
decltype(std::declval< T >().template get< U >()) get_template_function
Definition: XrdOucJson.hh:3505
Definition: XrdOucJson.hh:3800
void write_msgpack(const BasicJsonType &j)
Definition: XrdOucJson.hh:13974
typename std::iterator_traits< T >::value_type value_type
Definition: XrdOucJson.hh:5680
static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
Definition: XrdOucJson.hh:14612
bool get_bson_string(const NumberType len, string_t &result)
Parses a zero-terminated string of length len from the BSON input.
Definition: XrdOucJson.hh:8508
const string_type & key() const
return key of the iterator
Definition: XrdOucJson.hh:4427
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: XrdOucJson.hh:21621
void swap(typename binary_t::container_type &other)
exchanges the values
Definition: XrdOucJson.hh:23673
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is &gt;= 2^(q-1)
Definition: XrdOucJson.hh:15366
typename BasicJsonType::exception exception_t
Definition: XrdOucJson.hh:8239
primitive_iterator_t const operator++(int) noexcept
Definition: XrdOucJson.hh:11426
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: XrdOucJson.hh:25268
typename T::difference_type difference_type_t
Definition: XrdOucJson.hh:3484
typename BasicJsonType::parser_callback_t parser_callback_t
Definition: XrdOucJson.hh:6154
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: XrdOucJson.hh:12038
void write_bson_string(const string_t &name, const string_t &value)
Writes a BSON element with key name and string value value.
Definition: XrdOucJson.hh:14562
iter_impl const operator++(int)
post-increment (it++)
Definition: XrdOucJson.hh:11846
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: XrdOucJson.hh:5560
typename BasicJsonType::number_float_t number_float_t
Definition: XrdOucJson.hh:8357
decltype(std::declval< T & >().end_object()) end_object_function_t
Definition: XrdOucJson.hh:8213
basic_json(const basic_json &other)
copy constructor
Definition: XrdOucJson.hh:19595
std::is_convertible< detected_t< Op, Args...>, To > is_detected_convertible
Definition: XrdOucJson.hh:3342
IteratorType iterator_type
Definition: XrdOucJson.hh:5667
decltype(input_adapter(begin(std::declval< ContainerType >()), end(std::declval< ContainerType >()))) adapter_type
Definition: XrdOucJson.hh:5726
SAX implementation to create a JSON value from SAX events.
Definition: XrdOucJson.hh:5972
typename detector< nonesuch, void, Op, Args...>::type detected_t
Definition: XrdOucJson.hh:3329
Definition: XrdOucJson.hh:3600
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: XrdOucJson.hh:4745
token_type scan_number()
scan a number literal
Definition: XrdOucJson.hh:7495
token_type
token types for the parser
Definition: XrdOucJson.hh:6564
static void to_msgpack(const basic_json &j, detail::output_adapter< char > o)
Definition: XrdOucJson.hh:24822
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: XrdOucJson.hh:20181
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: XrdOucJson.hh:18255
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: XrdOucJson.hh:5502
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: XrdOucJson.hh:8235
span_input_adapter(CharT b, std::size_t l)
Definition: XrdOucJson.hh:5795
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: XrdOucJson.hh:21868
bool get_cbor_string(string_t &result)
reads a CBOR string
Definition: XrdOucJson.hh:9189
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: XrdOucJson.hh:21384
exception indicating a parse error
Definition: XrdOucJson.hh:2784
bool null()
Definition: XrdOucJson.hh:5997
input_stream_adapter(input_stream_adapter &&rhs) noexcept
Definition: XrdOucJson.hh:5429
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: XrdOucJson.hh:12282
char char_type
Definition: XrdOucJson.hh:5623
const char * what() const noexceptoverride
returns the explanatory string
Definition: XrdOucJson.hh:2653
decltype(std::declval< T & >().parse_error(std::declval< std::size_t >(), std::declval< const std::string & >(), std::declval< const Exception & >())) parse_error_function_t
Definition: XrdOucJson.hh:8225
bool get_binary(const input_format_t format, const NumberType len, binary_t &result)
create a byte array by reading bytes from the input
Definition: XrdOucJson.hh:10719
typename detector< nonesuch, void, Op, Args...>::value_t is_detected
Definition: XrdOucJson.hh:3323
json_reverse_iterator const operator++(int)
post-increment (it++)
Definition: XrdOucJson.hh:12285
bool number_unsigned(number_unsigned_t val)
Definition: XrdOucJson.hh:6190
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: XrdOucJson.hh:4675
bool get_string(const input_format_t format, const NumberType len, string_t &result)
create a string by reading characters from the input
Definition: XrdOucJson.hh:10686
decltype(std::declval< T & >().end_array()) end_array_function_t
Definition: XrdOucJson.hh:8220
json_value(boolean_t v) noexcept
constructor for booleans
Definition: XrdOucJson.hh:18401
std::vector< CharType > & v
Definition: XrdOucJson.hh:13508
friend json_pointer operator/(const json_pointer &ptr, std::size_t array_idx)
create a new JSON pointer by appending the array-index-token at the end of the JSON pointer ...
Definition: XrdOucJson.hh:12565
const binary_t & get_binary() const
Definition: XrdOucJson.hh:20844
bool parse_bson_internal()
Reads in a BSON-object and passes it to the SAX-parser.
Definition: XrdOucJson.hh:8453
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: XrdOucJson.hh:22115
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: XrdOucJson.hh:22216
std::ptrdiff_t difference_type
Definition: XrdOucJson.hh:4375
typename Base::reference reference
the reference type for the pointed-to element
Definition: XrdOucJson.hh:12275
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: XrdOucJson.hh:11479
abstract output adapter interface
Definition: XrdOucJson.hh:13470
void write_character(CharType c) override
Definition: XrdOucJson.hh:13496
std::uint64_t f
Definition: XrdOucJson.hh:15280
general exception of the basic_json class
Definition: XrdOucJson.hh:2649
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
Definition: XrdOucJson.hh:26381
IteratorType::reference container
the container to iterate
Definition: XrdOucJson.hh:4474
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
Definition: XrdOucJson.hh:20330
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: XrdOucJson.hh:16147
BinaryType container_type
the type of the underlying container
Definition: XrdOucJson.hh:5036
boundaries compute_boundaries(FloatType value)
Definition: XrdOucJson.hh:15408
out_of_range(int id_, const char *what_arg)
Definition: XrdOucJson.hh:2987
Definition: XrdOucJson.hh:3452
static one test(decltype(&C::capacity))
constexpr bool is_object() const noexcept
return whether value is an object
Definition: XrdOucJson.hh:20115
json_value(value_t t)
constructor for empty values of a given type
Definition: XrdOucJson.hh:18409
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
Definition: XrdOucJson.hh:20276
typename lexer_t::token_type token_type
Definition: XrdOucJson.hh:10890
json_value(binary_t &&value)
constructor for rvalue binary arrays (internal type)
Definition: XrdOucJson.hh:18535
BasicJsonType & get_unchecked(BasicJsonType *ptr) const
return a reference to the pointed to value
Definition: XrdOucJson.hh:12839
Definition: XrdOucJson.hh:3638
static parse_error create(int id_, const position_t &pos, const std::string &what_arg, const BasicJsonType &context)
create a parse error exception
Definition: XrdOucJson.hh:2797
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: XrdOucJson.hh:25385
void write_bson_null(const string_t &name)
Writes a BSON element with key name and null value.
Definition: XrdOucJson.hh:14576
void clear() noexcept
clears the contents
Definition: XrdOucJson.hh:22767
bool get_msgpack_array(const std::size_t len)
Definition: XrdOucJson.hh:10045
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition: XrdOucJson.hh:2339
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: XrdOucJson.hh:22290
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition: XrdOucJson.hh:17281
static auto from_json(BasicJsonType &&j) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType >{}))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType >
convert a JSON value to any value type
Definition: XrdOucJson.hh:4982
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
Definition: XrdOucJson.hh:20247
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: XrdOucJson.hh:4662
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: XrdOucJson.hh:11477
IteratorType current
Definition: XrdOucJson.hh:5482
std::string exception_message(const token_type expected, const std::string &context)
Definition: XrdOucJson.hh:11289
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition: XrdOucJson.hh:11567
bool number_integer(number_integer_t val)
Definition: XrdOucJson.hh:6184
output_adapter(std::vector< CharType > &vec)
Definition: XrdOucJson.hh:13565
an internal type for a backed binary type
Definition: XrdOucJson.hh:5032
return result
Definition: XrdOucJson.hh:12748
ValueType & get_to(ValueType &v) const
Definition: XrdOucJson.hh:20710
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition: XrdOucJson.hh:12227
typename std::remove_cv< typename std::remove_reference< decltype(std::declval< IteratorType >().key()) >::type >::type string_type
Definition: XrdOucJson.hh:4380
typename BasicJsonType::number_float_t number_float_t
Definition: XrdOucJson.hh:13604
contiguous_bytes_input_adapter ia
Definition: XrdOucJson.hh:5811
bool next_byte_in_range(std::initializer_list< char_int_type > ranges)
check if the next byte(s) are inside a given range
Definition: XrdOucJson.hh:6743
BasicJsonType & get_checked(BasicJsonType *ptr) const
Definition: XrdOucJson.hh:12906
void push_back(const std::string &token)
append an unescaped token at the end of the reference pointer
Definition: XrdOucJson.hh:12654
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
Definition: XrdOucJson.hh:25515
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: XrdOucJson.hh:24715
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition: XrdOucJson.hh:5121
json_ref(std::initializer_list< json_ref > init)
Definition: XrdOucJson.hh:13379
exception indicating errors with iterators
Definition: XrdOucJson.hh:2872
int e
Definition: XrdOucJson.hh:15281
Definition: XrdOucJson.hh:3534
void swap(array_t &other)
exchanges the values
Definition: XrdOucJson.hh:23560
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: XrdOucJson.hh:147
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: XrdOucJson.hh:22688
Definition: XrdOucJson.hh:6453
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition: XrdOucJson.hh:17759
the parser read [ and started to process a JSON array
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition: XrdOucJson.hh:16047
reference operator+=(basic_json &&val)
add an object to an array
Definition: XrdOucJson.hh:22873
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: XrdOucJson.hh:19365
std::pair< iterator, bool > emplace(Args &&...args)
add an object to an object if key does not exist
Definition: XrdOucJson.hh:23089
bool number_integer(number_integer_t)
Definition: XrdOucJson.hh:6472
bool number_float(number_float_t val, const string_t &)
Definition: XrdOucJson.hh:6196
token_type scan_string()
scan a string literal
Definition: XrdOucJson.hh:6780
ValueType get_impl(detail::priority_tag< 1 >) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >())))
get a value (explicit); special case
Definition: XrdOucJson.hh:20516
static type_error create(int id_, const std::string &what_arg, const BasicJsonType &context)
Definition: XrdOucJson.hh:2931
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: XrdOucJson.hh:6085
typename BasicJsonType::string_t string_t
Definition: XrdOucJson.hh:8358
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: XrdOucJson.hh:19876
constexpr difference_type get_value() const noexcept
Definition: XrdOucJson.hh:11369
std::char_traits< char >::int_type get_character() noexcept
Definition: XrdOucJson.hh:5628
typename BasicJsonType::string_t string_t
Definition: XrdOucJson.hh:6642
const_reference operator[](size_type idx) const
access specified array element
Definition: XrdOucJson.hh:21139
typename BasicJsonType::number_integer_t number_integer_t
Definition: XrdOucJson.hh:16373
bool start_object(std::size_t len)
Definition: XrdOucJson.hh:6039
object (unordered set of name/value pairs)
void write_number(const NumberType n)
Definition: XrdOucJson.hh:15115
Definition: XrdOucJson.hh:3090
token_type get_token()
get next token from lexer
Definition: XrdOucJson.hh:11284
void write_bson_unsigned(const string_t &name, const BasicJsonType &j)
Writes a BSON element with key name and unsigned value.
Definition: XrdOucJson.hh:14622
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: XrdOucJson.hh:18187
static std::string diagnostics(const BasicJsonType &leaf_element)
Definition: XrdOucJson.hh:2671
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: XrdOucJson.hh:3554
Definition: XrdOucJson.hh:4919
typename BasicJsonType::number_float_t number_float_t
Definition: XrdOucJson.hh:10887
BasicJsonType get_impl(detail::priority_tag< 2 >) const
get special-case overload
Definition: XrdOucJson.hh:20541
std::string get_token_string() const
Definition: XrdOucJson.hh:7974
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: XrdOucJson.hh:19321
Definition: XrdOucJson.hh:15533
Definition: XrdOucJson.hh:3179
iterator find(KeyT &&key)
find an element in a JSON object
Definition: XrdOucJson.hh:21921
number_float_t number_float
number (floating-point)
Definition: XrdOucJson.hh:18396
typename std::enable_if< B, T >::type enable_if_t
Definition: XrdOucJson.hh:3063
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
Definition: XrdOucJson.hh:18403
ordered_map(const Allocator &alloc=Allocator())
Definition: XrdOucJson.hh:17324
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition: XrdOucJson.hh:11562
basic_json(const value_t v)
create an empty value with a given type
Definition: XrdOucJson.hh:18879
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition: XrdOucJson.hh:955
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for inequality
Definition: XrdOucJson.hh:13341
exception indicating executing a member function with a wrong type
Definition: XrdOucJson.hh:2927
std::size_t combine(std::size_t seed, std::size_t h) noexcept
Definition: XrdOucJson.hh:5203
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: XrdOucJson.hh:20065
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
Definition: XrdOucJson.hh:25499
bool operator==(const byte_container_with_subtype &rhs) const
Definition: XrdOucJson.hh:5064
#define JSON_HEDLEY_CONST
Definition: XrdOucJson.hh:1670
static void flatten(const std::string &reference_string, const BasicJsonType &value, BasicJsonType &result)
Definition: XrdOucJson.hh:13215
void write_bson_entry_header(const string_t &name, const std::uint8_t element_type)
Writes the given element_type and name to the output adapter.
Definition: XrdOucJson.hh:14522
typename BasicJsonType::number_integer_t number_integer_t
Definition: XrdOucJson.hh:10885
static constexpr CharType get_cbor_float_prefix(double)
Definition: XrdOucJson.hh:14842
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: XrdOucJson.hh:11387
Definition: XrdOucJson.hh:5496
the parser read } and finished processing a JSON object
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: XrdOucJson.hh:19907
ValueType get_impl(detail::priority_tag< 0 >) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), std::declval< ValueType & >())))
get a value (explicit)
Definition: XrdOucJson.hh:20474
static adapter_type create(IteratorType first, IteratorType last)
Definition: XrdOucJson.hh:5671
bool binary(binary_t &val)
Definition: XrdOucJson.hh:6208
boolean_t boolean
boolean
Definition: XrdOucJson.hh:18390
typename BasicJsonType::number_float_t number_float_t
Definition: XrdOucJson.hh:6151
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: XrdOucJson.hh:24520
std::tuple< Args...> from_json_tuple_impl_base(BasicJsonType &&j, index_sequence< Idx...>)
Definition: XrdOucJson.hh:4232
bool get_msgpack_binary(binary_t &result)
reads a MessagePack byte array
Definition: XrdOucJson.hh:9934
std::initializer_list< detail::json_ref< basic_json >> initializer_list_t
helper type for initializer lists of basic_json values
Definition: XrdOucJson.hh:17652
#define JSON_PRIVATE_UNLESS_TESTED
Definition: XrdOucJson.hh:2302
typename BasicJsonType::parse_event_t parse_event_t
Definition: XrdOucJson.hh:6155
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: XrdOucJson.hh:25830
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition: XrdOucJson.hh:19218
size_type count(KeyT &&key) const
returns the number of occurrences of a key in a JSON object
Definition: XrdOucJson.hh:21972
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: XrdOucJson.hh:3524
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: XrdOucJson.hh:23751
Definition: XrdOucJson.hh:5678
friend json_pointer operator/(const json_pointer &ptr, std::string token)
create a new JSON pointer by appending the unescaped token at the end of the JSON pointer ...
Definition: XrdOucJson.hh:12545
cbor_tag_handler_t
how to treat CBOR tags
Definition: XrdOucJson.hh:8325
#define JSON_INTERNAL_CATCH(exception)
Definition: XrdOucJson.hh:2269
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition: XrdOucJson.hh:4755
T conditional_static_cast(U value)
Definition: XrdOucJson.hh:3872
json_ref(value_type &&value)
Definition: XrdOucJson.hh:13371
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: XrdOucJson.hh:6457
make_integer_sequence< size_t, N > make_index_sequence
Definition: XrdOucJson.hh:3159
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
Definition: XrdOucJson.hh:8186
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition: XrdOucJson.hh:4623
#define JSON_CATCH(exception)
Definition: XrdOucJson.hh:2268
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: XrdOucJson.hh:19137
typename T::value_type value_type_t
Definition: XrdOucJson.hh:3481
output_vector_adapter(std::vector< CharType > &vec) noexcept
Definition: XrdOucJson.hh:13492
char_int_type get_ignore_noop()
Definition: XrdOucJson.hh:10618
static JSON_HEDLEY_PURE char get_decimal_point() noexcept
return the locale-dependent decimal point
Definition: XrdOucJson.hh:6669
typename BasicJsonType::binary_t binary_t
Definition: XrdOucJson.hh:8269
static::nlohmann::detail::parser< basic_json, InputAdapterType > parser(InputAdapterType adapter, detail::parser_callback_t< basic_json >cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
Definition: XrdOucJson.hh:17610
bool start_array(std::size_t=std::size_t(-1))
Definition: XrdOucJson.hh:6512
static constexpr T value
Definition: XrdOucJson.hh:3181
const_reference front() const
access the first element
Definition: XrdOucJson.hh:21518
j template void())
Definition: XrdOucJson.hh:4121
static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t &value)
Definition: XrdOucJson.hh:14654
decltype(std::declval< T & >().null()) null_function_t
Definition: XrdOucJson.hh:8178
std::ptrdiff_t difference_type
Definition: XrdOucJson.hh:11360
static auto to_json(BasicJsonType &j, TargetType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< TargetType >(val)))) -> decltype(::nlohmann::to_json(j, std::forward< TargetType >(val)), void())
convert any value type to a JSON value
Definition: XrdOucJson.hh:4999
bool empty() const noexcept
return whether pointer points to the root document
Definition: XrdOucJson.hh:12679
T & To(AnyObject &any)
Definition: XrdClAnyObject.hh:151
friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
comparison: equal
Definition: XrdOucJson.hh:23844
#define JSON_ASSERT(x)
Definition: XrdOucJson.hh:2295
typename BasicJsonType::number_float_t number_float_t
Definition: XrdOucJson.hh:5845
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition: XrdOucJson.hh:4614
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition: XrdOucJson.hh:12504
IteratorType anchor
the iterator
Definition: XrdOucJson.hh:4384
Definition: XrdOucJson.hh:5368
void write_bson_array(const string_t &name, const typename BasicJsonType::array_t &value)
Writes a BSON element with key name and array value.
Definition: XrdOucJson.hh:14677
std::is_same< Expected, detected_t< Op, Args...>> is_detected_exact
Definition: XrdOucJson.hh:3338
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition: XrdOucJson.hh:22036
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: XrdOucJson.hh:10916
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: XrdOucJson.hh:25401
#define NLOHMANN_BASIC_JSON_TPL
Definition: XrdOucJson.hh:2348
bool get_number(const input_format_t format, NumberType &result)
Definition: XrdOucJson.hh:10643
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: XrdOucJson.hh:17710
bool empty() const noexcept
checks whether the container is empty.
Definition: XrdOucJson.hh:22530
typename BasicJsonType::exception exception_t
Definition: XrdOucJson.hh:8270
void assert_invariant(bool check_parents=true) const noexcept
checks the class invariants
Definition: XrdOucJson.hh:18658
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: XrdOucJson.hh:20093
BasicJsonType & root
the parsed JSON value
Definition: XrdOucJson.hh:6134
typename BasicJsonType::binary_t binary_t
Definition: XrdOucJson.hh:13603
Definition: XrdOucJson.hh:15394
iteration_proxy_value< IteratorType > begin() noexcept
return iterator begin (needed for range-based for)
Definition: XrdOucJson.hh:4482
bool parse_bson_element_internal(const char_int_type element_type, const std::size_t element_type_parse_position)
Read a BSON document element of the given element_type.
Definition: XrdOucJson.hh:8555
bool get_cbor_object(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition: XrdOucJson.hh:9416
char char_type
Definition: XrdOucJson.hh:5408
reference at(size_type idx)
access specified array element with bounds checking
Definition: XrdOucJson.hh:20891
void add(char_int_type c)
add a character to token_buffer
Definition: XrdOucJson.hh:7927
reference front()
access the first element
Definition: XrdOucJson.hh:21510
char x[2]
Definition: XrdOucJson.hh:3861
typename T::key_type key_type_t
Definition: XrdOucJson.hh:3478
output adapter for basic_string
Definition: XrdOucJson.hh:13539
typename std::char_traits< char_type >::int_type char_int_type
Definition: XrdOucJson.hh:8362
input_stream_adapter(std::istream &i)
Definition: XrdOucJson.hh:5420
static void to_ubjson(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
Definition: XrdOucJson.hh:24928
Definition: XrdOucJson.hh:8259
T value_type
Definition: XrdOucJson.hh:3092
bool get_ubjson_object()
Definition: XrdOucJson.hh:10458
StringType string_t
a type for a string
Definition: XrdOucJson.hh:18018
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: XrdOucJson.hh:24081
typename BasicJsonType::number_float_t number_float_t
Definition: XrdOucJson.hh:6458
bool number_unsigned(number_unsigned_t)
Definition: XrdOucJson.hh:6477
iteration_proxy_value & operator*()
dereference operator (needed for range-based for)
Definition: XrdOucJson.hh:4400
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: XrdOucJson.hh:23497
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: XrdOucJson.hh:13612
static BasicJsonType unflatten(const BasicJsonType &value)
Definition: XrdOucJson.hh:13286
typename BasicJsonType::string_t string_t
Definition: XrdOucJson.hh:10888
output adapter for output streams
Definition: XrdOucJson.hh:13514
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: XrdOucJson.hh:11760
static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t &value)
Calculates the size of the BSON serialization of the given JSON-object j.
Definition: XrdOucJson.hh:14806
string_t * string
string (stored with pointer to save storage)
Definition: XrdOucJson.hh:18386
int get_codepoint()
get codepoint from 4 hex characters following \u
Definition: XrdOucJson.hh:6695
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: XrdOucJson.hh:19392
typename BasicJsonType::object_t object_t
Definition: XrdOucJson.hh:11540
BooleanType boolean_t
a type for a boolean
Definition: XrdOucJson.hh:18044
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
Definition: XrdOucJson.hh:18405
constexpr const number_unsigned_t * get_impl_ptr(const number_unsigned_t *) const noexcept
get a pointer to the value (unsigned number)
Definition: XrdOucJson.hh:20324
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: XrdOucJson.hh:11994
static std::size_t calc_bson_entry_header_size(const string_t &name, const BasicJsonType &j)
Definition: XrdOucJson.hh:14507
friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
comparison: less than
Definition: XrdOucJson.hh:24000
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx...>)
Definition: XrdOucJson.hh:4908
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, const BasicJsonType &context)
Definition: XrdOucJson.hh:2805
Key key_type
Definition: XrdOucJson.hh:17314
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(InputType &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a compatible input
Definition: XrdOucJson.hh:24286
exception indicating other library errors
Definition: XrdOucJson.hh:3014
typename BasicJsonType::number_integer_t number_integer_t
Definition: XrdOucJson.hh:5843
bool get_ubjson_size_value(std::size_t &result)
Definition: XrdOucJson.hh:10177
std::input_iterator_tag iterator_category
Definition: XrdOucJson.hh:4379
Definition: XrdOucJson.hh:3574
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
Definition: XrdOucJson.hh:23395
typename BasicJsonType::number_float_t number_float_t
Definition: XrdOucJson.hh:8267
JSON_HEDLEY_RETURNS_NON_NULL constexpr const char * get_error_message() const noexcept
return syntax error message
Definition: XrdOucJson.hh:7999
decltype(std::declval< T & >().number_float(std::declval< Float >(), std::declval< const String & >())) number_float_function_t
Definition: XrdOucJson.hh:8194
last
Definition: XrdOucJson.hh:17327
invalid_iterator(int id_, const char *what_arg)
Definition: XrdOucJson.hh:2884
Definition: XrdOucJson.hh:3198
bool binary(binary_t &)
Definition: XrdOucJson.hh:6492
void fill_buffer()
Definition: XrdOucJson.hh:5649
static std::string name(const std::string &ename, int id_)
Definition: XrdOucJson.hh:2665
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: XrdOucJson.hh:11393
typename BasicJsonType::string_t string_t
Definition: XrdOucJson.hh:16371
reference operator+=(const basic_json &val)
add an object to an array
Definition: XrdOucJson.hh:22909
Definition: XrdOucJson.hh:3256
std::pair< bool, BasicJsonType * > handle_value(Value &&v, const bool skip_callback=false)
Definition: XrdOucJson.hh:6369
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
Definition: XrdOucJson.hh:8206
Definition: XrdOucJson.hh:3295
static invalid_iterator create(int id_, const std::string &what_arg, const BasicJsonType &context)
Definition: XrdOucJson.hh:2876
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: XrdOucJson.hh:25591
Definition: XrdOucJson.hh:3309
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: XrdOucJson.hh:12458
deserialization of CBOR, MessagePack, and UBJSON values
Definition: XrdOucJson.hh:8353
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition: XrdOucJson.hh:20721
const_iterator find(KeyT &&key) const
find an element in a JSON object
Definition: XrdOucJson.hh:21938
const BasicJsonType & get_checked(const BasicJsonType *ptr) const
Definition: XrdOucJson.hh:13011
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: XrdOucJson.hh:23160
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: XrdOucJson.hh:18903
friend void swap(reference left, reference right) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: XrdOucJson.hh:23530
AllocatorType< basic_json > allocator_type
the allocator type
Definition: XrdOucJson.hh:17705
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: XrdOucJson.hh:20037
static void to_bson(const basic_json &j, detail::output_adapter< char > o)
Serializes the given JSON object j to BSON and forwards the corresponding BSON-representation to the ...
Definition: XrdOucJson.hh:25014
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: XrdOucJson.hh:11556
static std::vector< std::uint8_t > to_bson(const basic_json &j)
Serializes the given JSON object j to BSON and returns a vector containing the corresponding BSON-rep...
Definition: XrdOucJson.hh:24991
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array (without subtype)
Definition: XrdOucJson.hh:19265
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: XrdOucJson.hh:6335
bool scan_comment()
scan a comment
Definition: XrdOucJson.hh:7370
std::size_t lines_read
the number of lines read
Definition: XrdOucJson.hh:2598
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
Definition: XrdOucJson.hh:8190
bool operator()(nlohmann::detail::value_t lhs, nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: XrdOucJson.hh:26397
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition: XrdOucJson.hh:5986
std::string escape(std::string s)
string escaping as described in RFC 6901 (Sect. 4)
Definition: XrdOucJson.hh:2558
value_type const & operator*() const
Definition: XrdOucJson.hh:13406
bool get_bson_cstr(string_t &result)
Parses a C-style string from the BSON input.
Definition: XrdOucJson.hh:8478
typename BasicJsonType::number_float_t number_float_t
Definition: XrdOucJson.hh:8236
static std::size_t calc_bson_integer_size(const std::int64_t value)
Definition: XrdOucJson.hh:14584
std::uint64_t subtype_type
the type of the subtype
Definition: XrdOucJson.hh:5038
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition: XrdOucJson.hh:954
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: XrdOucJson.hh:19255
void insert(const_iterator first, const_iterator last)
inserts elements
Definition: XrdOucJson.hh:23353
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: XrdOucJson.hh:11398
constexpr bool is_errored() const
Definition: XrdOucJson.hh:6097
std::basic_ostream< CharType > & stream
Definition: XrdOucJson.hh:13533
InputAdapterType ia
input adapter
Definition: XrdOucJson.hh:10803
Definition: XrdOucJson.hh:3549
const_reference back() const
access the last element
Definition: XrdOucJson.hh:21564
typename BasicJsonType::binary_t binary_t
Definition: XrdOucJson.hh:5979
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
Definition: XrdOucJson.hh:22224
reference operator+=(initializer_list_t init)
add an object to an object
Definition: XrdOucJson.hh:23009
static constexpr CharType get_msgpack_float_prefix(float)
Definition: XrdOucJson.hh:14851
IteratorType::reference value() const
return value of the iterator
Definition: XrdOucJson.hh:4463
auto get_ptr() noexcept-> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: XrdOucJson.hh:20411
bool get_ubjson_high_precision_number()
Definition: XrdOucJson.hh:10533
constexpr const number_float_t * get_impl_ptr(const number_float_t *) const noexcept
get a pointer to the value (floating-point number)
Definition: XrdOucJson.hh:20336
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: XrdOucJson.hh:4710
bool key(string_t &val)
Definition: XrdOucJson.hh:6232
StringType & str
Definition: XrdOucJson.hh:13558
constexpr bool is_number() const noexcept
return whether value is a number
Definition: XrdOucJson.hh:20008
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
Definition: XrdOucJson.hh:20258
void write_character(CharType c) override
Definition: XrdOucJson.hh:13521
void write_bson_integer(const string_t &name, const std::int64_t value)
Writes a BSON element with key name and integer value.
Definition: XrdOucJson.hh:14594
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition: XrdOucJson.hh:3502
Definition: XrdOucJson.hh:5460
std::string to_string() const
return a string representation of the JSON pointer
Definition: XrdOucJson.hh:12426
static CharType to_char_type(std::uint8_t x) noexcept
Definition: XrdOucJson.hh:15172
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: XrdOucJson.hh:11665
static std::size_t calc_bson_element_size(const string_t &name, const BasicJsonType &j)
Calculates the size necessary to serialize the JSON value j with its name.
Definition: XrdOucJson.hh:14711
iterator insert(const_iterator pos, basic_json &&val)
inserts element
Definition: XrdOucJson.hh:23182
#define JSON_HEDLEY_NON_NULL(...)
Definition: XrdOucJson.hh:1458
Definition: XrdOucJson.hh:3664
#define NLOHMANN_JSON_VERSION_PATCH
Definition: XrdOucJson.hh:35
void write_bson_boolean(const string_t &name, const bool value)
Writes a BSON element with key name and boolean value value.
Definition: XrdOucJson.hh:14534
iter_impl & operator--()
pre-decrement (–it)
Definition: XrdOucJson.hh:11908
Definition: XrdOucJson.hh:3757
replace invalid UTF-8 sequences with U+FFFD
an iterator value
Definition: XrdOucJson.hh:11472
typename make_void< Ts...>::type void_t
Definition: XrdOucJson.hh:3226
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition: XrdOucJson.hh:4726
friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
comparison: greater than or equal
Definition: XrdOucJson.hh:24138
bool contains(KeyT &&key) const
check the existence of an element in a JSON object
Definition: XrdOucJson.hh:22005
constexpr bool is_array() const noexcept
return whether value is an array
Definition: XrdOucJson.hh:20137
friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: XrdOucJson.hh:24057
diyfp plus
Definition: XrdOucJson.hh:15398
iterator_input_adapter(IteratorType first, IteratorType last)
Definition: XrdOucJson.hh:5465
char char_type
Definition: XrdOucJson.hh:5371
static constexpr CharType to_char_type(std::uint8_t x) noexcept
Definition: XrdOucJson.hh:15165
Definition: XrdOucJson.hh:3462
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition: XrdOucJson.hh:15711
void update(const_iterator first, const_iterator last)
updates a JSON object from another object, overwriting existing keys
Definition: XrdOucJson.hh:23446
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: XrdOucJson.hh:10886
typename BasicJsonType::string_t string_t
Definition: XrdOucJson.hh:13602
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
Definition: XrdOucJson.hh:6157
the parser finished reading a JSON value
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: XrdOucJson.hh:3539
input_format_t
the supported input formats
Definition: XrdOucJson.hh:5357
typename BasicJsonType::number_integer_t number_integer_t
Definition: XrdOucJson.hh:6149
iteration_proxy_value< IteratorType > end() noexcept
return iterator end (needed for range-based for)
Definition: XrdOucJson.hh:4488
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: XrdOucJson.hh:8266
constexpr bool is_null() const noexcept
return whether value is null
Definition: XrdOucJson.hh:19956
Definition: XrdOucJson.hh:5620
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: XrdOucJson.hh:4766
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: XrdOucJson.hh:7938
basic_json(const JsonRef &ref)
Definition: XrdOucJson.hh:19568
typename BasicJsonType::number_integer_t number_integer_t
Definition: XrdOucJson.hh:8355
bool get_msgpack_string(string_t &result)
reads a MessagePack string
Definition: XrdOucJson.hh:9852
decltype(get< N >(std::declval< ::nlohmann::detail::iteration_proxy_value< IteratorType >>())) type
Definition: XrdOucJson.hh:4533
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: XrdOucJson.hh:16374
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: XrdOucJson.hh:5691
typename BasicJsonType::string_t string_t
Definition: XrdOucJson.hh:8268
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: XrdOucJson.hh:11558
std::pair< A1, A2 > from_json_tuple_impl(BasicJsonType &&j, identity_tag< std::pair< A1, A2 >>, priority_tag< 0 >)
Definition: XrdOucJson.hh:4238
primitive_iterator_t const operator--(int) noexcept
Definition: XrdOucJson.hh:11439
typename detected_or< Default, Op, Args...>::type detected_or_t
Definition: XrdOucJson.hh:3335
static adapter_type create(IteratorType first, IteratorType last)
Definition: XrdOucJson.hh:5695
void swap(string_t &other)
exchanges the values
Definition: XrdOucJson.hh:23626
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
Definition: XrdOucJson.hh:20288
BasicJsonType & root
the parsed JSON value
Definition: XrdOucJson.hh:6433
parser(InputAdapterType &&adapter, const parser_callback_t< BasicJsonType > cb=nullptr, const bool allow_exceptions_=true, const bool skip_comments=false)
a parser reading from an input adapter
Definition: XrdOucJson.hh:10894
ReferenceType get_ref() const
get a reference value (implicit)
Definition: XrdOucJson.hh:20770
int k
Definition: XrdOucJson.hh:15537
constexpr bool is_errored() const
Definition: XrdOucJson.hh:6347
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true)
Definition: XrdOucJson.hh:14299
constexpr position_t get_position() const noexcept
return position of last read token
Definition: XrdOucJson.hh:7966
JSON Pointer.
Definition: XrdOucJson.hh:3398
void swap(object_t &other)
exchanges the values
Definition: XrdOucJson.hh:23593
Definition: XrdOucJson.hh:3567
static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t &value)
Definition: XrdOucJson.hh:14669
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: XrdOucJson.hh:19275
Definition: XrdOucJson.hh:3580
struct to capture the start position of the current token
Definition: XrdOucJson.hh:2591
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: XrdOucJson.hh:12029
static void to_cbor(const basic_json &j, detail::output_adapter< char > o)
Definition: XrdOucJson.hh:24727
iterator insert_iterator(const_iterator pos, Args &&...args)
Definition: XrdOucJson.hh:23121
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: XrdOucJson.hh:8356
~basic_json() noexcept
destructor
Definition: XrdOucJson.hh:19759
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: XrdOucJson.hh:17700
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition: XrdOucJson.hh:4415
bool parse_ubjson_internal(const bool get_char=true)
Definition: XrdOucJson.hh:10104
number value (unsigned integer)
friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
comparison: less than
Definition: XrdOucJson.hh:24011
parse_event_t
Definition: XrdOucJson.hh:10857
number_integer_t number_integer
number (integer)
Definition: XrdOucJson.hh:18392
static bool accept(InputType &&i, const bool ignore_comments=false)
check if the input is valid JSON
Definition: XrdOucJson.hh:24378
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition: XrdOucJson.hh:11630
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: XrdOucJson.hh:22960
static other_error create(int id_, const std::string &what_arg, const BasicJsonType &context)
Definition: XrdOucJson.hh:3018
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
Definition: XrdOucJson.hh:20365
typename BasicJsonType::array_t array_t
Definition: XrdOucJson.hh:11541
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition: XrdOucJson.hh:16385
CharType ubjson_prefix(const BasicJsonType &j) const noexcept
determine the type prefix of container values
Definition: XrdOucJson.hh:15008
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
Definition: XrdOucJson.hh:20270
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
Definition: XrdOucJson.hh:21226
friend BasicJsonType
Definition: XrdOucJson.hh:11536
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
Definition: XrdOucJson.hh:8210
std::FILE * m_file
the file pointer to read from
Definition: XrdOucJson.hh:5392
Default type
Definition: XrdOucJson.hh:3312
lexer_t m_lexer
the lexer
Definition: XrdOucJson.hh:11324
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
Definition: XrdOucJson.hh:22473
json_value(const typename binary_t::container_type &value)
constructor for binary arrays
Definition: XrdOucJson.hh:18517
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: XrdOucJson.hh:19934
const BasicJsonType & get_unchecked(const BasicJsonType *ptr) const
return a const reference to the pointed to value
Definition: XrdOucJson.hh:12963
basic_json<> json
default JSON class
Definition: XrdOucJson.hh:3408
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: XrdOucJson.hh:20989
XrdOucString const operator+(const char *s1, const XrdOucString s2)
#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
Definition: XrdOucJson.hh:1248
typename T::iterator_category iterator_category_t
Definition: XrdOucJson.hh:3493
the parser read a key of a value in an object
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: XrdOucJson.hh:11415
typename BasicJsonType::number_integer_t number_integer_t
Definition: XrdOucJson.hh:8265
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: XrdOucJson.hh:26319
iterator set_parents(iterator it, typename iterator::difference_type count)
Definition: XrdOucJson.hh:18716
const object_t::key_type & key() const
return the key of an object iterator
Definition: XrdOucJson.hh:12202
ReferenceType get_ref()
get a reference value (implicit)
Definition: XrdOucJson.hh:20757
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition: XrdOucJson.hh:1899
span_input_adapter(IteratorType first, IteratorType last)
Definition: XrdOucJson.hh:5802
json_value m_value
the value of the current element
Definition: XrdOucJson.hh:24602
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: XrdOucJson.hh:22465
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: XrdOucJson.hh:12583
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: XrdOucJson.hh:12321
static void to_ubjson(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
Definition: XrdOucJson.hh:24922
std::string get_token_string() const
Definition: XrdOucJson.hh:10756
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: XrdOucJson.hh:17727
JSON_HEDLEY_RETURNS_NON_NULL char * format_buffer(char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
prettify v = buf * 10^decimal_exponent
Definition: XrdOucJson.hh:16199
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition: XrdOucJson.hh:3499
friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
comparison: not equal
Definition: XrdOucJson.hh:23878
typename BasicJsonType::number_integer_t number_integer_t
Definition: XrdOucJson.hh:5975
JSONSerializer< T, SFINAE > json_serializer
Definition: XrdOucJson.hh:17646
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition: XrdOucJson.hh:3167
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: XrdOucJson.hh:5070
Definition: XrdOucJson.hh:3411
json_value(array_t &&value)
constructor for rvalue arrays
Definition: XrdOucJson.hh:18511
typename T::reference reference_t
Definition: XrdOucJson.hh:3490
void push_back(initializer_list_t init)
add an object to an object
Definition: XrdOucJson.hh:22991
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition: XrdOucJson.hh:25662
constexpr const binary_t * get_impl_ptr(const binary_t *) const noexcept
get a pointer to the value (binary)
Definition: XrdOucJson.hh:20348
proxy class for the items() function
Definition: XrdOucJson.hh:4470
basic_json get_impl(detail::priority_tag< 3 >) const
get special-case overload
Definition: XrdOucJson.hh:20564
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: XrdOucJson.hh:12303
bool null()
Definition: XrdOucJson.hh:6172
typename BasicJsonType::binary_t binary_t
Definition: XrdOucJson.hh:6460
reference value() const
return the value of an iterator
Definition: XrdOucJson.hh:12218
friend json_pointer operator/(const json_pointer &lhs, const json_pointer &rhs)
create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer ...
Definition: XrdOucJson.hh:12524
bool number_unsigned(number_unsigned_t val)
Definition: XrdOucJson.hh:6015
friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
comparison: less than or equal
Definition: XrdOucJson.hh:24046
binary_t & get_binary()
Definition: XrdOucJson.hh:20833
static void to_msgpack(const basic_json &j, detail::output_adapter< std::uint8_t > o)
Definition: XrdOucJson.hh:24817
typename BasicJsonType::number_float_t number_float_t
Definition: XrdOucJson.hh:5977
json_value(const object_t &value)
constructor for objects
Definition: XrdOucJson.hh:18493
string_t indent_string
the indentation string
Definition: XrdOucJson.hh:17278
other_error(int id_, const char *what_arg)
Definition: XrdOucJson.hh:3026
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: XrdOucJson.hh:7944
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: XrdOucJson.hh:20938
SAX json_sax_t
Definition: XrdOucJson.hh:8360
std::size_t size_type
a type to represent container sizes
Definition: XrdOucJson.hh:17702
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a pair of character iterators
Definition: XrdOucJson.hh:24324
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: XrdOucJson.hh:11403
reference operator[](size_type idx)
access specified array element
Definition: XrdOucJson.hh:21086
SAX interface.
Definition: XrdOucJson.hh:5841
void write_bson_binary(const string_t &name, const binary_t &value)
Writes a BSON element with key name and binary value value.
Definition: XrdOucJson.hh:14696
bool binary(binary_t &val)
Definition: XrdOucJson.hh:6033
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
Definition: XrdOucJson.hh:20300
Definition: XrdOucJson.hh:3867
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: XrdOucJson.hh:24035
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: XrdOucJson.hh:25619
iterator_input_adapter_factory< IteratorType >::adapter_type input_adapter(IteratorType first, IteratorType last)
Definition: XrdOucJson.hh:5703
number value (floating-point)
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: XrdOucJson.hh:5976
constexpr diyfp(std::uint64_t f_, int e_) noexcept
Definition: XrdOucJson.hh:15283
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: XrdOucJson.hh:24127
value_type const * operator->() const
Definition: XrdOucJson.hh:13411
typename BasicJsonType::number_integer_t number_integer_t
Definition: XrdOucJson.hh:8234
std::vector< std::string > reference_tokens
the reference tokens
Definition: XrdOucJson.hh:13348
basic_json(basic_json &&other) noexcept
move constructor
Definition: XrdOucJson.hh:19687
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: XrdOucJson.hh:23867
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: XrdOucJson.hh:20208
#define JSON_HEDLEY_UNLIKELY(expr)
Definition: XrdOucJson.hh:1566
typename BasicJsonType::number_integer_t number_integer_t
Definition: XrdOucJson.hh:6639
void write_cbor(const BasicJsonType &j)
Definition: XrdOucJson.hh:13650
typename BasicJsonType::string_t string_t
Definition: XrdOucJson.hh:6459
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: XrdOucJson.hh:4568
reference operator[](const typename object_t::key_type &key)
access specified object element
Definition: XrdOucJson.hh:21177
the parser read { and started to process a JSON object
std::size_t chars_read_total
the total number of characters read
Definition: XrdOucJson.hh:2594
typename lexer_base< BasicJsonType >::token_type token_type
Definition: XrdOucJson.hh:6647
Definition: XrdOucJson.hh:3111
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition: XrdOucJson.hh:4590
const_iterator end() const noexcept
returns a const iterator to one past the last element
Definition: XrdOucJson.hh:22156
lexer(InputAdapterType &&adapter, bool ignore_comments_=false) noexcept
Definition: XrdOucJson.hh:6649
Definition: XrdOucJson.hh:3616
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: XrdOucJson.hh:25705
IteratorType end
Definition: XrdOucJson.hh:5483
void replace_substring(std::string &s, const std::string &f, const std::string &t)
replace all occurrences of a substring by another string
Definition: XrdOucJson.hh:2540
binary_t * binary
binary (stored with pointer to save storage)
Definition: XrdOucJson.hh:18388
bool parse_bson_array()
Reads an array from the BSON input and passes it to the SAX-parser.
Definition: XrdOucJson.hh:8671
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition: XrdOucJson.hh:1300
Definition: XrdOucJson.hh:3568
Definition: XrdOucJson.hh:3847
Definition: XrdOucJson.hh:5786
json_value(object_t &&value)
constructor for rvalue objects
Definition: XrdOucJson.hh:18499
void write_bson_element(const string_t &name, const BasicJsonType &j)
Serializes the JSON value j to BSON and associates it with the key name.
Definition: XrdOucJson.hh:14759
bool boolean(bool val)
Definition: XrdOucJson.hh:6178
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: XrdOucJson.hh:12291
friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
comparison: greater than
Definition: XrdOucJson.hh:24092
void int_to_string(string_type &target, std::size_t value)
Definition: XrdOucJson.hh:4366
output_string_adapter(StringType &s) noexcept
Definition: XrdOucJson.hh:13542
bool get_ubjson_size_type(std::pair< std::size_t, char_int_type > &result)
determine the type and size for a container
Definition: XrdOucJson.hh:10254
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition: XrdOucJson.hh:11452
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one before the first
Definition: XrdOucJson.hh:22261
void set_parents()
Definition: XrdOucJson.hh:18679
json_value(typename binary_t::container_type &&value)
constructor for rvalue binary arrays
Definition: XrdOucJson.hh:18523
decltype(std::declval< T & >().binary(std::declval< Binary & >())) binary_function_t
Definition: XrdOucJson.hh:8202
static constexpr CharType get_msgpack_float_prefix(double)
Definition: XrdOucJson.hh:14856
JSON_HEDLEY_RETURNS_NON_NULL char * to_chars(char *first, const char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
Definition: XrdOucJson.hh:16284
bool m_has_subtype
Definition: XrdOucJson.hh:5174
void clear_subtype() noexcept
clears the binary subtype
Definition: XrdOucJson.hh:5166
bool end_array()
Definition: XrdOucJson.hh:6077
bool null()
Definition: XrdOucJson.hh:6462
typename BasicJsonType::string_t string_t
Definition: XrdOucJson.hh:5846
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: XrdOucJson.hh:7956
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: XrdOucJson.hh:12113
discarded by the parser callback function
void pop_back()
remove last reference token
Definition: XrdOucJson.hh:12608
diyfp w
Definition: XrdOucJson.hh:15396
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition: XrdOucJson.hh:4406
constexpr bool is_string() const noexcept
return whether value is a string
Definition: XrdOucJson.hh:20159
bool get_ubjson_string(string_t &result, const bool get_char=true)
reads a UBJSON string
Definition: XrdOucJson.hh:10123
typename T::mapped_type mapped_type_t
Definition: XrdOucJson.hh:3475
constexpr auto get_ptr() const noexcept-> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: XrdOucJson.hh:20424
bool number_float(number_float_t, const string_t &)
Definition: XrdOucJson.hh:6482
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: XrdOucJson.hh:15301
typename BasicJsonType::binary_t binary_t
Definition: XrdOucJson.hh:5847
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: XrdOucJson.hh:5142