JSON for Modern C++  3.10.0
json.hpp
1 /*
2  __ _____ _____ _____
3  __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.10.0
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 0
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,
127  number_integer,
128  number_unsigned,
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()
1265  #undef
1266 #endif
1267 #if defined(_MSG)
1268  #undef _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 __attribute__((__warn_unused_result__))
1289  #define _MSG(msg) __attribute__((__warn_unused_result__))
1290 #elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1291  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1292  #define _MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1293 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1294  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1295  #define _MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1296 #elif defined(_Check_return_) /* SAL */
1297  #define _Check_return_
1298  #define _MSG(msg) _Check_return_
1299 #else
1300  #define
1301  #define _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 
1434 JSON_HEDLEY_DIAGNOSTIC_PUSH
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
1460 JSON_HEDLEY_DIAGNOSTIC_POP
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()
1889  #undef
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 __attribute__((__returns_nonnull__))
1896 #elif defined(_Ret_notnull_) /* SAL */
1897  #define _Ret_notnull_
1898 #else
1899  #define
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 
2518 namespace nlohmann
2519 {
2520 namespace detail
2521 {
2522 
2536 inline void replace_substring(std::string& s, const std::string& f,
2537  const std::string& t)
2538 {
2539  JSON_ASSERT(!f.empty());
2540  for (auto pos = s.find(f); // find first occurrence of f
2541  pos != std::string::npos; // make sure f was found
2542  s.replace(pos, f.size(), t), // replace with t, and
2543  pos = s.find(f, pos + t.size())) // find next occurrence of f
2544  {}
2545 }
2546 
2554 inline std::string escape(std::string s)
2555 {
2556  replace_substring(s, "~", "~0");
2557  replace_substring(s, "/", "~1");
2558  return s;
2559 }
2560 
2568 static void unescape(std::string& s)
2569 {
2570  replace_substring(s, "~1", "/");
2571  replace_substring(s, "~0", "~");
2572 }
2573 
2574 } // namespace detail
2575 } // namespace nlohmann
2576 
2577 // #include <nlohmann/detail/input/position_t.hpp>
2578 
2579 
2580 #include <cstddef> // size_t
2581 
2582 namespace nlohmann
2583 {
2584 namespace detail
2585 {
2587 struct position_t
2588 {
2590  std::size_t chars_read_total = 0;
2592  std::size_t chars_read_current_line = 0;
2594  std::size_t lines_read = 0;
2595 
2597  constexpr operator size_t() const
2598  {
2599  return chars_read_total;
2600  }
2601 };
2602 
2603 } // namespace detail
2604 } // namespace nlohmann
2605 
2606 // #include <nlohmann/detail/macro_scope.hpp>
2607 
2608 
2609 namespace nlohmann
2610 {
2611 namespace detail
2612 {
2614 // exceptions //
2616 
2645 class exception : public std::exception
2646 {
2647  public:
2649  const char* what() const noexcept override
2650  {
2651  return m.what();
2652  }
2653 
2655  const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
2656 
2657  protected:
2658  JSON_HEDLEY_NON_NULL(3)
2659  exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
2660 
2661  static std::string name(const std::string& ename, int id_)
2662  {
2663  return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2664  }
2665 
2666  template<typename BasicJsonType>
2667  static std::string diagnostics(const BasicJsonType& leaf_element)
2668  {
2669 #if JSON_DIAGNOSTICS
2670  std::vector<std::string> tokens;
2671  for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent)
2672  {
2673  switch (current->m_parent->type())
2674  {
2675  case value_t::array:
2676  {
2677  for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
2678  {
2679  if (&current->m_parent->m_value.array->operator[](i) == current)
2680  {
2681  tokens.emplace_back(std::to_string(i));
2682  break;
2683  }
2684  }
2685  break;
2686  }
2687 
2688  case value_t::object:
2689  {
2690  for (const auto& element : *current->m_parent->m_value.object)
2691  {
2692  if (&element.second == current)
2693  {
2694  tokens.emplace_back(element.first.c_str());
2695  break;
2696  }
2697  }
2698  break;
2699  }
2700 
2701  case value_t::null: // LCOV_EXCL_LINE
2702  case value_t::string: // LCOV_EXCL_LINE
2703  case value_t::boolean: // LCOV_EXCL_LINE
2704  case value_t::number_integer: // LCOV_EXCL_LINE
2705  case value_t::number_unsigned: // LCOV_EXCL_LINE
2706  case value_t::number_float: // LCOV_EXCL_LINE
2707  case value_t::binary: // LCOV_EXCL_LINE
2708  case value_t::discarded: // LCOV_EXCL_LINE
2709  default: // LCOV_EXCL_LINE
2710  break; // LCOV_EXCL_LINE
2711  }
2712  }
2713 
2714  if (tokens.empty())
2715  {
2716  return "";
2717  }
2718 
2719  return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
2720  [](const std::string & a, const std::string & b)
2721  {
2722  return a + "/" + detail::escape(b);
2723  }) + ") ";
2724 #else
2725  static_cast<void>(leaf_element);
2726  return "";
2727 #endif
2728  }
2729 
2730  private:
2732  std::runtime_error m;
2733 };
2734 
2780 class parse_error : public exception
2781 {
2782  public:
2792  template<typename BasicJsonType>
2793  static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context)
2794  {
2795  std::string w = exception::name("parse_error", id_) + "parse error" +
2796  position_string(pos) + ": " + exception::diagnostics(context) + what_arg;
2797  return parse_error(id_, pos.chars_read_total, w.c_str());
2798  }
2799 
2800  template<typename BasicJsonType>
2801  static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context)
2802  {
2803  std::string w = exception::name("parse_error", id_) + "parse error" +
2804  (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2805  ": " + exception::diagnostics(context) + what_arg;
2806  return parse_error(id_, byte_, w.c_str());
2807  }
2808 
2818  const std::size_t byte;
2819 
2820  private:
2821  parse_error(int id_, std::size_t byte_, const char* what_arg)
2822  : exception(id_, what_arg), byte(byte_) {}
2823 
2824  static std::string position_string(const position_t& pos)
2825  {
2826  return " at line " + std::to_string(pos.lines_read + 1) +
2827  ", column " + std::to_string(pos.chars_read_current_line);
2828  }
2829 };
2830 
2868 class invalid_iterator : public exception
2869 {
2870  public:
2871  template<typename BasicJsonType>
2872  static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context)
2873  {
2874  std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg;
2875  return invalid_iterator(id_, w.c_str());
2876  }
2877 
2878  private:
2879  JSON_HEDLEY_NON_NULL(3)
2880  invalid_iterator(int id_, const char* what_arg)
2881  : exception(id_, what_arg) {}
2882 };
2883 
2923 class type_error : public exception
2924 {
2925  public:
2926  template<typename BasicJsonType>
2927  static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
2928  {
2929  std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg;
2930  return type_error(id_, w.c_str());
2931  }
2932 
2933  private:
2934  JSON_HEDLEY_NON_NULL(3)
2935  type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2936 };
2937 
2971 class out_of_range : public exception
2972 {
2973  public:
2974  template<typename BasicJsonType>
2975  static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context)
2976  {
2977  std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg;
2978  return out_of_range(id_, w.c_str());
2979  }
2980 
2981  private:
2982  JSON_HEDLEY_NON_NULL(3)
2983  out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
2984 };
2985 
3010 class other_error : public exception
3011 {
3012  public:
3013  template<typename BasicJsonType>
3014  static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
3015  {
3016  std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg;
3017  return other_error(id_, w.c_str());
3018  }
3019 
3020  private:
3021  JSON_HEDLEY_NON_NULL(3)
3022  other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
3023 };
3024 } // namespace detail
3025 } // namespace nlohmann
3026 
3027 // #include <nlohmann/detail/macro_scope.hpp>
3028 
3029 // #include <nlohmann/detail/meta/cpp_future.hpp>
3030 
3031 
3032 #include <cstddef> // size_t
3033 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3034 #include <utility> // index_sequence, make_index_sequence, index_sequence_for
3035 
3036 // #include <nlohmann/detail/macro_scope.hpp>
3037 
3038 
3039 namespace nlohmann
3040 {
3041 namespace detail
3042 {
3043 
3044 template<typename T>
3045 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3046 
3047 #ifdef JSON_HAS_CPP_14
3048 
3049 // the following utilities are natively available in C++14
3050 using std::enable_if_t;
3051 using std::index_sequence;
3052 using std::make_index_sequence;
3053 using std::index_sequence_for;
3054 
3055 #else
3056 
3057 // alias templates to reduce boilerplate
3058 template<bool B, typename T = void>
3059 using enable_if_t = typename std::enable_if<B, T>::type;
3060 
3061 // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3062 // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3063 
3065 
3066 // integer_sequence
3067 //
3068 // Class template representing a compile-time integer sequence. An instantiation
3069 // of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3070 // type through its template arguments (which is a common need when
3071 // working with C++11 variadic templates). `absl::integer_sequence` is designed
3072 // to be a drop-in replacement for C++14's `std::integer_sequence`.
3073 //
3074 // Example:
3075 //
3076 // template< class T, T... Ints >
3077 // void user_function(integer_sequence<T, Ints...>);
3078 //
3079 // int main()
3080 // {
3081 // // user_function's `T` will be deduced to `int` and `Ints...`
3082 // // will be deduced to `0, 1, 2, 3, 4`.
3083 // user_function(make_integer_sequence<int, 5>());
3084 // }
3085 template <typename T, T... Ints>
3086 struct integer_sequence
3087 {
3088  using value_type = T;
3089  static constexpr std::size_t size() noexcept
3090  {
3091  return sizeof...(Ints);
3092  }
3093 };
3094 
3095 // index_sequence
3096 //
3097 // A helper template for an `integer_sequence` of `size_t`,
3098 // `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3099 // `std::index_sequence`.
3100 template <size_t... Ints>
3101 using index_sequence = integer_sequence<size_t, Ints...>;
3102 
3103 namespace utility_internal
3104 {
3105 
3106 template <typename Seq, size_t SeqSize, size_t Rem>
3107 struct Extend;
3108 
3109 // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3110 template <typename T, T... Ints, size_t SeqSize>
3111 struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3112 {
3113  using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3114 };
3115 
3116 template <typename T, T... Ints, size_t SeqSize>
3117 struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3118 {
3119  using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3120 };
3121 
3122 // Recursion helper for 'make_integer_sequence<T, N>'.
3123 // 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3124 template <typename T, size_t N>
3125 struct Gen
3126 {
3127  using type =
3128  typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3129 };
3130 
3131 template <typename T>
3132 struct Gen<T, 0>
3133 {
3134  using type = integer_sequence<T>;
3135 };
3136 
3137 } // namespace utility_internal
3138 
3139 // Compile-time sequences of integers
3140 
3141 // make_integer_sequence
3142 //
3143 // This template alias is equivalent to
3144 // `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3145 // replacement for C++14's `std::make_integer_sequence`.
3146 template <typename T, T N>
3147 using make_integer_sequence = typename utility_internal::Gen<T, N>::type;
3148 
3149 // make_index_sequence
3150 //
3151 // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3152 // and is designed to be a drop-in replacement for C++14's
3153 // `std::make_index_sequence`.
3154 template <size_t N>
3155 using make_index_sequence = make_integer_sequence<size_t, N>;
3156 
3157 // index_sequence_for
3158 //
3159 // Converts a typename pack into an index sequence of the same length, and
3160 // is designed to be a drop-in replacement for C++14's
3161 // `std::index_sequence_for()`
3162 template <typename... Ts>
3163 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
3164 
3166 
3167 #endif
3168 
3169 // dispatch utility (taken from ranges-v3)
3170 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3171 template<> struct priority_tag<0> {};
3172 
3173 // taken from ranges-v3
3174 template<typename T>
3175 struct static_const
3176 {
3177  static constexpr T value{};
3178 };
3179 
3180 template<typename T>
3181 constexpr T static_const<T>::value;
3182 
3183 } // namespace detail
3184 } // namespace nlohmann
3185 
3186 // #include <nlohmann/detail/meta/identity_tag.hpp>
3187 
3188 
3189 namespace nlohmann
3190 {
3191 namespace detail
3192 {
3193 // dispatching helper struct
3194 template <class T> struct identity_tag {};
3195 } // namespace detail
3196 } // namespace nlohmann
3197 
3198 // #include <nlohmann/detail/meta/type_traits.hpp>
3199 
3200 
3201 #include <limits> // numeric_limits
3202 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3203 #include <utility> // declval
3204 #include <tuple> // tuple
3205 
3206 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
3207 
3208 
3209 #include <iterator> // random_access_iterator_tag
3210 
3211 // #include <nlohmann/detail/meta/void_t.hpp>
3212 
3213 
3214 namespace nlohmann
3215 {
3216 namespace detail
3217 {
3218 template<typename ...Ts> struct make_void
3219 {
3220  using type = void;
3221 };
3222 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
3223 } // namespace detail
3224 } // namespace nlohmann
3225 
3226 // #include <nlohmann/detail/meta/cpp_future.hpp>
3227 
3228 
3229 namespace nlohmann
3230 {
3231 namespace detail
3232 {
3233 template<typename It, typename = void>
3234 struct iterator_types {};
3235 
3236 template<typename It>
3237 struct iterator_types <
3238  It,
3239  void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3240  typename It::reference, typename It::iterator_category >>
3241 {
3242  using difference_type = typename It::difference_type;
3243  using value_type = typename It::value_type;
3244  using pointer = typename It::pointer;
3245  using reference = typename It::reference;
3246  using iterator_category = typename It::iterator_category;
3247 };
3248 
3249 // This is required as some compilers implement std::iterator_traits in a way that
3250 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3251 template<typename T, typename = void>
3252 struct iterator_traits
3253 {
3254 };
3255 
3256 template<typename T>
3257 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3258  : iterator_types<T>
3259 {
3260 };
3261 
3262 template<typename T>
3263 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
3264 {
3265  using iterator_category = std::random_access_iterator_tag;
3266  using value_type = T;
3267  using difference_type = ptrdiff_t;
3268  using pointer = T*;
3269  using reference = T&;
3270 };
3271 } // namespace detail
3272 } // namespace nlohmann
3273 
3274 // #include <nlohmann/detail/macro_scope.hpp>
3275 
3276 // #include <nlohmann/detail/meta/cpp_future.hpp>
3277 
3278 // #include <nlohmann/detail/meta/detected.hpp>
3279 
3280 
3281 #include <type_traits>
3282 
3283 // #include <nlohmann/detail/meta/void_t.hpp>
3284 
3285 
3286 // https://en.cppreference.com/w/cpp/experimental/is_detected
3287 namespace nlohmann
3288 {
3289 namespace detail
3290 {
3291 struct nonesuch
3292 {
3293  nonesuch() = delete;
3294  ~nonesuch() = delete;
3295  nonesuch(nonesuch const&) = delete;
3296  nonesuch(nonesuch const&&) = delete;
3297  void operator=(nonesuch const&) = delete;
3298  void operator=(nonesuch&&) = delete;
3299 };
3300 
3301 template<class Default,
3302  class AlwaysVoid,
3303  template<class...> class Op,
3304  class... Args>
3305 struct detector
3306 {
3307  using value_t = std::false_type;
3308  using type = Default;
3309 };
3310 
3311 template<class Default, template<class...> class Op, class... Args>
3312 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
3313 {
3314  using value_t = std::true_type;
3315  using type = Op<Args...>;
3316 };
3317 
3318 template<template<class...> class Op, class... Args>
3319 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
3320 
3321 template<template<class...> class Op, class... Args>
3322 struct is_detected_lazy : is_detected<Op, Args...> { };
3323 
3324 template<template<class...> class Op, class... Args>
3325 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
3326 
3327 template<class Default, template<class...> class Op, class... Args>
3328 using detected_or = detector<Default, void, Op, Args...>;
3329 
3330 template<class Default, template<class...> class Op, class... Args>
3331 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
3332 
3333 template<class Expected, template<class...> class Op, class... Args>
3334 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
3335 
3336 template<class To, template<class...> class Op, class... Args>
3337 using is_detected_convertible =
3338  std::is_convertible<detected_t<Op, Args...>, To>;
3339 } // namespace detail
3340 } // namespace nlohmann
3341 
3342 // #include <nlohmann/json_fwd.hpp>
3343 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3344 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3345 
3346 #include <cstdint> // int64_t, uint64_t
3347 #include <map> // map
3348 #include <memory> // allocator
3349 #include <string> // string
3350 #include <vector> // vector
3351 
3357 namespace nlohmann
3358 {
3366 template<typename T = void, typename SFINAE = void>
3367 struct adl_serializer;
3368 
3369 template<template<typename U, typename V, typename... Args> class ObjectType =
3370  std::map,
3371  template<typename U, typename... Args> class ArrayType = std::vector,
3372  class StringType = std::string, class BooleanType = bool,
3373  class NumberIntegerType = std::int64_t,
3374  class NumberUnsignedType = std::uint64_t,
3375  class NumberFloatType = double,
3376  template<typename U> class AllocatorType = std::allocator,
3377  template<typename T, typename SFINAE = void> class JSONSerializer =
3378  adl_serializer,
3379  class BinaryType = std::vector<std::uint8_t>>
3380 class basic_json;
3381 
3393 template<typename BasicJsonType>
3394 class json_pointer;
3395 
3405 
3406 template<class Key, class T, class IgnoredLess, class Allocator>
3407 struct ordered_map;
3408 
3417 
3418 } // namespace nlohmann
3419 
3420 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3421 
3422 
3423 namespace nlohmann
3424 {
3433 namespace detail
3434 {
3436 // helpers //
3438 
3439 // Note to maintainers:
3440 //
3441 // Every trait in this file expects a non CV-qualified type.
3442 // The only exceptions are in the 'aliases for detected' section
3443 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3444 //
3445 // In this case, T has to be properly CV-qualified to constraint the function arguments
3446 // (e.g. to_json(BasicJsonType&, const T&))
3447 
3448 template<typename> struct is_basic_json : std::false_type {};
3449 
3450 NLOHMANN_BASIC_JSON_TPL_DECLARATION
3451 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3452 
3454 // json_ref helpers //
3456 
3457 template<typename>
3458 class json_ref;
3459 
3460 template<typename>
3461 struct is_json_ref : std::false_type {};
3462 
3463 template<typename T>
3464 struct is_json_ref<json_ref<T>> : std::true_type {};
3465 
3467 // aliases for detected //
3469 
3470 template<typename T>
3471 using mapped_type_t = typename T::mapped_type;
3472 
3473 template<typename T>
3474 using key_type_t = typename T::key_type;
3475 
3476 template<typename T>
3477 using value_type_t = typename T::value_type;
3478 
3479 template<typename T>
3480 using difference_type_t = typename T::difference_type;
3481 
3482 template<typename T>
3483 using pointer_t = typename T::pointer;
3484 
3485 template<typename T>
3486 using reference_t = typename T::reference;
3487 
3488 template<typename T>
3489 using iterator_category_t = typename T::iterator_category;
3490 
3491 template<typename T>
3492 using iterator_t = typename T::iterator;
3493 
3494 template<typename T, typename... Args>
3495 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3496 
3497 template<typename T, typename... Args>
3498 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3499 
3500 template<typename T, typename U>
3501 using get_template_function = decltype(std::declval<T>().template get<U>());
3502 
3503 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3504 template<typename BasicJsonType, typename T, typename = void>
3505 struct has_from_json : std::false_type {};
3506 
3507 // trait checking if j.get<T> is valid
3508 // use this trait instead of std::is_constructible or std::is_convertible,
3509 // both rely on, or make use of implicit conversions, and thus fail when T
3510 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3511 template <typename BasicJsonType, typename T>
3512 struct is_getable
3513 {
3514  static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
3515 };
3516 
3517 template<typename BasicJsonType, typename T>
3518 struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3519 {
3520  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3521 
3522  static constexpr bool value =
3523  is_detected_exact<void, from_json_function, serializer,
3524  const BasicJsonType&, T&>::value;
3525 };
3526 
3527 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3528 // this overload is used for non-default-constructible user-defined-types
3529 template<typename BasicJsonType, typename T, typename = void>
3530 struct has_non_default_from_json : std::false_type {};
3531 
3532 template<typename BasicJsonType, typename T>
3533 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3534 {
3535  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3536 
3537  static constexpr bool value =
3538  is_detected_exact<T, from_json_function, serializer,
3539  const BasicJsonType&>::value;
3540 };
3541 
3542 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3543 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3544 template<typename BasicJsonType, typename T, typename = void>
3545 struct has_to_json : std::false_type {};
3546 
3547 template<typename BasicJsonType, typename T>
3548 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3549 {
3550  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3551 
3552  static constexpr bool value =
3553  is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3554  T>::value;
3555 };
3556 
3557 
3559 // is_ functions //
3561 
3562 // https://en.cppreference.com/w/cpp/types/conjunction
3563 template<class...> struct conjunction : std::true_type { };
3564 template<class B1> struct conjunction<B1> : B1 { };
3565 template<class B1, class... Bn>
3566 struct conjunction<B1, Bn...>
3567 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3568 
3569 // https://en.cppreference.com/w/cpp/types/negation
3570 template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3571 
3572 // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3573 // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3574 // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3575 template <typename T>
3576 struct is_default_constructible : std::is_default_constructible<T> {};
3577 
3578 template <typename T1, typename T2>
3579 struct is_default_constructible<std::pair<T1, T2>>
3580  : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3581 
3582 template <typename T1, typename T2>
3583 struct is_default_constructible<const std::pair<T1, T2>>
3584  : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3585 
3586 template <typename... Ts>
3587 struct is_default_constructible<std::tuple<Ts...>>
3588  : conjunction<is_default_constructible<Ts>...> {};
3589 
3590 template <typename... Ts>
3591 struct is_default_constructible<const std::tuple<Ts...>>
3592  : conjunction<is_default_constructible<Ts>...> {};
3593 
3594 
3595 template <typename T, typename... Args>
3596 struct is_constructible : std::is_constructible<T, Args...> {};
3597 
3598 template <typename T1, typename T2>
3599 struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3600 
3601 template <typename T1, typename T2>
3602 struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3603 
3604 template <typename... Ts>
3605 struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3606 
3607 template <typename... Ts>
3608 struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3609 
3610 
3611 template<typename T, typename = void>
3612 struct is_iterator_traits : std::false_type {};
3613 
3614 template<typename T>
3615 struct is_iterator_traits<iterator_traits<T>>
3616 {
3617  private:
3618  using traits = iterator_traits<T>;
3619 
3620  public:
3621  static constexpr auto value =
3622  is_detected<value_type_t, traits>::value &&
3623  is_detected<difference_type_t, traits>::value &&
3624  is_detected<pointer_t, traits>::value &&
3625  is_detected<iterator_category_t, traits>::value &&
3626  is_detected<reference_t, traits>::value;
3627 };
3628 
3629 // The following implementation of is_complete_type is taken from
3630 // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3631 // and is written by Xiang Fan who agreed to using it in this library.
3632 
3633 template<typename T, typename = void>
3634 struct is_complete_type : std::false_type {};
3635 
3636 template<typename T>
3637 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3638 
3639 template<typename BasicJsonType, typename CompatibleObjectType,
3640  typename = void>
3641 struct is_compatible_object_type_impl : std::false_type {};
3642 
3643 template<typename BasicJsonType, typename CompatibleObjectType>
3644 struct is_compatible_object_type_impl <
3645  BasicJsonType, CompatibleObjectType,
3646  enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3647  is_detected<key_type_t, CompatibleObjectType>::value >>
3648 {
3649  using object_t = typename BasicJsonType::object_t;
3650 
3651  // macOS's is_constructible does not play well with nonesuch...
3652  static constexpr bool value =
3653  is_constructible<typename object_t::key_type,
3654  typename CompatibleObjectType::key_type>::value &&
3655  is_constructible<typename object_t::mapped_type,
3656  typename CompatibleObjectType::mapped_type>::value;
3657 };
3658 
3659 template<typename BasicJsonType, typename CompatibleObjectType>
3660 struct is_compatible_object_type
3661  : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3662 
3663 template<typename BasicJsonType, typename ConstructibleObjectType,
3664  typename = void>
3665 struct is_constructible_object_type_impl : std::false_type {};
3666 
3667 template<typename BasicJsonType, typename ConstructibleObjectType>
3668 struct is_constructible_object_type_impl <
3669  BasicJsonType, ConstructibleObjectType,
3670  enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3671  is_detected<key_type_t, ConstructibleObjectType>::value >>
3672 {
3673  using object_t = typename BasicJsonType::object_t;
3674 
3675  static constexpr bool value =
3676  (is_default_constructible<ConstructibleObjectType>::value &&
3677  (std::is_move_assignable<ConstructibleObjectType>::value ||
3678  std::is_copy_assignable<ConstructibleObjectType>::value) &&
3679  (is_constructible<typename ConstructibleObjectType::key_type,
3680  typename object_t::key_type>::value &&
3681  std::is_same <
3682  typename object_t::mapped_type,
3683  typename ConstructibleObjectType::mapped_type >::value)) ||
3684  (has_from_json<BasicJsonType,
3685  typename ConstructibleObjectType::mapped_type>::value ||
3686  has_non_default_from_json <
3687  BasicJsonType,
3688  typename ConstructibleObjectType::mapped_type >::value);
3689 };
3690 
3691 template<typename BasicJsonType, typename ConstructibleObjectType>
3692 struct is_constructible_object_type
3693  : is_constructible_object_type_impl<BasicJsonType,
3694  ConstructibleObjectType> {};
3695 
3696 template<typename BasicJsonType, typename CompatibleStringType,
3697  typename = void>
3698 struct is_compatible_string_type_impl : std::false_type {};
3699 
3700 template<typename BasicJsonType, typename CompatibleStringType>
3701 struct is_compatible_string_type_impl <
3702  BasicJsonType, CompatibleStringType,
3703  enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3704  value_type_t, CompatibleStringType>::value >>
3705 {
3706  static constexpr auto value =
3707  is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
3708 };
3709 
3710 template<typename BasicJsonType, typename ConstructibleStringType>
3711 struct is_compatible_string_type
3712  : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3713 
3714 template<typename BasicJsonType, typename ConstructibleStringType,
3715  typename = void>
3716 struct is_constructible_string_type_impl : std::false_type {};
3717 
3718 template<typename BasicJsonType, typename ConstructibleStringType>
3719 struct is_constructible_string_type_impl <
3720  BasicJsonType, ConstructibleStringType,
3721  enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3722  value_type_t, ConstructibleStringType>::value >>
3723 {
3724  static constexpr auto value =
3725  is_constructible<ConstructibleStringType,
3726  typename BasicJsonType::string_t>::value;
3727 };
3728 
3729 template<typename BasicJsonType, typename ConstructibleStringType>
3730 struct is_constructible_string_type
3731  : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3732 
3733 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3734 struct is_compatible_array_type_impl : std::false_type {};
3735 
3736 template<typename BasicJsonType, typename CompatibleArrayType>
3737 struct is_compatible_array_type_impl <
3738  BasicJsonType, CompatibleArrayType,
3739  enable_if_t < is_detected<value_type_t, CompatibleArrayType>::value&&
3740  is_detected<iterator_t, CompatibleArrayType>::value&&
3741 // This is needed because json_reverse_iterator has a ::iterator type...
3742 // Therefore it is detected as a CompatibleArrayType.
3743 // The real fix would be to have an Iterable concept.
3744  !is_iterator_traits <
3745  iterator_traits<CompatibleArrayType >>::value >>
3746 {
3747  static constexpr bool value =
3748  is_constructible<BasicJsonType,
3749  typename CompatibleArrayType::value_type>::value;
3750 };
3751 
3752 template<typename BasicJsonType, typename CompatibleArrayType>
3753 struct is_compatible_array_type
3754  : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3755 
3756 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3757 struct is_constructible_array_type_impl : std::false_type {};
3758 
3759 template<typename BasicJsonType, typename ConstructibleArrayType>
3760 struct is_constructible_array_type_impl <
3761  BasicJsonType, ConstructibleArrayType,
3762  enable_if_t<std::is_same<ConstructibleArrayType,
3763  typename BasicJsonType::value_type>::value >>
3764  : std::true_type {};
3765 
3766 template<typename BasicJsonType, typename ConstructibleArrayType>
3767 struct is_constructible_array_type_impl <
3768  BasicJsonType, ConstructibleArrayType,
3769  enable_if_t < !std::is_same<ConstructibleArrayType,
3770  typename BasicJsonType::value_type>::value&&
3771  is_default_constructible<ConstructibleArrayType>::value&&
3772 (std::is_move_assignable<ConstructibleArrayType>::value ||
3773  std::is_copy_assignable<ConstructibleArrayType>::value)&&
3774 is_detected<value_type_t, ConstructibleArrayType>::value&&
3775 is_detected<iterator_t, ConstructibleArrayType>::value&&
3776 is_complete_type <
3777 detected_t<value_type_t, ConstructibleArrayType >>::value >>
3778 {
3779  static constexpr bool value =
3780  // This is needed because json_reverse_iterator has a ::iterator type,
3781  // furthermore, std::back_insert_iterator (and other iterators) have a
3782  // base class `iterator`... Therefore it is detected as a
3783  // ConstructibleArrayType. The real fix would be to have an Iterable
3784  // concept.
3785  !is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value &&
3786 
3787  (std::is_same<typename ConstructibleArrayType::value_type,
3788  typename BasicJsonType::array_t::value_type>::value ||
3789  has_from_json<BasicJsonType,
3790  typename ConstructibleArrayType::value_type>::value ||
3791  has_non_default_from_json <
3792  BasicJsonType, typename ConstructibleArrayType::value_type >::value);
3793 };
3794 
3795 template<typename BasicJsonType, typename ConstructibleArrayType>
3796 struct is_constructible_array_type
3797  : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3798 
3799 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3800  typename = void>
3801 struct is_compatible_integer_type_impl : std::false_type {};
3802 
3803 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3804 struct is_compatible_integer_type_impl <
3805  RealIntegerType, CompatibleNumberIntegerType,
3806  enable_if_t < std::is_integral<RealIntegerType>::value&&
3807  std::is_integral<CompatibleNumberIntegerType>::value&&
3808  !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3809 {
3810  // is there an assert somewhere on overflows?
3811  using RealLimits = std::numeric_limits<RealIntegerType>;
3812  using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3813 
3814  static constexpr auto value =
3815  is_constructible<RealIntegerType,
3816  CompatibleNumberIntegerType>::value &&
3817  CompatibleLimits::is_integer &&
3818  RealLimits::is_signed == CompatibleLimits::is_signed;
3819 };
3820 
3821 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3822 struct is_compatible_integer_type
3823  : is_compatible_integer_type_impl<RealIntegerType,
3824  CompatibleNumberIntegerType> {};
3825 
3826 template<typename BasicJsonType, typename CompatibleType, typename = void>
3827 struct is_compatible_type_impl: std::false_type {};
3828 
3829 template<typename BasicJsonType, typename CompatibleType>
3830 struct is_compatible_type_impl <
3831  BasicJsonType, CompatibleType,
3832  enable_if_t<is_complete_type<CompatibleType>::value >>
3833 {
3834  static constexpr bool value =
3835  has_to_json<BasicJsonType, CompatibleType>::value;
3836 };
3837 
3838 template<typename BasicJsonType, typename CompatibleType>
3839 struct is_compatible_type
3840  : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3841 
3842 template<typename T1, typename T2>
3843 struct is_constructible_tuple : std::false_type {};
3844 
3845 template<typename T1, typename... Args>
3846 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3847 
3848 // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3849 template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3850 T conditional_static_cast(U value)
3851 {
3852  return static_cast<T>(value);
3853 }
3854 
3855 template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3856 T conditional_static_cast(U value)
3857 {
3858  return value;
3859 }
3860 
3861 } // namespace detail
3862 } // namespace nlohmann
3863 
3864 // #include <nlohmann/detail/value_t.hpp>
3865 
3866 
3867 namespace nlohmann
3868 {
3869 namespace detail
3870 {
3871 template<typename BasicJsonType>
3872 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3873 {
3874  if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
3875  {
3876  JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()), j));
3877  }
3878  n = nullptr;
3879 }
3880 
3881 // overloads for basic_json template parameters
3882 template < typename BasicJsonType, typename ArithmeticType,
3883  enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
3884  !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3885  int > = 0 >
3886 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3887 {
3888  switch (static_cast<value_t>(j))
3889  {
3890  case value_t::number_unsigned:
3891  {
3892  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3893  break;
3894  }
3895  case value_t::number_integer:
3896  {
3897  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3898  break;
3899  }
3900  case value_t::number_float:
3901  {
3902  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3903  break;
3904  }
3905 
3906  case value_t::null:
3907  case value_t::object:
3908  case value_t::array:
3909  case value_t::string:
3910  case value_t::boolean:
3911  case value_t::binary:
3912  case value_t::discarded:
3913  default:
3914  JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
3915  }
3916 }
3917 
3918 template<typename BasicJsonType>
3919 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
3920 {
3921  if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
3922  {
3923  JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()), j));
3924  }
3925  b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
3926 }
3927 
3928 template<typename BasicJsonType>
3929 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
3930 {
3931  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3932  {
3933  JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
3934  }
3935  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3936 }
3937 
3938 template <
3939  typename BasicJsonType, typename ConstructibleStringType,
3940  enable_if_t <
3941  is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&
3942  !std::is_same<typename BasicJsonType::string_t,
3943  ConstructibleStringType>::value,
3944  int > = 0 >
3945 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
3946 {
3947  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3948  {
3949  JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
3950  }
3951 
3952  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3953 }
3954 
3955 template<typename BasicJsonType>
3956 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
3957 {
3958  get_arithmetic_value(j, val);
3959 }
3960 
3961 template<typename BasicJsonType>
3962 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
3963 {
3964  get_arithmetic_value(j, val);
3965 }
3966 
3967 template<typename BasicJsonType>
3968 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
3969 {
3970  get_arithmetic_value(j, val);
3971 }
3972 
3973 template<typename BasicJsonType, typename EnumType,
3974  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
3975 void from_json(const BasicJsonType& j, EnumType& e)
3976 {
3977  typename std::underlying_type<EnumType>::type val;
3978  get_arithmetic_value(j, val);
3979  e = static_cast<EnumType>(val);
3980 }
3981 
3982 // forward_list doesn't have an insert method
3983 template<typename BasicJsonType, typename T, typename Allocator,
3984  enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
3985 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
3986 {
3987  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3988  {
3989  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
3990  }
3991  l.clear();
3992  std::transform(j.rbegin(), j.rend(),
3993  std::front_inserter(l), [](const BasicJsonType & i)
3994  {
3995  return i.template get<T>();
3996  });
3997 }
3998 
3999 // valarray doesn't have an insert method
4000 template<typename BasicJsonType, typename T,
4001  enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4002 void from_json(const BasicJsonType& j, std::valarray<T>& l)
4003 {
4004  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4005  {
4006  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4007  }
4008  l.resize(j.size());
4009  std::transform(j.begin(), j.end(), std::begin(l),
4010  [](const BasicJsonType & elem)
4011  {
4012  return elem.template get<T>();
4013  });
4014 }
4015 
4016 template<typename BasicJsonType, typename T, std::size_t N>
4017 auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4018 -> decltype(j.template get<T>(), void())
4019 {
4020  for (std::size_t i = 0; i < N; ++i)
4021  {
4022  arr[i] = j.at(i).template get<T>();
4023  }
4024 }
4025 
4026 template<typename BasicJsonType>
4027 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4028 {
4029  arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4030 }
4031 
4032 template<typename BasicJsonType, typename T, std::size_t N>
4033 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4034  priority_tag<2> /*unused*/)
4035 -> decltype(j.template get<T>(), void())
4036 {
4037  for (std::size_t i = 0; i < N; ++i)
4038  {
4039  arr[i] = j.at(i).template get<T>();
4040  }
4041 }
4042 
4043 template<typename BasicJsonType, typename ConstructibleArrayType,
4044  enable_if_t<
4045  std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4046  int> = 0>
4047 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4048 -> decltype(
4049  arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4050  j.template get<typename ConstructibleArrayType::value_type>(),
4051  void())
4052 {
4053  using std::end;
4054 
4055  ConstructibleArrayType ret;
4056  ret.reserve(j.size());
4057  std::transform(j.begin(), j.end(),
4058  std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4059  {
4060  // get<BasicJsonType>() returns *this, this won't call a from_json
4061  // method when value_type is BasicJsonType
4062  return i.template get<typename ConstructibleArrayType::value_type>();
4063  });
4064  arr = std::move(ret);
4065 }
4066 
4067 template<typename BasicJsonType, typename ConstructibleArrayType,
4068  enable_if_t<
4069  std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4070  int> = 0>
4071 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4072  priority_tag<0> /*unused*/)
4073 {
4074  using std::end;
4075 
4076  ConstructibleArrayType ret;
4077  std::transform(
4078  j.begin(), j.end(), std::inserter(ret, end(ret)),
4079  [](const BasicJsonType & i)
4080  {
4081  // get<BasicJsonType>() returns *this, this won't call a from_json
4082  // method when value_type is BasicJsonType
4083  return i.template get<typename ConstructibleArrayType::value_type>();
4084  });
4085  arr = std::move(ret);
4086 }
4087 
4088 template < typename BasicJsonType, typename ConstructibleArrayType,
4089  enable_if_t <
4090  is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
4091  !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
4092  !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
4093  !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
4094  !is_basic_json<ConstructibleArrayType>::value,
4095  int > = 0 >
4096 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4097 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4098 j.template get<typename ConstructibleArrayType::value_type>(),
4099 void())
4100 {
4101  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4102  {
4103  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4104  }
4105 
4106  from_json_array_impl(j, arr, priority_tag<3> {});
4107 }
4108 
4109 template < typename BasicJsonType, typename T, std::size_t... Idx >
4110 std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4111  identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4112 {
4113  return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4114 }
4115 
4116 template < typename BasicJsonType, typename T, std::size_t N >
4117 auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4118 -> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4119 {
4120  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4121  {
4122  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4123  }
4124 
4125  return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4126 }
4127 
4128 template<typename BasicJsonType>
4129 void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4130 {
4131  if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4132  {
4133  JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()), j));
4134  }
4135 
4136  bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4137 }
4138 
4139 template<typename BasicJsonType, typename ConstructibleObjectType,
4140  enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4141 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4142 {
4143  if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4144  {
4145  JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()), j));
4146  }
4147 
4148  ConstructibleObjectType ret;
4149  const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4150  using value_type = typename ConstructibleObjectType::value_type;
4151  std::transform(
4152  inner_object->begin(), inner_object->end(),
4153  std::inserter(ret, ret.begin()),
4154  [](typename BasicJsonType::object_t::value_type const & p)
4155  {
4156  return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4157  });
4158  obj = std::move(ret);
4159 }
4160 
4161 // overload for arithmetic types, not chosen for basic_json template arguments
4162 // (BooleanType, etc..); note: Is it really necessary to provide explicit
4163 // overloads for boolean_t etc. in case of a custom BooleanType which is not
4164 // an arithmetic type?
4165 template < typename BasicJsonType, typename ArithmeticType,
4166  enable_if_t <
4167  std::is_arithmetic<ArithmeticType>::value&&
4168  !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
4169  !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
4170  !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
4171  !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4172  int > = 0 >
4173 void from_json(const BasicJsonType& j, ArithmeticType& val)
4174 {
4175  switch (static_cast<value_t>(j))
4176  {
4177  case value_t::number_unsigned:
4178  {
4179  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4180  break;
4181  }
4182  case value_t::number_integer:
4183  {
4184  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4185  break;
4186  }
4187  case value_t::number_float:
4188  {
4189  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4190  break;
4191  }
4192  case value_t::boolean:
4193  {
4194  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4195  break;
4196  }
4197 
4198  case value_t::null:
4199  case value_t::object:
4200  case value_t::array:
4201  case value_t::string:
4202  case value_t::binary:
4203  case value_t::discarded:
4204  default:
4205  JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4206  }
4207 }
4208 
4209 template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4210 std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4211 {
4212  return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4213 }
4214 
4215 template < typename BasicJsonType, class A1, class A2 >
4216 std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4217 {
4218  return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4219  std::forward<BasicJsonType>(j).at(1).template get<A2>()};
4220 }
4221 
4222 template<typename BasicJsonType, typename A1, typename A2>
4223 void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4224 {
4225  p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4226 }
4227 
4228 template<typename BasicJsonType, typename... Args>
4229 std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4230 {
4231  return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4232 }
4233 
4234 template<typename BasicJsonType, typename... Args>
4235 void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4236 {
4237  t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4238 }
4239 
4240 template<typename BasicJsonType, typename TupleRelated>
4241 auto from_json(BasicJsonType&& j, TupleRelated&& t)
4242 -> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4243 {
4244  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4245  {
4246  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4247  }
4248 
4249  return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4250 }
4251 
4252 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4253  typename = enable_if_t < !std::is_constructible <
4254  typename BasicJsonType::string_t, Key >::value >>
4255 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4256 {
4257  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4258  {
4259  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4260  }
4261  m.clear();
4262  for (const auto& p : j)
4263  {
4264  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4265  {
4266  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4267  }
4268  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4269  }
4270 }
4271 
4272 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4273  typename = enable_if_t < !std::is_constructible <
4274  typename BasicJsonType::string_t, Key >::value >>
4275 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
4276 {
4277  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4278  {
4279  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4280  }
4281  m.clear();
4282  for (const auto& p : j)
4283  {
4284  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4285  {
4286  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4287  }
4288  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4289  }
4290 }
4291 
4292 struct from_json_fn
4293 {
4294  template<typename BasicJsonType, typename T>
4295  auto operator()(const BasicJsonType& j, T&& val) const
4296  noexcept(noexcept(from_json(j, std::forward<T>(val))))
4297  -> decltype(from_json(j, std::forward<T>(val)))
4298  {
4299  return from_json(j, std::forward<T>(val));
4300  }
4301 };
4302 } // namespace detail
4303 
4307 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4308 {
4309 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4310 } // namespace
4311 } // namespace nlohmann
4312 
4313 // #include <nlohmann/detail/conversions/to_json.hpp>
4314 
4315 
4316 #include <algorithm> // copy
4317 #include <iterator> // begin, end
4318 #include <string> // string
4319 #include <tuple> // tuple, get
4320 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
4321 #include <utility> // move, forward, declval, pair
4322 #include <valarray> // valarray
4323 #include <vector> // vector
4324 
4325 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4326 
4327 
4328 #include <cstddef> // size_t
4329 #include <iterator> // input_iterator_tag
4330 #include <string> // string, to_string
4331 #include <tuple> // tuple_size, get, tuple_element
4332 #include <utility> // move
4333 
4334 // #include <nlohmann/detail/meta/type_traits.hpp>
4335 
4336 // #include <nlohmann/detail/value_t.hpp>
4337 
4338 
4339 namespace nlohmann
4340 {
4341 namespace detail
4342 {
4343 template<typename string_type>
4344 void int_to_string( string_type& target, std::size_t value )
4345 {
4346  // For ADL
4347  using std::to_string;
4348  target = to_string(value);
4349 }
4350 template<typename IteratorType> class iteration_proxy_value
4351 {
4352  public:
4353  using difference_type = std::ptrdiff_t;
4354  using value_type = iteration_proxy_value;
4355  using pointer = value_type * ;
4356  using reference = value_type & ;
4357  using iterator_category = std::input_iterator_tag;
4358  using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
4359 
4360  private:
4362  IteratorType anchor;
4364  std::size_t array_index = 0;
4366  mutable std::size_t array_index_last = 0;
4368  mutable string_type array_index_str = "0";
4370  const string_type empty_str{};
4371 
4372  public:
4373  explicit iteration_proxy_value(IteratorType it) noexcept
4374  : anchor(std::move(it))
4375  {}
4376 
4378  iteration_proxy_value& operator*()
4379  {
4380  return *this;
4381  }
4382 
4384  iteration_proxy_value& operator++()
4385  {
4386  ++anchor;
4387  ++array_index;
4388 
4389  return *this;
4390  }
4391 
4393  bool operator==(const iteration_proxy_value& o) const
4394  {
4395  return anchor == o.anchor;
4396  }
4397 
4399  bool operator!=(const iteration_proxy_value& o) const
4400  {
4401  return anchor != o.anchor;
4402  }
4403 
4405  const string_type& key() const
4406  {
4407  JSON_ASSERT(anchor.m_object != nullptr);
4408 
4409  switch (anchor.m_object->type())
4410  {
4411  // use integer array index as key
4412  case value_t::array:
4413  {
4414  if (array_index != array_index_last)
4415  {
4416  int_to_string( array_index_str, array_index );
4417  array_index_last = array_index;
4418  }
4419  return array_index_str;
4420  }
4421 
4422  // use key from the object
4423  case value_t::object:
4424  return anchor.key();
4425 
4426  // use an empty key for all primitive types
4427  case value_t::null:
4428  case value_t::string:
4429  case value_t::boolean:
4430  case value_t::number_integer:
4431  case value_t::number_unsigned:
4432  case value_t::number_float:
4433  case value_t::binary:
4434  case value_t::discarded:
4435  default:
4436  return empty_str;
4437  }
4438  }
4439 
4441  typename IteratorType::reference value() const
4442  {
4443  return anchor.value();
4444  }
4445 };
4446 
4448 template<typename IteratorType> class iteration_proxy
4449 {
4450  private:
4452  typename IteratorType::reference container;
4453 
4454  public:
4456  explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4457  : container(cont) {}
4458 
4460  iteration_proxy_value<IteratorType> begin() noexcept
4461  {
4462  return iteration_proxy_value<IteratorType>(container.begin());
4463  }
4464 
4466  iteration_proxy_value<IteratorType> end() noexcept
4467  {
4468  return iteration_proxy_value<IteratorType>(container.end());
4469  }
4470 };
4471 // Structured Bindings Support
4472 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4473 // And see https://github.com/nlohmann/json/pull/1391
4474 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
4475 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
4476 {
4477  return i.key();
4478 }
4479 // Structured Bindings Support
4480 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4481 // And see https://github.com/nlohmann/json/pull/1391
4482 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
4483 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
4484 {
4485  return i.value();
4486 }
4487 } // namespace detail
4488 } // namespace nlohmann
4489 
4490 // The Addition to the STD Namespace is required to add
4491 // Structured Bindings Support to the iteration_proxy_value class
4492 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4493 // And see https://github.com/nlohmann/json/pull/1391
4494 namespace std
4495 {
4496 #if defined(__clang__)
4497  // Fix: https://github.com/nlohmann/json/issues/1401
4498  #pragma clang diagnostic push
4499  #pragma clang diagnostic ignored "-Wmismatched-tags"
4500 #endif
4501 template<typename IteratorType>
4502 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4503  : public std::integral_constant<std::size_t, 2> {};
4504 
4505 template<std::size_t N, typename IteratorType>
4506 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4507 {
4508  public:
4509  using type = decltype(
4510  get<N>(std::declval <
4511  ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
4512 };
4513 #if defined(__clang__)
4514  #pragma clang diagnostic pop
4515 #endif
4516 } // namespace std
4517 
4518 // #include <nlohmann/detail/meta/cpp_future.hpp>
4519 
4520 // #include <nlohmann/detail/meta/type_traits.hpp>
4521 
4522 // #include <nlohmann/detail/value_t.hpp>
4523 
4524 
4525 namespace nlohmann
4526 {
4527 namespace detail
4528 {
4530 // constructors //
4532 
4533 /*
4534  * Note all external_constructor<>::construct functions need to call
4535  * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
4536  * allocated value (e.g., a string). See bug issue
4537  * https://github.com/nlohmann/json/issues/2865 for more information.
4538  */
4539 
4540 template<value_t> struct external_constructor;
4541 
4542 template<>
4543 struct external_constructor<value_t::boolean>
4544 {
4545  template<typename BasicJsonType>
4546  static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4547  {
4548  j.m_value.destroy(j.m_type);
4549  j.m_type = value_t::boolean;
4550  j.m_value = b;
4551  j.assert_invariant();
4552  }
4553 };
4554 
4555 template<>
4556 struct external_constructor<value_t::string>
4557 {
4558  template<typename BasicJsonType>
4559  static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4560  {
4561  j.m_value.destroy(j.m_type);
4562  j.m_type = value_t::string;
4563  j.m_value = s;
4564  j.assert_invariant();
4565  }
4566 
4567  template<typename BasicJsonType>
4568  static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4569  {
4570  j.m_value.destroy(j.m_type);
4571  j.m_type = value_t::string;
4572  j.m_value = std::move(s);
4573  j.assert_invariant();
4574  }
4575 
4576  template < typename BasicJsonType, typename CompatibleStringType,
4577  enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
4578  int > = 0 >
4579  static void construct(BasicJsonType& j, const CompatibleStringType& str)
4580  {
4581  j.m_value.destroy(j.m_type);
4582  j.m_type = value_t::string;
4583  j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4584  j.assert_invariant();
4585  }
4586 };
4587 
4588 template<>
4589 struct external_constructor<value_t::binary>
4590 {
4591  template<typename BasicJsonType>
4592  static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4593  {
4594  j.m_value.destroy(j.m_type);
4595  j.m_type = value_t::binary;
4596  j.m_value = typename BasicJsonType::binary_t(b);
4597  j.assert_invariant();
4598  }
4599 
4600  template<typename BasicJsonType>
4601  static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4602  {
4603  j.m_value.destroy(j.m_type);
4604  j.m_type = value_t::binary;
4605  j.m_value = typename BasicJsonType::binary_t(std::move(b));;
4606  j.assert_invariant();
4607  }
4608 };
4609 
4610 template<>
4611 struct external_constructor<value_t::number_float>
4612 {
4613  template<typename BasicJsonType>
4614  static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4615  {
4616  j.m_value.destroy(j.m_type);
4617  j.m_type = value_t::number_float;
4618  j.m_value = val;
4619  j.assert_invariant();
4620  }
4621 };
4622 
4623 template<>
4624 struct external_constructor<value_t::number_unsigned>
4625 {
4626  template<typename BasicJsonType>
4627  static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4628  {
4629  j.m_value.destroy(j.m_type);
4630  j.m_type = value_t::number_unsigned;
4631  j.m_value = val;
4632  j.assert_invariant();
4633  }
4634 };
4635 
4636 template<>
4637 struct external_constructor<value_t::number_integer>
4638 {
4639  template<typename BasicJsonType>
4640  static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4641  {
4642  j.m_value.destroy(j.m_type);
4643  j.m_type = value_t::number_integer;
4644  j.m_value = val;
4645  j.assert_invariant();
4646  }
4647 };
4648 
4649 template<>
4650 struct external_constructor<value_t::array>
4651 {
4652  template<typename BasicJsonType>
4653  static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4654  {
4655  j.m_value.destroy(j.m_type);
4656  j.m_type = value_t::array;
4657  j.m_value = arr;
4658  j.set_parents();
4659  j.assert_invariant();
4660  }
4661 
4662  template<typename BasicJsonType>
4663  static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4664  {
4665  j.m_value.destroy(j.m_type);
4666  j.m_type = value_t::array;
4667  j.m_value = std::move(arr);
4668  j.set_parents();
4669  j.assert_invariant();
4670  }
4671 
4672  template < typename BasicJsonType, typename CompatibleArrayType,
4673  enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
4674  int > = 0 >
4675  static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4676  {
4677  using std::begin;
4678  using std::end;
4679 
4680  j.m_value.destroy(j.m_type);
4681  j.m_type = value_t::array;
4682  j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4683  j.set_parents();
4684  j.assert_invariant();
4685  }
4686 
4687  template<typename BasicJsonType>
4688  static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4689  {
4690  j.m_value.destroy(j.m_type);
4691  j.m_type = value_t::array;
4692  j.m_value = value_t::array;
4693  j.m_value.array->reserve(arr.size());
4694  for (const bool x : arr)
4695  {
4696  j.m_value.array->push_back(x);
4697  j.set_parent(j.m_value.array->back());
4698  }
4699  j.assert_invariant();
4700  }
4701 
4702  template<typename BasicJsonType, typename T,
4703  enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4704  static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4705  {
4706  j.m_value.destroy(j.m_type);
4707  j.m_type = value_t::array;
4708  j.m_value = value_t::array;
4709  j.m_value.array->resize(arr.size());
4710  if (arr.size() > 0)
4711  {
4712  std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4713  }
4714  j.set_parents();
4715  j.assert_invariant();
4716  }
4717 };
4718 
4719 template<>
4720 struct external_constructor<value_t::object>
4721 {
4722  template<typename BasicJsonType>
4723  static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
4724  {
4725  j.m_value.destroy(j.m_type);
4726  j.m_type = value_t::object;
4727  j.m_value = obj;
4728  j.set_parents();
4729  j.assert_invariant();
4730  }
4731 
4732  template<typename BasicJsonType>
4733  static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4734  {
4735  j.m_value.destroy(j.m_type);
4736  j.m_type = value_t::object;
4737  j.m_value = std::move(obj);
4738  j.set_parents();
4739  j.assert_invariant();
4740  }
4741 
4742  template < typename BasicJsonType, typename CompatibleObjectType,
4743  enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
4744  static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4745  {
4746  using std::begin;
4747  using std::end;
4748 
4749  j.m_value.destroy(j.m_type);
4750  j.m_type = value_t::object;
4751  j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4752  j.set_parents();
4753  j.assert_invariant();
4754  }
4755 };
4756 
4758 // to_json //
4760 
4761 template<typename BasicJsonType, typename T,
4762  enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
4763 void to_json(BasicJsonType& j, T b) noexcept
4764 {
4765  external_constructor<value_t::boolean>::construct(j, b);
4766 }
4767 
4768 template<typename BasicJsonType, typename CompatibleString,
4769  enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
4770 void to_json(BasicJsonType& j, const CompatibleString& s)
4771 {
4772  external_constructor<value_t::string>::construct(j, s);
4773 }
4774 
4775 template<typename BasicJsonType>
4776 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4777 {
4778  external_constructor<value_t::string>::construct(j, std::move(s));
4779 }
4780 
4781 template<typename BasicJsonType, typename FloatType,
4782  enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
4783 void to_json(BasicJsonType& j, FloatType val) noexcept
4784 {
4785  external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4786 }
4787 
4788 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4789  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
4790 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4791 {
4792  external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4793 }
4794 
4795 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4796  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
4797 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4798 {
4799  external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4800 }
4801 
4802 template<typename BasicJsonType, typename EnumType,
4803  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4804 void to_json(BasicJsonType& j, EnumType e) noexcept
4805 {
4806  using underlying_type = typename std::underlying_type<EnumType>::type;
4807  external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4808 }
4809 
4810 template<typename BasicJsonType>
4811 void to_json(BasicJsonType& j, const std::vector<bool>& e)
4812 {
4813  external_constructor<value_t::array>::construct(j, e);
4814 }
4815 
4816 template < typename BasicJsonType, typename CompatibleArrayType,
4817  enable_if_t < is_compatible_array_type<BasicJsonType,
4818  CompatibleArrayType>::value&&
4819  !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
4820  !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
4821  !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
4822  !is_basic_json<CompatibleArrayType>::value,
4823  int > = 0 >
4824 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4825 {
4826  external_constructor<value_t::array>::construct(j, arr);
4827 }
4828 
4829 template<typename BasicJsonType>
4830 void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4831 {
4832  external_constructor<value_t::binary>::construct(j, bin);
4833 }
4834 
4835 template<typename BasicJsonType, typename T,
4836  enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4837 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4838 {
4839  external_constructor<value_t::array>::construct(j, std::move(arr));
4840 }
4841 
4842 template<typename BasicJsonType>
4843 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4844 {
4845  external_constructor<value_t::array>::construct(j, std::move(arr));
4846 }
4847 
4848 template < typename BasicJsonType, typename CompatibleObjectType,
4849  enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
4850 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4851 {
4852  external_constructor<value_t::object>::construct(j, obj);
4853 }
4854 
4855 template<typename BasicJsonType>
4856 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4857 {
4858  external_constructor<value_t::object>::construct(j, std::move(obj));
4859 }
4860 
4861 template <
4862  typename BasicJsonType, typename T, std::size_t N,
4863  enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4864  const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4865  int > = 0 >
4866 void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4867 {
4868  external_constructor<value_t::array>::construct(j, arr);
4869 }
4870 
4871 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
4872 void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4873 {
4874  j = { p.first, p.second };
4875 }
4876 
4877 // for https://github.com/nlohmann/json/pull/1134
4878 template<typename BasicJsonType, typename T,
4879  enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
4880 void to_json(BasicJsonType& j, const T& b)
4881 {
4882  j = { {b.key(), b.value()} };
4883 }
4884 
4885 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
4886 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4887 {
4888  j = { std::get<Idx>(t)... };
4889 }
4890 
4891 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
4892 void to_json(BasicJsonType& j, const T& t)
4893 {
4894  to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
4895 }
4896 
4897 struct to_json_fn
4898 {
4899  template<typename BasicJsonType, typename T>
4900  auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
4901  -> decltype(to_json(j, std::forward<T>(val)), void())
4902  {
4903  return to_json(j, std::forward<T>(val));
4904  }
4905 };
4906 } // namespace detail
4907 
4911 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4912 {
4913 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4914 } // namespace
4915 } // namespace nlohmann
4916 
4917 // #include <nlohmann/detail/meta/identity_tag.hpp>
4918 
4919 // #include <nlohmann/detail/meta/type_traits.hpp>
4920 
4921 
4922 namespace nlohmann
4923 {
4924 
4925 template<typename ValueType, typename>
4927 {
4939  template<typename BasicJsonType, typename TargetType = ValueType>
4940  static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
4941  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
4942  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
4943  {
4944  ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
4945  }
4946 
4959  template<typename BasicJsonType, typename TargetType = ValueType>
4960  static auto from_json(BasicJsonType && j) noexcept(
4961  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
4962  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
4963  {
4964  return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
4965  }
4966 
4976  template<typename BasicJsonType, typename TargetType = ValueType>
4977  static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
4978  noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
4979  -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
4980  {
4981  ::nlohmann::to_json(j, std::forward<TargetType>(val));
4982  }
4983 };
4984 } // namespace nlohmann
4985 
4986 // #include <nlohmann/byte_container_with_subtype.hpp>
4987 
4988 
4989 #include <cstdint> // uint8_t, uint64_t
4990 #include <tuple> // tie
4991 #include <utility> // move
4992 
4993 namespace nlohmann
4994 {
4995 
5009 template<typename BinaryType>
5010 class byte_container_with_subtype : public BinaryType
5011 {
5012  public:
5014  using container_type = BinaryType;
5016  using subtype_type = std::uint64_t;
5017 
5019  : container_type()
5020  {}
5021 
5023  : container_type(b)
5024  {}
5025 
5026  byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5027  : container_type(std::move(b))
5028  {}
5029 
5030  byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
5031  : container_type(b)
5032  , m_subtype(subtype_)
5033  , m_has_subtype(true)
5034  {}
5035 
5036  byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5037  : container_type(std::move(b))
5038  , m_subtype(subtype_)
5039  , m_has_subtype(true)
5040  {}
5041 
5043  {
5044  return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5045  std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5046  }
5047 
5049  {
5050  return !(rhs == *this);
5051  }
5052 
5071  void set_subtype(subtype_type subtype_) noexcept
5072  {
5073  m_subtype = subtype_;
5074  m_has_subtype = true;
5075  }
5076 
5099  constexpr subtype_type subtype() const noexcept
5100  {
5101  return m_has_subtype ? m_subtype : subtype_type(-1);
5102  }
5103 
5120  constexpr bool has_subtype() const noexcept
5121  {
5122  return m_has_subtype;
5123  }
5124 
5144  void clear_subtype() noexcept
5145  {
5146  m_subtype = 0;
5147  m_has_subtype = false;
5148  }
5149 
5150  private:
5151  subtype_type m_subtype = 0;
5152  bool m_has_subtype = false;
5153 };
5154 
5155 } // namespace nlohmann
5156 
5157 // #include <nlohmann/detail/conversions/from_json.hpp>
5158 
5159 // #include <nlohmann/detail/conversions/to_json.hpp>
5160 
5161 // #include <nlohmann/detail/exceptions.hpp>
5162 
5163 // #include <nlohmann/detail/hash.hpp>
5164 
5165 
5166 #include <cstdint> // uint8_t
5167 #include <cstddef> // size_t
5168 #include <functional> // hash
5169 
5170 // #include <nlohmann/detail/macro_scope.hpp>
5171 
5172 // #include <nlohmann/detail/value_t.hpp>
5173 
5174 
5175 namespace nlohmann
5176 {
5177 namespace detail
5178 {
5179 
5180 // boost::hash_combine
5181 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5182 {
5183  seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5184  return seed;
5185 }
5186 
5198 template<typename BasicJsonType>
5199 std::size_t hash(const BasicJsonType& j)
5200 {
5201  using string_t = typename BasicJsonType::string_t;
5202  using number_integer_t = typename BasicJsonType::number_integer_t;
5203  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5204  using number_float_t = typename BasicJsonType::number_float_t;
5205 
5206  const auto type = static_cast<std::size_t>(j.type());
5207  switch (j.type())
5208  {
5209  case BasicJsonType::value_t::null:
5210  case BasicJsonType::value_t::discarded:
5211  {
5212  return combine(type, 0);
5213  }
5214 
5215  case BasicJsonType::value_t::object:
5216  {
5217  auto seed = combine(type, j.size());
5218  for (const auto& element : j.items())
5219  {
5220  const auto h = std::hash<string_t> {}(element.key());
5221  seed = combine(seed, h);
5222  seed = combine(seed, hash(element.value()));
5223  }
5224  return seed;
5225  }
5226 
5227  case BasicJsonType::value_t::array:
5228  {
5229  auto seed = combine(type, j.size());
5230  for (const auto& element : j)
5231  {
5232  seed = combine(seed, hash(element));
5233  }
5234  return seed;
5235  }
5236 
5237  case BasicJsonType::value_t::string:
5238  {
5239  const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
5240  return combine(type, h);
5241  }
5242 
5243  case BasicJsonType::value_t::boolean:
5244  {
5245  const auto h = std::hash<bool> {}(j.template get<bool>());
5246  return combine(type, h);
5247  }
5248 
5249  case BasicJsonType::value_t::number_integer:
5250  {
5251  const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
5252  return combine(type, h);
5253  }
5254 
5255  case BasicJsonType::value_t::number_unsigned:
5256  {
5257  const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
5258  return combine(type, h);
5259  }
5260 
5261  case BasicJsonType::value_t::number_float:
5262  {
5263  const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
5264  return combine(type, h);
5265  }
5266 
5267  case BasicJsonType::value_t::binary:
5268  {
5269  auto seed = combine(type, j.get_binary().size());
5270  const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
5271  seed = combine(seed, h);
5272  seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
5273  for (const auto byte : j.get_binary())
5274  {
5275  seed = combine(seed, std::hash<std::uint8_t> {}(byte));
5276  }
5277  return seed;
5278  }
5279 
5280  default: // LCOV_EXCL_LINE
5281  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
5282  return 0; // LCOV_EXCL_LINE
5283  }
5284 }
5285 
5286 } // namespace detail
5287 } // namespace nlohmann
5288 
5289 // #include <nlohmann/detail/input/binary_reader.hpp>
5290 
5291 
5292 #include <algorithm> // generate_n
5293 #include <array> // array
5294 #include <cmath> // ldexp
5295 #include <cstddef> // size_t
5296 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5297 #include <cstdio> // snprintf
5298 #include <cstring> // memcpy
5299 #include <iterator> // back_inserter
5300 #include <limits> // numeric_limits
5301 #include <string> // char_traits, string
5302 #include <utility> // make_pair, move
5303 #include <vector> // vector
5304 
5305 // #include <nlohmann/detail/exceptions.hpp>
5306 
5307 // #include <nlohmann/detail/input/input_adapters.hpp>
5308 
5309 
5310 #include <array> // array
5311 #include <cstddef> // size_t
5312 #include <cstring> // strlen
5313 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
5314 #include <memory> // shared_ptr, make_shared, addressof
5315 #include <numeric> // accumulate
5316 #include <string> // string, char_traits
5317 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
5318 #include <utility> // pair, declval
5319 
5320 #ifndef JSON_NO_IO
5321  #include <cstdio> // FILE *
5322  #include <istream> // istream
5323 #endif // JSON_NO_IO
5324 
5325 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
5326 
5327 // #include <nlohmann/detail/macro_scope.hpp>
5328 
5329 
5330 namespace nlohmann
5331 {
5332 namespace detail
5333 {
5335 enum class input_format_t { json, cbor, msgpack, ubjson, bson };
5336 
5338 // input adapters //
5340 
5341 #ifndef JSON_NO_IO
5346 class file_input_adapter
5347 {
5348  public:
5349  using char_type = char;
5350 
5351  JSON_HEDLEY_NON_NULL(2)
5352  explicit file_input_adapter(std::FILE* f) noexcept
5353  : m_file(f)
5354  {}
5355 
5356  // make class move-only
5357  file_input_adapter(const file_input_adapter&) = delete;
5358  file_input_adapter(file_input_adapter&&) noexcept = default;
5359  file_input_adapter& operator=(const file_input_adapter&) = delete;
5360  file_input_adapter& operator=(file_input_adapter&&) = delete;
5361  ~file_input_adapter() = default;
5362 
5363  std::char_traits<char>::int_type get_character() noexcept
5364  {
5365  return std::fgetc(m_file);
5366  }
5367 
5368  private:
5370  std::FILE* m_file;
5371 };
5372 
5373 
5383 class input_stream_adapter
5384 {
5385  public:
5386  using char_type = char;
5387 
5388  ~input_stream_adapter()
5389  {
5390  // clear stream flags; we use underlying streambuf I/O, do not
5391  // maintain ifstream flags, except eof
5392  if (is != nullptr)
5393  {
5394  is->clear(is->rdstate() & std::ios::eofbit);
5395  }
5396  }
5397 
5398  explicit input_stream_adapter(std::istream& i)
5399  : is(&i), sb(i.rdbuf())
5400  {}
5401 
5402  // delete because of pointer members
5403  input_stream_adapter(const input_stream_adapter&) = delete;
5404  input_stream_adapter& operator=(input_stream_adapter&) = delete;
5405  input_stream_adapter& operator=(input_stream_adapter&&) = delete;
5406 
5407  input_stream_adapter(input_stream_adapter&& rhs) noexcept
5408  : is(rhs.is), sb(rhs.sb)
5409  {
5410  rhs.is = nullptr;
5411  rhs.sb = nullptr;
5412  }
5413 
5414  // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
5415  // ensure that std::char_traits<char>::eof() and the character 0xFF do not
5416  // end up as the same value, eg. 0xFFFFFFFF.
5417  std::char_traits<char>::int_type get_character()
5418  {
5419  auto res = sb->sbumpc();
5420  // set eof manually, as we don't use the istream interface.
5421  if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
5422  {
5423  is->clear(is->rdstate() | std::ios::eofbit);
5424  }
5425  return res;
5426  }
5427 
5428  private:
5430  std::istream* is = nullptr;
5431  std::streambuf* sb = nullptr;
5432 };
5433 #endif // JSON_NO_IO
5434 
5435 // General-purpose iterator-based adapter. It might not be as fast as
5436 // theoretically possible for some containers, but it is extremely versatile.
5437 template<typename IteratorType>
5438 class iterator_input_adapter
5439 {
5440  public:
5441  using char_type = typename std::iterator_traits<IteratorType>::value_type;
5442 
5443  iterator_input_adapter(IteratorType first, IteratorType last)
5444  : current(std::move(first)), end(std::move(last))
5445  {}
5446 
5447  typename std::char_traits<char_type>::int_type get_character()
5448  {
5449  if (JSON_HEDLEY_LIKELY(current != end))
5450  {
5451  auto result = std::char_traits<char_type>::to_int_type(*current);
5452  std::advance(current, 1);
5453  return result;
5454  }
5455 
5456  return std::char_traits<char_type>::eof();
5457  }
5458 
5459  private:
5460  IteratorType current;
5461  IteratorType end;
5462 
5463  template<typename BaseInputAdapter, size_t T>
5464  friend struct wide_string_input_helper;
5465 
5466  bool empty() const
5467  {
5468  return current == end;
5469  }
5470 };
5471 
5472 
5473 template<typename BaseInputAdapter, size_t T>
5474 struct wide_string_input_helper;
5475 
5476 template<typename BaseInputAdapter>
5477 struct wide_string_input_helper<BaseInputAdapter, 4>
5478 {
5479  // UTF-32
5480  static void fill_buffer(BaseInputAdapter& input,
5481  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5482  size_t& utf8_bytes_index,
5483  size_t& utf8_bytes_filled)
5484  {
5485  utf8_bytes_index = 0;
5486 
5487  if (JSON_HEDLEY_UNLIKELY(input.empty()))
5488  {
5489  utf8_bytes[0] = std::char_traits<char>::eof();
5490  utf8_bytes_filled = 1;
5491  }
5492  else
5493  {
5494  // get the current character
5495  const auto wc = input.get_character();
5496 
5497  // UTF-32 to UTF-8 encoding
5498  if (wc < 0x80)
5499  {
5500  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5501  utf8_bytes_filled = 1;
5502  }
5503  else if (wc <= 0x7FF)
5504  {
5505  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
5506  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5507  utf8_bytes_filled = 2;
5508  }
5509  else if (wc <= 0xFFFF)
5510  {
5511  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
5512  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5513  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5514  utf8_bytes_filled = 3;
5515  }
5516  else if (wc <= 0x10FFFF)
5517  {
5518  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
5519  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
5520  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5521  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5522  utf8_bytes_filled = 4;
5523  }
5524  else
5525  {
5526  // unknown character
5527  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5528  utf8_bytes_filled = 1;
5529  }
5530  }
5531  }
5532 };
5533 
5534 template<typename BaseInputAdapter>
5535 struct wide_string_input_helper<BaseInputAdapter, 2>
5536 {
5537  // UTF-16
5538  static void fill_buffer(BaseInputAdapter& input,
5539  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5540  size_t& utf8_bytes_index,
5541  size_t& utf8_bytes_filled)
5542  {
5543  utf8_bytes_index = 0;
5544 
5545  if (JSON_HEDLEY_UNLIKELY(input.empty()))
5546  {
5547  utf8_bytes[0] = std::char_traits<char>::eof();
5548  utf8_bytes_filled = 1;
5549  }
5550  else
5551  {
5552  // get the current character
5553  const auto wc = input.get_character();
5554 
5555  // UTF-16 to UTF-8 encoding
5556  if (wc < 0x80)
5557  {
5558  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5559  utf8_bytes_filled = 1;
5560  }
5561  else if (wc <= 0x7FF)
5562  {
5563  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5564  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5565  utf8_bytes_filled = 2;
5566  }
5567  else if (0xD800 > wc || wc >= 0xE000)
5568  {
5569  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5570  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5571  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5572  utf8_bytes_filled = 3;
5573  }
5574  else
5575  {
5576  if (JSON_HEDLEY_UNLIKELY(!input.empty()))
5577  {
5578  const auto wc2 = static_cast<unsigned int>(input.get_character());
5579  const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
5580  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
5581  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
5582  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
5583  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
5584  utf8_bytes_filled = 4;
5585  }
5586  else
5587  {
5588  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5589  utf8_bytes_filled = 1;
5590  }
5591  }
5592  }
5593  }
5594 };
5595 
5596 // Wraps another input apdater to convert wide character types into individual bytes.
5597 template<typename BaseInputAdapter, typename WideCharType>
5598 class wide_string_input_adapter
5599 {
5600  public:
5601  using char_type = char;
5602 
5603  wide_string_input_adapter(BaseInputAdapter base)
5604  : base_adapter(base) {}
5605 
5606  typename std::char_traits<char>::int_type get_character() noexcept
5607  {
5608  // check if buffer needs to be filled
5609  if (utf8_bytes_index == utf8_bytes_filled)
5610  {
5611  fill_buffer<sizeof(WideCharType)>();
5612 
5613  JSON_ASSERT(utf8_bytes_filled > 0);
5614  JSON_ASSERT(utf8_bytes_index == 0);
5615  }
5616 
5617  // use buffer
5618  JSON_ASSERT(utf8_bytes_filled > 0);
5619  JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
5620  return utf8_bytes[utf8_bytes_index++];
5621  }
5622 
5623  private:
5624  BaseInputAdapter base_adapter;
5625 
5626  template<size_t T>
5627  void fill_buffer()
5628  {
5629  wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
5630  }
5631 
5633  std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5634 
5636  std::size_t utf8_bytes_index = 0;
5638  std::size_t utf8_bytes_filled = 0;
5639 };
5640 
5641 
5642 template<typename IteratorType, typename Enable = void>
5643 struct iterator_input_adapter_factory
5644 {
5645  using iterator_type = IteratorType;
5646  using char_type = typename std::iterator_traits<iterator_type>::value_type;
5647  using adapter_type = iterator_input_adapter<iterator_type>;
5648 
5649  static adapter_type create(IteratorType first, IteratorType last)
5650  {
5651  return adapter_type(std::move(first), std::move(last));
5652  }
5653 };
5654 
5655 template<typename T>
5656 struct is_iterator_of_multibyte
5657 {
5658  using value_type = typename std::iterator_traits<T>::value_type;
5659  enum
5660  {
5661  value = sizeof(value_type) > 1
5662  };
5663 };
5664 
5665 template<typename IteratorType>
5666 struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
5667 {
5668  using iterator_type = IteratorType;
5669  using char_type = typename std::iterator_traits<iterator_type>::value_type;
5670  using base_adapter_type = iterator_input_adapter<iterator_type>;
5671  using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
5672 
5673  static adapter_type create(IteratorType first, IteratorType last)
5674  {
5675  return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5676  }
5677 };
5678 
5679 // General purpose iterator-based input
5680 template<typename IteratorType>
5681 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
5682 {
5683  using factory_type = iterator_input_adapter_factory<IteratorType>;
5684  return factory_type::create(first, last);
5685 }
5686 
5687 // Convenience shorthand from container to iterator
5688 // Enables ADL on begin(container) and end(container)
5689 // Encloses the using declarations in namespace for not to leak them to outside scope
5690 
5691 namespace container_input_adapter_factory_impl
5692 {
5693 
5694 using std::begin;
5695 using std::end;
5696 
5697 template<typename ContainerType, typename Enable = void>
5698 struct container_input_adapter_factory {};
5699 
5700 template<typename ContainerType>
5701 struct container_input_adapter_factory< ContainerType,
5702  void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
5703  {
5704  using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
5705 
5706  static adapter_type create(const ContainerType& container)
5707 {
5708  return input_adapter(begin(container), end(container));
5709 }
5710  };
5711 
5712 } // namespace container_input_adapter_factory_impl
5713 
5714 template<typename ContainerType>
5715 typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)
5716 {
5717  return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);
5718 }
5719 
5720 #ifndef JSON_NO_IO
5721 // Special cases with fast paths
5722 inline file_input_adapter input_adapter(std::FILE* file)
5723 {
5724  return file_input_adapter(file);
5725 }
5726 
5727 inline input_stream_adapter input_adapter(std::istream& stream)
5728 {
5729  return input_stream_adapter(stream);
5730 }
5731 
5732 inline input_stream_adapter input_adapter(std::istream&& stream)
5733 {
5734  return input_stream_adapter(stream);
5735 }
5736 #endif // JSON_NO_IO
5737 
5738 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5739 
5740 // Null-delimited strings, and the like.
5741 template < typename CharT,
5742  typename std::enable_if <
5743  std::is_pointer<CharT>::value&&
5744  !std::is_array<CharT>::value&&
5745  std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5746  sizeof(typename std::remove_pointer<CharT>::type) == 1,
5747  int >::type = 0 >
5748 contiguous_bytes_input_adapter input_adapter(CharT b)
5749 {
5750  auto length = std::strlen(reinterpret_cast<const char*>(b));
5751  const auto* ptr = reinterpret_cast<const char*>(b);
5752  return input_adapter(ptr, ptr + length);
5753 }
5754 
5755 template<typename T, std::size_t N>
5756 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)
5757 {
5758  return input_adapter(array, array + N);
5759 }
5760 
5761 // This class only handles inputs of input_buffer_adapter type.
5762 // It's required so that expressions like {ptr, len} can be implicitely casted
5763 // to the correct adapter.
5764 class span_input_adapter
5765 {
5766  public:
5767  template < typename CharT,
5768  typename std::enable_if <
5769  std::is_pointer<CharT>::value&&
5770  std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5771  sizeof(typename std::remove_pointer<CharT>::type) == 1,
5772  int >::type = 0 >
5773  span_input_adapter(CharT b, std::size_t l)
5774  : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5775 
5776  template<class IteratorType,
5777  typename std::enable_if<
5778  std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5779  int>::type = 0>
5780  span_input_adapter(IteratorType first, IteratorType last)
5781  : ia(input_adapter(first, last)) {}
5782 
5783  contiguous_bytes_input_adapter&& get()
5784  {
5785  return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
5786  }
5787 
5788  private:
5789  contiguous_bytes_input_adapter ia;
5790 };
5791 } // namespace detail
5792 } // namespace nlohmann
5793 
5794 // #include <nlohmann/detail/input/json_sax.hpp>
5795 
5796 
5797 #include <cstddef>
5798 #include <string> // string
5799 #include <utility> // move
5800 #include <vector> // vector
5801 
5802 // #include <nlohmann/detail/exceptions.hpp>
5803 
5804 // #include <nlohmann/detail/macro_scope.hpp>
5805 
5806 
5807 namespace nlohmann
5808 {
5809 
5818 template<typename BasicJsonType>
5819 struct json_sax
5820 {
5821  using number_integer_t = typename BasicJsonType::number_integer_t;
5822  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5823  using number_float_t = typename BasicJsonType::number_float_t;
5824  using string_t = typename BasicJsonType::string_t;
5825  using binary_t = typename BasicJsonType::binary_t;
5826 
5831  virtual bool null() = 0;
5832 
5838  virtual bool boolean(bool val) = 0;
5839 
5845  virtual bool number_integer(number_integer_t val) = 0;
5846 
5852  virtual bool number_unsigned(number_unsigned_t val) = 0;
5853 
5860  virtual bool number_float(number_float_t val, const string_t& s) = 0;
5861 
5868  virtual bool string(string_t& val) = 0;
5869 
5876  virtual bool binary(binary_t& val) = 0;
5877 
5884  virtual bool start_object(std::size_t elements) = 0;
5885 
5892  virtual bool key(string_t& val) = 0;
5893 
5898  virtual bool end_object() = 0;
5899 
5906  virtual bool start_array(std::size_t elements) = 0;
5907 
5912  virtual bool end_array() = 0;
5913 
5921  virtual bool parse_error(std::size_t position,
5922  const std::string& last_token,
5923  const detail::exception& ex) = 0;
5924 
5925  json_sax() = default;
5926  json_sax(const json_sax&) = default;
5927  json_sax(json_sax&&) noexcept = default;
5928  json_sax& operator=(const json_sax&) = default;
5929  json_sax& operator=(json_sax&&) noexcept = default;
5930  virtual ~json_sax() = default;
5931 };
5932 
5933 
5934 namespace detail
5935 {
5949 template<typename BasicJsonType>
5950 class json_sax_dom_parser
5951 {
5952  public:
5953  using number_integer_t = typename BasicJsonType::number_integer_t;
5954  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5955  using number_float_t = typename BasicJsonType::number_float_t;
5956  using string_t = typename BasicJsonType::string_t;
5957  using binary_t = typename BasicJsonType::binary_t;
5958 
5964  explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
5965  : root(r), allow_exceptions(allow_exceptions_)
5966  {}
5967 
5968  // make class move-only
5969  json_sax_dom_parser(const json_sax_dom_parser&) = delete;
5970  json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
5971  json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
5972  json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
5973  ~json_sax_dom_parser() = default;
5974 
5975  bool null()
5976  {
5977  handle_value(nullptr);
5978  return true;
5979  }
5980 
5981  bool boolean(bool val)
5982  {
5983  handle_value(val);
5984  return true;
5985  }
5986 
5988  {
5989  handle_value(val);
5990  return true;
5991  }
5992 
5994  {
5995  handle_value(val);
5996  return true;
5997  }
5998 
5999  bool number_float(number_float_t val, const string_t& /*unused*/)
6000  {
6001  handle_value(val);
6002  return true;
6003  }
6004 
6005  bool string(string_t& val)
6006  {
6007  handle_value(val);
6008  return true;
6009  }
6010 
6011  bool binary(binary_t& val)
6012  {
6013  handle_value(std::move(val));
6014  return true;
6015  }
6016 
6017  bool start_object(std::size_t len)
6018  {
6019  ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6020 
6021  if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6022  {
6023  JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6024  }
6025 
6026  return true;
6027  }
6028 
6029  bool key(string_t& val)
6030  {
6031  // add null at given key and store the reference for later
6032  object_element = &(ref_stack.back()->m_value.object->operator[](val));
6033  return true;
6034  }
6035 
6036  bool end_object()
6037  {
6038  ref_stack.back()->set_parents();
6039  ref_stack.pop_back();
6040  return true;
6041  }
6042 
6043  bool start_array(std::size_t len)
6044  {
6045  ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6046 
6047  if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6048  {
6049  JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6050  }
6051 
6052  return true;
6053  }
6054 
6055  bool end_array()
6056  {
6057  ref_stack.back()->set_parents();
6058  ref_stack.pop_back();
6059  return true;
6060  }
6061 
6062  template<class Exception>
6063  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6064  const Exception& ex)
6065  {
6066  errored = true;
6067  static_cast<void>(ex);
6068  if (allow_exceptions)
6069  {
6070  JSON_THROW(ex);
6071  }
6072  return false;
6073  }
6074 
6075  constexpr bool is_errored() const
6076  {
6077  return errored;
6078  }
6079 
6080  private:
6087  template<typename Value>
6088 
6089  BasicJsonType* handle_value(Value&& v)
6090  {
6091  if (ref_stack.empty())
6092  {
6093  root = BasicJsonType(std::forward<Value>(v));
6094  return &root;
6095  }
6096 
6097  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6098 
6099  if (ref_stack.back()->is_array())
6100  {
6101  ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6102  return &(ref_stack.back()->m_value.array->back());
6103  }
6104 
6105  JSON_ASSERT(ref_stack.back()->is_object());
6106  JSON_ASSERT(object_element);
6107  *object_element = BasicJsonType(std::forward<Value>(v));
6108  return object_element;
6109  }
6110 
6112  BasicJsonType& root;
6114  std::vector<BasicJsonType*> ref_stack {};
6116  BasicJsonType* object_element = nullptr;
6118  bool errored = false;
6120  const bool allow_exceptions = true;
6121 };
6122 
6123 template<typename BasicJsonType>
6124 class json_sax_dom_callback_parser
6125 {
6126  public:
6127  using number_integer_t = typename BasicJsonType::number_integer_t;
6128  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6129  using number_float_t = typename BasicJsonType::number_float_t;
6130  using string_t = typename BasicJsonType::string_t;
6131  using binary_t = typename BasicJsonType::binary_t;
6132  using parser_callback_t = typename BasicJsonType::parser_callback_t;
6133  using parse_event_t = typename BasicJsonType::parse_event_t;
6134 
6135  json_sax_dom_callback_parser(BasicJsonType& r,
6136  const parser_callback_t cb,
6137  const bool allow_exceptions_ = true)
6138  : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6139  {
6140  keep_stack.push_back(true);
6141  }
6142 
6143  // make class move-only
6144  json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
6145  json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6146  json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
6147  json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6148  ~json_sax_dom_callback_parser() = default;
6149 
6150  bool null()
6151  {
6152  handle_value(nullptr);
6153  return true;
6154  }
6155 
6156  bool boolean(bool val)
6157  {
6158  handle_value(val);
6159  return true;
6160  }
6161 
6163  {
6164  handle_value(val);
6165  return true;
6166  }
6167 
6169  {
6170  handle_value(val);
6171  return true;
6172  }
6173 
6174  bool number_float(number_float_t val, const string_t& /*unused*/)
6175  {
6176  handle_value(val);
6177  return true;
6178  }
6179 
6180  bool string(string_t& val)
6181  {
6182  handle_value(val);
6183  return true;
6184  }
6185 
6186  bool binary(binary_t& val)
6187  {
6188  handle_value(std::move(val));
6189  return true;
6190  }
6191 
6192  bool start_object(std::size_t len)
6193  {
6194  // check callback for object start
6195  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6196  keep_stack.push_back(keep);
6197 
6198  auto val = handle_value(BasicJsonType::value_t::object, true);
6199  ref_stack.push_back(val.second);
6200 
6201  // check object limit
6202  if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6203  {
6204  JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6205  }
6206 
6207  return true;
6208  }
6209 
6210  bool key(string_t& val)
6211  {
6212  BasicJsonType k = BasicJsonType(val);
6213 
6214  // check callback for key
6215  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
6216  key_keep_stack.push_back(keep);
6217 
6218  // add discarded value at given key and store the reference for later
6219  if (keep && ref_stack.back())
6220  {
6221  object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
6222  }
6223 
6224  return true;
6225  }
6226 
6227  bool end_object()
6228  {
6229  if (ref_stack.back())
6230  {
6231  if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
6232  {
6233  // discard object
6234  *ref_stack.back() = discarded;
6235  }
6236  else
6237  {
6238  ref_stack.back()->set_parents();
6239  }
6240  }
6241 
6242  JSON_ASSERT(!ref_stack.empty());
6243  JSON_ASSERT(!keep_stack.empty());
6244  ref_stack.pop_back();
6245  keep_stack.pop_back();
6246 
6247  if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
6248  {
6249  // remove discarded value
6250  for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
6251  {
6252  if (it->is_discarded())
6253  {
6254  ref_stack.back()->erase(it);
6255  break;
6256  }
6257  }
6258  }
6259 
6260  return true;
6261  }
6262 
6263  bool start_array(std::size_t len)
6264  {
6265  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
6266  keep_stack.push_back(keep);
6267 
6268  auto val = handle_value(BasicJsonType::value_t::array, true);
6269  ref_stack.push_back(val.second);
6270 
6271  // check array limit
6272  if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6273  {
6274  JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6275  }
6276 
6277  return true;
6278  }
6279 
6280  bool end_array()
6281  {
6282  bool keep = true;
6283 
6284  if (ref_stack.back())
6285  {
6286  keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
6287  if (keep)
6288  {
6289  ref_stack.back()->set_parents();
6290  }
6291  else
6292  {
6293  // discard array
6294  *ref_stack.back() = discarded;
6295  }
6296  }
6297 
6298  JSON_ASSERT(!ref_stack.empty());
6299  JSON_ASSERT(!keep_stack.empty());
6300  ref_stack.pop_back();
6301  keep_stack.pop_back();
6302 
6303  // remove discarded value
6304  if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
6305  {
6306  ref_stack.back()->m_value.array->pop_back();
6307  }
6308 
6309  return true;
6310  }
6311 
6312  template<class Exception>
6313  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6314  const Exception& ex)
6315  {
6316  errored = true;
6317  static_cast<void>(ex);
6318  if (allow_exceptions)
6319  {
6320  JSON_THROW(ex);
6321  }
6322  return false;
6323  }
6324 
6325  constexpr bool is_errored() const
6326  {
6327  return errored;
6328  }
6329 
6330  private:
6346  template<typename Value>
6347  std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
6348  {
6349  JSON_ASSERT(!keep_stack.empty());
6350 
6351  // do not handle this value if we know it would be added to a discarded
6352  // container
6353  if (!keep_stack.back())
6354  {
6355  return {false, nullptr};
6356  }
6357 
6358  // create value
6359  auto value = BasicJsonType(std::forward<Value>(v));
6360 
6361  // check callback
6362  const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
6363 
6364  // do not handle this value if we just learnt it shall be discarded
6365  if (!keep)
6366  {
6367  return {false, nullptr};
6368  }
6369 
6370  if (ref_stack.empty())
6371  {
6372  root = std::move(value);
6373  return {true, &root};
6374  }
6375 
6376  // skip this value if we already decided to skip the parent
6377  // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
6378  if (!ref_stack.back())
6379  {
6380  return {false, nullptr};
6381  }
6382 
6383  // we now only expect arrays and objects
6384  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6385 
6386  // array
6387  if (ref_stack.back()->is_array())
6388  {
6389  ref_stack.back()->m_value.array->emplace_back(std::move(value));
6390  return {true, &(ref_stack.back()->m_value.array->back())};
6391  }
6392 
6393  // object
6394  JSON_ASSERT(ref_stack.back()->is_object());
6395  // check if we should store an element for the current key
6396  JSON_ASSERT(!key_keep_stack.empty());
6397  const bool store_element = key_keep_stack.back();
6398  key_keep_stack.pop_back();
6399 
6400  if (!store_element)
6401  {
6402  return {false, nullptr};
6403  }
6404 
6405  JSON_ASSERT(object_element);
6406  *object_element = std::move(value);
6407  return {true, object_element};
6408  }
6409 
6411  BasicJsonType& root;
6413  std::vector<BasicJsonType*> ref_stack {};
6415  std::vector<bool> keep_stack {};
6417  std::vector<bool> key_keep_stack {};
6419  BasicJsonType* object_element = nullptr;
6421  bool errored = false;
6423  const parser_callback_t callback = nullptr;
6425  const bool allow_exceptions = true;
6427  BasicJsonType discarded = BasicJsonType::value_t::discarded;
6428 };
6429 
6430 template<typename BasicJsonType>
6431 class json_sax_acceptor
6432 {
6433  public:
6434  using number_integer_t = typename BasicJsonType::number_integer_t;
6435  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6436  using number_float_t = typename BasicJsonType::number_float_t;
6437  using string_t = typename BasicJsonType::string_t;
6438  using binary_t = typename BasicJsonType::binary_t;
6439 
6440  bool null()
6441  {
6442  return true;
6443  }
6444 
6445  bool boolean(bool /*unused*/)
6446  {
6447  return true;
6448  }
6449 
6450  bool number_integer(number_integer_t /*unused*/)
6451  {
6452  return true;
6453  }
6454 
6455  bool number_unsigned(number_unsigned_t /*unused*/)
6456  {
6457  return true;
6458  }
6459 
6460  bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
6461  {
6462  return true;
6463  }
6464 
6465  bool string(string_t& /*unused*/)
6466  {
6467  return true;
6468  }
6469 
6470  bool binary(binary_t& /*unused*/)
6471  {
6472  return true;
6473  }
6474 
6475  bool start_object(std::size_t /*unused*/ = std::size_t(-1))
6476  {
6477  return true;
6478  }
6479 
6480  bool key(string_t& /*unused*/)
6481  {
6482  return true;
6483  }
6484 
6485  bool end_object()
6486  {
6487  return true;
6488  }
6489 
6490  bool start_array(std::size_t /*unused*/ = std::size_t(-1))
6491  {
6492  return true;
6493  }
6494 
6495  bool end_array()
6496  {
6497  return true;
6498  }
6499 
6500  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
6501  {
6502  return false;
6503  }
6504 };
6505 } // namespace detail
6506 
6507 } // namespace nlohmann
6508 
6509 // #include <nlohmann/detail/input/lexer.hpp>
6510 
6511 
6512 #include <array> // array
6513 #include <clocale> // localeconv
6514 #include <cstddef> // size_t
6515 #include <cstdio> // snprintf
6516 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
6517 #include <initializer_list> // initializer_list
6518 #include <string> // char_traits, string
6519 #include <utility> // move
6520 #include <vector> // vector
6521 
6522 // #include <nlohmann/detail/input/input_adapters.hpp>
6523 
6524 // #include <nlohmann/detail/input/position_t.hpp>
6525 
6526 // #include <nlohmann/detail/macro_scope.hpp>
6527 
6528 
6529 namespace nlohmann
6530 {
6531 namespace detail
6532 {
6534 // lexer //
6536 
6537 template<typename BasicJsonType>
6538 class lexer_base
6539 {
6540  public:
6542  enum class token_type
6543  {
6544  uninitialized,
6545  literal_true,
6546  literal_false,
6547  literal_null,
6548  value_string,
6549  value_unsigned,
6550  value_integer,
6551  value_float,
6552  begin_array,
6553  begin_object,
6554  end_array,
6555  end_object,
6556  name_separator,
6557  value_separator,
6558  parse_error,
6559  end_of_input,
6560  literal_or_value
6561  };
6562 
6564 
6565  JSON_HEDLEY_CONST
6566  static const char* token_type_name(const token_type t) noexcept
6567  {
6568  switch (t)
6569  {
6570  case token_type::uninitialized:
6571  return "<uninitialized>";
6572  case token_type::literal_true:
6573  return "true literal";
6574  case token_type::literal_false:
6575  return "false literal";
6576  case token_type::literal_null:
6577  return "null literal";
6578  case token_type::value_string:
6579  return "string literal";
6580  case token_type::value_unsigned:
6581  case token_type::value_integer:
6582  case token_type::value_float:
6583  return "number literal";
6584  case token_type::begin_array:
6585  return "'['";
6586  case token_type::begin_object:
6587  return "'{'";
6588  case token_type::end_array:
6589  return "']'";
6590  case token_type::end_object:
6591  return "'}'";
6592  case token_type::name_separator:
6593  return "':'";
6594  case token_type::value_separator:
6595  return "','";
6596  case token_type::parse_error:
6597  return "<parse error>";
6598  case token_type::end_of_input:
6599  return "end of input";
6600  case token_type::literal_or_value:
6601  return "'[', '{', or a literal";
6602  // LCOV_EXCL_START
6603  default: // catch non-enum values
6604  return "unknown token";
6605  // LCOV_EXCL_STOP
6606  }
6607  }
6608 };
6614 template<typename BasicJsonType, typename InputAdapterType>
6615 class lexer : public lexer_base<BasicJsonType>
6616 {
6617  using number_integer_t = typename BasicJsonType::number_integer_t;
6618  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6619  using number_float_t = typename BasicJsonType::number_float_t;
6620  using string_t = typename BasicJsonType::string_t;
6621  using char_type = typename InputAdapterType::char_type;
6622  using char_int_type = typename std::char_traits<char_type>::int_type;
6623 
6624  public:
6625  using token_type = typename lexer_base<BasicJsonType>::token_type;
6626 
6627  explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
6628  : ia(std::move(adapter))
6629  , ignore_comments(ignore_comments_)
6630  , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
6631  {}
6632 
6633  // delete because of pointer members
6634  lexer(const lexer&) = delete;
6635  lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6636  lexer& operator=(lexer&) = delete;
6637  lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6638  ~lexer() = default;
6639 
6640  private:
6642  // locales
6644 
6646  JSON_HEDLEY_PURE
6647  static char get_decimal_point() noexcept
6648  {
6649  const auto* loc = localeconv();
6650  JSON_ASSERT(loc != nullptr);
6651  return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6652  }
6653 
6655  // scan functions
6657 
6673  int get_codepoint()
6674  {
6675  // this function only makes sense after reading `\u`
6676  JSON_ASSERT(current == 'u');
6677  int codepoint = 0;
6678 
6679  const auto factors = { 12u, 8u, 4u, 0u };
6680  for (const auto factor : factors)
6681  {
6682  get();
6683 
6684  if (current >= '0' && current <= '9')
6685  {
6686  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6687  }
6688  else if (current >= 'A' && current <= 'F')
6689  {
6690  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6691  }
6692  else if (current >= 'a' && current <= 'f')
6693  {
6694  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6695  }
6696  else
6697  {
6698  return -1;
6699  }
6700  }
6701 
6702  JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6703  return codepoint;
6704  }
6705 
6721  bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6722  {
6723  JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6724  add(current);
6725 
6726  for (auto range = ranges.begin(); range != ranges.end(); ++range)
6727  {
6728  get();
6729  if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6730  {
6731  add(current);
6732  }
6733  else
6734  {
6735  error_message = "invalid string: ill-formed UTF-8 byte";
6736  return false;
6737  }
6738  }
6739 
6740  return true;
6741  }
6742 
6758  token_type scan_string()
6759  {
6760  // reset token_buffer (ignore opening quote)
6761  reset();
6762 
6763  // we entered the function by reading an open quote
6764  JSON_ASSERT(current == '\"');
6765 
6766  while (true)
6767  {
6768  // get next character
6769  switch (get())
6770  {
6771  // end of file while parsing string
6772  case std::char_traits<char_type>::eof():
6773  {
6774  error_message = "invalid string: missing closing quote";
6775  return token_type::parse_error;
6776  }
6777 
6778  // closing quote
6779  case '\"':
6780  {
6781  return token_type::value_string;
6782  }
6783 
6784  // escapes
6785  case '\\':
6786  {
6787  switch (get())
6788  {
6789  // quotation mark
6790  case '\"':
6791  add('\"');
6792  break;
6793  // reverse solidus
6794  case '\\':
6795  add('\\');
6796  break;
6797  // solidus
6798  case '/':
6799  add('/');
6800  break;
6801  // backspace
6802  case 'b':
6803  add('\b');
6804  break;
6805  // form feed
6806  case 'f':
6807  add('\f');
6808  break;
6809  // line feed
6810  case 'n':
6811  add('\n');
6812  break;
6813  // carriage return
6814  case 'r':
6815  add('\r');
6816  break;
6817  // tab
6818  case 't':
6819  add('\t');
6820  break;
6821 
6822  // unicode escapes
6823  case 'u':
6824  {
6825  const int codepoint1 = get_codepoint();
6826  int codepoint = codepoint1; // start with codepoint1
6827 
6828  if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
6829  {
6830  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6831  return token_type::parse_error;
6832  }
6833 
6834  // check if code point is a high surrogate
6835  if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6836  {
6837  // expect next \uxxxx entry
6838  if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6839  {
6840  const int codepoint2 = get_codepoint();
6841 
6842  if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
6843  {
6844  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6845  return token_type::parse_error;
6846  }
6847 
6848  // check if codepoint2 is a low surrogate
6849  if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6850  {
6851  // overwrite codepoint
6852  codepoint = static_cast<int>(
6853  // high surrogate occupies the most significant 22 bits
6854  (static_cast<unsigned int>(codepoint1) << 10u)
6855  // low surrogate occupies the least significant 15 bits
6856  + static_cast<unsigned int>(codepoint2)
6857  // there is still the 0xD800, 0xDC00 and 0x10000 noise
6858  // in the result so we have to subtract with:
6859  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6860  - 0x35FDC00u);
6861  }
6862  else
6863  {
6864  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6865  return token_type::parse_error;
6866  }
6867  }
6868  else
6869  {
6870  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6871  return token_type::parse_error;
6872  }
6873  }
6874  else
6875  {
6876  if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6877  {
6878  error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6879  return token_type::parse_error;
6880  }
6881  }
6882 
6883  // result of the above calculation yields a proper codepoint
6884  JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
6885 
6886  // translate codepoint into bytes
6887  if (codepoint < 0x80)
6888  {
6889  // 1-byte characters: 0xxxxxxx (ASCII)
6890  add(static_cast<char_int_type>(codepoint));
6891  }
6892  else if (codepoint <= 0x7FF)
6893  {
6894  // 2-byte characters: 110xxxxx 10xxxxxx
6895  add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
6896  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6897  }
6898  else if (codepoint <= 0xFFFF)
6899  {
6900  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
6901  add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
6902  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6903  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6904  }
6905  else
6906  {
6907  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
6908  add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
6909  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
6910  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6911  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6912  }
6913 
6914  break;
6915  }
6916 
6917  // other characters after escape
6918  default:
6919  error_message = "invalid string: forbidden character after backslash";
6920  return token_type::parse_error;
6921  }
6922 
6923  break;
6924  }
6925 
6926  // invalid control characters
6927  case 0x00:
6928  {
6929  error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
6930  return token_type::parse_error;
6931  }
6932 
6933  case 0x01:
6934  {
6935  error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
6936  return token_type::parse_error;
6937  }
6938 
6939  case 0x02:
6940  {
6941  error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
6942  return token_type::parse_error;
6943  }
6944 
6945  case 0x03:
6946  {
6947  error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
6948  return token_type::parse_error;
6949  }
6950 
6951  case 0x04:
6952  {
6953  error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
6954  return token_type::parse_error;
6955  }
6956 
6957  case 0x05:
6958  {
6959  error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
6960  return token_type::parse_error;
6961  }
6962 
6963  case 0x06:
6964  {
6965  error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
6966  return token_type::parse_error;
6967  }
6968 
6969  case 0x07:
6970  {
6971  error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
6972  return token_type::parse_error;
6973  }
6974 
6975  case 0x08:
6976  {
6977  error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
6978  return token_type::parse_error;
6979  }
6980 
6981  case 0x09:
6982  {
6983  error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
6984  return token_type::parse_error;
6985  }
6986 
6987  case 0x0A:
6988  {
6989  error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
6990  return token_type::parse_error;
6991  }
6992 
6993  case 0x0B:
6994  {
6995  error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
6996  return token_type::parse_error;
6997  }
6998 
6999  case 0x0C:
7000  {
7001  error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7002  return token_type::parse_error;
7003  }
7004 
7005  case 0x0D:
7006  {
7007  error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7008  return token_type::parse_error;
7009  }
7010 
7011  case 0x0E:
7012  {
7013  error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7014  return token_type::parse_error;
7015  }
7016 
7017  case 0x0F:
7018  {
7019  error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7020  return token_type::parse_error;
7021  }
7022 
7023  case 0x10:
7024  {
7025  error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7026  return token_type::parse_error;
7027  }
7028 
7029  case 0x11:
7030  {
7031  error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7032  return token_type::parse_error;
7033  }
7034 
7035  case 0x12:
7036  {
7037  error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7038  return token_type::parse_error;
7039  }
7040 
7041  case 0x13:
7042  {
7043  error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7044  return token_type::parse_error;
7045  }
7046 
7047  case 0x14:
7048  {
7049  error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7050  return token_type::parse_error;
7051  }
7052 
7053  case 0x15:
7054  {
7055  error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7056  return token_type::parse_error;
7057  }
7058 
7059  case 0x16:
7060  {
7061  error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7062  return token_type::parse_error;
7063  }
7064 
7065  case 0x17:
7066  {
7067  error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7068  return token_type::parse_error;
7069  }
7070 
7071  case 0x18:
7072  {
7073  error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7074  return token_type::parse_error;
7075  }
7076 
7077  case 0x19:
7078  {
7079  error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7080  return token_type::parse_error;
7081  }
7082 
7083  case 0x1A:
7084  {
7085  error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7086  return token_type::parse_error;
7087  }
7088 
7089  case 0x1B:
7090  {
7091  error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7092  return token_type::parse_error;
7093  }
7094 
7095  case 0x1C:
7096  {
7097  error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7098  return token_type::parse_error;
7099  }
7100 
7101  case 0x1D:
7102  {
7103  error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7104  return token_type::parse_error;
7105  }
7106 
7107  case 0x1E:
7108  {
7109  error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7110  return token_type::parse_error;
7111  }
7112 
7113  case 0x1F:
7114  {
7115  error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7116  return token_type::parse_error;
7117  }
7118 
7119  // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7120  case 0x20:
7121  case 0x21:
7122  case 0x23:
7123  case 0x24:
7124  case 0x25:
7125  case 0x26:
7126  case 0x27:
7127  case 0x28:
7128  case 0x29:
7129  case 0x2A:
7130  case 0x2B:
7131  case 0x2C:
7132  case 0x2D:
7133  case 0x2E:
7134  case 0x2F:
7135  case 0x30:
7136  case 0x31:
7137  case 0x32:
7138  case 0x33:
7139  case 0x34:
7140  case 0x35:
7141  case 0x36:
7142  case 0x37:
7143  case 0x38:
7144  case 0x39:
7145  case 0x3A:
7146  case 0x3B:
7147  case 0x3C:
7148  case 0x3D:
7149  case 0x3E:
7150  case 0x3F:
7151  case 0x40:
7152  case 0x41:
7153  case 0x42:
7154  case 0x43:
7155  case 0x44:
7156  case 0x45:
7157  case 0x46:
7158  case 0x47:
7159  case 0x48:
7160  case 0x49:
7161  case 0x4A:
7162  case 0x4B:
7163  case 0x4C:
7164  case 0x4D:
7165  case 0x4E:
7166  case 0x4F:
7167  case 0x50:
7168  case 0x51:
7169  case 0x52:
7170  case 0x53:
7171  case 0x54:
7172  case 0x55:
7173  case 0x56:
7174  case 0x57:
7175  case 0x58:
7176  case 0x59:
7177  case 0x5A:
7178  case 0x5B:
7179  case 0x5D:
7180  case 0x5E:
7181  case 0x5F:
7182  case 0x60:
7183  case 0x61:
7184  case 0x62:
7185  case 0x63:
7186  case 0x64:
7187  case 0x65:
7188  case 0x66:
7189  case 0x67:
7190  case 0x68:
7191  case 0x69:
7192  case 0x6A:
7193  case 0x6B:
7194  case 0x6C:
7195  case 0x6D:
7196  case 0x6E:
7197  case 0x6F:
7198  case 0x70:
7199  case 0x71:
7200  case 0x72:
7201  case 0x73:
7202  case 0x74:
7203  case 0x75:
7204  case 0x76:
7205  case 0x77:
7206  case 0x78:
7207  case 0x79:
7208  case 0x7A:
7209  case 0x7B:
7210  case 0x7C:
7211  case 0x7D:
7212  case 0x7E:
7213  case 0x7F:
7214  {
7215  add(current);
7216  break;
7217  }
7218 
7219  // U+0080..U+07FF: bytes C2..DF 80..BF
7220  case 0xC2:
7221  case 0xC3:
7222  case 0xC4:
7223  case 0xC5:
7224  case 0xC6:
7225  case 0xC7:
7226  case 0xC8:
7227  case 0xC9:
7228  case 0xCA:
7229  case 0xCB:
7230  case 0xCC:
7231  case 0xCD:
7232  case 0xCE:
7233  case 0xCF:
7234  case 0xD0:
7235  case 0xD1:
7236  case 0xD2:
7237  case 0xD3:
7238  case 0xD4:
7239  case 0xD5:
7240  case 0xD6:
7241  case 0xD7:
7242  case 0xD8:
7243  case 0xD9:
7244  case 0xDA:
7245  case 0xDB:
7246  case 0xDC:
7247  case 0xDD:
7248  case 0xDE:
7249  case 0xDF:
7250  {
7251  if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
7252  {
7253  return token_type::parse_error;
7254  }
7255  break;
7256  }
7257 
7258  // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7259  case 0xE0:
7260  {
7261  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7262  {
7263  return token_type::parse_error;
7264  }
7265  break;
7266  }
7267 
7268  // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7269  // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7270  case 0xE1:
7271  case 0xE2:
7272  case 0xE3:
7273  case 0xE4:
7274  case 0xE5:
7275  case 0xE6:
7276  case 0xE7:
7277  case 0xE8:
7278  case 0xE9:
7279  case 0xEA:
7280  case 0xEB:
7281  case 0xEC:
7282  case 0xEE:
7283  case 0xEF:
7284  {
7285  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
7286  {
7287  return token_type::parse_error;
7288  }
7289  break;
7290  }
7291 
7292  // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7293  case 0xED:
7294  {
7295  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
7296  {
7297  return token_type::parse_error;
7298  }
7299  break;
7300  }
7301 
7302  // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7303  case 0xF0:
7304  {
7305  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7306  {
7307  return token_type::parse_error;
7308  }
7309  break;
7310  }
7311 
7312  // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7313  case 0xF1:
7314  case 0xF2:
7315  case 0xF3:
7316  {
7317  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7318  {
7319  return token_type::parse_error;
7320  }
7321  break;
7322  }
7323 
7324  // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7325  case 0xF4:
7326  {
7327  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
7328  {
7329  return token_type::parse_error;
7330  }
7331  break;
7332  }
7333 
7334  // remaining bytes (80..C1 and F5..FF) are ill-formed
7335  default:
7336  {
7337  error_message = "invalid string: ill-formed UTF-8 byte";
7338  return token_type::parse_error;
7339  }
7340  }
7341  }
7342  }
7343 
7348  bool scan_comment()
7349  {
7350  switch (get())
7351  {
7352  // single-line comments skip input until a newline or EOF is read
7353  case '/':
7354  {
7355  while (true)
7356  {
7357  switch (get())
7358  {
7359  case '\n':
7360  case '\r':
7361  case std::char_traits<char_type>::eof():
7362  case '\0':
7363  return true;
7364 
7365  default:
7366  break;
7367  }
7368  }
7369  }
7370 
7371  // multi-line comments skip input until */ is read
7372  case '*':
7373  {
7374  while (true)
7375  {
7376  switch (get())
7377  {
7378  case std::char_traits<char_type>::eof():
7379  case '\0':
7380  {
7381  error_message = "invalid comment; missing closing '*/'";
7382  return false;
7383  }
7384 
7385  case '*':
7386  {
7387  switch (get())
7388  {
7389  case '/':
7390  return true;
7391 
7392  default:
7393  {
7394  unget();
7395  continue;
7396  }
7397  }
7398  }
7399 
7400  default:
7401  continue;
7402  }
7403  }
7404  }
7405 
7406  // unexpected character after reading '/'
7407  default:
7408  {
7409  error_message = "invalid comment; expecting '/' or '*' after '/'";
7410  return false;
7411  }
7412  }
7413  }
7414 
7415  JSON_HEDLEY_NON_NULL(2)
7416  static void strtof(float& f, const char* str, char** endptr) noexcept
7417  {
7418  f = std::strtof(str, endptr);
7419  }
7420 
7421  JSON_HEDLEY_NON_NULL(2)
7422  static void strtof(double& f, const char* str, char** endptr) noexcept
7423  {
7424  f = std::strtod(str, endptr);
7425  }
7426 
7427  JSON_HEDLEY_NON_NULL(2)
7428  static void strtof(long double& f, const char* str, char** endptr) noexcept
7429  {
7430  f = std::strtold(str, endptr);
7431  }
7432 
7473  token_type scan_number() // lgtm [cpp/use-of-goto]
7474  {
7475  // reset token_buffer to store the number's bytes
7476  reset();
7477 
7478  // the type of the parsed number; initially set to unsigned; will be
7479  // changed if minus sign, decimal point or exponent is read
7480  token_type number_type = token_type::value_unsigned;
7481 
7482  // state (init): we just found out we need to scan a number
7483  switch (current)
7484  {
7485  case '-':
7486  {
7487  add(current);
7488  goto scan_number_minus;
7489  }
7490 
7491  case '0':
7492  {
7493  add(current);
7494  goto scan_number_zero;
7495  }
7496 
7497  case '1':
7498  case '2':
7499  case '3':
7500  case '4':
7501  case '5':
7502  case '6':
7503  case '7':
7504  case '8':
7505  case '9':
7506  {
7507  add(current);
7508  goto scan_number_any1;
7509  }
7510 
7511  // all other characters are rejected outside scan_number()
7512  default: // LCOV_EXCL_LINE
7513  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
7514  }
7515 
7516 scan_number_minus:
7517  // state: we just parsed a leading minus sign
7518  number_type = token_type::value_integer;
7519  switch (get())
7520  {
7521  case '0':
7522  {
7523  add(current);
7524  goto scan_number_zero;
7525  }
7526 
7527  case '1':
7528  case '2':
7529  case '3':
7530  case '4':
7531  case '5':
7532  case '6':
7533  case '7':
7534  case '8':
7535  case '9':
7536  {
7537  add(current);
7538  goto scan_number_any1;
7539  }
7540 
7541  default:
7542  {
7543  error_message = "invalid number; expected digit after '-'";
7544  return token_type::parse_error;
7545  }
7546  }
7547 
7548 scan_number_zero:
7549  // state: we just parse a zero (maybe with a leading minus sign)
7550  switch (get())
7551  {
7552  case '.':
7553  {
7554  add(decimal_point_char);
7555  goto scan_number_decimal1;
7556  }
7557 
7558  case 'e':
7559  case 'E':
7560  {
7561  add(current);
7562  goto scan_number_exponent;
7563  }
7564 
7565  default:
7566  goto scan_number_done;
7567  }
7568 
7569 scan_number_any1:
7570  // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7571  switch (get())
7572  {
7573  case '0':
7574  case '1':
7575  case '2':
7576  case '3':
7577  case '4':
7578  case '5':
7579  case '6':
7580  case '7':
7581  case '8':
7582  case '9':
7583  {
7584  add(current);
7585  goto scan_number_any1;
7586  }
7587 
7588  case '.':
7589  {
7590  add(decimal_point_char);
7591  goto scan_number_decimal1;
7592  }
7593 
7594  case 'e':
7595  case 'E':
7596  {
7597  add(current);
7598  goto scan_number_exponent;
7599  }
7600 
7601  default:
7602  goto scan_number_done;
7603  }
7604 
7605 scan_number_decimal1:
7606  // state: we just parsed a decimal point
7607  number_type = token_type::value_float;
7608  switch (get())
7609  {
7610  case '0':
7611  case '1':
7612  case '2':
7613  case '3':
7614  case '4':
7615  case '5':
7616  case '6':
7617  case '7':
7618  case '8':
7619  case '9':
7620  {
7621  add(current);
7622  goto scan_number_decimal2;
7623  }
7624 
7625  default:
7626  {
7627  error_message = "invalid number; expected digit after '.'";
7628  return token_type::parse_error;
7629  }
7630  }
7631 
7632 scan_number_decimal2:
7633  // we just parsed at least one number after a decimal point
7634  switch (get())
7635  {
7636  case '0':
7637  case '1':
7638  case '2':
7639  case '3':
7640  case '4':
7641  case '5':
7642  case '6':
7643  case '7':
7644  case '8':
7645  case '9':
7646  {
7647  add(current);
7648  goto scan_number_decimal2;
7649  }
7650 
7651  case 'e':
7652  case 'E':
7653  {
7654  add(current);
7655  goto scan_number_exponent;
7656  }
7657 
7658  default:
7659  goto scan_number_done;
7660  }
7661 
7662 scan_number_exponent:
7663  // we just parsed an exponent
7664  number_type = token_type::value_float;
7665  switch (get())
7666  {
7667  case '+':
7668  case '-':
7669  {
7670  add(current);
7671  goto scan_number_sign;
7672  }
7673 
7674  case '0':
7675  case '1':
7676  case '2':
7677  case '3':
7678  case '4':
7679  case '5':
7680  case '6':
7681  case '7':
7682  case '8':
7683  case '9':
7684  {
7685  add(current);
7686  goto scan_number_any2;
7687  }
7688 
7689  default:
7690  {
7691  error_message =
7692  "invalid number; expected '+', '-', or digit after exponent";
7693  return token_type::parse_error;
7694  }
7695  }
7696 
7697 scan_number_sign:
7698  // we just parsed an exponent sign
7699  switch (get())
7700  {
7701  case '0':
7702  case '1':
7703  case '2':
7704  case '3':
7705  case '4':
7706  case '5':
7707  case '6':
7708  case '7':
7709  case '8':
7710  case '9':
7711  {
7712  add(current);
7713  goto scan_number_any2;
7714  }
7715 
7716  default:
7717  {
7718  error_message = "invalid number; expected digit after exponent sign";
7719  return token_type::parse_error;
7720  }
7721  }
7722 
7723 scan_number_any2:
7724  // we just parsed a number after the exponent or exponent sign
7725  switch (get())
7726  {
7727  case '0':
7728  case '1':
7729  case '2':
7730  case '3':
7731  case '4':
7732  case '5':
7733  case '6':
7734  case '7':
7735  case '8':
7736  case '9':
7737  {
7738  add(current);
7739  goto scan_number_any2;
7740  }
7741 
7742  default:
7743  goto scan_number_done;
7744  }
7745 
7746 scan_number_done:
7747  // unget the character after the number (we only read it to know that
7748  // we are done scanning a number)
7749  unget();
7750 
7751  char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7752  errno = 0;
7753 
7754  // try to parse integers first and fall back to floats
7755  if (number_type == token_type::value_unsigned)
7756  {
7757  const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7758 
7759  // we checked the number format before
7760  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7761 
7762  if (errno == 0)
7763  {
7764  value_unsigned = static_cast<number_unsigned_t>(x);
7765  if (value_unsigned == x)
7766  {
7767  return token_type::value_unsigned;
7768  }
7769  }
7770  }
7771  else if (number_type == token_type::value_integer)
7772  {
7773  const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7774 
7775  // we checked the number format before
7776  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7777 
7778  if (errno == 0)
7779  {
7780  value_integer = static_cast<number_integer_t>(x);
7781  if (value_integer == x)
7782  {
7783  return token_type::value_integer;
7784  }
7785  }
7786  }
7787 
7788  // this code is reached if we parse a floating-point number or if an
7789  // integer conversion above failed
7790  strtof(value_float, token_buffer.data(), &endptr);
7791 
7792  // we checked the number format before
7793  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7794 
7795  return token_type::value_float;
7796  }
7797 
7803  JSON_HEDLEY_NON_NULL(2)
7804  token_type scan_literal(const char_type* literal_text, const std::size_t length,
7805  token_type return_type)
7806  {
7807  JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
7808  for (std::size_t i = 1; i < length; ++i)
7809  {
7810  if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
7811  {
7812  error_message = "invalid literal";
7813  return token_type::parse_error;
7814  }
7815  }
7816  return return_type;
7817  }
7818 
7820  // input management
7822 
7824  void reset() noexcept
7825  {
7826  token_buffer.clear();
7827  token_string.clear();
7828  token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7829  }
7830 
7831  /*
7832  @brief get next character from the input
7833 
7834  This function provides the interface to the used input adapter. It does
7835  not throw in case the input reached EOF, but returns a
7836  `std::char_traits<char>::eof()` in that case. Stores the scanned characters
7837  for use in error messages.
7838 
7839  @return character read from the input
7840  */
7841  char_int_type get()
7842  {
7843  ++position.chars_read_total;
7844  ++position.chars_read_current_line;
7845 
7846  if (next_unget)
7847  {
7848  // just reset the next_unget variable and work with current
7849  next_unget = false;
7850  }
7851  else
7852  {
7853  current = ia.get_character();
7854  }
7855 
7856  if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7857  {
7858  token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7859  }
7860 
7861  if (current == '\n')
7862  {
7863  ++position.lines_read;
7864  position.chars_read_current_line = 0;
7865  }
7866 
7867  return current;
7868  }
7869 
7878  void unget()
7879  {
7880  next_unget = true;
7881 
7882  --position.chars_read_total;
7883 
7884  // in case we "unget" a newline, we have to also decrement the lines_read
7885  if (position.chars_read_current_line == 0)
7886  {
7887  if (position.lines_read > 0)
7888  {
7889  --position.lines_read;
7890  }
7891  }
7892  else
7893  {
7894  --position.chars_read_current_line;
7895  }
7896 
7897  if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7898  {
7899  JSON_ASSERT(!token_string.empty());
7900  token_string.pop_back();
7901  }
7902  }
7903 
7905  void add(char_int_type c)
7906  {
7907  token_buffer.push_back(static_cast<typename string_t::value_type>(c));
7908  }
7909 
7910  public:
7912  // value getters
7914 
7916  constexpr number_integer_t get_number_integer() const noexcept
7917  {
7918  return value_integer;
7919  }
7920 
7922  constexpr number_unsigned_t get_number_unsigned() const noexcept
7923  {
7924  return value_unsigned;
7925  }
7926 
7928  constexpr number_float_t get_number_float() const noexcept
7929  {
7930  return value_float;
7931  }
7932 
7934  string_t& get_string()
7935  {
7936  return token_buffer;
7937  }
7938 
7940  // diagnostics
7942 
7944  constexpr position_t get_position() const noexcept
7945  {
7946  return position;
7947  }
7948 
7952  std::string get_token_string() const
7953  {
7954  // escape control characters
7955  std::string result;
7956  for (const auto c : token_string)
7957  {
7958  if (static_cast<unsigned char>(c) <= '\x1F')
7959  {
7960  // escape control characters
7961  std::array<char, 9> cs{{}};
7962  (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7963  result += cs.data();
7964  }
7965  else
7966  {
7967  // add character as is
7968  result.push_back(static_cast<std::string::value_type>(c));
7969  }
7970  }
7971 
7972  return result;
7973  }
7974 
7976 
7977  constexpr const char* get_error_message() const noexcept
7978  {
7979  return error_message;
7980  }
7981 
7983  // actual scanner
7985 
7990  bool skip_bom()
7991  {
7992  if (get() == 0xEF)
7993  {
7994  // check if we completely parse the BOM
7995  return get() == 0xBB && get() == 0xBF;
7996  }
7997 
7998  // the first character is not the beginning of the BOM; unget it to
7999  // process is later
8000  unget();
8001  return true;
8002  }
8003 
8004  void skip_whitespace()
8005  {
8006  do
8007  {
8008  get();
8009  }
8010  while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8011  }
8012 
8013  token_type scan()
8014  {
8015  // initially, skip the BOM
8016  if (position.chars_read_total == 0 && !skip_bom())
8017  {
8018  error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8019  return token_type::parse_error;
8020  }
8021 
8022  // read next character and ignore whitespace
8023  skip_whitespace();
8024 
8025  // ignore comments
8026  while (ignore_comments && current == '/')
8027  {
8028  if (!scan_comment())
8029  {
8030  return token_type::parse_error;
8031  }
8032 
8033  // skip following whitespace
8034  skip_whitespace();
8035  }
8036 
8037  switch (current)
8038  {
8039  // structural characters
8040  case '[':
8041  return token_type::begin_array;
8042  case ']':
8043  return token_type::end_array;
8044  case '{':
8045  return token_type::begin_object;
8046  case '}':
8047  return token_type::end_object;
8048  case ':':
8049  return token_type::name_separator;
8050  case ',':
8051  return token_type::value_separator;
8052 
8053  // literals
8054  case 't':
8055  {
8056  std::array<char_type, 4> true_literal = {{char_type('t'), char_type('r'), char_type('u'), char_type('e')}};
8057  return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8058  }
8059  case 'f':
8060  {
8061  std::array<char_type, 5> false_literal = {{char_type('f'), char_type('a'), char_type('l'), char_type('s'), char_type('e')}};
8062  return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8063  }
8064  case 'n':
8065  {
8066  std::array<char_type, 4> null_literal = {{char_type('n'), char_type('u'), char_type('l'), char_type('l')}};
8067  return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8068  }
8069 
8070  // string
8071  case '\"':
8072  return scan_string();
8073 
8074  // number
8075  case '-':
8076  case '0':
8077  case '1':
8078  case '2':
8079  case '3':
8080  case '4':
8081  case '5':
8082  case '6':
8083  case '7':
8084  case '8':
8085  case '9':
8086  return scan_number();
8087 
8088  // end of input (the null byte is needed when parsing from
8089  // string literals)
8090  case '\0':
8091  case std::char_traits<char_type>::eof():
8092  return token_type::end_of_input;
8093 
8094  // error
8095  default:
8096  error_message = "invalid literal";
8097  return token_type::parse_error;
8098  }
8099  }
8100 
8101  private:
8103  InputAdapterType ia;
8104 
8106  const bool ignore_comments = false;
8107 
8109  char_int_type current = std::char_traits<char_type>::eof();
8110 
8112  bool next_unget = false;
8113 
8115  position_t position {};
8116 
8118  std::vector<char_type> token_string {};
8119 
8121  string_t token_buffer {};
8122 
8124  const char* error_message = "";
8125 
8126  // number values
8127  number_integer_t value_integer = 0;
8128  number_unsigned_t value_unsigned = 0;
8129  number_float_t value_float = 0;
8130 
8132  const char_int_type decimal_point_char = '.';
8133 };
8134 } // namespace detail
8135 } // namespace nlohmann
8136 
8137 // #include <nlohmann/detail/macro_scope.hpp>
8138 
8139 // #include <nlohmann/detail/meta/is_sax.hpp>
8140 
8141 
8142 #include <cstdint> // size_t
8143 #include <utility> // declval
8144 #include <string> // string
8145 
8146 // #include <nlohmann/detail/meta/detected.hpp>
8147 
8148 // #include <nlohmann/detail/meta/type_traits.hpp>
8149 
8150 
8151 namespace nlohmann
8152 {
8153 namespace detail
8154 {
8155 template<typename T>
8156 using null_function_t = decltype(std::declval<T&>().null());
8157 
8158 template<typename T>
8159 using boolean_function_t =
8160  decltype(std::declval<T&>().boolean(std::declval<bool>()));
8161 
8162 template<typename T, typename Integer>
8163 using number_integer_function_t =
8164  decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8165 
8166 template<typename T, typename Unsigned>
8167 using number_unsigned_function_t =
8168  decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8169 
8170 template<typename T, typename Float, typename String>
8171 using number_float_function_t = decltype(std::declval<T&>().number_float(
8172  std::declval<Float>(), std::declval<const String&>()));
8173 
8174 template<typename T, typename String>
8175 using string_function_t =
8176  decltype(std::declval<T&>().string(std::declval<String&>()));
8177 
8178 template<typename T, typename Binary>
8179 using binary_function_t =
8180  decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8181 
8182 template<typename T>
8183 using start_object_function_t =
8184  decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8185 
8186 template<typename T, typename String>
8187 using key_function_t =
8188  decltype(std::declval<T&>().key(std::declval<String&>()));
8189 
8190 template<typename T>
8191 using end_object_function_t = decltype(std::declval<T&>().end_object());
8192 
8193 template<typename T>
8194 using start_array_function_t =
8195  decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
8196 
8197 template<typename T>
8198 using end_array_function_t = decltype(std::declval<T&>().end_array());
8199 
8200 template<typename T, typename Exception>
8201 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
8202  std::declval<std::size_t>(), std::declval<const std::string&>(),
8203  std::declval<const Exception&>()));
8204 
8205 template<typename SAX, typename BasicJsonType>
8206 struct is_sax
8207 {
8208  private:
8209  static_assert(is_basic_json<BasicJsonType>::value,
8210  "BasicJsonType must be of type basic_json<...>");
8211 
8212  using number_integer_t = typename BasicJsonType::number_integer_t;
8213  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8214  using number_float_t = typename BasicJsonType::number_float_t;
8215  using string_t = typename BasicJsonType::string_t;
8216  using binary_t = typename BasicJsonType::binary_t;
8217  using exception_t = typename BasicJsonType::exception;
8218 
8219  public:
8220  static constexpr bool value =
8221  is_detected_exact<bool, null_function_t, SAX>::value &&
8222  is_detected_exact<bool, boolean_function_t, SAX>::value &&
8223  is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
8224  is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
8225  is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
8226  is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
8227  is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
8228  is_detected_exact<bool, start_object_function_t, SAX>::value &&
8229  is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
8230  is_detected_exact<bool, end_object_function_t, SAX>::value &&
8231  is_detected_exact<bool, start_array_function_t, SAX>::value &&
8232  is_detected_exact<bool, end_array_function_t, SAX>::value &&
8233  is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
8234 };
8235 
8236 template<typename SAX, typename BasicJsonType>
8237 struct is_sax_static_asserts
8238 {
8239  private:
8240  static_assert(is_basic_json<BasicJsonType>::value,
8241  "BasicJsonType must be of type basic_json<...>");
8242 
8243  using number_integer_t = typename BasicJsonType::number_integer_t;
8244  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8245  using number_float_t = typename BasicJsonType::number_float_t;
8246  using string_t = typename BasicJsonType::string_t;
8247  using binary_t = typename BasicJsonType::binary_t;
8248  using exception_t = typename BasicJsonType::exception;
8249 
8250  public:
8251  static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
8252  "Missing/invalid function: bool null()");
8253  static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
8254  "Missing/invalid function: bool boolean(bool)");
8255  static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
8256  "Missing/invalid function: bool boolean(bool)");
8257  static_assert(
8258  is_detected_exact<bool, number_integer_function_t, SAX,
8259  number_integer_t>::value,
8260  "Missing/invalid function: bool number_integer(number_integer_t)");
8261  static_assert(
8262  is_detected_exact<bool, number_unsigned_function_t, SAX,
8263  number_unsigned_t>::value,
8264  "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
8265  static_assert(is_detected_exact<bool, number_float_function_t, SAX,
8266  number_float_t, string_t>::value,
8267  "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
8268  static_assert(
8269  is_detected_exact<bool, string_function_t, SAX, string_t>::value,
8270  "Missing/invalid function: bool string(string_t&)");
8271  static_assert(
8272  is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,
8273  "Missing/invalid function: bool binary(binary_t&)");
8274  static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
8275  "Missing/invalid function: bool start_object(std::size_t)");
8276  static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
8277  "Missing/invalid function: bool key(string_t&)");
8278  static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
8279  "Missing/invalid function: bool end_object()");
8280  static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
8281  "Missing/invalid function: bool start_array(std::size_t)");
8282  static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
8283  "Missing/invalid function: bool end_array()");
8284  static_assert(
8285  is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
8286  "Missing/invalid function: bool parse_error(std::size_t, const "
8287  "std::string&, const exception&)");
8288 };
8289 } // namespace detail
8290 } // namespace nlohmann
8291 
8292 // #include <nlohmann/detail/meta/type_traits.hpp>
8293 
8294 // #include <nlohmann/detail/value_t.hpp>
8295 
8296 
8297 namespace nlohmann
8298 {
8299 namespace detail
8300 {
8301 
8303 enum class cbor_tag_handler_t
8304 {
8305  error,
8306  ignore,
8307  store
8308 };
8309 
8317 static inline bool little_endianess(int num = 1) noexcept
8318 {
8319  return *reinterpret_cast<char*>(&num) == 1;
8320 }
8321 
8322 
8324 // binary reader //
8326 
8330 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
8331 class binary_reader
8332 {
8333  using number_integer_t = typename BasicJsonType::number_integer_t;
8334  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8335  using number_float_t = typename BasicJsonType::number_float_t;
8336  using string_t = typename BasicJsonType::string_t;
8337  using binary_t = typename BasicJsonType::binary_t;
8338  using json_sax_t = SAX;
8339  using char_type = typename InputAdapterType::char_type;
8340  using char_int_type = typename std::char_traits<char_type>::int_type;
8341 
8342  public:
8348  explicit binary_reader(InputAdapterType&& adapter) noexcept : ia(std::move(adapter))
8349  {
8350  (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
8351  }
8352 
8353  // make class move-only
8354  binary_reader(const binary_reader&) = delete;
8355  binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8356  binary_reader& operator=(const binary_reader&) = delete;
8357  binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8358  ~binary_reader() = default;
8359 
8368  JSON_HEDLEY_NON_NULL(3)
8369  bool sax_parse(const input_format_t format,
8370  json_sax_t* sax_,
8371  const bool strict = true,
8372  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
8373  {
8374  sax = sax_;
8375  bool result = false;
8376 
8377  switch (format)
8378  {
8379  case input_format_t::bson:
8380  result = parse_bson_internal();
8381  break;
8382 
8383  case input_format_t::cbor:
8384  result = parse_cbor_internal(true, tag_handler);
8385  break;
8386 
8387  case input_format_t::msgpack:
8388  result = parse_msgpack_internal();
8389  break;
8390 
8391  case input_format_t::ubjson:
8392  result = parse_ubjson_internal();
8393  break;
8394 
8395  case input_format_t::json: // LCOV_EXCL_LINE
8396  default: // LCOV_EXCL_LINE
8397  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8398  }
8399 
8400  // strict mode: next byte must be EOF
8401  if (result && strict)
8402  {
8403  if (format == input_format_t::ubjson)
8404  {
8405  get_ignore_noop();
8406  }
8407  else
8408  {
8409  get();
8410  }
8411 
8412  if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
8413  {
8414  return sax->parse_error(chars_read, get_token_string(),
8415  parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value"), BasicJsonType()));
8416  }
8417  }
8418 
8419  return result;
8420  }
8421 
8422  private:
8424  // BSON //
8426 
8431  bool parse_bson_internal()
8432  {
8433  std::int32_t document_size{};
8434  get_number<std::int32_t, true>(input_format_t::bson, document_size);
8435 
8436  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
8437  {
8438  return false;
8439  }
8440 
8441  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
8442  {
8443  return false;
8444  }
8445 
8446  return sax->end_object();
8447  }
8448 
8456  bool get_bson_cstr(string_t& result)
8457  {
8458  auto out = std::back_inserter(result);
8459  while (true)
8460  {
8461  get();
8462  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
8463  {
8464  return false;
8465  }
8466  if (current == 0x00)
8467  {
8468  return true;
8469  }
8470  *out++ = static_cast<typename string_t::value_type>(current);
8471  }
8472  }
8473 
8485  template<typename NumberType>
8486  bool get_bson_string(const NumberType len, string_t& result)
8487  {
8488  if (JSON_HEDLEY_UNLIKELY(len < 1))
8489  {
8490  auto last_token = get_token_string();
8491  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()));
8492  }
8493 
8494  return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
8495  }
8496 
8506  template<typename NumberType>
8507  bool get_bson_binary(const NumberType len, binary_t& result)
8508  {
8509  if (JSON_HEDLEY_UNLIKELY(len < 0))
8510  {
8511  auto last_token = get_token_string();
8512  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()));
8513  }
8514 
8515  // All BSON binary values have a subtype
8516  std::uint8_t subtype{};
8517  get_number<std::uint8_t>(input_format_t::bson, subtype);
8518  result.set_subtype(subtype);
8519 
8520  return get_binary(input_format_t::bson, len, result);
8521  }
8522 
8533  bool parse_bson_element_internal(const char_int_type element_type,
8534  const std::size_t element_type_parse_position)
8535  {
8536  switch (element_type)
8537  {
8538  case 0x01: // double
8539  {
8540  double number{};
8541  return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
8542  }
8543 
8544  case 0x02: // string
8545  {
8546  std::int32_t len{};
8547  string_t value;
8548  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
8549  }
8550 
8551  case 0x03: // object
8552  {
8553  return parse_bson_internal();
8554  }
8555 
8556  case 0x04: // array
8557  {
8558  return parse_bson_array();
8559  }
8560 
8561  case 0x05: // binary
8562  {
8563  std::int32_t len{};
8564  binary_t value;
8565  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
8566  }
8567 
8568  case 0x08: // boolean
8569  {
8570  return sax->boolean(get() != 0);
8571  }
8572 
8573  case 0x0A: // null
8574  {
8575  return sax->null();
8576  }
8577 
8578  case 0x10: // int32
8579  {
8580  std::int32_t value{};
8581  return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8582  }
8583 
8584  case 0x12: // int64
8585  {
8586  std::int64_t value{};
8587  return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8588  }
8589 
8590  default: // anything else not supported (yet)
8591  {
8592  std::array<char, 3> cr{{}};
8593  (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8594  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()));
8595  }
8596  }
8597  }
8598 
8611  bool parse_bson_element_list(const bool is_array)
8612  {
8613  string_t key;
8614 
8615  while (auto element_type = get())
8616  {
8617  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
8618  {
8619  return false;
8620  }
8621 
8622  const std::size_t element_type_parse_position = chars_read;
8623  if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
8624  {
8625  return false;
8626  }
8627 
8628  if (!is_array && !sax->key(key))
8629  {
8630  return false;
8631  }
8632 
8633  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
8634  {
8635  return false;
8636  }
8637 
8638  // get_bson_cstr only appends
8639  key.clear();
8640  }
8641 
8642  return true;
8643  }
8644 
8649  bool parse_bson_array()
8650  {
8651  std::int32_t document_size{};
8652  get_number<std::int32_t, true>(input_format_t::bson, document_size);
8653 
8654  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
8655  {
8656  return false;
8657  }
8658 
8659  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8660  {
8661  return false;
8662  }
8663 
8664  return sax->end_array();
8665  }
8666 
8668  // CBOR //
8670 
8679  bool parse_cbor_internal(const bool get_char,
8680  const cbor_tag_handler_t tag_handler)
8681  {
8682  switch (get_char ? get() : current)
8683  {
8684  // EOF
8685  case std::char_traits<char_type>::eof():
8686  return unexpect_eof(input_format_t::cbor, "value");
8687 
8688  // Integer 0x00..0x17 (0..23)
8689  case 0x00:
8690  case 0x01:
8691  case 0x02:
8692  case 0x03:
8693  case 0x04:
8694  case 0x05:
8695  case 0x06:
8696  case 0x07:
8697  case 0x08:
8698  case 0x09:
8699  case 0x0A:
8700  case 0x0B:
8701  case 0x0C:
8702  case 0x0D:
8703  case 0x0E:
8704  case 0x0F:
8705  case 0x10:
8706  case 0x11:
8707  case 0x12:
8708  case 0x13:
8709  case 0x14:
8710  case 0x15:
8711  case 0x16:
8712  case 0x17:
8713  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8714 
8715  case 0x18: // Unsigned integer (one-byte uint8_t follows)
8716  {
8717  std::uint8_t number{};
8718  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8719  }
8720 
8721  case 0x19: // Unsigned integer (two-byte uint16_t follows)
8722  {
8723  std::uint16_t number{};
8724  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8725  }
8726 
8727  case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8728  {
8729  std::uint32_t number{};
8730  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8731  }
8732 
8733  case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8734  {
8735  std::uint64_t number{};
8736  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8737  }
8738 
8739  // Negative integer -1-0x00..-1-0x17 (-1..-24)
8740  case 0x20:
8741  case 0x21:
8742  case 0x22:
8743  case 0x23:
8744  case 0x24:
8745  case 0x25:
8746  case 0x26:
8747  case 0x27:
8748  case 0x28:
8749  case 0x29:
8750  case 0x2A:
8751  case 0x2B:
8752  case 0x2C:
8753  case 0x2D:
8754  case 0x2E:
8755  case 0x2F:
8756  case 0x30:
8757  case 0x31:
8758  case 0x32:
8759  case 0x33:
8760  case 0x34:
8761  case 0x35:
8762  case 0x36:
8763  case 0x37:
8764  return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8765 
8766  case 0x38: // Negative integer (one-byte uint8_t follows)
8767  {
8768  std::uint8_t number{};
8769  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8770  }
8771 
8772  case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8773  {
8774  std::uint16_t number{};
8775  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8776  }
8777 
8778  case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8779  {
8780  std::uint32_t number{};
8781  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8782  }
8783 
8784  case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8785  {
8786  std::uint64_t number{};
8787  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8788  - static_cast<number_integer_t>(number));
8789  }
8790 
8791  // Binary data (0x00..0x17 bytes follow)
8792  case 0x40:
8793  case 0x41:
8794  case 0x42:
8795  case 0x43:
8796  case 0x44:
8797  case 0x45:
8798  case 0x46:
8799  case 0x47:
8800  case 0x48:
8801  case 0x49:
8802  case 0x4A:
8803  case 0x4B:
8804  case 0x4C:
8805  case 0x4D:
8806  case 0x4E:
8807  case 0x4F:
8808  case 0x50:
8809  case 0x51:
8810  case 0x52:
8811  case 0x53:
8812  case 0x54:
8813  case 0x55:
8814  case 0x56:
8815  case 0x57:
8816  case 0x58: // Binary data (one-byte uint8_t for n follows)
8817  case 0x59: // Binary data (two-byte uint16_t for n follow)
8818  case 0x5A: // Binary data (four-byte uint32_t for n follow)
8819  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8820  case 0x5F: // Binary data (indefinite length)
8821  {
8822  binary_t b;
8823  return get_cbor_binary(b) && sax->binary(b);
8824  }
8825 
8826  // UTF-8 string (0x00..0x17 bytes follow)
8827  case 0x60:
8828  case 0x61:
8829  case 0x62:
8830  case 0x63:
8831  case 0x64:
8832  case 0x65:
8833  case 0x66:
8834  case 0x67:
8835  case 0x68:
8836  case 0x69:
8837  case 0x6A:
8838  case 0x6B:
8839  case 0x6C:
8840  case 0x6D:
8841  case 0x6E:
8842  case 0x6F:
8843  case 0x70:
8844  case 0x71:
8845  case 0x72:
8846  case 0x73:
8847  case 0x74:
8848  case 0x75:
8849  case 0x76:
8850  case 0x77:
8851  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8852  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8853  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8854  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8855  case 0x7F: // UTF-8 string (indefinite length)
8856  {
8857  string_t s;
8858  return get_cbor_string(s) && sax->string(s);
8859  }
8860 
8861  // array (0x00..0x17 data items follow)
8862  case 0x80:
8863  case 0x81:
8864  case 0x82:
8865  case 0x83:
8866  case 0x84:
8867  case 0x85:
8868  case 0x86:
8869  case 0x87:
8870  case 0x88:
8871  case 0x89:
8872  case 0x8A:
8873  case 0x8B:
8874  case 0x8C:
8875  case 0x8D:
8876  case 0x8E:
8877  case 0x8F:
8878  case 0x90:
8879  case 0x91:
8880  case 0x92:
8881  case 0x93:
8882  case 0x94:
8883  case 0x95:
8884  case 0x96:
8885  case 0x97:
8886  return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8887 
8888  case 0x98: // array (one-byte uint8_t for n follows)
8889  {
8890  std::uint8_t len{};
8891  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8892  }
8893 
8894  case 0x99: // array (two-byte uint16_t for n follow)
8895  {
8896  std::uint16_t len{};
8897  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8898  }
8899 
8900  case 0x9A: // array (four-byte uint32_t for n follow)
8901  {
8902  std::uint32_t len{};
8903  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8904  }
8905 
8906  case 0x9B: // array (eight-byte uint64_t for n follow)
8907  {
8908  std::uint64_t len{};
8909  return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast<std::size_t>(len), tag_handler);
8910  }
8911 
8912  case 0x9F: // array (indefinite length)
8913  return get_cbor_array(std::size_t(-1), tag_handler);
8914 
8915  // map (0x00..0x17 pairs of data items follow)
8916  case 0xA0:
8917  case 0xA1:
8918  case 0xA2:
8919  case 0xA3:
8920  case 0xA4:
8921  case 0xA5:
8922  case 0xA6:
8923  case 0xA7:
8924  case 0xA8:
8925  case 0xA9:
8926  case 0xAA:
8927  case 0xAB:
8928  case 0xAC:
8929  case 0xAD:
8930  case 0xAE:
8931  case 0xAF:
8932  case 0xB0:
8933  case 0xB1:
8934  case 0xB2:
8935  case 0xB3:
8936  case 0xB4:
8937  case 0xB5:
8938  case 0xB6:
8939  case 0xB7:
8940  return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8941 
8942  case 0xB8: // map (one-byte uint8_t for n follows)
8943  {
8944  std::uint8_t len{};
8945  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8946  }
8947 
8948  case 0xB9: // map (two-byte uint16_t for n follow)
8949  {
8950  std::uint16_t len{};
8951  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8952  }
8953 
8954  case 0xBA: // map (four-byte uint32_t for n follow)
8955  {
8956  std::uint32_t len{};
8957  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8958  }
8959 
8960  case 0xBB: // map (eight-byte uint64_t for n follow)
8961  {
8962  std::uint64_t len{};
8963  return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast<std::size_t>(len), tag_handler);
8964  }
8965 
8966  case 0xBF: // map (indefinite length)
8967  return get_cbor_object(std::size_t(-1), tag_handler);
8968 
8969  case 0xC6: // tagged item
8970  case 0xC7:
8971  case 0xC8:
8972  case 0xC9:
8973  case 0xCA:
8974  case 0xCB:
8975  case 0xCC:
8976  case 0xCD:
8977  case 0xCE:
8978  case 0xCF:
8979  case 0xD0:
8980  case 0xD1:
8981  case 0xD2:
8982  case 0xD3:
8983  case 0xD4:
8984  case 0xD8: // tagged item (1 bytes follow)
8985  case 0xD9: // tagged item (2 bytes follow)
8986  case 0xDA: // tagged item (4 bytes follow)
8987  case 0xDB: // tagged item (8 bytes follow)
8988  {
8989  switch (tag_handler)
8990  {
8991  case cbor_tag_handler_t::error:
8992  {
8993  auto last_token = get_token_string();
8994  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()));
8995  }
8996 
8997  case cbor_tag_handler_t::ignore:
8998  {
8999  // ignore binary subtype
9000  switch (current)
9001  {
9002  case 0xD8:
9003  {
9004  std::uint8_t subtype_to_ignore{};
9005  get_number(input_format_t::cbor, subtype_to_ignore);
9006  break;
9007  }
9008  case 0xD9:
9009  {
9010  std::uint16_t subtype_to_ignore{};
9011  get_number(input_format_t::cbor, subtype_to_ignore);
9012  break;
9013  }
9014  case 0xDA:
9015  {
9016  std::uint32_t subtype_to_ignore{};
9017  get_number(input_format_t::cbor, subtype_to_ignore);
9018  break;
9019  }
9020  case 0xDB:
9021  {
9022  std::uint64_t subtype_to_ignore{};
9023  get_number(input_format_t::cbor, subtype_to_ignore);
9024  break;
9025  }
9026  default:
9027  break;
9028  }
9029  return parse_cbor_internal(true, tag_handler);
9030  }
9031 
9032  case cbor_tag_handler_t::store:
9033  {
9034  binary_t b;
9035  // use binary subtype and store in binary container
9036  switch (current)
9037  {
9038  case 0xD8:
9039  {
9040  std::uint8_t subtype{};
9041  get_number(input_format_t::cbor, subtype);
9042  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9043  break;
9044  }
9045  case 0xD9:
9046  {
9047  std::uint16_t subtype{};
9048  get_number(input_format_t::cbor, subtype);
9049  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9050  break;
9051  }
9052  case 0xDA:
9053  {
9054  std::uint32_t subtype{};
9055  get_number(input_format_t::cbor, subtype);
9056  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9057  break;
9058  }
9059  case 0xDB:
9060  {
9061  std::uint64_t subtype{};
9062  get_number(input_format_t::cbor, subtype);
9063  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9064  break;
9065  }
9066  default:
9067  return parse_cbor_internal(true, tag_handler);
9068  }
9069  get();
9070  return get_cbor_binary(b) && sax->binary(b);
9071  }
9072 
9073  default: // LCOV_EXCL_LINE
9074  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9075  return false; // LCOV_EXCL_LINE
9076  }
9077  }
9078 
9079  case 0xF4: // false
9080  return sax->boolean(false);
9081 
9082  case 0xF5: // true
9083  return sax->boolean(true);
9084 
9085  case 0xF6: // null
9086  return sax->null();
9087 
9088  case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9089  {
9090  const auto byte1_raw = get();
9091  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9092  {
9093  return false;
9094  }
9095  const auto byte2_raw = get();
9096  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9097  {
9098  return false;
9099  }
9100 
9101  const auto byte1 = static_cast<unsigned char>(byte1_raw);
9102  const auto byte2 = static_cast<unsigned char>(byte2_raw);
9103 
9104  // code from RFC 7049, Appendix D, Figure 3:
9105  // As half-precision floating-point numbers were only added
9106  // to IEEE 754 in 2008, today's programming platforms often
9107  // still only have limited support for them. It is very
9108  // easy to include at least decoding support for them even
9109  // without such support. An example of a small decoder for
9110  // half-precision floating-point numbers in the C language
9111  // is shown in Fig. 3.
9112  const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
9113  const double val = [&half]
9114  {
9115  const int exp = (half >> 10u) & 0x1Fu;
9116  const unsigned int mant = half & 0x3FFu;
9117  JSON_ASSERT(0 <= exp&& exp <= 32);
9118  JSON_ASSERT(mant <= 1024);
9119  switch (exp)
9120  {
9121  case 0:
9122  return std::ldexp(mant, -24);
9123  case 31:
9124  return (mant == 0)
9125  ? std::numeric_limits<double>::infinity()
9126  : std::numeric_limits<double>::quiet_NaN();
9127  default:
9128  return std::ldexp(mant + 1024, exp - 25);
9129  }
9130  }();
9131  return sax->number_float((half & 0x8000u) != 0
9132  ? static_cast<number_float_t>(-val)
9133  : static_cast<number_float_t>(val), "");
9134  }
9135 
9136  case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9137  {
9138  float number{};
9139  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9140  }
9141 
9142  case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9143  {
9144  double number{};
9145  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9146  }
9147 
9148  default: // anything else (0xFF is handled inside the other types)
9149  {
9150  auto last_token = get_token_string();
9151  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()));
9152  }
9153  }
9154  }
9155 
9167  bool get_cbor_string(string_t& result)
9168  {
9169  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
9170  {
9171  return false;
9172  }
9173 
9174  switch (current)
9175  {
9176  // UTF-8 string (0x00..0x17 bytes follow)
9177  case 0x60:
9178  case 0x61:
9179  case 0x62:
9180  case 0x63:
9181  case 0x64:
9182  case 0x65:
9183  case 0x66:
9184  case 0x67:
9185  case 0x68:
9186  case 0x69:
9187  case 0x6A:
9188  case 0x6B:
9189  case 0x6C:
9190  case 0x6D:
9191  case 0x6E:
9192  case 0x6F:
9193  case 0x70:
9194  case 0x71:
9195  case 0x72:
9196  case 0x73:
9197  case 0x74:
9198  case 0x75:
9199  case 0x76:
9200  case 0x77:
9201  {
9202  return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9203  }
9204 
9205  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9206  {
9207  std::uint8_t len{};
9208  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9209  }
9210 
9211  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9212  {
9213  std::uint16_t len{};
9214  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9215  }
9216 
9217  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9218  {
9219  std::uint32_t len{};
9220  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9221  }
9222 
9223  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9224  {
9225  std::uint64_t len{};
9226  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9227  }
9228 
9229  case 0x7F: // UTF-8 string (indefinite length)
9230  {
9231  while (get() != 0xFF)
9232  {
9233  string_t chunk;
9234  if (!get_cbor_string(chunk))
9235  {
9236  return false;
9237  }
9238  result.append(chunk);
9239  }
9240  return true;
9241  }
9242 
9243  default:
9244  {
9245  auto last_token = get_token_string();
9246  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()));
9247  }
9248  }
9249  }
9250 
9262  bool get_cbor_binary(binary_t& result)
9263  {
9264  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
9265  {
9266  return false;
9267  }
9268 
9269  switch (current)
9270  {
9271  // Binary data (0x00..0x17 bytes follow)
9272  case 0x40:
9273  case 0x41:
9274  case 0x42:
9275  case 0x43:
9276  case 0x44:
9277  case 0x45:
9278  case 0x46:
9279  case 0x47:
9280  case 0x48:
9281  case 0x49:
9282  case 0x4A:
9283  case 0x4B:
9284  case 0x4C:
9285  case 0x4D:
9286  case 0x4E:
9287  case 0x4F:
9288  case 0x50:
9289  case 0x51:
9290  case 0x52:
9291  case 0x53:
9292  case 0x54:
9293  case 0x55:
9294  case 0x56:
9295  case 0x57:
9296  {
9297  return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9298  }
9299 
9300  case 0x58: // Binary data (one-byte uint8_t for n follows)
9301  {
9302  std::uint8_t len{};
9303  return get_number(input_format_t::cbor, len) &&
9304  get_binary(input_format_t::cbor, len, result);
9305  }
9306 
9307  case 0x59: // Binary data (two-byte uint16_t for n follow)
9308  {
9309  std::uint16_t len{};
9310  return get_number(input_format_t::cbor, len) &&
9311  get_binary(input_format_t::cbor, len, result);
9312  }
9313 
9314  case 0x5A: // Binary data (four-byte uint32_t for n follow)
9315  {
9316  std::uint32_t len{};
9317  return get_number(input_format_t::cbor, len) &&
9318  get_binary(input_format_t::cbor, len, result);
9319  }
9320 
9321  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9322  {
9323  std::uint64_t len{};
9324  return get_number(input_format_t::cbor, len) &&
9325  get_binary(input_format_t::cbor, len, result);
9326  }
9327 
9328  case 0x5F: // Binary data (indefinite length)
9329  {
9330  while (get() != 0xFF)
9331  {
9332  binary_t chunk;
9333  if (!get_cbor_binary(chunk))
9334  {
9335  return false;
9336  }
9337  result.insert(result.end(), chunk.begin(), chunk.end());
9338  }
9339  return true;
9340  }
9341 
9342  default:
9343  {
9344  auto last_token = get_token_string();
9345  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()));
9346  }
9347  }
9348  }
9349 
9356  bool get_cbor_array(const std::size_t len,
9357  const cbor_tag_handler_t tag_handler)
9358  {
9359  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9360  {
9361  return false;
9362  }
9363 
9364  if (len != std::size_t(-1))
9365  {
9366  for (std::size_t i = 0; i < len; ++i)
9367  {
9368  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9369  {
9370  return false;
9371  }
9372  }
9373  }
9374  else
9375  {
9376  while (get() != 0xFF)
9377  {
9378  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
9379  {
9380  return false;
9381  }
9382  }
9383  }
9384 
9385  return sax->end_array();
9386  }
9387 
9394  bool get_cbor_object(const std::size_t len,
9395  const cbor_tag_handler_t tag_handler)
9396  {
9397  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9398  {
9399  return false;
9400  }
9401 
9402  if (len != 0)
9403  {
9404  string_t key;
9405  if (len != std::size_t(-1))
9406  {
9407  for (std::size_t i = 0; i < len; ++i)
9408  {
9409  get();
9410  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9411  {
9412  return false;
9413  }
9414 
9415  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9416  {
9417  return false;
9418  }
9419  key.clear();
9420  }
9421  }
9422  else
9423  {
9424  while (get() != 0xFF)
9425  {
9426  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9427  {
9428  return false;
9429  }
9430 
9431  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9432  {
9433  return false;
9434  }
9435  key.clear();
9436  }
9437  }
9438  }
9439 
9440  return sax->end_object();
9441  }
9442 
9444  // MsgPack //
9446 
9450  bool parse_msgpack_internal()
9451  {
9452  switch (get())
9453  {
9454  // EOF
9455  case std::char_traits<char_type>::eof():
9456  return unexpect_eof(input_format_t::msgpack, "value");
9457 
9458  // positive fixint
9459  case 0x00:
9460  case 0x01:
9461  case 0x02:
9462  case 0x03:
9463  case 0x04:
9464  case 0x05:
9465  case 0x06:
9466  case 0x07:
9467  case 0x08:
9468  case 0x09:
9469  case 0x0A:
9470  case 0x0B:
9471  case 0x0C:
9472  case 0x0D:
9473  case 0x0E:
9474  case 0x0F:
9475  case 0x10:
9476  case 0x11:
9477  case 0x12:
9478  case 0x13:
9479  case 0x14:
9480  case 0x15:
9481  case 0x16:
9482  case 0x17:
9483  case 0x18:
9484  case 0x19:
9485  case 0x1A:
9486  case 0x1B:
9487  case 0x1C:
9488  case 0x1D:
9489  case 0x1E:
9490  case 0x1F:
9491  case 0x20:
9492  case 0x21:
9493  case 0x22:
9494  case 0x23:
9495  case 0x24:
9496  case 0x25:
9497  case 0x26:
9498  case 0x27:
9499  case 0x28:
9500  case 0x29:
9501  case 0x2A:
9502  case 0x2B:
9503  case 0x2C:
9504  case 0x2D:
9505  case 0x2E:
9506  case 0x2F:
9507  case 0x30:
9508  case 0x31:
9509  case 0x32:
9510  case 0x33:
9511  case 0x34:
9512  case 0x35:
9513  case 0x36:
9514  case 0x37:
9515  case 0x38:
9516  case 0x39:
9517  case 0x3A:
9518  case 0x3B:
9519  case 0x3C:
9520  case 0x3D:
9521  case 0x3E:
9522  case 0x3F:
9523  case 0x40:
9524  case 0x41:
9525  case 0x42:
9526  case 0x43:
9527  case 0x44:
9528  case 0x45:
9529  case 0x46:
9530  case 0x47:
9531  case 0x48:
9532  case 0x49:
9533  case 0x4A:
9534  case 0x4B:
9535  case 0x4C:
9536  case 0x4D:
9537  case 0x4E:
9538  case 0x4F:
9539  case 0x50:
9540  case 0x51:
9541  case 0x52:
9542  case 0x53:
9543  case 0x54:
9544  case 0x55:
9545  case 0x56:
9546  case 0x57:
9547  case 0x58:
9548  case 0x59:
9549  case 0x5A:
9550  case 0x5B:
9551  case 0x5C:
9552  case 0x5D:
9553  case 0x5E:
9554  case 0x5F:
9555  case 0x60:
9556  case 0x61:
9557  case 0x62:
9558  case 0x63:
9559  case 0x64:
9560  case 0x65:
9561  case 0x66:
9562  case 0x67:
9563  case 0x68:
9564  case 0x69:
9565  case 0x6A:
9566  case 0x6B:
9567  case 0x6C:
9568  case 0x6D:
9569  case 0x6E:
9570  case 0x6F:
9571  case 0x70:
9572  case 0x71:
9573  case 0x72:
9574  case 0x73:
9575  case 0x74:
9576  case 0x75:
9577  case 0x76:
9578  case 0x77:
9579  case 0x78:
9580  case 0x79:
9581  case 0x7A:
9582  case 0x7B:
9583  case 0x7C:
9584  case 0x7D:
9585  case 0x7E:
9586  case 0x7F:
9587  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9588 
9589  // fixmap
9590  case 0x80:
9591  case 0x81:
9592  case 0x82:
9593  case 0x83:
9594  case 0x84:
9595  case 0x85:
9596  case 0x86:
9597  case 0x87:
9598  case 0x88:
9599  case 0x89:
9600  case 0x8A:
9601  case 0x8B:
9602  case 0x8C:
9603  case 0x8D:
9604  case 0x8E:
9605  case 0x8F:
9606  return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9607 
9608  // fixarray
9609  case 0x90:
9610  case 0x91:
9611  case 0x92:
9612  case 0x93:
9613  case 0x94:
9614  case 0x95:
9615  case 0x96:
9616  case 0x97:
9617  case 0x98:
9618  case 0x99:
9619  case 0x9A:
9620  case 0x9B:
9621  case 0x9C:
9622  case 0x9D:
9623  case 0x9E:
9624  case 0x9F:
9625  return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9626 
9627  // fixstr
9628  case 0xA0:
9629  case 0xA1:
9630  case 0xA2:
9631  case 0xA3:
9632  case 0xA4:
9633  case 0xA5:
9634  case 0xA6:
9635  case 0xA7:
9636  case 0xA8:
9637  case 0xA9:
9638  case 0xAA:
9639  case 0xAB:
9640  case 0xAC:
9641  case 0xAD:
9642  case 0xAE:
9643  case 0xAF:
9644  case 0xB0:
9645  case 0xB1:
9646  case 0xB2:
9647  case 0xB3:
9648  case 0xB4:
9649  case 0xB5:
9650  case 0xB6:
9651  case 0xB7:
9652  case 0xB8:
9653  case 0xB9:
9654  case 0xBA:
9655  case 0xBB:
9656  case 0xBC:
9657  case 0xBD:
9658  case 0xBE:
9659  case 0xBF:
9660  case 0xD9: // str 8
9661  case 0xDA: // str 16
9662  case 0xDB: // str 32
9663  {
9664  string_t s;
9665  return get_msgpack_string(s) && sax->string(s);
9666  }
9667 
9668  case 0xC0: // nil
9669  return sax->null();
9670 
9671  case 0xC2: // false
9672  return sax->boolean(false);
9673 
9674  case 0xC3: // true
9675  return sax->boolean(true);
9676 
9677  case 0xC4: // bin 8
9678  case 0xC5: // bin 16
9679  case 0xC6: // bin 32
9680  case 0xC7: // ext 8
9681  case 0xC8: // ext 16
9682  case 0xC9: // ext 32
9683  case 0xD4: // fixext 1
9684  case 0xD5: // fixext 2
9685  case 0xD6: // fixext 4
9686  case 0xD7: // fixext 8
9687  case 0xD8: // fixext 16
9688  {
9689  binary_t b;
9690  return get_msgpack_binary(b) && sax->binary(b);
9691  }
9692 
9693  case 0xCA: // float 32
9694  {
9695  float number{};
9696  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9697  }
9698 
9699  case 0xCB: // float 64
9700  {
9701  double number{};
9702  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9703  }
9704 
9705  case 0xCC: // uint 8
9706  {
9707  std::uint8_t number{};
9708  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9709  }
9710 
9711  case 0xCD: // uint 16
9712  {
9713  std::uint16_t number{};
9714  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9715  }
9716 
9717  case 0xCE: // uint 32
9718  {
9719  std::uint32_t number{};
9720  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9721  }
9722 
9723  case 0xCF: // uint 64
9724  {
9725  std::uint64_t number{};
9726  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9727  }
9728 
9729  case 0xD0: // int 8
9730  {
9731  std::int8_t number{};
9732  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9733  }
9734 
9735  case 0xD1: // int 16
9736  {
9737  std::int16_t number{};
9738  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9739  }
9740 
9741  case 0xD2: // int 32
9742  {
9743  std::int32_t number{};
9744  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9745  }
9746 
9747  case 0xD3: // int 64
9748  {
9749  std::int64_t number{};
9750  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9751  }
9752 
9753  case 0xDC: // array 16
9754  {
9755  std::uint16_t len{};
9756  return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9757  }
9758 
9759  case 0xDD: // array 32
9760  {
9761  std::uint32_t len{};
9762  return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9763  }
9764 
9765  case 0xDE: // map 16
9766  {
9767  std::uint16_t len{};
9768  return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9769  }
9770 
9771  case 0xDF: // map 32
9772  {
9773  std::uint32_t len{};
9774  return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9775  }
9776 
9777  // negative fixint
9778  case 0xE0:
9779  case 0xE1:
9780  case 0xE2:
9781  case 0xE3:
9782  case 0xE4:
9783  case 0xE5:
9784  case 0xE6:
9785  case 0xE7:
9786  case 0xE8:
9787  case 0xE9:
9788  case 0xEA:
9789  case 0xEB:
9790  case 0xEC:
9791  case 0xED:
9792  case 0xEE:
9793  case 0xEF:
9794  case 0xF0:
9795  case 0xF1:
9796  case 0xF2:
9797  case 0xF3:
9798  case 0xF4:
9799  case 0xF5:
9800  case 0xF6:
9801  case 0xF7:
9802  case 0xF8:
9803  case 0xF9:
9804  case 0xFA:
9805  case 0xFB:
9806  case 0xFC:
9807  case 0xFD:
9808  case 0xFE:
9809  case 0xFF:
9810  return sax->number_integer(static_cast<std::int8_t>(current));
9811 
9812  default: // anything else
9813  {
9814  auto last_token = get_token_string();
9815  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()));
9816  }
9817  }
9818  }
9819 
9830  bool get_msgpack_string(string_t& result)
9831  {
9832  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
9833  {
9834  return false;
9835  }
9836 
9837  switch (current)
9838  {
9839  // fixstr
9840  case 0xA0:
9841  case 0xA1:
9842  case 0xA2:
9843  case 0xA3:
9844  case 0xA4:
9845  case 0xA5:
9846  case 0xA6:
9847  case 0xA7:
9848  case 0xA8:
9849  case 0xA9:
9850  case 0xAA:
9851  case 0xAB:
9852  case 0xAC:
9853  case 0xAD:
9854  case 0xAE:
9855  case 0xAF:
9856  case 0xB0:
9857  case 0xB1:
9858  case 0xB2:
9859  case 0xB3:
9860  case 0xB4:
9861  case 0xB5:
9862  case 0xB6:
9863  case 0xB7:
9864  case 0xB8:
9865  case 0xB9:
9866  case 0xBA:
9867  case 0xBB:
9868  case 0xBC:
9869  case 0xBD:
9870  case 0xBE:
9871  case 0xBF:
9872  {
9873  return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
9874  }
9875 
9876  case 0xD9: // str 8
9877  {
9878  std::uint8_t len{};
9879  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9880  }
9881 
9882  case 0xDA: // str 16
9883  {
9884  std::uint16_t len{};
9885  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9886  }
9887 
9888  case 0xDB: // str 32
9889  {
9890  std::uint32_t len{};
9891  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9892  }
9893 
9894  default:
9895  {
9896  auto last_token = get_token_string();
9897  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()));
9898  }
9899  }
9900  }
9901 
9912  bool get_msgpack_binary(binary_t& result)
9913  {
9914  // helper function to set the subtype
9915  auto assign_and_return_true = [&result](std::int8_t subtype)
9916  {
9917  result.set_subtype(static_cast<std::uint8_t>(subtype));
9918  return true;
9919  };
9920 
9921  switch (current)
9922  {
9923  case 0xC4: // bin 8
9924  {
9925  std::uint8_t len{};
9926  return get_number(input_format_t::msgpack, len) &&
9927  get_binary(input_format_t::msgpack, len, result);
9928  }
9929 
9930  case 0xC5: // bin 16
9931  {
9932  std::uint16_t len{};
9933  return get_number(input_format_t::msgpack, len) &&
9934  get_binary(input_format_t::msgpack, len, result);
9935  }
9936 
9937  case 0xC6: // bin 32
9938  {
9939  std::uint32_t len{};
9940  return get_number(input_format_t::msgpack, len) &&
9941  get_binary(input_format_t::msgpack, len, result);
9942  }
9943 
9944  case 0xC7: // ext 8
9945  {
9946  std::uint8_t len{};
9947  std::int8_t subtype{};
9948  return get_number(input_format_t::msgpack, len) &&
9949  get_number(input_format_t::msgpack, subtype) &&
9950  get_binary(input_format_t::msgpack, len, result) &&
9951  assign_and_return_true(subtype);
9952  }
9953 
9954  case 0xC8: // ext 16
9955  {
9956  std::uint16_t len{};
9957  std::int8_t subtype{};
9958  return get_number(input_format_t::msgpack, len) &&
9959  get_number(input_format_t::msgpack, subtype) &&
9960  get_binary(input_format_t::msgpack, len, result) &&
9961  assign_and_return_true(subtype);
9962  }
9963 
9964  case 0xC9: // ext 32
9965  {
9966  std::uint32_t len{};
9967  std::int8_t subtype{};
9968  return get_number(input_format_t::msgpack, len) &&
9969  get_number(input_format_t::msgpack, subtype) &&
9970  get_binary(input_format_t::msgpack, len, result) &&
9971  assign_and_return_true(subtype);
9972  }
9973 
9974  case 0xD4: // fixext 1
9975  {
9976  std::int8_t subtype{};
9977  return get_number(input_format_t::msgpack, subtype) &&
9978  get_binary(input_format_t::msgpack, 1, result) &&
9979  assign_and_return_true(subtype);
9980  }
9981 
9982  case 0xD5: // fixext 2
9983  {
9984  std::int8_t subtype{};
9985  return get_number(input_format_t::msgpack, subtype) &&
9986  get_binary(input_format_t::msgpack, 2, result) &&
9987  assign_and_return_true(subtype);
9988  }
9989 
9990  case 0xD6: // fixext 4
9991  {
9992  std::int8_t subtype{};
9993  return get_number(input_format_t::msgpack, subtype) &&
9994  get_binary(input_format_t::msgpack, 4, result) &&
9995  assign_and_return_true(subtype);
9996  }
9997 
9998  case 0xD7: // fixext 8
9999  {
10000  std::int8_t subtype{};
10001  return get_number(input_format_t::msgpack, subtype) &&
10002  get_binary(input_format_t::msgpack, 8, result) &&
10003  assign_and_return_true(subtype);
10004  }
10005 
10006  case 0xD8: // fixext 16
10007  {
10008  std::int8_t subtype{};
10009  return get_number(input_format_t::msgpack, subtype) &&
10010  get_binary(input_format_t::msgpack, 16, result) &&
10011  assign_and_return_true(subtype);
10012  }
10013 
10014  default: // LCOV_EXCL_LINE
10015  return false; // LCOV_EXCL_LINE
10016  }
10017  }
10018 
10023  bool get_msgpack_array(const std::size_t len)
10024  {
10025  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10026  {
10027  return false;
10028  }
10029 
10030  for (std::size_t i = 0; i < len; ++i)
10031  {
10032  if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10033  {
10034  return false;
10035  }
10036  }
10037 
10038  return sax->end_array();
10039  }
10040 
10045  bool get_msgpack_object(const std::size_t len)
10046  {
10047  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10048  {
10049  return false;
10050  }
10051 
10052  string_t key;
10053  for (std::size_t i = 0; i < len; ++i)
10054  {
10055  get();
10056  if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
10057  {
10058  return false;
10059  }
10060 
10061  if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10062  {
10063  return false;
10064  }
10065  key.clear();
10066  }
10067 
10068  return sax->end_object();
10069  }
10070 
10072  // UBJSON //
10074 
10082  bool parse_ubjson_internal(const bool get_char = true)
10083  {
10084  return get_ubjson_value(get_char ? get_ignore_noop() : current);
10085  }
10086 
10101  bool get_ubjson_string(string_t& result, const bool get_char = true)
10102  {
10103  if (get_char)
10104  {
10105  get(); // TODO(niels): may we ignore N here?
10106  }
10107 
10108  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
10109  {
10110  return false;
10111  }
10112 
10113  switch (current)
10114  {
10115  case 'U':
10116  {
10117  std::uint8_t len{};
10118  return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10119  }
10120 
10121  case 'i':
10122  {
10123  std::int8_t len{};
10124  return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10125  }
10126 
10127  case 'I':
10128  {
10129  std::int16_t len{};
10130  return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10131  }
10132 
10133  case 'l':
10134  {
10135  std::int32_t len{};
10136  return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10137  }
10138 
10139  case 'L':
10140  {
10141  std::int64_t len{};
10142  return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10143  }
10144 
10145  default:
10146  auto last_token = get_token_string();
10147  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()));
10148  }
10149  }
10150 
10155  bool get_ubjson_size_value(std::size_t& result)
10156  {
10157  switch (get_ignore_noop())
10158  {
10159  case 'U':
10160  {
10161  std::uint8_t number{};
10162  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10163  {
10164  return false;
10165  }
10166  result = static_cast<std::size_t>(number);
10167  return true;
10168  }
10169 
10170  case 'i':
10171  {
10172  std::int8_t number{};
10173  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10174  {
10175  return false;
10176  }
10177  result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
10178  return true;
10179  }
10180 
10181  case 'I':
10182  {
10183  std::int16_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 'l':
10193  {
10194  std::int32_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);
10200  return true;
10201  }
10202 
10203  case 'L':
10204  {
10205  std::int64_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  default:
10215  {
10216  auto last_token = get_token_string();
10217  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()));
10218  }
10219  }
10220  }
10221 
10232  bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
10233  {
10234  result.first = string_t::npos; // size
10235  result.second = 0; // type
10236 
10237  get_ignore_noop();
10238 
10239  if (current == '$')
10240  {
10241  result.second = get(); // must not ignore 'N', because 'N' maybe the type
10242  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type")))
10243  {
10244  return false;
10245  }
10246 
10247  get_ignore_noop();
10248  if (JSON_HEDLEY_UNLIKELY(current != '#'))
10249  {
10250  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
10251  {
10252  return false;
10253  }
10254  auto last_token = get_token_string();
10255  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()));
10256  }
10257 
10258  return get_ubjson_size_value(result.first);
10259  }
10260 
10261  if (current == '#')
10262  {
10263  return get_ubjson_size_value(result.first);
10264  }
10265 
10266  return true;
10267  }
10268 
10273  bool get_ubjson_value(const char_int_type prefix)
10274  {
10275  switch (prefix)
10276  {
10277  case std::char_traits<char_type>::eof(): // EOF
10278  return unexpect_eof(input_format_t::ubjson, "value");
10279 
10280  case 'T': // true
10281  return sax->boolean(true);
10282  case 'F': // false
10283  return sax->boolean(false);
10284 
10285  case 'Z': // null
10286  return sax->null();
10287 
10288  case 'U':
10289  {
10290  std::uint8_t number{};
10291  return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
10292  }
10293 
10294  case 'i':
10295  {
10296  std::int8_t number{};
10297  return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10298  }
10299 
10300  case 'I':
10301  {
10302  std::int16_t number{};
10303  return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10304  }
10305 
10306  case 'l':
10307  {
10308  std::int32_t number{};
10309  return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10310  }
10311 
10312  case 'L':
10313  {
10314  std::int64_t number{};
10315  return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10316  }
10317 
10318  case 'd':
10319  {
10320  float number{};
10321  return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10322  }
10323 
10324  case 'D':
10325  {
10326  double number{};
10327  return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10328  }
10329 
10330  case 'H':
10331  {
10332  return get_ubjson_high_precision_number();
10333  }
10334 
10335  case 'C': // char
10336  {
10337  get();
10338  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char")))
10339  {
10340  return false;
10341  }
10342  if (JSON_HEDLEY_UNLIKELY(current > 127))
10343  {
10344  auto last_token = get_token_string();
10345  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()));
10346  }
10347  string_t s(1, static_cast<typename string_t::value_type>(current));
10348  return sax->string(s);
10349  }
10350 
10351  case 'S': // string
10352  {
10353  string_t s;
10354  return get_ubjson_string(s) && sax->string(s);
10355  }
10356 
10357  case '[': // array
10358  return get_ubjson_array();
10359 
10360  case '{': // object
10361  return get_ubjson_object();
10362 
10363  default: // anything else
10364  {
10365  auto last_token = get_token_string();
10366  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()));
10367  }
10368  }
10369  }
10370 
10374  bool get_ubjson_array()
10375  {
10376  std::pair<std::size_t, char_int_type> size_and_type;
10377  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10378  {
10379  return false;
10380  }
10381 
10382  if (size_and_type.first != string_t::npos)
10383  {
10384  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
10385  {
10386  return false;
10387  }
10388 
10389  if (size_and_type.second != 0)
10390  {
10391  if (size_and_type.second != 'N')
10392  {
10393  for (std::size_t i = 0; i < size_and_type.first; ++i)
10394  {
10395  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10396  {
10397  return false;
10398  }
10399  }
10400  }
10401  }
10402  else
10403  {
10404  for (std::size_t i = 0; i < size_and_type.first; ++i)
10405  {
10406  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10407  {
10408  return false;
10409  }
10410  }
10411  }
10412  }
10413  else
10414  {
10415  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10416  {
10417  return false;
10418  }
10419 
10420  while (current != ']')
10421  {
10422  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
10423  {
10424  return false;
10425  }
10426  get_ignore_noop();
10427  }
10428  }
10429 
10430  return sax->end_array();
10431  }
10432 
10436  bool get_ubjson_object()
10437  {
10438  std::pair<std::size_t, char_int_type> size_and_type;
10439  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10440  {
10441  return false;
10442  }
10443 
10444  string_t key;
10445  if (size_and_type.first != string_t::npos)
10446  {
10447  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
10448  {
10449  return false;
10450  }
10451 
10452  if (size_and_type.second != 0)
10453  {
10454  for (std::size_t i = 0; i < size_and_type.first; ++i)
10455  {
10456  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10457  {
10458  return false;
10459  }
10460  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10461  {
10462  return false;
10463  }
10464  key.clear();
10465  }
10466  }
10467  else
10468  {
10469  for (std::size_t i = 0; i < size_and_type.first; ++i)
10470  {
10471  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10472  {
10473  return false;
10474  }
10475  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10476  {
10477  return false;
10478  }
10479  key.clear();
10480  }
10481  }
10482  }
10483  else
10484  {
10485  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10486  {
10487  return false;
10488  }
10489 
10490  while (current != '}')
10491  {
10492  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
10493  {
10494  return false;
10495  }
10496  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10497  {
10498  return false;
10499  }
10500  get_ignore_noop();
10501  key.clear();
10502  }
10503  }
10504 
10505  return sax->end_object();
10506  }
10507 
10508  // Note, no reader for UBJSON binary types is implemented because they do
10509  // not exist
10510 
10511  bool get_ubjson_high_precision_number()
10512  {
10513  // get size of following number string
10514  std::size_t size{};
10515  auto res = get_ubjson_size_value(size);
10516  if (JSON_HEDLEY_UNLIKELY(!res))
10517  {
10518  return res;
10519  }
10520 
10521  // get number string
10522  std::vector<char> number_vector;
10523  for (std::size_t i = 0; i < size; ++i)
10524  {
10525  get();
10526  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number")))
10527  {
10528  return false;
10529  }
10530  number_vector.push_back(static_cast<char>(current));
10531  }
10532 
10533  // parse number string
10534  using ia_type = decltype(detail::input_adapter(number_vector));
10535  auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
10536  const auto result_number = number_lexer.scan();
10537  const auto number_string = number_lexer.get_token_string();
10538  const auto result_remainder = number_lexer.scan();
10539 
10540  using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
10541 
10542  if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
10543  {
10544  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()));
10545  }
10546 
10547  switch (result_number)
10548  {
10549  case token_type::value_integer:
10550  return sax->number_integer(number_lexer.get_number_integer());
10551  case token_type::value_unsigned:
10552  return sax->number_unsigned(number_lexer.get_number_unsigned());
10553  case token_type::value_float:
10554  return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
10555  case token_type::uninitialized:
10556  case token_type::literal_true:
10557  case token_type::literal_false:
10558  case token_type::literal_null:
10559  case token_type::value_string:
10560  case token_type::begin_array:
10561  case token_type::begin_object:
10562  case token_type::end_array:
10563  case token_type::end_object:
10564  case token_type::name_separator:
10565  case token_type::value_separator:
10566  case token_type::parse_error:
10567  case token_type::end_of_input:
10568  case token_type::literal_or_value:
10569  default:
10570  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()));
10571  }
10572  }
10573 
10575  // Utility functions //
10577 
10587  char_int_type get()
10588  {
10589  ++chars_read;
10590  return current = ia.get_character();
10591  }
10592 
10596  char_int_type get_ignore_noop()
10597  {
10598  do
10599  {
10600  get();
10601  }
10602  while (current == 'N');
10603 
10604  return current;
10605  }
10606 
10607  /*
10608  @brief read a number from the input
10609 
10610  @tparam NumberType the type of the number
10611  @param[in] format the current format (for diagnostics)
10612  @param[out] result number of type @a NumberType
10613 
10614  @return whether conversion completed
10615 
10616  @note This function needs to respect the system's endianess, because
10617  bytes in CBOR, MessagePack, and UBJSON are stored in network order
10618  (big endian) and therefore need reordering on little endian systems.
10619  */
10620  template<typename NumberType, bool InputIsLittleEndian = false>
10621  bool get_number(const input_format_t format, NumberType& result)
10622  {
10623  // step 1: read input into array with system's byte order
10624  std::array<std::uint8_t, sizeof(NumberType)> vec{};
10625  for (std::size_t i = 0; i < sizeof(NumberType); ++i)
10626  {
10627  get();
10628  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
10629  {
10630  return false;
10631  }
10632 
10633  // reverse byte order prior to conversion if necessary
10634  if (is_little_endian != InputIsLittleEndian)
10635  {
10636  vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
10637  }
10638  else
10639  {
10640  vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
10641  }
10642  }
10643 
10644  // step 2: convert array into number of type T and return
10645  std::memcpy(&result, vec.data(), sizeof(NumberType));
10646  return true;
10647  }
10648 
10663  template<typename NumberType>
10664  bool get_string(const input_format_t format,
10665  const NumberType len,
10666  string_t& result)
10667  {
10668  bool success = true;
10669  for (NumberType i = 0; i < len; i++)
10670  {
10671  get();
10672  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
10673  {
10674  success = false;
10675  break;
10676  }
10677  result.push_back(static_cast<typename string_t::value_type>(current));
10678  }
10679  return success;
10680  }
10681 
10696  template<typename NumberType>
10697  bool get_binary(const input_format_t format,
10698  const NumberType len,
10699  binary_t& result)
10700  {
10701  bool success = true;
10702  for (NumberType i = 0; i < len; i++)
10703  {
10704  get();
10705  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10706  {
10707  success = false;
10708  break;
10709  }
10710  result.push_back(static_cast<std::uint8_t>(current));
10711  }
10712  return success;
10713  }
10714 
10720  JSON_HEDLEY_NON_NULL(3)
10721  bool unexpect_eof(const input_format_t format, const char* context) const
10722  {
10723  if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
10724  {
10725  return sax->parse_error(chars_read, "<end of file>",
10726  parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), BasicJsonType()));
10727  }
10728  return true;
10729  }
10730 
10734  std::string get_token_string() const
10735  {
10736  std::array<char, 3> cr{{}};
10737  (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
10738  return std::string{cr.data()};
10739  }
10740 
10747  std::string exception_message(const input_format_t format,
10748  const std::string& detail,
10749  const std::string& context) const
10750  {
10751  std::string error_msg = "syntax error while parsing ";
10752 
10753  switch (format)
10754  {
10755  case input_format_t::cbor:
10756  error_msg += "CBOR";
10757  break;
10758 
10759  case input_format_t::msgpack:
10760  error_msg += "MessagePack";
10761  break;
10762 
10763  case input_format_t::ubjson:
10764  error_msg += "UBJSON";
10765  break;
10766 
10767  case input_format_t::bson:
10768  error_msg += "BSON";
10769  break;
10770 
10771  case input_format_t::json: // LCOV_EXCL_LINE
10772  default: // LCOV_EXCL_LINE
10773  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
10774  }
10775 
10776  return error_msg + " " + context + ": " + detail;
10777  }
10778 
10779  private:
10781  InputAdapterType ia;
10782 
10784  char_int_type current = std::char_traits<char_type>::eof();
10785 
10787  std::size_t chars_read = 0;
10788 
10790  const bool is_little_endian = little_endianess();
10791 
10793  json_sax_t* sax = nullptr;
10794 };
10795 } // namespace detail
10796 } // namespace nlohmann
10797 
10798 // #include <nlohmann/detail/input/input_adapters.hpp>
10799 
10800 // #include <nlohmann/detail/input/lexer.hpp>
10801 
10802 // #include <nlohmann/detail/input/parser.hpp>
10803 
10804 
10805 #include <cmath> // isfinite
10806 #include <cstdint> // uint8_t
10807 #include <functional> // function
10808 #include <string> // string
10809 #include <utility> // move
10810 #include <vector> // vector
10811 
10812 // #include <nlohmann/detail/exceptions.hpp>
10813 
10814 // #include <nlohmann/detail/input/input_adapters.hpp>
10815 
10816 // #include <nlohmann/detail/input/json_sax.hpp>
10817 
10818 // #include <nlohmann/detail/input/lexer.hpp>
10819 
10820 // #include <nlohmann/detail/macro_scope.hpp>
10821 
10822 // #include <nlohmann/detail/meta/is_sax.hpp>
10823 
10824 // #include <nlohmann/detail/value_t.hpp>
10825 
10826 
10827 namespace nlohmann
10828 {
10829 namespace detail
10830 {
10832 // parser //
10834 
10835 enum class parse_event_t : std::uint8_t
10836 {
10838  object_start,
10840  object_end,
10842  array_start,
10844  array_end,
10846  key,
10848  value
10849 };
10850 
10851 template<typename BasicJsonType>
10852 using parser_callback_t =
10853  std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
10854 
10860 template<typename BasicJsonType, typename InputAdapterType>
10861 class parser
10862 {
10863  using number_integer_t = typename BasicJsonType::number_integer_t;
10864  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10865  using number_float_t = typename BasicJsonType::number_float_t;
10866  using string_t = typename BasicJsonType::string_t;
10867  using lexer_t = lexer<BasicJsonType, InputAdapterType>;
10868  using token_type = typename lexer_t::token_type;
10869 
10870  public:
10872  explicit parser(InputAdapterType&& adapter,
10873  const parser_callback_t<BasicJsonType> cb = nullptr,
10874  const bool allow_exceptions_ = true,
10875  const bool skip_comments = false)
10876  : callback(cb)
10877  , m_lexer(std::move(adapter), skip_comments)
10878  , allow_exceptions(allow_exceptions_)
10879  {
10880  // read first token
10881  get_token();
10882  }
10883 
10894  void parse(const bool strict, BasicJsonType& result)
10895  {
10896  if (callback)
10897  {
10898  json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
10899  sax_parse_internal(&sdp);
10900 
10901  // in strict mode, input must be completely read
10902  if (strict && (get_token() != token_type::end_of_input))
10903  {
10904  sdp.parse_error(m_lexer.get_position(),
10905  m_lexer.get_token_string(),
10906  parse_error::create(101, m_lexer.get_position(),
10907  exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10908  }
10909 
10910  // in case of an error, return discarded value
10911  if (sdp.is_errored())
10912  {
10913  result = value_t::discarded;
10914  return;
10915  }
10916 
10917  // set top-level value to null if it was discarded by the callback
10918  // function
10919  if (result.is_discarded())
10920  {
10921  result = nullptr;
10922  }
10923  }
10924  else
10925  {
10926  json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
10927  sax_parse_internal(&sdp);
10928 
10929  // in strict mode, input must be completely read
10930  if (strict && (get_token() != token_type::end_of_input))
10931  {
10932  sdp.parse_error(m_lexer.get_position(),
10933  m_lexer.get_token_string(),
10934  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10935  }
10936 
10937  // in case of an error, return discarded value
10938  if (sdp.is_errored())
10939  {
10940  result = value_t::discarded;
10941  return;
10942  }
10943  }
10944 
10945  result.assert_invariant();
10946  }
10947 
10954  bool accept(const bool strict = true)
10955  {
10956  json_sax_acceptor<BasicJsonType> sax_acceptor;
10957  return sax_parse(&sax_acceptor, strict);
10958  }
10959 
10960  template<typename SAX>
10961  JSON_HEDLEY_NON_NULL(2)
10962  bool sax_parse(SAX* sax, const bool strict = true)
10963  {
10964  (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
10965  const bool result = sax_parse_internal(sax);
10966 
10967  // strict mode: next byte must be EOF
10968  if (result && strict && (get_token() != token_type::end_of_input))
10969  {
10970  return sax->parse_error(m_lexer.get_position(),
10971  m_lexer.get_token_string(),
10972  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10973  }
10974 
10975  return result;
10976  }
10977 
10978  private:
10979  template<typename SAX>
10980  JSON_HEDLEY_NON_NULL(2)
10981  bool sax_parse_internal(SAX* sax)
10982  {
10983  // stack to remember the hierarchy of structured values we are parsing
10984  // true = array; false = object
10985  std::vector<bool> states;
10986  // value to avoid a goto (see comment where set to true)
10987  bool skip_to_state_evaluation = false;
10988 
10989  while (true)
10990  {
10991  if (!skip_to_state_evaluation)
10992  {
10993  // invariant: get_token() was called before each iteration
10994  switch (last_token)
10995  {
10996  case token_type::begin_object:
10997  {
10998  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10999  {
11000  return false;
11001  }
11002 
11003  // closing } -> we are done
11004  if (get_token() == token_type::end_object)
11005  {
11006  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11007  {
11008  return false;
11009  }
11010  break;
11011  }
11012 
11013  // parse key
11014  if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
11015  {
11016  return sax->parse_error(m_lexer.get_position(),
11017  m_lexer.get_token_string(),
11018  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11019  }
11020  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11021  {
11022  return false;
11023  }
11024 
11025  // parse separator (:)
11026  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11027  {
11028  return sax->parse_error(m_lexer.get_position(),
11029  m_lexer.get_token_string(),
11030  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11031  }
11032 
11033  // remember we are now inside an object
11034  states.push_back(false);
11035 
11036  // parse values
11037  get_token();
11038  continue;
11039  }
11040 
11041  case token_type::begin_array:
11042  {
11043  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
11044  {
11045  return false;
11046  }
11047 
11048  // closing ] -> we are done
11049  if (get_token() == token_type::end_array)
11050  {
11051  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11052  {
11053  return false;
11054  }
11055  break;
11056  }
11057 
11058  // remember we are now inside an array
11059  states.push_back(true);
11060 
11061  // parse values (no need to call get_token)
11062  continue;
11063  }
11064 
11065  case token_type::value_float:
11066  {
11067  const auto res = m_lexer.get_number_float();
11068 
11069  if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
11070  {
11071  return sax->parse_error(m_lexer.get_position(),
11072  m_lexer.get_token_string(),
11073  out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType()));
11074  }
11075 
11076  if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
11077  {
11078  return false;
11079  }
11080 
11081  break;
11082  }
11083 
11084  case token_type::literal_false:
11085  {
11086  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
11087  {
11088  return false;
11089  }
11090  break;
11091  }
11092 
11093  case token_type::literal_null:
11094  {
11095  if (JSON_HEDLEY_UNLIKELY(!sax->null()))
11096  {
11097  return false;
11098  }
11099  break;
11100  }
11101 
11102  case token_type::literal_true:
11103  {
11104  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
11105  {
11106  return false;
11107  }
11108  break;
11109  }
11110 
11111  case token_type::value_integer:
11112  {
11113  if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
11114  {
11115  return false;
11116  }
11117  break;
11118  }
11119 
11120  case token_type::value_string:
11121  {
11122  if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
11123  {
11124  return false;
11125  }
11126  break;
11127  }
11128 
11129  case token_type::value_unsigned:
11130  {
11131  if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
11132  {
11133  return false;
11134  }
11135  break;
11136  }
11137 
11138  case token_type::parse_error:
11139  {
11140  // using "uninitialized" to avoid "expected" message
11141  return sax->parse_error(m_lexer.get_position(),
11142  m_lexer.get_token_string(),
11143  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType()));
11144  }
11145 
11146  case token_type::uninitialized:
11147  case token_type::end_array:
11148  case token_type::end_object:
11149  case token_type::name_separator:
11150  case token_type::value_separator:
11151  case token_type::end_of_input:
11152  case token_type::literal_or_value:
11153  default: // the last token was unexpected
11154  {
11155  return sax->parse_error(m_lexer.get_position(),
11156  m_lexer.get_token_string(),
11157  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), BasicJsonType()));
11158  }
11159  }
11160  }
11161  else
11162  {
11163  skip_to_state_evaluation = false;
11164  }
11165 
11166  // we reached this line after we successfully parsed a value
11167  if (states.empty())
11168  {
11169  // empty stack: we reached the end of the hierarchy: done
11170  return true;
11171  }
11172 
11173  if (states.back()) // array
11174  {
11175  // comma -> next value
11176  if (get_token() == token_type::value_separator)
11177  {
11178  // parse a new value
11179  get_token();
11180  continue;
11181  }
11182 
11183  // closing ]
11184  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
11185  {
11186  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11187  {
11188  return false;
11189  }
11190 
11191  // We are done with this array. Before we can parse a
11192  // new value, we need to evaluate the new state first.
11193  // By setting skip_to_state_evaluation to false, we
11194  // are effectively jumping to the beginning of this if.
11195  JSON_ASSERT(!states.empty());
11196  states.pop_back();
11197  skip_to_state_evaluation = true;
11198  continue;
11199  }
11200 
11201  return sax->parse_error(m_lexer.get_position(),
11202  m_lexer.get_token_string(),
11203  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), BasicJsonType()));
11204  }
11205 
11206  // states.back() is false -> object
11207 
11208  // comma -> next value
11209  if (get_token() == token_type::value_separator)
11210  {
11211  // parse key
11212  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
11213  {
11214  return sax->parse_error(m_lexer.get_position(),
11215  m_lexer.get_token_string(),
11216  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11217  }
11218 
11219  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11220  {
11221  return false;
11222  }
11223 
11224  // parse separator (:)
11225  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11226  {
11227  return sax->parse_error(m_lexer.get_position(),
11228  m_lexer.get_token_string(),
11229  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11230  }
11231 
11232  // parse values
11233  get_token();
11234  continue;
11235  }
11236 
11237  // closing }
11238  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
11239  {
11240  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11241  {
11242  return false;
11243  }
11244 
11245  // We are done with this object. Before we can parse a
11246  // new value, we need to evaluate the new state first.
11247  // By setting skip_to_state_evaluation to false, we
11248  // are effectively jumping to the beginning of this if.
11249  JSON_ASSERT(!states.empty());
11250  states.pop_back();
11251  skip_to_state_evaluation = true;
11252  continue;
11253  }
11254 
11255  return sax->parse_error(m_lexer.get_position(),
11256  m_lexer.get_token_string(),
11257  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), BasicJsonType()));
11258  }
11259  }
11260 
11262  token_type get_token()
11263  {
11264  return last_token = m_lexer.scan();
11265  }
11266 
11267  std::string exception_message(const token_type expected, const std::string& context)
11268  {
11269  std::string error_msg = "syntax error ";
11270 
11271  if (!context.empty())
11272  {
11273  error_msg += "while parsing " + context + " ";
11274  }
11275 
11276  error_msg += "- ";
11277 
11278  if (last_token == token_type::parse_error)
11279  {
11280  error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
11281  m_lexer.get_token_string() + "'";
11282  }
11283  else
11284  {
11285  error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
11286  }
11287 
11288  if (expected != token_type::uninitialized)
11289  {
11290  error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
11291  }
11292 
11293  return error_msg;
11294  }
11295 
11296  private:
11298  const parser_callback_t<BasicJsonType> callback = nullptr;
11300  token_type last_token = token_type::uninitialized;
11302  lexer_t m_lexer;
11304  const bool allow_exceptions = true;
11305 };
11306 
11307 } // namespace detail
11308 } // namespace nlohmann
11309 
11310 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
11311 
11312 
11313 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11314 
11315 
11316 #include <cstddef> // ptrdiff_t
11317 #include <limits> // numeric_limits
11318 
11319 // #include <nlohmann/detail/macro_scope.hpp>
11320 
11321 
11322 namespace nlohmann
11323 {
11324 namespace detail
11325 {
11326 /*
11327 @brief an iterator for primitive JSON types
11328 
11329 This class models an iterator for primitive JSON types (boolean, number,
11330 string). It's only purpose is to allow the iterator/const_iterator classes
11331 to "iterate" over primitive values. Internally, the iterator is modeled by
11332 a `difference_type` variable. Value begin_value (`0`) models the begin,
11333 end_value (`1`) models past the end.
11334 */
11335 class primitive_iterator_t
11336 {
11337  private:
11338  using difference_type = std::ptrdiff_t;
11339  static constexpr difference_type begin_value = 0;
11340  static constexpr difference_type end_value = begin_value + 1;
11341 
11342  JSON_PRIVATE_UNLESS_TESTED:
11344  difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
11345 
11346  public:
11347  constexpr difference_type get_value() const noexcept
11348  {
11349  return m_it;
11350  }
11351 
11353  void set_begin() noexcept
11354  {
11355  m_it = begin_value;
11356  }
11357 
11359  void set_end() noexcept
11360  {
11361  m_it = end_value;
11362  }
11363 
11365  constexpr bool is_begin() const noexcept
11366  {
11367  return m_it == begin_value;
11368  }
11369 
11371  constexpr bool is_end() const noexcept
11372  {
11373  return m_it == end_value;
11374  }
11375 
11376  friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11377  {
11378  return lhs.m_it == rhs.m_it;
11379  }
11380 
11381  friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11382  {
11383  return lhs.m_it < rhs.m_it;
11384  }
11385 
11386  primitive_iterator_t operator+(difference_type n) noexcept
11387  {
11388  auto result = *this;
11389  result += n;
11390  return result;
11391  }
11392 
11393  friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11394  {
11395  return lhs.m_it - rhs.m_it;
11396  }
11397 
11398  primitive_iterator_t& operator++() noexcept
11399  {
11400  ++m_it;
11401  return *this;
11402  }
11403 
11404  primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)
11405  {
11406  auto result = *this;
11407  ++m_it;
11408  return result;
11409  }
11410 
11411  primitive_iterator_t& operator--() noexcept
11412  {
11413  --m_it;
11414  return *this;
11415  }
11416 
11417  primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)
11418  {
11419  auto result = *this;
11420  --m_it;
11421  return result;
11422  }
11423 
11424  primitive_iterator_t& operator+=(difference_type n) noexcept
11425  {
11426  m_it += n;
11427  return *this;
11428  }
11429 
11430  primitive_iterator_t& operator-=(difference_type n) noexcept
11431  {
11432  m_it -= n;
11433  return *this;
11434  }
11435 };
11436 } // namespace detail
11437 } // namespace nlohmann
11438 
11439 
11440 namespace nlohmann
11441 {
11442 namespace detail
11443 {
11450 template<typename BasicJsonType> struct internal_iterator
11451 {
11453  typename BasicJsonType::object_t::iterator object_iterator {};
11455  typename BasicJsonType::array_t::iterator array_iterator {};
11457  primitive_iterator_t primitive_iterator {};
11458 };
11459 } // namespace detail
11460 } // namespace nlohmann
11461 
11462 // #include <nlohmann/detail/iterators/iter_impl.hpp>
11463 
11464 
11465 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
11466 #include <type_traits> // conditional, is_const, remove_const
11467 
11468 // #include <nlohmann/detail/exceptions.hpp>
11469 
11470 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
11471 
11472 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11473 
11474 // #include <nlohmann/detail/macro_scope.hpp>
11475 
11476 // #include <nlohmann/detail/meta/cpp_future.hpp>
11477 
11478 // #include <nlohmann/detail/meta/type_traits.hpp>
11479 
11480 // #include <nlohmann/detail/value_t.hpp>
11481 
11482 
11483 namespace nlohmann
11484 {
11485 namespace detail
11486 {
11487 // forward declare, to be able to friend it later on
11488 template<typename IteratorType> class iteration_proxy;
11489 template<typename IteratorType> class iteration_proxy_value;
11490 
11507 template<typename BasicJsonType>
11508 class iter_impl
11509 {
11511  using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
11513  friend other_iter_impl;
11514  friend BasicJsonType;
11515  friend iteration_proxy<iter_impl>;
11516  friend iteration_proxy_value<iter_impl>;
11517 
11518  using object_t = typename BasicJsonType::object_t;
11519  using array_t = typename BasicJsonType::array_t;
11520  // make sure BasicJsonType is basic_json or const basic_json
11521  static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
11522  "iter_impl only accepts (const) basic_json");
11523 
11524  public:
11525 
11531  using iterator_category = std::bidirectional_iterator_tag;
11532 
11534  using value_type = typename BasicJsonType::value_type;
11536  using difference_type = typename BasicJsonType::difference_type;
11538  using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
11539  typename BasicJsonType::const_pointer,
11540  typename BasicJsonType::pointer>::type;
11542  using reference =
11543  typename std::conditional<std::is_const<BasicJsonType>::value,
11544  typename BasicJsonType::const_reference,
11545  typename BasicJsonType::reference>::type;
11546 
11547  iter_impl() = default;
11548  ~iter_impl() = default;
11549  iter_impl(iter_impl&&) noexcept = default;
11550  iter_impl& operator=(iter_impl&&) noexcept = default;
11551 
11558  explicit iter_impl(pointer object) noexcept : m_object(object)
11559  {
11560  JSON_ASSERT(m_object != nullptr);
11561 
11562  switch (m_object->m_type)
11563  {
11564  case value_t::object:
11565  {
11566  m_it.object_iterator = typename object_t::iterator();
11567  break;
11568  }
11569 
11570  case value_t::array:
11571  {
11572  m_it.array_iterator = typename array_t::iterator();
11573  break;
11574  }
11575 
11576  case value_t::null:
11577  case value_t::string:
11578  case value_t::boolean:
11579  case value_t::number_integer:
11580  case value_t::number_unsigned:
11581  case value_t::number_float:
11582  case value_t::binary:
11583  case value_t::discarded:
11584  default:
11585  {
11586  m_it.primitive_iterator = primitive_iterator_t();
11587  break;
11588  }
11589  }
11590  }
11591 
11608  iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
11609  : m_object(other.m_object), m_it(other.m_it)
11610  {}
11611 
11618  iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
11619  {
11620  if (&other != this)
11621  {
11622  m_object = other.m_object;
11623  m_it = other.m_it;
11624  }
11625  return *this;
11626  }
11627 
11633  iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
11634  : m_object(other.m_object), m_it(other.m_it)
11635  {}
11636 
11643  iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
11644  {
11645  m_object = other.m_object;
11646  m_it = other.m_it;
11647  return *this;
11648  }
11649 
11650  JSON_PRIVATE_UNLESS_TESTED:
11655  void set_begin() noexcept
11656  {
11657  JSON_ASSERT(m_object != nullptr);
11658 
11659  switch (m_object->m_type)
11660  {
11661  case value_t::object:
11662  {
11663  m_it.object_iterator = m_object->m_value.object->begin();
11664  break;
11665  }
11666 
11667  case value_t::array:
11668  {
11669  m_it.array_iterator = m_object->m_value.array->begin();
11670  break;
11671  }
11672 
11673  case value_t::null:
11674  {
11675  // set to end so begin()==end() is true: null is empty
11676  m_it.primitive_iterator.set_end();
11677  break;
11678  }
11679 
11680  case value_t::string:
11681  case value_t::boolean:
11682  case value_t::number_integer:
11683  case value_t::number_unsigned:
11684  case value_t::number_float:
11685  case value_t::binary:
11686  case value_t::discarded:
11687  default:
11688  {
11689  m_it.primitive_iterator.set_begin();
11690  break;
11691  }
11692  }
11693  }
11694 
11699  void set_end() noexcept
11700  {
11701  JSON_ASSERT(m_object != nullptr);
11702 
11703  switch (m_object->m_type)
11704  {
11705  case value_t::object:
11706  {
11707  m_it.object_iterator = m_object->m_value.object->end();
11708  break;
11709  }
11710 
11711  case value_t::array:
11712  {
11713  m_it.array_iterator = m_object->m_value.array->end();
11714  break;
11715  }
11716 
11717  case value_t::null:
11718  case value_t::string:
11719  case value_t::boolean:
11720  case value_t::number_integer:
11721  case value_t::number_unsigned:
11722  case value_t::number_float:
11723  case value_t::binary:
11724  case value_t::discarded:
11725  default:
11726  {
11727  m_it.primitive_iterator.set_end();
11728  break;
11729  }
11730  }
11731  }
11732 
11733  public:
11738  reference operator*() const
11739  {
11740  JSON_ASSERT(m_object != nullptr);
11741 
11742  switch (m_object->m_type)
11743  {
11744  case value_t::object:
11745  {
11746  JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11747  return m_it.object_iterator->second;
11748  }
11749 
11750  case value_t::array:
11751  {
11752  JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11753  return *m_it.array_iterator;
11754  }
11755 
11756  case value_t::null:
11757  JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11758 
11759  case value_t::string:
11760  case value_t::boolean:
11761  case value_t::number_integer:
11762  case value_t::number_unsigned:
11763  case value_t::number_float:
11764  case value_t::binary:
11765  case value_t::discarded:
11766  default:
11767  {
11768  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11769  {
11770  return *m_object;
11771  }
11772 
11773  JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11774  }
11775  }
11776  }
11777 
11782  pointer operator->() const
11783  {
11784  JSON_ASSERT(m_object != nullptr);
11785 
11786  switch (m_object->m_type)
11787  {
11788  case value_t::object:
11789  {
11790  JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11791  return &(m_it.object_iterator->second);
11792  }
11793 
11794  case value_t::array:
11795  {
11796  JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11797  return &*m_it.array_iterator;
11798  }
11799 
11800  case value_t::null:
11801  case value_t::string:
11802  case value_t::boolean:
11803  case value_t::number_integer:
11804  case value_t::number_unsigned:
11805  case value_t::number_float:
11806  case value_t::binary:
11807  case value_t::discarded:
11808  default:
11809  {
11810  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11811  {
11812  return m_object;
11813  }
11814 
11815  JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11816  }
11817  }
11818  }
11819 
11824  iter_impl const operator++(int) // NOLINT(readability-const-return-type)
11825  {
11826  auto result = *this;
11827  ++(*this);
11828  return result;
11829  }
11830 
11835  iter_impl& operator++()
11836  {
11837  JSON_ASSERT(m_object != nullptr);
11838 
11839  switch (m_object->m_type)
11840  {
11841  case value_t::object:
11842  {
11843  std::advance(m_it.object_iterator, 1);
11844  break;
11845  }
11846 
11847  case value_t::array:
11848  {
11849  std::advance(m_it.array_iterator, 1);
11850  break;
11851  }
11852 
11853  case value_t::null:
11854  case value_t::string:
11855  case value_t::boolean:
11856  case value_t::number_integer:
11857  case value_t::number_unsigned:
11858  case value_t::number_float:
11859  case value_t::binary:
11860  case value_t::discarded:
11861  default:
11862  {
11863  ++m_it.primitive_iterator;
11864  break;
11865  }
11866  }
11867 
11868  return *this;
11869  }
11870 
11875  iter_impl const operator--(int) // NOLINT(readability-const-return-type)
11876  {
11877  auto result = *this;
11878  --(*this);
11879  return result;
11880  }
11881 
11886  iter_impl& operator--()
11887  {
11888  JSON_ASSERT(m_object != nullptr);
11889 
11890  switch (m_object->m_type)
11891  {
11892  case value_t::object:
11893  {
11894  std::advance(m_it.object_iterator, -1);
11895  break;
11896  }
11897 
11898  case value_t::array:
11899  {
11900  std::advance(m_it.array_iterator, -1);
11901  break;
11902  }
11903 
11904  case value_t::null:
11905  case value_t::string:
11906  case value_t::boolean:
11907  case value_t::number_integer:
11908  case value_t::number_unsigned:
11909  case value_t::number_float:
11910  case value_t::binary:
11911  case value_t::discarded:
11912  default:
11913  {
11914  --m_it.primitive_iterator;
11915  break;
11916  }
11917  }
11918 
11919  return *this;
11920  }
11921 
11926  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 >
11927  bool operator==(const IterImpl& other) const
11928  {
11929  // if objects are not the same, the comparison is undefined
11930  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11931  {
11932  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
11933  }
11934 
11935  JSON_ASSERT(m_object != nullptr);
11936 
11937  switch (m_object->m_type)
11938  {
11939  case value_t::object:
11940  return (m_it.object_iterator == other.m_it.object_iterator);
11941 
11942  case value_t::array:
11943  return (m_it.array_iterator == other.m_it.array_iterator);
11944 
11945  case value_t::null:
11946  case value_t::string:
11947  case value_t::boolean:
11948  case value_t::number_integer:
11949  case value_t::number_unsigned:
11950  case value_t::number_float:
11951  case value_t::binary:
11952  case value_t::discarded:
11953  default:
11954  return (m_it.primitive_iterator == other.m_it.primitive_iterator);
11955  }
11956  }
11957 
11962  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 >
11963  bool operator!=(const IterImpl& other) const
11964  {
11965  return !operator==(other);
11966  }
11967 
11972  bool operator<(const iter_impl& other) const
11973  {
11974  // if objects are not the same, the comparison is undefined
11975  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11976  {
11977  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
11978  }
11979 
11980  JSON_ASSERT(m_object != nullptr);
11981 
11982  switch (m_object->m_type)
11983  {
11984  case value_t::object:
11985  JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", *m_object));
11986 
11987  case value_t::array:
11988  return (m_it.array_iterator < other.m_it.array_iterator);
11989 
11990  case value_t::null:
11991  case value_t::string:
11992  case value_t::boolean:
11993  case value_t::number_integer:
11994  case value_t::number_unsigned:
11995  case value_t::number_float:
11996  case value_t::binary:
11997  case value_t::discarded:
11998  default:
11999  return (m_it.primitive_iterator < other.m_it.primitive_iterator);
12000  }
12001  }
12002 
12007  bool operator<=(const iter_impl& other) const
12008  {
12009  return !other.operator < (*this);
12010  }
12011 
12016  bool operator>(const iter_impl& other) const
12017  {
12018  return !operator<=(other);
12019  }
12020 
12025  bool operator>=(const iter_impl& other) const
12026  {
12027  return !operator<(other);
12028  }
12029 
12034  iter_impl& operator+=(difference_type i)
12035  {
12036  JSON_ASSERT(m_object != nullptr);
12037 
12038  switch (m_object->m_type)
12039  {
12040  case value_t::object:
12041  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12042 
12043  case value_t::array:
12044  {
12045  std::advance(m_it.array_iterator, i);
12046  break;
12047  }
12048 
12049  case value_t::null:
12050  case value_t::string:
12051  case value_t::boolean:
12052  case value_t::number_integer:
12053  case value_t::number_unsigned:
12054  case value_t::number_float:
12055  case value_t::binary:
12056  case value_t::discarded:
12057  default:
12058  {
12059  m_it.primitive_iterator += i;
12060  break;
12061  }
12062  }
12063 
12064  return *this;
12065  }
12066 
12071  iter_impl& operator-=(difference_type i)
12072  {
12073  return operator+=(-i);
12074  }
12075 
12080  iter_impl operator+(difference_type i) const
12081  {
12082  auto result = *this;
12083  result += i;
12084  return result;
12085  }
12086 
12091  friend iter_impl operator+(difference_type i, const iter_impl& it)
12092  {
12093  auto result = it;
12094  result += i;
12095  return result;
12096  }
12097 
12102  iter_impl operator-(difference_type i) const
12103  {
12104  auto result = *this;
12105  result -= i;
12106  return result;
12107  }
12108 
12113  difference_type operator-(const iter_impl& other) const
12114  {
12115  JSON_ASSERT(m_object != nullptr);
12116 
12117  switch (m_object->m_type)
12118  {
12119  case value_t::object:
12120  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12121 
12122  case value_t::array:
12123  return m_it.array_iterator - other.m_it.array_iterator;
12124 
12125  case value_t::null:
12126  case value_t::string:
12127  case value_t::boolean:
12128  case value_t::number_integer:
12129  case value_t::number_unsigned:
12130  case value_t::number_float:
12131  case value_t::binary:
12132  case value_t::discarded:
12133  default:
12134  return m_it.primitive_iterator - other.m_it.primitive_iterator;
12135  }
12136  }
12137 
12142  reference operator[](difference_type n) const
12143  {
12144  JSON_ASSERT(m_object != nullptr);
12145 
12146  switch (m_object->m_type)
12147  {
12148  case value_t::object:
12149  JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", *m_object));
12150 
12151  case value_t::array:
12152  return *std::next(m_it.array_iterator, n);
12153 
12154  case value_t::null:
12155  JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12156 
12157  case value_t::string:
12158  case value_t::boolean:
12159  case value_t::number_integer:
12160  case value_t::number_unsigned:
12161  case value_t::number_float:
12162  case value_t::binary:
12163  case value_t::discarded:
12164  default:
12165  {
12166  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
12167  {
12168  return *m_object;
12169  }
12170 
12171  JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12172  }
12173  }
12174  }
12175 
12180  const typename object_t::key_type& key() const
12181  {
12182  JSON_ASSERT(m_object != nullptr);
12183 
12184  if (JSON_HEDLEY_LIKELY(m_object->is_object()))
12185  {
12186  return m_it.object_iterator->first;
12187  }
12188 
12189  JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", *m_object));
12190  }
12191 
12196  reference value() const
12197  {
12198  return operator*();
12199  }
12200 
12201  JSON_PRIVATE_UNLESS_TESTED:
12203  pointer m_object = nullptr;
12205  internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
12206 };
12207 } // namespace detail
12208 } // namespace nlohmann
12209 
12210 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
12211 
12212 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
12213 
12214 
12215 #include <cstddef> // ptrdiff_t
12216 #include <iterator> // reverse_iterator
12217 #include <utility> // declval
12218 
12219 namespace nlohmann
12220 {
12221 namespace detail
12222 {
12224 // reverse_iterator //
12226 
12245 template<typename Base>
12246 class json_reverse_iterator : public std::reverse_iterator<Base>
12247 {
12248  public:
12249  using difference_type = std::ptrdiff_t;
12251  using base_iterator = std::reverse_iterator<Base>;
12253  using reference = typename Base::reference;
12254 
12256  explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
12257  : base_iterator(it) {}
12258 
12260  explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
12261 
12263  json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)
12264  {
12265  return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
12266  }
12267 
12269  json_reverse_iterator& operator++()
12270  {
12271  return static_cast<json_reverse_iterator&>(base_iterator::operator++());
12272  }
12273 
12275  json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)
12276  {
12277  return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
12278  }
12279 
12281  json_reverse_iterator& operator--()
12282  {
12283  return static_cast<json_reverse_iterator&>(base_iterator::operator--());
12284  }
12285 
12287  json_reverse_iterator& operator+=(difference_type i)
12288  {
12289  return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
12290  }
12291 
12293  json_reverse_iterator operator+(difference_type i) const
12294  {
12295  return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
12296  }
12297 
12299  json_reverse_iterator operator-(difference_type i) const
12300  {
12301  return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
12302  }
12303 
12305  difference_type operator-(const json_reverse_iterator& other) const
12306  {
12307  return base_iterator(*this) - base_iterator(other);
12308  }
12309 
12311  reference operator[](difference_type n) const
12312  {
12313  return *(this->operator+(n));
12314  }
12315 
12317  auto key() const -> decltype(std::declval<Base>().key())
12318  {
12319  auto it = --this->base();
12320  return it.key();
12321  }
12322 
12324  reference value() const
12325  {
12326  auto it = --this->base();
12327  return it.operator * ();
12328  }
12329 };
12330 } // namespace detail
12331 } // namespace nlohmann
12332 
12333 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12334 
12335 // #include <nlohmann/detail/json_pointer.hpp>
12336 
12337 
12338 #include <algorithm> // all_of
12339 #include <cctype> // isdigit
12340 #include <limits> // max
12341 #include <numeric> // accumulate
12342 #include <string> // string
12343 #include <utility> // move
12344 #include <vector> // vector
12345 
12346 // #include <nlohmann/detail/exceptions.hpp>
12347 
12348 // #include <nlohmann/detail/macro_scope.hpp>
12349 
12350 // #include <nlohmann/detail/string_escape.hpp>
12351 
12352 // #include <nlohmann/detail/value_t.hpp>
12353 
12354 
12355 namespace nlohmann
12356 {
12357 template<typename BasicJsonType>
12359 {
12360  // allow basic_json to access private members
12361  NLOHMANN_BASIC_JSON_TPL_DECLARATION
12362  friend class basic_json;
12363 
12364  public:
12386  explicit json_pointer(const std::string& s = "")
12387  : reference_tokens(split(s))
12388  {}
12389 
12404  std::string to_string() const
12405  {
12406  return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
12407  std::string{},
12408  [](const std::string & a, const std::string & b)
12409  {
12410  return a + "/" + detail::escape(b);
12411  });
12412  }
12413 
12415  operator std::string() const
12416  {
12417  return to_string();
12418  }
12419 
12437  {
12438  reference_tokens.insert(reference_tokens.end(),
12439  ptr.reference_tokens.begin(),
12440  ptr.reference_tokens.end());
12441  return *this;
12442  }
12443 
12460  json_pointer& operator/=(std::string token)
12461  {
12462  push_back(std::move(token));
12463  return *this;
12464  }
12465 
12482  json_pointer& operator/=(std::size_t array_idx)
12483  {
12484  return *this /= std::to_string(array_idx);
12485  }
12486 
12503  const json_pointer& rhs)
12504  {
12505  return json_pointer(lhs) /= rhs;
12506  }
12507 
12523  friend json_pointer operator/(const json_pointer& ptr, std::string token) // NOLINT(performance-unnecessary-value-param)
12524  {
12525  return json_pointer(ptr) /= std::move(token);
12526  }
12527 
12543  friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
12544  {
12545  return json_pointer(ptr) /= array_idx;
12546  }
12547 
12562  {
12563  if (empty())
12564  {
12565  return *this;
12566  }
12567 
12568  json_pointer res = *this;
12569  res.pop_back();
12570  return res;
12571  }
12572 
12586  void pop_back()
12587  {
12588  if (JSON_HEDLEY_UNLIKELY(empty()))
12589  {
12590  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12591  }
12592 
12593  reference_tokens.pop_back();
12594  }
12595 
12610  const std::string& back() const
12611  {
12612  if (JSON_HEDLEY_UNLIKELY(empty()))
12613  {
12614  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12615  }
12616 
12617  return reference_tokens.back();
12618  }
12619 
12632  void push_back(const std::string& token)
12633  {
12634  reference_tokens.push_back(token);
12635  }
12636 
12638  void push_back(std::string&& token)
12639  {
12640  reference_tokens.push_back(std::move(token));
12641  }
12642 
12657  bool empty() const noexcept
12658  {
12659  return reference_tokens.empty();
12660  }
12661 
12662  private:
12673  static typename BasicJsonType::size_type array_index(const std::string& s)
12674  {
12675  using size_type = typename BasicJsonType::size_type;
12676 
12677  // error condition (cf. RFC 6901, Sect. 4)
12678  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
12679  {
12680  JSON_THROW(detail::parse_error::create(106, 0, "array index '" + s + "' must not begin with '0'", BasicJsonType()));
12681  }
12682 
12683  // error condition (cf. RFC 6901, Sect. 4)
12684  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
12685  {
12686  JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number", BasicJsonType()));
12687  }
12688 
12689  std::size_t processed_chars = 0;
12690  unsigned long long res = 0; // NOLINT(runtime/int)
12691  JSON_TRY
12692  {
12693  res = std::stoull(s, &processed_chars);
12694  }
12695  JSON_CATCH(std::out_of_range&)
12696  {
12697  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12698  }
12699 
12700  // check if the string was completely read
12701  if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
12702  {
12703  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12704  }
12705 
12706  // only triggered on special platforms (like 32bit), see also
12707  // https://github.com/nlohmann/json/pull/2203
12708  if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
12709  {
12710  JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type", BasicJsonType())); // LCOV_EXCL_LINE
12711  }
12712 
12713  return static_cast<size_type>(res);
12714  }
12715 
12716  JSON_PRIVATE_UNLESS_TESTED:
12717  json_pointer top() const
12718  {
12719  if (JSON_HEDLEY_UNLIKELY(empty()))
12720  {
12721  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12722  }
12723 
12724  json_pointer result = *this;
12725  result.reference_tokens = {reference_tokens[0]};
12726  return result;
12727  }
12728 
12729  private:
12738  BasicJsonType& get_and_create(BasicJsonType& j) const
12739  {
12740  auto* result = &j;
12741 
12742  // in case no reference tokens exist, return a reference to the JSON value
12743  // j which will be overwritten by a primitive value
12744  for (const auto& reference_token : reference_tokens)
12745  {
12746  switch (result->type())
12747  {
12748  case detail::value_t::null:
12749  {
12750  if (reference_token == "0")
12751  {
12752  // start a new array if reference token is 0
12753  result = &result->operator[](0);
12754  }
12755  else
12756  {
12757  // start a new object otherwise
12758  result = &result->operator[](reference_token);
12759  }
12760  break;
12761  }
12762 
12763  case detail::value_t::object:
12764  {
12765  // create an entry in the object
12766  result = &result->operator[](reference_token);
12767  break;
12768  }
12769 
12770  case detail::value_t::array:
12771  {
12772  // create an entry in the array
12773  result = &result->operator[](array_index(reference_token));
12774  break;
12775  }
12776 
12777  /*
12778  The following code is only reached if there exists a reference
12779  token _and_ the current value is primitive. In this case, we have
12780  an error situation, because primitive values may only occur as
12781  single value; that is, with an empty list of reference tokens.
12782  */
12783  case detail::value_t::string:
12784  case detail::value_t::boolean:
12785  case detail::value_t::number_integer:
12786  case detail::value_t::number_unsigned:
12787  case detail::value_t::number_float:
12788  case detail::value_t::binary:
12789  case detail::value_t::discarded:
12790  default:
12791  JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j));
12792  }
12793  }
12794 
12795  return *result;
12796  }
12797 
12817  BasicJsonType& get_unchecked(BasicJsonType* ptr) const
12818  {
12819  for (const auto& reference_token : reference_tokens)
12820  {
12821  // convert null values to arrays or objects before continuing
12822  if (ptr->is_null())
12823  {
12824  // check if reference token is a number
12825  const bool nums =
12826  std::all_of(reference_token.begin(), reference_token.end(),
12827  [](const unsigned char x)
12828  {
12829  return std::isdigit(x);
12830  });
12831 
12832  // change value to array for numbers or "-" or to object otherwise
12833  *ptr = (nums || reference_token == "-")
12834  ? detail::value_t::array
12835  : detail::value_t::object;
12836  }
12837 
12838  switch (ptr->type())
12839  {
12840  case detail::value_t::object:
12841  {
12842  // use unchecked object access
12843  ptr = &ptr->operator[](reference_token);
12844  break;
12845  }
12846 
12847  case detail::value_t::array:
12848  {
12849  if (reference_token == "-")
12850  {
12851  // explicitly treat "-" as index beyond the end
12852  ptr = &ptr->operator[](ptr->m_value.array->size());
12853  }
12854  else
12855  {
12856  // convert array index to number; unchecked access
12857  ptr = &ptr->operator[](array_index(reference_token));
12858  }
12859  break;
12860  }
12861 
12862  case detail::value_t::null:
12863  case detail::value_t::string:
12864  case detail::value_t::boolean:
12865  case detail::value_t::number_integer:
12866  case detail::value_t::number_unsigned:
12867  case detail::value_t::number_float:
12868  case detail::value_t::binary:
12869  case detail::value_t::discarded:
12870  default:
12871  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12872  }
12873  }
12874 
12875  return *ptr;
12876  }
12877 
12884  BasicJsonType& get_checked(BasicJsonType* ptr) const
12885  {
12886  for (const auto& reference_token : reference_tokens)
12887  {
12888  switch (ptr->type())
12889  {
12890  case detail::value_t::object:
12891  {
12892  // note: at performs range check
12893  ptr = &ptr->at(reference_token);
12894  break;
12895  }
12896 
12897  case detail::value_t::array:
12898  {
12899  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12900  {
12901  // "-" always fails the range check
12902  JSON_THROW(detail::out_of_range::create(402,
12903  "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12904  ") is out of range", *ptr));
12905  }
12906 
12907  // note: at performs range check
12908  ptr = &ptr->at(array_index(reference_token));
12909  break;
12910  }
12911 
12912  case detail::value_t::null:
12913  case detail::value_t::string:
12914  case detail::value_t::boolean:
12915  case detail::value_t::number_integer:
12916  case detail::value_t::number_unsigned:
12917  case detail::value_t::number_float:
12918  case detail::value_t::binary:
12919  case detail::value_t::discarded:
12920  default:
12921  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12922  }
12923  }
12924 
12925  return *ptr;
12926  }
12927 
12941  const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
12942  {
12943  for (const auto& reference_token : reference_tokens)
12944  {
12945  switch (ptr->type())
12946  {
12947  case detail::value_t::object:
12948  {
12949  // use unchecked object access
12950  ptr = &ptr->operator[](reference_token);
12951  break;
12952  }
12953 
12954  case detail::value_t::array:
12955  {
12956  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12957  {
12958  // "-" cannot be used for const access
12959  JSON_THROW(detail::out_of_range::create(402, "array index '-' (" + std::to_string(ptr->m_value.array->size()) + ") is out of range", *ptr));
12960  }
12961 
12962  // use unchecked array access
12963  ptr = &ptr->operator[](array_index(reference_token));
12964  break;
12965  }
12966 
12967  case detail::value_t::null:
12968  case detail::value_t::string:
12969  case detail::value_t::boolean:
12970  case detail::value_t::number_integer:
12971  case detail::value_t::number_unsigned:
12972  case detail::value_t::number_float:
12973  case detail::value_t::binary:
12974  case detail::value_t::discarded:
12975  default:
12976  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12977  }
12978  }
12979 
12980  return *ptr;
12981  }
12982 
12989  const BasicJsonType& get_checked(const BasicJsonType* ptr) const
12990  {
12991  for (const auto& reference_token : reference_tokens)
12992  {
12993  switch (ptr->type())
12994  {
12995  case detail::value_t::object:
12996  {
12997  // note: at performs range check
12998  ptr = &ptr->at(reference_token);
12999  break;
13000  }
13001 
13002  case detail::value_t::array:
13003  {
13004  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13005  {
13006  // "-" always fails the range check
13007  JSON_THROW(detail::out_of_range::create(402,
13008  "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13009  ") is out of range", *ptr));
13010  }
13011 
13012  // note: at performs range check
13013  ptr = &ptr->at(array_index(reference_token));
13014  break;
13015  }
13016 
13017  case detail::value_t::null:
13018  case detail::value_t::string:
13019  case detail::value_t::boolean:
13020  case detail::value_t::number_integer:
13021  case detail::value_t::number_unsigned:
13022  case detail::value_t::number_float:
13023  case detail::value_t::binary:
13024  case detail::value_t::discarded:
13025  default:
13026  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13027  }
13028  }
13029 
13030  return *ptr;
13031  }
13032 
13037  bool contains(const BasicJsonType* ptr) const
13038  {
13039  for (const auto& reference_token : reference_tokens)
13040  {
13041  switch (ptr->type())
13042  {
13043  case detail::value_t::object:
13044  {
13045  if (!ptr->contains(reference_token))
13046  {
13047  // we did not find the key in the object
13048  return false;
13049  }
13050 
13051  ptr = &ptr->operator[](reference_token);
13052  break;
13053  }
13054 
13055  case detail::value_t::array:
13056  {
13057  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13058  {
13059  // "-" always fails the range check
13060  return false;
13061  }
13062  if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
13063  {
13064  // invalid char
13065  return false;
13066  }
13067  if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
13068  {
13069  if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
13070  {
13071  // first char should be between '1' and '9'
13072  return false;
13073  }
13074  for (std::size_t i = 1; i < reference_token.size(); i++)
13075  {
13076  if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
13077  {
13078  // other char should be between '0' and '9'
13079  return false;
13080  }
13081  }
13082  }
13083 
13084  const auto idx = array_index(reference_token);
13085  if (idx >= ptr->size())
13086  {
13087  // index out of range
13088  return false;
13089  }
13090 
13091  ptr = &ptr->operator[](idx);
13092  break;
13093  }
13094 
13095  case detail::value_t::null:
13096  case detail::value_t::string:
13097  case detail::value_t::boolean:
13098  case detail::value_t::number_integer:
13099  case detail::value_t::number_unsigned:
13100  case detail::value_t::number_float:
13101  case detail::value_t::binary:
13102  case detail::value_t::discarded:
13103  default:
13104  {
13105  // we do not expect primitive values if there is still a
13106  // reference token to process
13107  return false;
13108  }
13109  }
13110  }
13111 
13112  // no reference token left means we found a primitive value
13113  return true;
13114  }
13115 
13125  static std::vector<std::string> split(const std::string& reference_string)
13126  {
13127  std::vector<std::string> result;
13128 
13129  // special case: empty reference string -> no reference tokens
13130  if (reference_string.empty())
13131  {
13132  return result;
13133  }
13134 
13135  // check if nonempty reference string begins with slash
13136  if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
13137  {
13138  JSON_THROW(detail::parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'", BasicJsonType()));
13139  }
13140 
13141  // extract the reference tokens:
13142  // - slash: position of the last read slash (or end of string)
13143  // - start: position after the previous slash
13144  for (
13145  // search for the first slash after the first character
13146  std::size_t slash = reference_string.find_first_of('/', 1),
13147  // set the beginning of the first reference token
13148  start = 1;
13149  // we can stop if start == 0 (if slash == std::string::npos)
13150  start != 0;
13151  // set the beginning of the next reference token
13152  // (will eventually be 0 if slash == std::string::npos)
13153  start = (slash == std::string::npos) ? 0 : slash + 1,
13154  // find next slash
13155  slash = reference_string.find_first_of('/', start))
13156  {
13157  // use the text between the beginning of the reference token
13158  // (start) and the last slash (slash).
13159  auto reference_token = reference_string.substr(start, slash - start);
13160 
13161  // check reference tokens are properly escaped
13162  for (std::size_t pos = reference_token.find_first_of('~');
13163  pos != std::string::npos;
13164  pos = reference_token.find_first_of('~', pos + 1))
13165  {
13166  JSON_ASSERT(reference_token[pos] == '~');
13167 
13168  // ~ must be followed by 0 or 1
13169  if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
13170  (reference_token[pos + 1] != '0' &&
13171  reference_token[pos + 1] != '1')))
13172  {
13173  JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", BasicJsonType()));
13174  }
13175  }
13176 
13177  // finally, store the reference token
13178  detail::unescape(reference_token);
13179  result.push_back(reference_token);
13180  }
13181 
13182  return result;
13183  }
13184 
13185  private:
13193  static void flatten(const std::string& reference_string,
13194  const BasicJsonType& value,
13195  BasicJsonType& result)
13196  {
13197  switch (value.type())
13198  {
13199  case detail::value_t::array:
13200  {
13201  if (value.m_value.array->empty())
13202  {
13203  // flatten empty array as null
13204  result[reference_string] = nullptr;
13205  }
13206  else
13207  {
13208  // iterate array and use index as reference string
13209  for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
13210  {
13211  flatten(reference_string + "/" + std::to_string(i),
13212  value.m_value.array->operator[](i), result);
13213  }
13214  }
13215  break;
13216  }
13217 
13218  case detail::value_t::object:
13219  {
13220  if (value.m_value.object->empty())
13221  {
13222  // flatten empty object as null
13223  result[reference_string] = nullptr;
13224  }
13225  else
13226  {
13227  // iterate object and use keys as reference string
13228  for (const auto& element : *value.m_value.object)
13229  {
13230  flatten(reference_string + "/" + detail::escape(element.first), element.second, result);
13231  }
13232  }
13233  break;
13234  }
13235 
13236  case detail::value_t::null:
13237  case detail::value_t::string:
13238  case detail::value_t::boolean:
13239  case detail::value_t::number_integer:
13240  case detail::value_t::number_unsigned:
13241  case detail::value_t::number_float:
13242  case detail::value_t::binary:
13243  case detail::value_t::discarded:
13244  default:
13245  {
13246  // add primitive value with its reference string
13247  result[reference_string] = value;
13248  break;
13249  }
13250  }
13251  }
13252 
13263  static BasicJsonType
13264  unflatten(const BasicJsonType& value)
13265  {
13266  if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
13267  {
13268  JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", value));
13269  }
13270 
13271  BasicJsonType result;
13272 
13273  // iterate the JSON object values
13274  for (const auto& element : *value.m_value.object)
13275  {
13276  if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
13277  {
13278  JSON_THROW(detail::type_error::create(315, "values in object must be primitive", element.second));
13279  }
13280 
13281  // assign value to reference pointed to by JSON pointer; Note that if
13282  // the JSON pointer is "" (i.e., points to the whole value), function
13283  // get_and_create returns a reference to result itself. An assignment
13284  // will then create a primitive value.
13285  json_pointer(element.first).get_and_create(result) = element.second;
13286  }
13287 
13288  return result;
13289  }
13290 
13302  friend bool operator==(json_pointer const& lhs,
13303  json_pointer const& rhs) noexcept
13304  {
13305  return lhs.reference_tokens == rhs.reference_tokens;
13306  }
13307 
13319  friend bool operator!=(json_pointer const& lhs,
13320  json_pointer const& rhs) noexcept
13321  {
13322  return !(lhs == rhs);
13323  }
13324 
13326  std::vector<std::string> reference_tokens;
13327 };
13328 } // namespace nlohmann
13329 
13330 // #include <nlohmann/detail/json_ref.hpp>
13331 
13332 
13333 #include <initializer_list>
13334 #include <utility>
13335 
13336 // #include <nlohmann/detail/meta/type_traits.hpp>
13337 
13338 
13339 namespace nlohmann
13340 {
13341 namespace detail
13342 {
13343 template<typename BasicJsonType>
13344 class json_ref
13345 {
13346  public:
13347  using value_type = BasicJsonType;
13348 
13349  json_ref(value_type&& value)
13350  : owned_value(std::move(value))
13351  {}
13352 
13353  json_ref(const value_type& value)
13354  : value_ref(&value)
13355  {}
13356 
13357  json_ref(std::initializer_list<json_ref> init)
13358  : owned_value(init)
13359  {}
13360 
13361  template <
13362  class... Args,
13363  enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
13364  json_ref(Args && ... args)
13365  : owned_value(std::forward<Args>(args)...)
13366  {}
13367 
13368  // class should be movable only
13369  json_ref(json_ref&&) noexcept = default;
13370  json_ref(const json_ref&) = delete;
13371  json_ref& operator=(const json_ref&) = delete;
13372  json_ref& operator=(json_ref&&) = delete;
13373  ~json_ref() = default;
13374 
13375  value_type moved_or_copied() const
13376  {
13377  if (value_ref == nullptr)
13378  {
13379  return std::move(owned_value);
13380  }
13381  return *value_ref;
13382  }
13383 
13384  value_type const& operator*() const
13385  {
13386  return value_ref ? *value_ref : owned_value;
13387  }
13388 
13389  value_type const* operator->() const
13390  {
13391  return &** this;
13392  }
13393 
13394  private:
13395  mutable value_type owned_value = nullptr;
13396  value_type const* value_ref = nullptr;
13397 };
13398 } // namespace detail
13399 } // namespace nlohmann
13400 
13401 // #include <nlohmann/detail/macro_scope.hpp>
13402 
13403 // #include <nlohmann/detail/string_escape.hpp>
13404 
13405 // #include <nlohmann/detail/meta/cpp_future.hpp>
13406 
13407 // #include <nlohmann/detail/meta/type_traits.hpp>
13408 
13409 // #include <nlohmann/detail/output/binary_writer.hpp>
13410 
13411 
13412 #include <algorithm> // reverse
13413 #include <array> // array
13414 #include <cmath> // isnan, isinf
13415 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
13416 #include <cstring> // memcpy
13417 #include <limits> // numeric_limits
13418 #include <string> // string
13419 #include <utility> // move
13420 
13421 // #include <nlohmann/detail/input/binary_reader.hpp>
13422 
13423 // #include <nlohmann/detail/macro_scope.hpp>
13424 
13425 // #include <nlohmann/detail/output/output_adapters.hpp>
13426 
13427 
13428 #include <algorithm> // copy
13429 #include <cstddef> // size_t
13430 #include <iterator> // back_inserter
13431 #include <memory> // shared_ptr, make_shared
13432 #include <string> // basic_string
13433 #include <vector> // vector
13434 
13435 #ifndef JSON_NO_IO
13436  #include <ios> // streamsize
13437  #include <ostream> // basic_ostream
13438 #endif // JSON_NO_IO
13439 
13440 // #include <nlohmann/detail/macro_scope.hpp>
13441 
13442 
13443 namespace nlohmann
13444 {
13445 namespace detail
13446 {
13448 template<typename CharType> struct output_adapter_protocol
13449 {
13450  virtual void write_character(CharType c) = 0;
13451  virtual void write_characters(const CharType* s, std::size_t length) = 0;
13452  virtual ~output_adapter_protocol() = default;
13453 
13454  output_adapter_protocol() = default;
13455  output_adapter_protocol(const output_adapter_protocol&) = default;
13456  output_adapter_protocol(output_adapter_protocol&&) noexcept = default;
13457  output_adapter_protocol& operator=(const output_adapter_protocol&) = default;
13458  output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
13459 };
13460 
13462 template<typename CharType>
13463 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
13464 
13466 template<typename CharType>
13467 class output_vector_adapter : public output_adapter_protocol<CharType>
13468 {
13469  public:
13470  explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
13471  : v(vec)
13472  {}
13473 
13474  void write_character(CharType c) override
13475  {
13476  v.push_back(c);
13477  }
13478 
13479  JSON_HEDLEY_NON_NULL(2)
13480  void write_characters(const CharType* s, std::size_t length) override
13481  {
13482  std::copy(s, s + length, std::back_inserter(v));
13483  }
13484 
13485  private:
13486  std::vector<CharType>& v;
13487 };
13488 
13489 #ifndef JSON_NO_IO
13491 template<typename CharType>
13492 class output_stream_adapter : public output_adapter_protocol<CharType>
13493 {
13494  public:
13495  explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
13496  : stream(s)
13497  {}
13498 
13499  void write_character(CharType c) override
13500  {
13501  stream.put(c);
13502  }
13503 
13504  JSON_HEDLEY_NON_NULL(2)
13505  void write_characters(const CharType* s, std::size_t length) override
13506  {
13507  stream.write(s, static_cast<std::streamsize>(length));
13508  }
13509 
13510  private:
13511  std::basic_ostream<CharType>& stream;
13512 };
13513 #endif // JSON_NO_IO
13514 
13516 template<typename CharType, typename StringType = std::basic_string<CharType>>
13517 class output_string_adapter : public output_adapter_protocol<CharType>
13518 {
13519  public:
13520  explicit output_string_adapter(StringType& s) noexcept
13521  : str(s)
13522  {}
13523 
13524  void write_character(CharType c) override
13525  {
13526  str.push_back(c);
13527  }
13528 
13529  JSON_HEDLEY_NON_NULL(2)
13530  void write_characters(const CharType* s, std::size_t length) override
13531  {
13532  str.append(s, length);
13533  }
13534 
13535  private:
13536  StringType& str;
13537 };
13538 
13539 template<typename CharType, typename StringType = std::basic_string<CharType>>
13540 class output_adapter
13541 {
13542  public:
13543  output_adapter(std::vector<CharType>& vec)
13544  : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
13545 
13546 #ifndef JSON_NO_IO
13547  output_adapter(std::basic_ostream<CharType>& s)
13548  : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
13549 #endif // JSON_NO_IO
13550 
13551  output_adapter(StringType& s)
13552  : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
13553 
13554  operator output_adapter_t<CharType>()
13555  {
13556  return oa;
13557  }
13558 
13559  private:
13560  output_adapter_t<CharType> oa = nullptr;
13561 };
13562 } // namespace detail
13563 } // namespace nlohmann
13564 
13565 
13566 namespace nlohmann
13567 {
13568 namespace detail
13569 {
13571 // binary writer //
13573 
13577 template<typename BasicJsonType, typename CharType>
13578 class binary_writer
13579 {
13580  using string_t = typename BasicJsonType::string_t;
13581  using binary_t = typename BasicJsonType::binary_t;
13582  using number_float_t = typename BasicJsonType::number_float_t;
13583 
13584  public:
13590  explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
13591  {
13592  JSON_ASSERT(oa);
13593  }
13594 
13599  void write_bson(const BasicJsonType& j)
13600  {
13601  switch (j.type())
13602  {
13603  case value_t::object:
13604  {
13605  write_bson_object(*j.m_value.object);
13606  break;
13607  }
13608 
13609  case value_t::null:
13610  case value_t::array:
13611  case value_t::string:
13612  case value_t::boolean:
13613  case value_t::number_integer:
13614  case value_t::number_unsigned:
13615  case value_t::number_float:
13616  case value_t::binary:
13617  case value_t::discarded:
13618  default:
13619  {
13620  JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));;
13621  }
13622  }
13623  }
13624 
13628  void write_cbor(const BasicJsonType& j)
13629  {
13630  switch (j.type())
13631  {
13632  case value_t::null:
13633  {
13634  oa->write_character(to_char_type(0xF6));
13635  break;
13636  }
13637 
13638  case value_t::boolean:
13639  {
13640  oa->write_character(j.m_value.boolean
13641  ? to_char_type(0xF5)
13642  : to_char_type(0xF4));
13643  break;
13644  }
13645 
13646  case value_t::number_integer:
13647  {
13648  if (j.m_value.number_integer >= 0)
13649  {
13650  // CBOR does not differentiate between positive signed
13651  // integers and unsigned integers. Therefore, we used the
13652  // code from the value_t::number_unsigned case here.
13653  if (j.m_value.number_integer <= 0x17)
13654  {
13655  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13656  }
13657  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
13658  {
13659  oa->write_character(to_char_type(0x18));
13660  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13661  }
13662  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
13663  {
13664  oa->write_character(to_char_type(0x19));
13665  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13666  }
13667  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
13668  {
13669  oa->write_character(to_char_type(0x1A));
13670  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13671  }
13672  else
13673  {
13674  oa->write_character(to_char_type(0x1B));
13675  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13676  }
13677  }
13678  else
13679  {
13680  // The conversions below encode the sign in the first
13681  // byte, and the value is converted to a positive number.
13682  const auto positive_number = -1 - j.m_value.number_integer;
13683  if (j.m_value.number_integer >= -24)
13684  {
13685  write_number(static_cast<std::uint8_t>(0x20 + positive_number));
13686  }
13687  else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
13688  {
13689  oa->write_character(to_char_type(0x38));
13690  write_number(static_cast<std::uint8_t>(positive_number));
13691  }
13692  else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
13693  {
13694  oa->write_character(to_char_type(0x39));
13695  write_number(static_cast<std::uint16_t>(positive_number));
13696  }
13697  else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
13698  {
13699  oa->write_character(to_char_type(0x3A));
13700  write_number(static_cast<std::uint32_t>(positive_number));
13701  }
13702  else
13703  {
13704  oa->write_character(to_char_type(0x3B));
13705  write_number(static_cast<std::uint64_t>(positive_number));
13706  }
13707  }
13708  break;
13709  }
13710 
13711  case value_t::number_unsigned:
13712  {
13713  if (j.m_value.number_unsigned <= 0x17)
13714  {
13715  write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13716  }
13717  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13718  {
13719  oa->write_character(to_char_type(0x18));
13720  write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13721  }
13722  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13723  {
13724  oa->write_character(to_char_type(0x19));
13725  write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
13726  }
13727  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13728  {
13729  oa->write_character(to_char_type(0x1A));
13730  write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
13731  }
13732  else
13733  {
13734  oa->write_character(to_char_type(0x1B));
13735  write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
13736  }
13737  break;
13738  }
13739 
13740  case value_t::number_float:
13741  {
13742  if (std::isnan(j.m_value.number_float))
13743  {
13744  // NaN is 0xf97e00 in CBOR
13745  oa->write_character(to_char_type(0xF9));
13746  oa->write_character(to_char_type(0x7E));
13747  oa->write_character(to_char_type(0x00));
13748  }
13749  else if (std::isinf(j.m_value.number_float))
13750  {
13751  // Infinity is 0xf97c00, -Infinity is 0xf9fc00
13752  oa->write_character(to_char_type(0xf9));
13753  oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
13754  oa->write_character(to_char_type(0x00));
13755  }
13756  else
13757  {
13758  write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
13759  }
13760  break;
13761  }
13762 
13763  case value_t::string:
13764  {
13765  // step 1: write control byte and the string length
13766  const auto N = j.m_value.string->size();
13767  if (N <= 0x17)
13768  {
13769  write_number(static_cast<std::uint8_t>(0x60 + N));
13770  }
13771  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13772  {
13773  oa->write_character(to_char_type(0x78));
13774  write_number(static_cast<std::uint8_t>(N));
13775  }
13776  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13777  {
13778  oa->write_character(to_char_type(0x79));
13779  write_number(static_cast<std::uint16_t>(N));
13780  }
13781  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13782  {
13783  oa->write_character(to_char_type(0x7A));
13784  write_number(static_cast<std::uint32_t>(N));
13785  }
13786  // LCOV_EXCL_START
13787  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13788  {
13789  oa->write_character(to_char_type(0x7B));
13790  write_number(static_cast<std::uint64_t>(N));
13791  }
13792  // LCOV_EXCL_STOP
13793 
13794  // step 2: write the string
13795  oa->write_characters(
13796  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13797  j.m_value.string->size());
13798  break;
13799  }
13800 
13801  case value_t::array:
13802  {
13803  // step 1: write control byte and the array size
13804  const auto N = j.m_value.array->size();
13805  if (N <= 0x17)
13806  {
13807  write_number(static_cast<std::uint8_t>(0x80 + N));
13808  }
13809  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13810  {
13811  oa->write_character(to_char_type(0x98));
13812  write_number(static_cast<std::uint8_t>(N));
13813  }
13814  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13815  {
13816  oa->write_character(to_char_type(0x99));
13817  write_number(static_cast<std::uint16_t>(N));
13818  }
13819  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13820  {
13821  oa->write_character(to_char_type(0x9A));
13822  write_number(static_cast<std::uint32_t>(N));
13823  }
13824  // LCOV_EXCL_START
13825  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13826  {
13827  oa->write_character(to_char_type(0x9B));
13828  write_number(static_cast<std::uint64_t>(N));
13829  }
13830  // LCOV_EXCL_STOP
13831 
13832  // step 2: write each element
13833  for (const auto& el : *j.m_value.array)
13834  {
13835  write_cbor(el);
13836  }
13837  break;
13838  }
13839 
13840  case value_t::binary:
13841  {
13842  if (j.m_value.binary->has_subtype())
13843  {
13844  if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
13845  {
13846  write_number(static_cast<std::uint8_t>(0xd8));
13847  write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
13848  }
13849  else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
13850  {
13851  write_number(static_cast<std::uint8_t>(0xd9));
13852  write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
13853  }
13854  else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
13855  {
13856  write_number(static_cast<std::uint8_t>(0xda));
13857  write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
13858  }
13859  else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
13860  {
13861  write_number(static_cast<std::uint8_t>(0xdb));
13862  write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
13863  }
13864  }
13865 
13866  // step 1: write control byte and the binary array size
13867  const auto N = j.m_value.binary->size();
13868  if (N <= 0x17)
13869  {
13870  write_number(static_cast<std::uint8_t>(0x40 + N));
13871  }
13872  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13873  {
13874  oa->write_character(to_char_type(0x58));
13875  write_number(static_cast<std::uint8_t>(N));
13876  }
13877  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13878  {
13879  oa->write_character(to_char_type(0x59));
13880  write_number(static_cast<std::uint16_t>(N));
13881  }
13882  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13883  {
13884  oa->write_character(to_char_type(0x5A));
13885  write_number(static_cast<std::uint32_t>(N));
13886  }
13887  // LCOV_EXCL_START
13888  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13889  {
13890  oa->write_character(to_char_type(0x5B));
13891  write_number(static_cast<std::uint64_t>(N));
13892  }
13893  // LCOV_EXCL_STOP
13894 
13895  // step 2: write each element
13896  oa->write_characters(
13897  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13898  N);
13899 
13900  break;
13901  }
13902 
13903  case value_t::object:
13904  {
13905  // step 1: write control byte and the object size
13906  const auto N = j.m_value.object->size();
13907  if (N <= 0x17)
13908  {
13909  write_number(static_cast<std::uint8_t>(0xA0 + N));
13910  }
13911  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13912  {
13913  oa->write_character(to_char_type(0xB8));
13914  write_number(static_cast<std::uint8_t>(N));
13915  }
13916  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13917  {
13918  oa->write_character(to_char_type(0xB9));
13919  write_number(static_cast<std::uint16_t>(N));
13920  }
13921  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13922  {
13923  oa->write_character(to_char_type(0xBA));
13924  write_number(static_cast<std::uint32_t>(N));
13925  }
13926  // LCOV_EXCL_START
13927  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13928  {
13929  oa->write_character(to_char_type(0xBB));
13930  write_number(static_cast<std::uint64_t>(N));
13931  }
13932  // LCOV_EXCL_STOP
13933 
13934  // step 2: write each element
13935  for (const auto& el : *j.m_value.object)
13936  {
13937  write_cbor(el.first);
13938  write_cbor(el.second);
13939  }
13940  break;
13941  }
13942 
13943  case value_t::discarded:
13944  default:
13945  break;
13946  }
13947  }
13948 
13952  void write_msgpack(const BasicJsonType& j)
13953  {
13954  switch (j.type())
13955  {
13956  case value_t::null: // nil
13957  {
13958  oa->write_character(to_char_type(0xC0));
13959  break;
13960  }
13961 
13962  case value_t::boolean: // true and false
13963  {
13964  oa->write_character(j.m_value.boolean
13965  ? to_char_type(0xC3)
13966  : to_char_type(0xC2));
13967  break;
13968  }
13969 
13970  case value_t::number_integer:
13971  {
13972  if (j.m_value.number_integer >= 0)
13973  {
13974  // MessagePack does not differentiate between positive
13975  // signed integers and unsigned integers. Therefore, we used
13976  // the code from the value_t::number_unsigned case here.
13977  if (j.m_value.number_unsigned < 128)
13978  {
13979  // positive fixnum
13980  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13981  }
13982  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13983  {
13984  // uint 8
13985  oa->write_character(to_char_type(0xCC));
13986  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13987  }
13988  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13989  {
13990  // uint 16
13991  oa->write_character(to_char_type(0xCD));
13992  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13993  }
13994  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13995  {
13996  // uint 32
13997  oa->write_character(to_char_type(0xCE));
13998  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13999  }
14000  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14001  {
14002  // uint 64
14003  oa->write_character(to_char_type(0xCF));
14004  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14005  }
14006  }
14007  else
14008  {
14009  if (j.m_value.number_integer >= -32)
14010  {
14011  // negative fixnum
14012  write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14013  }
14014  else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
14015  j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
14016  {
14017  // int 8
14018  oa->write_character(to_char_type(0xD0));
14019  write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14020  }
14021  else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
14022  j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
14023  {
14024  // int 16
14025  oa->write_character(to_char_type(0xD1));
14026  write_number(static_cast<std::int16_t>(j.m_value.number_integer));
14027  }
14028  else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
14029  j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
14030  {
14031  // int 32
14032  oa->write_character(to_char_type(0xD2));
14033  write_number(static_cast<std::int32_t>(j.m_value.number_integer));
14034  }
14035  else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
14036  j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
14037  {
14038  // int 64
14039  oa->write_character(to_char_type(0xD3));
14040  write_number(static_cast<std::int64_t>(j.m_value.number_integer));
14041  }
14042  }
14043  break;
14044  }
14045 
14046  case value_t::number_unsigned:
14047  {
14048  if (j.m_value.number_unsigned < 128)
14049  {
14050  // positive fixnum
14051  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14052  }
14053  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14054  {
14055  // uint 8
14056  oa->write_character(to_char_type(0xCC));
14057  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14058  }
14059  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14060  {
14061  // uint 16
14062  oa->write_character(to_char_type(0xCD));
14063  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14064  }
14065  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14066  {
14067  // uint 32
14068  oa->write_character(to_char_type(0xCE));
14069  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14070  }
14071  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14072  {
14073  // uint 64
14074  oa->write_character(to_char_type(0xCF));
14075  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14076  }
14077  break;
14078  }
14079 
14080  case value_t::number_float:
14081  {
14082  write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
14083  break;
14084  }
14085 
14086  case value_t::string:
14087  {
14088  // step 1: write control byte and the string length
14089  const auto N = j.m_value.string->size();
14090  if (N <= 31)
14091  {
14092  // fixstr
14093  write_number(static_cast<std::uint8_t>(0xA0 | N));
14094  }
14095  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14096  {
14097  // str 8
14098  oa->write_character(to_char_type(0xD9));
14099  write_number(static_cast<std::uint8_t>(N));
14100  }
14101  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14102  {
14103  // str 16
14104  oa->write_character(to_char_type(0xDA));
14105  write_number(static_cast<std::uint16_t>(N));
14106  }
14107  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14108  {
14109  // str 32
14110  oa->write_character(to_char_type(0xDB));
14111  write_number(static_cast<std::uint32_t>(N));
14112  }
14113 
14114  // step 2: write the string
14115  oa->write_characters(
14116  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14117  j.m_value.string->size());
14118  break;
14119  }
14120 
14121  case value_t::array:
14122  {
14123  // step 1: write control byte and the array size
14124  const auto N = j.m_value.array->size();
14125  if (N <= 15)
14126  {
14127  // fixarray
14128  write_number(static_cast<std::uint8_t>(0x90 | N));
14129  }
14130  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14131  {
14132  // array 16
14133  oa->write_character(to_char_type(0xDC));
14134  write_number(static_cast<std::uint16_t>(N));
14135  }
14136  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14137  {
14138  // array 32
14139  oa->write_character(to_char_type(0xDD));
14140  write_number(static_cast<std::uint32_t>(N));
14141  }
14142 
14143  // step 2: write each element
14144  for (const auto& el : *j.m_value.array)
14145  {
14146  write_msgpack(el);
14147  }
14148  break;
14149  }
14150 
14151  case value_t::binary:
14152  {
14153  // step 0: determine if the binary type has a set subtype to
14154  // determine whether or not to use the ext or fixext types
14155  const bool use_ext = j.m_value.binary->has_subtype();
14156 
14157  // step 1: write control byte and the byte string length
14158  const auto N = j.m_value.binary->size();
14159  if (N <= (std::numeric_limits<std::uint8_t>::max)())
14160  {
14161  std::uint8_t output_type{};
14162  bool fixed = true;
14163  if (use_ext)
14164  {
14165  switch (N)
14166  {
14167  case 1:
14168  output_type = 0xD4; // fixext 1
14169  break;
14170  case 2:
14171  output_type = 0xD5; // fixext 2
14172  break;
14173  case 4:
14174  output_type = 0xD6; // fixext 4
14175  break;
14176  case 8:
14177  output_type = 0xD7; // fixext 8
14178  break;
14179  case 16:
14180  output_type = 0xD8; // fixext 16
14181  break;
14182  default:
14183  output_type = 0xC7; // ext 8
14184  fixed = false;
14185  break;
14186  }
14187 
14188  }
14189  else
14190  {
14191  output_type = 0xC4; // bin 8
14192  fixed = false;
14193  }
14194 
14195  oa->write_character(to_char_type(output_type));
14196  if (!fixed)
14197  {
14198  write_number(static_cast<std::uint8_t>(N));
14199  }
14200  }
14201  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14202  {
14203  std::uint8_t output_type = use_ext
14204  ? 0xC8 // ext 16
14205  : 0xC5; // bin 16
14206 
14207  oa->write_character(to_char_type(output_type));
14208  write_number(static_cast<std::uint16_t>(N));
14209  }
14210  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14211  {
14212  std::uint8_t output_type = use_ext
14213  ? 0xC9 // ext 32
14214  : 0xC6; // bin 32
14215 
14216  oa->write_character(to_char_type(output_type));
14217  write_number(static_cast<std::uint32_t>(N));
14218  }
14219 
14220  // step 1.5: if this is an ext type, write the subtype
14221  if (use_ext)
14222  {
14223  write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
14224  }
14225 
14226  // step 2: write the byte string
14227  oa->write_characters(
14228  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14229  N);
14230 
14231  break;
14232  }
14233 
14234  case value_t::object:
14235  {
14236  // step 1: write control byte and the object size
14237  const auto N = j.m_value.object->size();
14238  if (N <= 15)
14239  {
14240  // fixmap
14241  write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
14242  }
14243  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14244  {
14245  // map 16
14246  oa->write_character(to_char_type(0xDE));
14247  write_number(static_cast<std::uint16_t>(N));
14248  }
14249  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14250  {
14251  // map 32
14252  oa->write_character(to_char_type(0xDF));
14253  write_number(static_cast<std::uint32_t>(N));
14254  }
14255 
14256  // step 2: write each element
14257  for (const auto& el : *j.m_value.object)
14258  {
14259  write_msgpack(el.first);
14260  write_msgpack(el.second);
14261  }
14262  break;
14263  }
14264 
14265  case value_t::discarded:
14266  default:
14267  break;
14268  }
14269  }
14270 
14277  void write_ubjson(const BasicJsonType& j, const bool use_count,
14278  const bool use_type, const bool add_prefix = true)
14279  {
14280  switch (j.type())
14281  {
14282  case value_t::null:
14283  {
14284  if (add_prefix)
14285  {
14286  oa->write_character(to_char_type('Z'));
14287  }
14288  break;
14289  }
14290 
14291  case value_t::boolean:
14292  {
14293  if (add_prefix)
14294  {
14295  oa->write_character(j.m_value.boolean
14296  ? to_char_type('T')
14297  : to_char_type('F'));
14298  }
14299  break;
14300  }
14301 
14302  case value_t::number_integer:
14303  {
14304  write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
14305  break;
14306  }
14307 
14308  case value_t::number_unsigned:
14309  {
14310  write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
14311  break;
14312  }
14313 
14314  case value_t::number_float:
14315  {
14316  write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
14317  break;
14318  }
14319 
14320  case value_t::string:
14321  {
14322  if (add_prefix)
14323  {
14324  oa->write_character(to_char_type('S'));
14325  }
14326  write_number_with_ubjson_prefix(j.m_value.string->size(), true);
14327  oa->write_characters(
14328  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14329  j.m_value.string->size());
14330  break;
14331  }
14332 
14333  case value_t::array:
14334  {
14335  if (add_prefix)
14336  {
14337  oa->write_character(to_char_type('['));
14338  }
14339 
14340  bool prefix_required = true;
14341  if (use_type && !j.m_value.array->empty())
14342  {
14343  JSON_ASSERT(use_count);
14344  const CharType first_prefix = ubjson_prefix(j.front());
14345  const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
14346  [this, first_prefix](const BasicJsonType & v)
14347  {
14348  return ubjson_prefix(v) == first_prefix;
14349  });
14350 
14351  if (same_prefix)
14352  {
14353  prefix_required = false;
14354  oa->write_character(to_char_type('$'));
14355  oa->write_character(first_prefix);
14356  }
14357  }
14358 
14359  if (use_count)
14360  {
14361  oa->write_character(to_char_type('#'));
14362  write_number_with_ubjson_prefix(j.m_value.array->size(), true);
14363  }
14364 
14365  for (const auto& el : *j.m_value.array)
14366  {
14367  write_ubjson(el, use_count, use_type, prefix_required);
14368  }
14369 
14370  if (!use_count)
14371  {
14372  oa->write_character(to_char_type(']'));
14373  }
14374 
14375  break;
14376  }
14377 
14378  case value_t::binary:
14379  {
14380  if (add_prefix)
14381  {
14382  oa->write_character(to_char_type('['));
14383  }
14384 
14385  if (use_type && !j.m_value.binary->empty())
14386  {
14387  JSON_ASSERT(use_count);
14388  oa->write_character(to_char_type('$'));
14389  oa->write_character('U');
14390  }
14391 
14392  if (use_count)
14393  {
14394  oa->write_character(to_char_type('#'));
14395  write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
14396  }
14397 
14398  if (use_type)
14399  {
14400  oa->write_characters(
14401  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14402  j.m_value.binary->size());
14403  }
14404  else
14405  {
14406  for (size_t i = 0; i < j.m_value.binary->size(); ++i)
14407  {
14408  oa->write_character(to_char_type('U'));
14409  oa->write_character(j.m_value.binary->data()[i]);
14410  }
14411  }
14412 
14413  if (!use_count)
14414  {
14415  oa->write_character(to_char_type(']'));
14416  }
14417 
14418  break;
14419  }
14420 
14421  case value_t::object:
14422  {
14423  if (add_prefix)
14424  {
14425  oa->write_character(to_char_type('{'));
14426  }
14427 
14428  bool prefix_required = true;
14429  if (use_type && !j.m_value.object->empty())
14430  {
14431  JSON_ASSERT(use_count);
14432  const CharType first_prefix = ubjson_prefix(j.front());
14433  const bool same_prefix = std::all_of(j.begin(), j.end(),
14434  [this, first_prefix](const BasicJsonType & v)
14435  {
14436  return ubjson_prefix(v) == first_prefix;
14437  });
14438 
14439  if (same_prefix)
14440  {
14441  prefix_required = false;
14442  oa->write_character(to_char_type('$'));
14443  oa->write_character(first_prefix);
14444  }
14445  }
14446 
14447  if (use_count)
14448  {
14449  oa->write_character(to_char_type('#'));
14450  write_number_with_ubjson_prefix(j.m_value.object->size(), true);
14451  }
14452 
14453  for (const auto& el : *j.m_value.object)
14454  {
14455  write_number_with_ubjson_prefix(el.first.size(), true);
14456  oa->write_characters(
14457  reinterpret_cast<const CharType*>(el.first.c_str()),
14458  el.first.size());
14459  write_ubjson(el.second, use_count, use_type, prefix_required);
14460  }
14461 
14462  if (!use_count)
14463  {
14464  oa->write_character(to_char_type('}'));
14465  }
14466 
14467  break;
14468  }
14469 
14470  case value_t::discarded:
14471  default:
14472  break;
14473  }
14474  }
14475 
14476  private:
14478  // BSON //
14480 
14485  static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
14486  {
14487  const auto it = name.find(static_cast<typename string_t::value_type>(0));
14488  if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
14489  {
14490  JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j));
14491  static_cast<void>(j);
14492  }
14493 
14494  return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
14495  }
14496 
14500  void write_bson_entry_header(const string_t& name,
14501  const std::uint8_t element_type)
14502  {
14503  oa->write_character(to_char_type(element_type)); // boolean
14504  oa->write_characters(
14505  reinterpret_cast<const CharType*>(name.c_str()),
14506  name.size() + 1u);
14507  }
14508 
14512  void write_bson_boolean(const string_t& name,
14513  const bool value)
14514  {
14515  write_bson_entry_header(name, 0x08);
14516  oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
14517  }
14518 
14522  void write_bson_double(const string_t& name,
14523  const double value)
14524  {
14525  write_bson_entry_header(name, 0x01);
14526  write_number<double, true>(value);
14527  }
14528 
14532  static std::size_t calc_bson_string_size(const string_t& value)
14533  {
14534  return sizeof(std::int32_t) + value.size() + 1ul;
14535  }
14536 
14540  void write_bson_string(const string_t& name,
14541  const string_t& value)
14542  {
14543  write_bson_entry_header(name, 0x02);
14544 
14545  write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
14546  oa->write_characters(
14547  reinterpret_cast<const CharType*>(value.c_str()),
14548  value.size() + 1);
14549  }
14550 
14554  void write_bson_null(const string_t& name)
14555  {
14556  write_bson_entry_header(name, 0x0A);
14557  }
14558 
14562  static std::size_t calc_bson_integer_size(const std::int64_t value)
14563  {
14564  return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
14565  ? sizeof(std::int32_t)
14566  : sizeof(std::int64_t);
14567  }
14568 
14572  void write_bson_integer(const string_t& name,
14573  const std::int64_t value)
14574  {
14575  if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
14576  {
14577  write_bson_entry_header(name, 0x10); // int32
14578  write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
14579  }
14580  else
14581  {
14582  write_bson_entry_header(name, 0x12); // int64
14583  write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
14584  }
14585  }
14586 
14590  static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
14591  {
14592  return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14593  ? sizeof(std::int32_t)
14594  : sizeof(std::int64_t);
14595  }
14596 
14600  void write_bson_unsigned(const string_t& name,
14601  const BasicJsonType& j)
14602  {
14603  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14604  {
14605  write_bson_entry_header(name, 0x10 /* int32 */);
14606  write_number<std::int32_t, true>(static_cast<std::int32_t>(j.m_value.number_unsigned));
14607  }
14608  else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14609  {
14610  write_bson_entry_header(name, 0x12 /* int64 */);
14611  write_number<std::int64_t, true>(static_cast<std::int64_t>(j.m_value.number_unsigned));
14612  }
14613  else
14614  {
14615  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));
14616  }
14617  }
14618 
14622  void write_bson_object_entry(const string_t& name,
14623  const typename BasicJsonType::object_t& value)
14624  {
14625  write_bson_entry_header(name, 0x03); // object
14626  write_bson_object(value);
14627  }
14628 
14632  static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
14633  {
14634  std::size_t array_index = 0ul;
14635 
14636  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)
14637  {
14638  return result + calc_bson_element_size(std::to_string(array_index++), el);
14639  });
14640 
14641  return sizeof(std::int32_t) + embedded_document_size + 1ul;
14642  }
14643 
14647  static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
14648  {
14649  return sizeof(std::int32_t) + value.size() + 1ul;
14650  }
14651 
14655  void write_bson_array(const string_t& name,
14656  const typename BasicJsonType::array_t& value)
14657  {
14658  write_bson_entry_header(name, 0x04); // array
14659  write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
14660 
14661  std::size_t array_index = 0ul;
14662 
14663  for (const auto& el : value)
14664  {
14665  write_bson_element(std::to_string(array_index++), el);
14666  }
14667 
14668  oa->write_character(to_char_type(0x00));
14669  }
14670 
14674  void write_bson_binary(const string_t& name,
14675  const binary_t& value)
14676  {
14677  write_bson_entry_header(name, 0x05);
14678 
14679  write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
14680  write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : std::uint8_t(0x00));
14681 
14682  oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
14683  }
14684 
14689  static std::size_t calc_bson_element_size(const string_t& name,
14690  const BasicJsonType& j)
14691  {
14692  const auto header_size = calc_bson_entry_header_size(name, j);
14693  switch (j.type())
14694  {
14695  case value_t::object:
14696  return header_size + calc_bson_object_size(*j.m_value.object);
14697 
14698  case value_t::array:
14699  return header_size + calc_bson_array_size(*j.m_value.array);
14700 
14701  case value_t::binary:
14702  return header_size + calc_bson_binary_size(*j.m_value.binary);
14703 
14704  case value_t::boolean:
14705  return header_size + 1ul;
14706 
14707  case value_t::number_float:
14708  return header_size + 8ul;
14709 
14710  case value_t::number_integer:
14711  return header_size + calc_bson_integer_size(j.m_value.number_integer);
14712 
14713  case value_t::number_unsigned:
14714  return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
14715 
14716  case value_t::string:
14717  return header_size + calc_bson_string_size(*j.m_value.string);
14718 
14719  case value_t::null:
14720  return header_size + 0ul;
14721 
14722  // LCOV_EXCL_START
14723  case value_t::discarded:
14724  default:
14725  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14726  return 0ul;
14727  // LCOV_EXCL_STOP
14728  }
14729  }
14730 
14737  void write_bson_element(const string_t& name,
14738  const BasicJsonType& j)
14739  {
14740  switch (j.type())
14741  {
14742  case value_t::object:
14743  return write_bson_object_entry(name, *j.m_value.object);
14744 
14745  case value_t::array:
14746  return write_bson_array(name, *j.m_value.array);
14747 
14748  case value_t::binary:
14749  return write_bson_binary(name, *j.m_value.binary);
14750 
14751  case value_t::boolean:
14752  return write_bson_boolean(name, j.m_value.boolean);
14753 
14754  case value_t::number_float:
14755  return write_bson_double(name, j.m_value.number_float);
14756 
14757  case value_t::number_integer:
14758  return write_bson_integer(name, j.m_value.number_integer);
14759 
14760  case value_t::number_unsigned:
14761  return write_bson_unsigned(name, j);
14762 
14763  case value_t::string:
14764  return write_bson_string(name, *j.m_value.string);
14765 
14766  case value_t::null:
14767  return write_bson_null(name);
14768 
14769  // LCOV_EXCL_START
14770  case value_t::discarded:
14771  default:
14772  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14773  return;
14774  // LCOV_EXCL_STOP
14775  }
14776  }
14777 
14784  static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
14785  {
14786  std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
14787  [](size_t result, const typename BasicJsonType::object_t::value_type & el)
14788  {
14789  return result += calc_bson_element_size(el.first, el.second);
14790  });
14791 
14792  return sizeof(std::int32_t) + document_size + 1ul;
14793  }
14794 
14799  void write_bson_object(const typename BasicJsonType::object_t& value)
14800  {
14801  write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
14802 
14803  for (const auto& el : value)
14804  {
14805  write_bson_element(el.first, el.second);
14806  }
14807 
14808  oa->write_character(to_char_type(0x00));
14809  }
14810 
14812  // CBOR //
14814 
14815  static constexpr CharType get_cbor_float_prefix(float /*unused*/)
14816  {
14817  return to_char_type(0xFA); // Single-Precision Float
14818  }
14819 
14820  static constexpr CharType get_cbor_float_prefix(double /*unused*/)
14821  {
14822  return to_char_type(0xFB); // Double-Precision Float
14823  }
14824 
14826  // MsgPack //
14828 
14829  static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
14830  {
14831  return to_char_type(0xCA); // float 32
14832  }
14833 
14834  static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
14835  {
14836  return to_char_type(0xCB); // float 64
14837  }
14838 
14840  // UBJSON //
14842 
14843  // UBJSON: write number (floating point)
14844  template<typename NumberType, typename std::enable_if<
14845  std::is_floating_point<NumberType>::value, int>::type = 0>
14846  void write_number_with_ubjson_prefix(const NumberType n,
14847  const bool add_prefix)
14848  {
14849  if (add_prefix)
14850  {
14851  oa->write_character(get_ubjson_float_prefix(n));
14852  }
14853  write_number(n);
14854  }
14855 
14856  // UBJSON: write number (unsigned integer)
14857  template<typename NumberType, typename std::enable_if<
14858  std::is_unsigned<NumberType>::value, int>::type = 0>
14859  void write_number_with_ubjson_prefix(const NumberType n,
14860  const bool add_prefix)
14861  {
14862  if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14863  {
14864  if (add_prefix)
14865  {
14866  oa->write_character(to_char_type('i')); // int8
14867  }
14868  write_number(static_cast<std::uint8_t>(n));
14869  }
14870  else if (n <= (std::numeric_limits<std::uint8_t>::max)())
14871  {
14872  if (add_prefix)
14873  {
14874  oa->write_character(to_char_type('U')); // uint8
14875  }
14876  write_number(static_cast<std::uint8_t>(n));
14877  }
14878  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14879  {
14880  if (add_prefix)
14881  {
14882  oa->write_character(to_char_type('I')); // int16
14883  }
14884  write_number(static_cast<std::int16_t>(n));
14885  }
14886  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14887  {
14888  if (add_prefix)
14889  {
14890  oa->write_character(to_char_type('l')); // int32
14891  }
14892  write_number(static_cast<std::int32_t>(n));
14893  }
14894  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14895  {
14896  if (add_prefix)
14897  {
14898  oa->write_character(to_char_type('L')); // int64
14899  }
14900  write_number(static_cast<std::int64_t>(n));
14901  }
14902  else
14903  {
14904  if (add_prefix)
14905  {
14906  oa->write_character(to_char_type('H')); // high-precision number
14907  }
14908 
14909  const auto number = BasicJsonType(n).dump();
14910  write_number_with_ubjson_prefix(number.size(), true);
14911  for (std::size_t i = 0; i < number.size(); ++i)
14912  {
14913  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14914  }
14915  }
14916  }
14917 
14918  // UBJSON: write number (signed integer)
14919  template < typename NumberType, typename std::enable_if <
14920  std::is_signed<NumberType>::value&&
14921  !std::is_floating_point<NumberType>::value, int >::type = 0 >
14922  void write_number_with_ubjson_prefix(const NumberType n,
14923  const bool add_prefix)
14924  {
14925  if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
14926  {
14927  if (add_prefix)
14928  {
14929  oa->write_character(to_char_type('i')); // int8
14930  }
14931  write_number(static_cast<std::int8_t>(n));
14932  }
14933  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)()))
14934  {
14935  if (add_prefix)
14936  {
14937  oa->write_character(to_char_type('U')); // uint8
14938  }
14939  write_number(static_cast<std::uint8_t>(n));
14940  }
14941  else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
14942  {
14943  if (add_prefix)
14944  {
14945  oa->write_character(to_char_type('I')); // int16
14946  }
14947  write_number(static_cast<std::int16_t>(n));
14948  }
14949  else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
14950  {
14951  if (add_prefix)
14952  {
14953  oa->write_character(to_char_type('l')); // int32
14954  }
14955  write_number(static_cast<std::int32_t>(n));
14956  }
14957  else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
14958  {
14959  if (add_prefix)
14960  {
14961  oa->write_character(to_char_type('L')); // int64
14962  }
14963  write_number(static_cast<std::int64_t>(n));
14964  }
14965  // LCOV_EXCL_START
14966  else
14967  {
14968  if (add_prefix)
14969  {
14970  oa->write_character(to_char_type('H')); // high-precision number
14971  }
14972 
14973  const auto number = BasicJsonType(n).dump();
14974  write_number_with_ubjson_prefix(number.size(), true);
14975  for (std::size_t i = 0; i < number.size(); ++i)
14976  {
14977  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14978  }
14979  }
14980  // LCOV_EXCL_STOP
14981  }
14982 
14986  CharType ubjson_prefix(const BasicJsonType& j) const noexcept
14987  {
14988  switch (j.type())
14989  {
14990  case value_t::null:
14991  return 'Z';
14992 
14993  case value_t::boolean:
14994  return j.m_value.boolean ? 'T' : 'F';
14995 
14996  case value_t::number_integer:
14997  {
14998  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)())
14999  {
15000  return 'i';
15001  }
15002  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)())
15003  {
15004  return 'U';
15005  }
15006  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)())
15007  {
15008  return 'I';
15009  }
15010  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)())
15011  {
15012  return 'l';
15013  }
15014  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)())
15015  {
15016  return 'L';
15017  }
15018  // anything else is treated as high-precision number
15019  return 'H'; // LCOV_EXCL_LINE
15020  }
15021 
15022  case value_t::number_unsigned:
15023  {
15024  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
15025  {
15026  return 'i';
15027  }
15028  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
15029  {
15030  return 'U';
15031  }
15032  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
15033  {
15034  return 'I';
15035  }
15036  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15037  {
15038  return 'l';
15039  }
15040  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15041  {
15042  return 'L';
15043  }
15044  // anything else is treated as high-precision number
15045  return 'H'; // LCOV_EXCL_LINE
15046  }
15047 
15048  case value_t::number_float:
15049  return get_ubjson_float_prefix(j.m_value.number_float);
15050 
15051  case value_t::string:
15052  return 'S';
15053 
15054  case value_t::array: // fallthrough
15055  case value_t::binary:
15056  return '[';
15057 
15058  case value_t::object:
15059  return '{';
15060 
15061  case value_t::discarded:
15062  default: // discarded values
15063  return 'N';
15064  }
15065  }
15066 
15067  static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
15068  {
15069  return 'd'; // float 32
15070  }
15071 
15072  static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
15073  {
15074  return 'D'; // float 64
15075  }
15076 
15078  // Utility functions //
15080 
15081  /*
15082  @brief write a number to output input
15083  @param[in] n number of type @a NumberType
15084  @tparam NumberType the type of the number
15085  @tparam OutputIsLittleEndian Set to true if output data is
15086  required to be little endian
15087 
15088  @note This function needs to respect the system's endianess, because bytes
15089  in CBOR, MessagePack, and UBJSON are stored in network order (big
15090  endian) and therefore need reordering on little endian systems.
15091  */
15092  template<typename NumberType, bool OutputIsLittleEndian = false>
15093  void write_number(const NumberType n)
15094  {
15095  // step 1: write number to array of length NumberType
15096  std::array<CharType, sizeof(NumberType)> vec{};
15097  std::memcpy(vec.data(), &n, sizeof(NumberType));
15098 
15099  // step 2: write array to output (with possible reordering)
15100  if (is_little_endian != OutputIsLittleEndian)
15101  {
15102  // reverse byte order prior to conversion if necessary
15103  std::reverse(vec.begin(), vec.end());
15104  }
15105 
15106  oa->write_characters(vec.data(), sizeof(NumberType));
15107  }
15108 
15109  void write_compact_float(const number_float_t n, detail::input_format_t format)
15110  {
15111 #ifdef __GNUC__
15112 #pragma GCC diagnostic push
15113 #pragma GCC diagnostic ignored "-Wfloat-equal"
15114 #endif
15115  if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
15116  static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
15117  static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
15118  {
15119  oa->write_character(format == detail::input_format_t::cbor
15120  ? get_cbor_float_prefix(static_cast<float>(n))
15121  : get_msgpack_float_prefix(static_cast<float>(n)));
15122  write_number(static_cast<float>(n));
15123  }
15124  else
15125  {
15126  oa->write_character(format == detail::input_format_t::cbor
15127  ? get_cbor_float_prefix(n)
15128  : get_msgpack_float_prefix(n));
15129  write_number(n);
15130  }
15131 #ifdef __GNUC__
15132 #pragma GCC diagnostic pop
15133 #endif
15134  }
15135 
15136  public:
15137  // The following to_char_type functions are implement the conversion
15138  // between uint8_t and CharType. In case CharType is not unsigned,
15139  // such a conversion is required to allow values greater than 128.
15140  // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
15141  template < typename C = CharType,
15142  enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
15143  static constexpr CharType to_char_type(std::uint8_t x) noexcept
15144  {
15145  return *reinterpret_cast<char*>(&x);
15146  }
15147 
15148  template < typename C = CharType,
15149  enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
15150  static CharType to_char_type(std::uint8_t x) noexcept
15151  {
15152  static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
15153  static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
15154  CharType result;
15155  std::memcpy(&result, &x, sizeof(x));
15156  return result;
15157  }
15158 
15159  template<typename C = CharType,
15160  enable_if_t<std::is_unsigned<C>::value>* = nullptr>
15161  static constexpr CharType to_char_type(std::uint8_t x) noexcept
15162  {
15163  return x;
15164  }
15165 
15166  template < typename InputCharType, typename C = CharType,
15167  enable_if_t <
15168  std::is_signed<C>::value &&
15169  std::is_signed<char>::value &&
15170  std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
15171  > * = nullptr >
15172  static constexpr CharType to_char_type(InputCharType x) noexcept
15173  {
15174  return x;
15175  }
15176 
15177  private:
15179  const bool is_little_endian = little_endianess();
15180 
15182  output_adapter_t<CharType> oa = nullptr;
15183 };
15184 } // namespace detail
15185 } // namespace nlohmann
15186 
15187 // #include <nlohmann/detail/output/output_adapters.hpp>
15188 
15189 // #include <nlohmann/detail/output/serializer.hpp>
15190 
15191 
15192 #include <algorithm> // reverse, remove, fill, find, none_of
15193 #include <array> // array
15194 #include <clocale> // localeconv, lconv
15195 #include <cmath> // labs, isfinite, isnan, signbit
15196 #include <cstddef> // size_t, ptrdiff_t
15197 #include <cstdint> // uint8_t
15198 #include <cstdio> // snprintf
15199 #include <limits> // numeric_limits
15200 #include <string> // string, char_traits
15201 #include <type_traits> // is_same
15202 #include <utility> // move
15203 
15204 // #include <nlohmann/detail/conversions/to_chars.hpp>
15205 
15206 
15207 #include <array> // array
15208 #include <cmath> // signbit, isfinite
15209 #include <cstdint> // intN_t, uintN_t
15210 #include <cstring> // memcpy, memmove
15211 #include <limits> // numeric_limits
15212 #include <type_traits> // conditional
15213 
15214 // #include <nlohmann/detail/macro_scope.hpp>
15215 
15216 
15217 namespace nlohmann
15218 {
15219 namespace detail
15220 {
15221 
15241 namespace dtoa_impl
15242 {
15243 
15244 template<typename Target, typename Source>
15245 Target reinterpret_bits(const Source source)
15246 {
15247  static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
15248 
15249  Target target;
15250  std::memcpy(&target, &source, sizeof(Source));
15251  return target;
15252 }
15253 
15254 struct diyfp // f * 2^e
15255 {
15256  static constexpr int kPrecision = 64; // = q
15257 
15258  std::uint64_t f = 0;
15259  int e = 0;
15260 
15261  constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
15262 
15267  static diyfp sub(const diyfp& x, const diyfp& y) noexcept
15268  {
15269  JSON_ASSERT(x.e == y.e);
15270  JSON_ASSERT(x.f >= y.f);
15271 
15272  return {x.f - y.f, x.e};
15273  }
15274 
15279  static diyfp mul(const diyfp& x, const diyfp& y) noexcept
15280  {
15281  static_assert(kPrecision == 64, "internal error");
15282 
15283  // Computes:
15284  // f = round((x.f * y.f) / 2^q)
15285  // e = x.e + y.e + q
15286 
15287  // Emulate the 64-bit * 64-bit multiplication:
15288  //
15289  // p = u * v
15290  // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
15291  // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
15292  // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
15293  // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
15294  // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
15295  // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
15296  // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
15297  //
15298  // (Since Q might be larger than 2^32 - 1)
15299  //
15300  // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
15301  //
15302  // (Q_hi + H does not overflow a 64-bit int)
15303  //
15304  // = p_lo + 2^64 p_hi
15305 
15306  const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
15307  const std::uint64_t u_hi = x.f >> 32u;
15308  const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
15309  const std::uint64_t v_hi = y.f >> 32u;
15310 
15311  const std::uint64_t p0 = u_lo * v_lo;
15312  const std::uint64_t p1 = u_lo * v_hi;
15313  const std::uint64_t p2 = u_hi * v_lo;
15314  const std::uint64_t p3 = u_hi * v_hi;
15315 
15316  const std::uint64_t p0_hi = p0 >> 32u;
15317  const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
15318  const std::uint64_t p1_hi = p1 >> 32u;
15319  const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
15320  const std::uint64_t p2_hi = p2 >> 32u;
15321 
15322  std::uint64_t Q = p0_hi + p1_lo + p2_lo;
15323 
15324  // The full product might now be computed as
15325  //
15326  // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
15327  // p_lo = p0_lo + (Q << 32)
15328  //
15329  // But in this particular case here, the full p_lo is not required.
15330  // Effectively we only need to add the highest bit in p_lo to p_hi (and
15331  // Q_hi + 1 does not overflow).
15332 
15333  Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
15334 
15335  const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
15336 
15337  return {h, x.e + y.e + 64};
15338  }
15339 
15344  static diyfp normalize(diyfp x) noexcept
15345  {
15346  JSON_ASSERT(x.f != 0);
15347 
15348  while ((x.f >> 63u) == 0)
15349  {
15350  x.f <<= 1u;
15351  x.e--;
15352  }
15353 
15354  return x;
15355  }
15356 
15361  static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
15362  {
15363  const int delta = x.e - target_exponent;
15364 
15365  JSON_ASSERT(delta >= 0);
15366  JSON_ASSERT(((x.f << delta) >> delta) == x.f);
15367 
15368  return {x.f << delta, target_exponent};
15369  }
15370 };
15371 
15372 struct boundaries
15373 {
15374  diyfp w;
15375  diyfp minus;
15376  diyfp plus;
15377 };
15378 
15385 template<typename FloatType>
15386 boundaries compute_boundaries(FloatType value)
15387 {
15388  JSON_ASSERT(std::isfinite(value));
15389  JSON_ASSERT(value > 0);
15390 
15391  // Convert the IEEE representation into a diyfp.
15392  //
15393  // If v is denormal:
15394  // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
15395  // If v is normalized:
15396  // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
15397 
15398  static_assert(std::numeric_limits<FloatType>::is_iec559,
15399  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
15400 
15401  constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
15402  constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
15403  constexpr int kMinExp = 1 - kBias;
15404  constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
15405 
15406  using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
15407 
15408  const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
15409  const std::uint64_t E = bits >> (kPrecision - 1);
15410  const std::uint64_t F = bits & (kHiddenBit - 1);
15411 
15412  const bool is_denormal = E == 0;
15413  const diyfp v = is_denormal
15414  ? diyfp(F, kMinExp)
15415  : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
15416 
15417  // Compute the boundaries m- and m+ of the floating-point value
15418  // v = f * 2^e.
15419  //
15420  // Determine v- and v+, the floating-point predecessor and successor if v,
15421  // respectively.
15422  //
15423  // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
15424  // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
15425  //
15426  // v+ = v + 2^e
15427  //
15428  // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
15429  // between m- and m+ round to v, regardless of how the input rounding
15430  // algorithm breaks ties.
15431  //
15432  // ---+-------------+-------------+-------------+-------------+--- (A)
15433  // v- m- v m+ v+
15434  //
15435  // -----------------+------+------+-------------+-------------+--- (B)
15436  // v- m- v m+ v+
15437 
15438  const bool lower_boundary_is_closer = F == 0 && E > 1;
15439  const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
15440  const diyfp m_minus = lower_boundary_is_closer
15441  ? diyfp(4 * v.f - 1, v.e - 2) // (B)
15442  : diyfp(2 * v.f - 1, v.e - 1); // (A)
15443 
15444  // Determine the normalized w+ = m+.
15445  const diyfp w_plus = diyfp::normalize(m_plus);
15446 
15447  // Determine w- = m- such that e_(w-) = e_(w+).
15448  const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
15449 
15450  return {diyfp::normalize(v), w_minus, w_plus};
15451 }
15452 
15453 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
15454 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
15455 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
15456 //
15457 // alpha <= e = e_c + e_w + q <= gamma
15458 //
15459 // or
15460 //
15461 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
15462 // <= f_c * f_w * 2^gamma
15463 //
15464 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
15465 //
15466 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
15467 //
15468 // or
15469 //
15470 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
15471 //
15472 // The choice of (alpha,gamma) determines the size of the table and the form of
15473 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
15474 // in practice:
15475 //
15476 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
15477 // processed independently: An integral part p1, and a fractional part p2:
15478 //
15479 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
15480 // = (f div 2^-e) + (f mod 2^-e) * 2^e
15481 // = p1 + p2 * 2^e
15482 //
15483 // The conversion of p1 into decimal form requires a series of divisions and
15484 // modulos by (a power of) 10. These operations are faster for 32-bit than for
15485 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
15486 // achieved by choosing
15487 //
15488 // -e >= 32 or e <= -32 := gamma
15489 //
15490 // In order to convert the fractional part
15491 //
15492 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
15493 //
15494 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
15495 // d[-i] are extracted in order:
15496 //
15497 // (10 * p2) div 2^-e = d[-1]
15498 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
15499 //
15500 // The multiplication by 10 must not overflow. It is sufficient to choose
15501 //
15502 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
15503 //
15504 // Since p2 = f mod 2^-e < 2^-e,
15505 //
15506 // -e <= 60 or e >= -60 := alpha
15507 
15508 constexpr int kAlpha = -60;
15509 constexpr int kGamma = -32;
15510 
15511 struct cached_power // c = f * 2^e ~= 10^k
15512 {
15513  std::uint64_t f;
15514  int e;
15515  int k;
15516 };
15517 
15525 inline cached_power get_cached_power_for_binary_exponent(int e)
15526 {
15527  // Now
15528  //
15529  // alpha <= e_c + e + q <= gamma (1)
15530  // ==> f_c * 2^alpha <= c * 2^e * 2^q
15531  //
15532  // and since the c's are normalized, 2^(q-1) <= f_c,
15533  //
15534  // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
15535  // ==> 2^(alpha - e - 1) <= c
15536  //
15537  // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
15538  //
15539  // k = ceil( log_10( 2^(alpha - e - 1) ) )
15540  // = ceil( (alpha - e - 1) * log_10(2) )
15541  //
15542  // From the paper:
15543  // "In theory the result of the procedure could be wrong since c is rounded,
15544  // and the computation itself is approximated [...]. In practice, however,
15545  // this simple function is sufficient."
15546  //
15547  // For IEEE double precision floating-point numbers converted into
15548  // normalized diyfp's w = f * 2^e, with q = 64,
15549  //
15550  // e >= -1022 (min IEEE exponent)
15551  // -52 (p - 1)
15552  // -52 (p - 1, possibly normalize denormal IEEE numbers)
15553  // -11 (normalize the diyfp)
15554  // = -1137
15555  //
15556  // and
15557  //
15558  // e <= +1023 (max IEEE exponent)
15559  // -52 (p - 1)
15560  // -11 (normalize the diyfp)
15561  // = 960
15562  //
15563  // This binary exponent range [-1137,960] results in a decimal exponent
15564  // range [-307,324]. One does not need to store a cached power for each
15565  // k in this range. For each such k it suffices to find a cached power
15566  // such that the exponent of the product lies in [alpha,gamma].
15567  // This implies that the difference of the decimal exponents of adjacent
15568  // table entries must be less than or equal to
15569  //
15570  // floor( (gamma - alpha) * log_10(2) ) = 8.
15571  //
15572  // (A smaller distance gamma-alpha would require a larger table.)
15573 
15574  // NB:
15575  // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
15576 
15577  constexpr int kCachedPowersMinDecExp = -300;
15578  constexpr int kCachedPowersDecStep = 8;
15579 
15580  static constexpr std::array<cached_power, 79> kCachedPowers =
15581  {
15582  {
15583  { 0xAB70FE17C79AC6CA, -1060, -300 },
15584  { 0xFF77B1FCBEBCDC4F, -1034, -292 },
15585  { 0xBE5691EF416BD60C, -1007, -284 },
15586  { 0x8DD01FAD907FFC3C, -980, -276 },
15587  { 0xD3515C2831559A83, -954, -268 },
15588  { 0x9D71AC8FADA6C9B5, -927, -260 },
15589  { 0xEA9C227723EE8BCB, -901, -252 },
15590  { 0xAECC49914078536D, -874, -244 },
15591  { 0x823C12795DB6CE57, -847, -236 },
15592  { 0xC21094364DFB5637, -821, -228 },
15593  { 0x9096EA6F3848984F, -794, -220 },
15594  { 0xD77485CB25823AC7, -768, -212 },
15595  { 0xA086CFCD97BF97F4, -741, -204 },
15596  { 0xEF340A98172AACE5, -715, -196 },
15597  { 0xB23867FB2A35B28E, -688, -188 },
15598  { 0x84C8D4DFD2C63F3B, -661, -180 },
15599  { 0xC5DD44271AD3CDBA, -635, -172 },
15600  { 0x936B9FCEBB25C996, -608, -164 },
15601  { 0xDBAC6C247D62A584, -582, -156 },
15602  { 0xA3AB66580D5FDAF6, -555, -148 },
15603  { 0xF3E2F893DEC3F126, -529, -140 },
15604  { 0xB5B5ADA8AAFF80B8, -502, -132 },
15605  { 0x87625F056C7C4A8B, -475, -124 },
15606  { 0xC9BCFF6034C13053, -449, -116 },
15607  { 0x964E858C91BA2655, -422, -108 },
15608  { 0xDFF9772470297EBD, -396, -100 },
15609  { 0xA6DFBD9FB8E5B88F, -369, -92 },
15610  { 0xF8A95FCF88747D94, -343, -84 },
15611  { 0xB94470938FA89BCF, -316, -76 },
15612  { 0x8A08F0F8BF0F156B, -289, -68 },
15613  { 0xCDB02555653131B6, -263, -60 },
15614  { 0x993FE2C6D07B7FAC, -236, -52 },
15615  { 0xE45C10C42A2B3B06, -210, -44 },
15616  { 0xAA242499697392D3, -183, -36 },
15617  { 0xFD87B5F28300CA0E, -157, -28 },
15618  { 0xBCE5086492111AEB, -130, -20 },
15619  { 0x8CBCCC096F5088CC, -103, -12 },
15620  { 0xD1B71758E219652C, -77, -4 },
15621  { 0x9C40000000000000, -50, 4 },
15622  { 0xE8D4A51000000000, -24, 12 },
15623  { 0xAD78EBC5AC620000, 3, 20 },
15624  { 0x813F3978F8940984, 30, 28 },
15625  { 0xC097CE7BC90715B3, 56, 36 },
15626  { 0x8F7E32CE7BEA5C70, 83, 44 },
15627  { 0xD5D238A4ABE98068, 109, 52 },
15628  { 0x9F4F2726179A2245, 136, 60 },
15629  { 0xED63A231D4C4FB27, 162, 68 },
15630  { 0xB0DE65388CC8ADA8, 189, 76 },
15631  { 0x83C7088E1AAB65DB, 216, 84 },
15632  { 0xC45D1DF942711D9A, 242, 92 },
15633  { 0x924D692CA61BE758, 269, 100 },
15634  { 0xDA01EE641A708DEA, 295, 108 },
15635  { 0xA26DA3999AEF774A, 322, 116 },
15636  { 0xF209787BB47D6B85, 348, 124 },
15637  { 0xB454E4A179DD1877, 375, 132 },
15638  { 0x865B86925B9BC5C2, 402, 140 },
15639  { 0xC83553C5C8965D3D, 428, 148 },
15640  { 0x952AB45CFA97A0B3, 455, 156 },
15641  { 0xDE469FBD99A05FE3, 481, 164 },
15642  { 0xA59BC234DB398C25, 508, 172 },
15643  { 0xF6C69A72A3989F5C, 534, 180 },
15644  { 0xB7DCBF5354E9BECE, 561, 188 },
15645  { 0x88FCF317F22241E2, 588, 196 },
15646  { 0xCC20CE9BD35C78A5, 614, 204 },
15647  { 0x98165AF37B2153DF, 641, 212 },
15648  { 0xE2A0B5DC971F303A, 667, 220 },
15649  { 0xA8D9D1535CE3B396, 694, 228 },
15650  { 0xFB9B7CD9A4A7443C, 720, 236 },
15651  { 0xBB764C4CA7A44410, 747, 244 },
15652  { 0x8BAB8EEFB6409C1A, 774, 252 },
15653  { 0xD01FEF10A657842C, 800, 260 },
15654  { 0x9B10A4E5E9913129, 827, 268 },
15655  { 0xE7109BFBA19C0C9D, 853, 276 },
15656  { 0xAC2820D9623BF429, 880, 284 },
15657  { 0x80444B5E7AA7CF85, 907, 292 },
15658  { 0xBF21E44003ACDD2D, 933, 300 },
15659  { 0x8E679C2F5E44FF8F, 960, 308 },
15660  { 0xD433179D9C8CB841, 986, 316 },
15661  { 0x9E19DB92B4E31BA9, 1013, 324 },
15662  }
15663  };
15664 
15665  // This computation gives exactly the same results for k as
15666  // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
15667  // for |e| <= 1500, but doesn't require floating-point operations.
15668  // NB: log_10(2) ~= 78913 / 2^18
15669  JSON_ASSERT(e >= -1500);
15670  JSON_ASSERT(e <= 1500);
15671  const int f = kAlpha - e - 1;
15672  const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
15673 
15674  const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
15675  JSON_ASSERT(index >= 0);
15676  JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
15677 
15678  const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
15679  JSON_ASSERT(kAlpha <= cached.e + e + 64);
15680  JSON_ASSERT(kGamma >= cached.e + e + 64);
15681 
15682  return cached;
15683 }
15684 
15689 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
15690 {
15691  // LCOV_EXCL_START
15692  if (n >= 1000000000)
15693  {
15694  pow10 = 1000000000;
15695  return 10;
15696  }
15697  // LCOV_EXCL_STOP
15698  if (n >= 100000000)
15699  {
15700  pow10 = 100000000;
15701  return 9;
15702  }
15703  if (n >= 10000000)
15704  {
15705  pow10 = 10000000;
15706  return 8;
15707  }
15708  if (n >= 1000000)
15709  {
15710  pow10 = 1000000;
15711  return 7;
15712  }
15713  if (n >= 100000)
15714  {
15715  pow10 = 100000;
15716  return 6;
15717  }
15718  if (n >= 10000)
15719  {
15720  pow10 = 10000;
15721  return 5;
15722  }
15723  if (n >= 1000)
15724  {
15725  pow10 = 1000;
15726  return 4;
15727  }
15728  if (n >= 100)
15729  {
15730  pow10 = 100;
15731  return 3;
15732  }
15733  if (n >= 10)
15734  {
15735  pow10 = 10;
15736  return 2;
15737  }
15738 
15739  pow10 = 1;
15740  return 1;
15741 }
15742 
15743 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
15744  std::uint64_t rest, std::uint64_t ten_k)
15745 {
15746  JSON_ASSERT(len >= 1);
15747  JSON_ASSERT(dist <= delta);
15748  JSON_ASSERT(rest <= delta);
15749  JSON_ASSERT(ten_k > 0);
15750 
15751  // <--------------------------- delta ---->
15752  // <---- dist --------->
15753  // --------------[------------------+-------------------]--------------
15754  // M- w M+
15755  //
15756  // ten_k
15757  // <------>
15758  // <---- rest ---->
15759  // --------------[------------------+----+--------------]--------------
15760  // w V
15761  // = buf * 10^k
15762  //
15763  // ten_k represents a unit-in-the-last-place in the decimal representation
15764  // stored in buf.
15765  // Decrement buf by ten_k while this takes buf closer to w.
15766 
15767  // The tests are written in this order to avoid overflow in unsigned
15768  // integer arithmetic.
15769 
15770  while (rest < dist
15771  && delta - rest >= ten_k
15772  && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
15773  {
15774  JSON_ASSERT(buf[len - 1] != '0');
15775  buf[len - 1]--;
15776  rest += ten_k;
15777  }
15778 }
15779 
15784 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
15785  diyfp M_minus, diyfp w, diyfp M_plus)
15786 {
15787  static_assert(kAlpha >= -60, "internal error");
15788  static_assert(kGamma <= -32, "internal error");
15789 
15790  // Generates the digits (and the exponent) of a decimal floating-point
15791  // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
15792  // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
15793  //
15794  // <--------------------------- delta ---->
15795  // <---- dist --------->
15796  // --------------[------------------+-------------------]--------------
15797  // M- w M+
15798  //
15799  // Grisu2 generates the digits of M+ from left to right and stops as soon as
15800  // V is in [M-,M+].
15801 
15802  JSON_ASSERT(M_plus.e >= kAlpha);
15803  JSON_ASSERT(M_plus.e <= kGamma);
15804 
15805  std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
15806  std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
15807 
15808  // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
15809  //
15810  // M+ = f * 2^e
15811  // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
15812  // = ((p1 ) * 2^-e + (p2 )) * 2^e
15813  // = p1 + p2 * 2^e
15814 
15815  const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
15816 
15817  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.)
15818  std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
15819 
15820  // 1)
15821  //
15822  // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
15823 
15824  JSON_ASSERT(p1 > 0);
15825 
15826  std::uint32_t pow10{};
15827  const int k = find_largest_pow10(p1, pow10);
15828 
15829  // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
15830  //
15831  // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
15832  // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
15833  //
15834  // M+ = p1 + p2 * 2^e
15835  // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
15836  // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
15837  // = d[k-1] * 10^(k-1) + ( rest) * 2^e
15838  //
15839  // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
15840  //
15841  // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
15842  //
15843  // but stop as soon as
15844  //
15845  // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
15846 
15847  int n = k;
15848  while (n > 0)
15849  {
15850  // Invariants:
15851  // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
15852  // pow10 = 10^(n-1) <= p1 < 10^n
15853  //
15854  const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
15855  const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
15856  //
15857  // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
15858  // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
15859  //
15860  JSON_ASSERT(d <= 9);
15861  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15862  //
15863  // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
15864  //
15865  p1 = r;
15866  n--;
15867  //
15868  // M+ = buffer * 10^n + (p1 + p2 * 2^e)
15869  // pow10 = 10^n
15870  //
15871 
15872  // Now check if enough digits have been generated.
15873  // Compute
15874  //
15875  // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
15876  //
15877  // Note:
15878  // Since rest and delta share the same exponent e, it suffices to
15879  // compare the significands.
15880  const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
15881  if (rest <= delta)
15882  {
15883  // V = buffer * 10^n, with M- <= V <= M+.
15884 
15885  decimal_exponent += n;
15886 
15887  // We may now just stop. But instead look if the buffer could be
15888  // decremented to bring V closer to w.
15889  //
15890  // pow10 = 10^n is now 1 ulp in the decimal representation V.
15891  // The rounding procedure works with diyfp's with an implicit
15892  // exponent of e.
15893  //
15894  // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
15895  //
15896  const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
15897  grisu2_round(buffer, length, dist, delta, rest, ten_n);
15898 
15899  return;
15900  }
15901 
15902  pow10 /= 10;
15903  //
15904  // pow10 = 10^(n-1) <= p1 < 10^n
15905  // Invariants restored.
15906  }
15907 
15908  // 2)
15909  //
15910  // The digits of the integral part have been generated:
15911  //
15912  // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
15913  // = buffer + p2 * 2^e
15914  //
15915  // Now generate the digits of the fractional part p2 * 2^e.
15916  //
15917  // Note:
15918  // No decimal point is generated: the exponent is adjusted instead.
15919  //
15920  // p2 actually represents the fraction
15921  //
15922  // p2 * 2^e
15923  // = p2 / 2^-e
15924  // = d[-1] / 10^1 + d[-2] / 10^2 + ...
15925  //
15926  // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
15927  //
15928  // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
15929  // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
15930  //
15931  // using
15932  //
15933  // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
15934  // = ( d) * 2^-e + ( r)
15935  //
15936  // or
15937  // 10^m * p2 * 2^e = d + r * 2^e
15938  //
15939  // i.e.
15940  //
15941  // M+ = buffer + p2 * 2^e
15942  // = buffer + 10^-m * (d + r * 2^e)
15943  // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
15944  //
15945  // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
15946 
15947  JSON_ASSERT(p2 > delta);
15948 
15949  int m = 0;
15950  for (;;)
15951  {
15952  // Invariant:
15953  // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
15954  // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
15955  // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
15956  // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
15957  //
15958  JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
15959  p2 *= 10;
15960  const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
15961  const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
15962  //
15963  // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
15964  // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
15965  // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
15966  //
15967  JSON_ASSERT(d <= 9);
15968  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15969  //
15970  // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
15971  //
15972  p2 = r;
15973  m++;
15974  //
15975  // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
15976  // Invariant restored.
15977 
15978  // Check if enough digits have been generated.
15979  //
15980  // 10^-m * p2 * 2^e <= delta * 2^e
15981  // p2 * 2^e <= 10^m * delta * 2^e
15982  // p2 <= 10^m * delta
15983  delta *= 10;
15984  dist *= 10;
15985  if (p2 <= delta)
15986  {
15987  break;
15988  }
15989  }
15990 
15991  // V = buffer * 10^-m, with M- <= V <= M+.
15992 
15993  decimal_exponent -= m;
15994 
15995  // 1 ulp in the decimal representation is now 10^-m.
15996  // Since delta and dist are now scaled by 10^m, we need to do the
15997  // same with ulp in order to keep the units in sync.
15998  //
15999  // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
16000  //
16001  const std::uint64_t ten_m = one.f;
16002  grisu2_round(buffer, length, dist, delta, p2, ten_m);
16003 
16004  // By construction this algorithm generates the shortest possible decimal
16005  // number (Loitsch, Theorem 6.2) which rounds back to w.
16006  // For an input number of precision p, at least
16007  //
16008  // N = 1 + ceil(p * log_10(2))
16009  //
16010  // decimal digits are sufficient to identify all binary floating-point
16011  // numbers (Matula, "In-and-Out conversions").
16012  // This implies that the algorithm does not produce more than N decimal
16013  // digits.
16014  //
16015  // N = 17 for p = 53 (IEEE double precision)
16016  // N = 9 for p = 24 (IEEE single precision)
16017 }
16018 
16024 JSON_HEDLEY_NON_NULL(1)
16025 inline void grisu2(char* buf, int& len, int& decimal_exponent,
16026  diyfp m_minus, diyfp v, diyfp m_plus)
16027 {
16028  JSON_ASSERT(m_plus.e == m_minus.e);
16029  JSON_ASSERT(m_plus.e == v.e);
16030 
16031  // --------(-----------------------+-----------------------)-------- (A)
16032  // m- v m+
16033  //
16034  // --------------------(-----------+-----------------------)-------- (B)
16035  // m- v m+
16036  //
16037  // First scale v (and m- and m+) such that the exponent is in the range
16038  // [alpha, gamma].
16039 
16040  const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
16041 
16042  const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
16043 
16044  // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
16045  const diyfp w = diyfp::mul(v, c_minus_k);
16046  const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
16047  const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
16048 
16049  // ----(---+---)---------------(---+---)---------------(---+---)----
16050  // w- w w+
16051  // = c*m- = c*v = c*m+
16052  //
16053  // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
16054  // w+ are now off by a small amount.
16055  // In fact:
16056  //
16057  // w - v * 10^k < 1 ulp
16058  //
16059  // To account for this inaccuracy, add resp. subtract 1 ulp.
16060  //
16061  // --------+---[---------------(---+---)---------------]---+--------
16062  // w- M- w M+ w+
16063  //
16064  // Now any number in [M-, M+] (bounds included) will round to w when input,
16065  // regardless of how the input rounding algorithm breaks ties.
16066  //
16067  // And digit_gen generates the shortest possible such number in [M-, M+].
16068  // Note that this does not mean that Grisu2 always generates the shortest
16069  // possible number in the interval (m-, m+).
16070  const diyfp M_minus(w_minus.f + 1, w_minus.e);
16071  const diyfp M_plus (w_plus.f - 1, w_plus.e );
16072 
16073  decimal_exponent = -cached.k; // = -(-k) = k
16074 
16075  grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
16076 }
16077 
16083 template<typename FloatType>
16084 JSON_HEDLEY_NON_NULL(1)
16085 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
16086 {
16087  static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
16088  "internal error: not enough precision");
16089 
16090  JSON_ASSERT(std::isfinite(value));
16091  JSON_ASSERT(value > 0);
16092 
16093  // If the neighbors (and boundaries) of 'value' are always computed for double-precision
16094  // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
16095  // decimal representations are not exactly "short".
16096  //
16097  // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
16098  // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
16099  // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
16100  // does.
16101  // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
16102  // representation using the corresponding std::from_chars function recovers value exactly". That
16103  // indicates that single precision floating-point numbers should be recovered using
16104  // 'std::strtof'.
16105  //
16106  // NB: If the neighbors are computed for single-precision numbers, there is a single float
16107  // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
16108  // value is off by 1 ulp.
16109 #if 0
16110  const boundaries w = compute_boundaries(static_cast<double>(value));
16111 #else
16112  const boundaries w = compute_boundaries(value);
16113 #endif
16114 
16115  grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
16116 }
16117 
16123 JSON_HEDLEY_NON_NULL(1)
16124 
16125 inline char* append_exponent(char* buf, int e)
16126 {
16127  JSON_ASSERT(e > -1000);
16128  JSON_ASSERT(e < 1000);
16129 
16130  if (e < 0)
16131  {
16132  e = -e;
16133  *buf++ = '-';
16134  }
16135  else
16136  {
16137  *buf++ = '+';
16138  }
16139 
16140  auto k = static_cast<std::uint32_t>(e);
16141  if (k < 10)
16142  {
16143  // Always print at least two digits in the exponent.
16144  // This is for compatibility with printf("%g").
16145  *buf++ = '0';
16146  *buf++ = static_cast<char>('0' + k);
16147  }
16148  else if (k < 100)
16149  {
16150  *buf++ = static_cast<char>('0' + k / 10);
16151  k %= 10;
16152  *buf++ = static_cast<char>('0' + k);
16153  }
16154  else
16155  {
16156  *buf++ = static_cast<char>('0' + k / 100);
16157  k %= 100;
16158  *buf++ = static_cast<char>('0' + k / 10);
16159  k %= 10;
16160  *buf++ = static_cast<char>('0' + k);
16161  }
16162 
16163  return buf;
16164 }
16165 
16175 JSON_HEDLEY_NON_NULL(1)
16176 
16177 inline char* format_buffer(char* buf, int len, int decimal_exponent,
16178  int min_exp, int max_exp)
16179 {
16180  JSON_ASSERT(min_exp < 0);
16181  JSON_ASSERT(max_exp > 0);
16182 
16183  const int k = len;
16184  const int n = len + decimal_exponent;
16185 
16186  // v = buf * 10^(n-k)
16187  // k is the length of the buffer (number of decimal digits)
16188  // n is the position of the decimal point relative to the start of the buffer.
16189 
16190  if (k <= n && n <= max_exp)
16191  {
16192  // digits[000]
16193  // len <= max_exp + 2
16194 
16195  std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
16196  // Make it look like a floating-point number (#362, #378)
16197  buf[n + 0] = '.';
16198  buf[n + 1] = '0';
16199  return buf + (static_cast<size_t>(n) + 2);
16200  }
16201 
16202  if (0 < n && n <= max_exp)
16203  {
16204  // dig.its
16205  // len <= max_digits10 + 1
16206 
16207  JSON_ASSERT(k > n);
16208 
16209  std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
16210  buf[n] = '.';
16211  return buf + (static_cast<size_t>(k) + 1U);
16212  }
16213 
16214  if (min_exp < n && n <= 0)
16215  {
16216  // 0.[000]digits
16217  // len <= 2 + (-min_exp - 1) + max_digits10
16218 
16219  std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
16220  buf[0] = '0';
16221  buf[1] = '.';
16222  std::memset(buf + 2, '0', static_cast<size_t>(-n));
16223  return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
16224  }
16225 
16226  if (k == 1)
16227  {
16228  // dE+123
16229  // len <= 1 + 5
16230 
16231  buf += 1;
16232  }
16233  else
16234  {
16235  // d.igitsE+123
16236  // len <= max_digits10 + 1 + 5
16237 
16238  std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
16239  buf[1] = '.';
16240  buf += 1 + static_cast<size_t>(k);
16241  }
16242 
16243  *buf++ = 'e';
16244  return append_exponent(buf, n - 1);
16245 }
16246 
16247 } // namespace dtoa_impl
16248 
16259 template<typename FloatType>
16260 JSON_HEDLEY_NON_NULL(1, 2)
16261 
16262 char* to_chars(char* first, const char* last, FloatType value)
16263 {
16264  static_cast<void>(last); // maybe unused - fix warning
16265  JSON_ASSERT(std::isfinite(value));
16266 
16267  // Use signbit(value) instead of (value < 0) since signbit works for -0.
16268  if (std::signbit(value))
16269  {
16270  value = -value;
16271  *first++ = '-';
16272  }
16273 
16274 #ifdef __GNUC__
16275 #pragma GCC diagnostic push
16276 #pragma GCC diagnostic ignored "-Wfloat-equal"
16277 #endif
16278  if (value == 0) // +-0
16279  {
16280  *first++ = '0';
16281  // Make it look like a floating-point number (#362, #378)
16282  *first++ = '.';
16283  *first++ = '0';
16284  return first;
16285  }
16286 #ifdef __GNUC__
16287 #pragma GCC diagnostic pop
16288 #endif
16289 
16290  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
16291 
16292  // Compute v = buffer * 10^decimal_exponent.
16293  // The decimal digits are stored in the buffer, which needs to be interpreted
16294  // as an unsigned decimal integer.
16295  // len is the length of the buffer, i.e. the number of decimal digits.
16296  int len = 0;
16297  int decimal_exponent = 0;
16298  dtoa_impl::grisu2(first, len, decimal_exponent, value);
16299 
16300  JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
16301 
16302  // Format the buffer like printf("%.*g", prec, value)
16303  constexpr int kMinExp = -4;
16304  // Use digits10 here to increase compatibility with version 2.
16305  constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
16306 
16307  JSON_ASSERT(last - first >= kMaxExp + 2);
16308  JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
16309  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
16310 
16311  return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
16312 }
16313 
16314 } // namespace detail
16315 } // namespace nlohmann
16316 
16317 // #include <nlohmann/detail/exceptions.hpp>
16318 
16319 // #include <nlohmann/detail/macro_scope.hpp>
16320 
16321 // #include <nlohmann/detail/meta/cpp_future.hpp>
16322 
16323 // #include <nlohmann/detail/output/binary_writer.hpp>
16324 
16325 // #include <nlohmann/detail/output/output_adapters.hpp>
16326 
16327 // #include <nlohmann/detail/value_t.hpp>
16328 
16329 
16330 namespace nlohmann
16331 {
16332 namespace detail
16333 {
16335 // serialization //
16337 
16339 enum class error_handler_t
16340 {
16341  strict,
16342  replace,
16343  ignore
16344 };
16345 
16346 template<typename BasicJsonType>
16347 class serializer
16348 {
16349  using string_t = typename BasicJsonType::string_t;
16350  using number_float_t = typename BasicJsonType::number_float_t;
16351  using number_integer_t = typename BasicJsonType::number_integer_t;
16352  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
16353  using binary_char_t = typename BasicJsonType::binary_t::value_type;
16354  static constexpr std::uint8_t UTF8_ACCEPT = 0;
16355  static constexpr std::uint8_t UTF8_REJECT = 1;
16356 
16357  public:
16363  serializer(output_adapter_t<char> s, const char ichar,
16364  error_handler_t error_handler_ = error_handler_t::strict)
16365  : o(std::move(s))
16366  , loc(std::localeconv())
16367  , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
16368  , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
16369  , indent_char(ichar)
16370  , indent_string(512, indent_char)
16371  , error_handler(error_handler_)
16372  {}
16373 
16374  // delete because of pointer members
16375  serializer(const serializer&) = delete;
16376  serializer& operator=(const serializer&) = delete;
16377  serializer(serializer&&) = delete;
16378  serializer& operator=(serializer&&) = delete;
16379  ~serializer() = default;
16380 
16403  void dump(const BasicJsonType& val,
16404  const bool pretty_print,
16405  const bool ensure_ascii,
16406  const unsigned int indent_step,
16407  const unsigned int current_indent = 0)
16408  {
16409  switch (val.m_type)
16410  {
16411  case value_t::object:
16412  {
16413  if (val.m_value.object->empty())
16414  {
16415  o->write_characters("{}", 2);
16416  return;
16417  }
16418 
16419  if (pretty_print)
16420  {
16421  o->write_characters("{\n", 2);
16422 
16423  // variable to hold indentation for recursive calls
16424  const auto new_indent = current_indent + indent_step;
16425  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16426  {
16427  indent_string.resize(indent_string.size() * 2, ' ');
16428  }
16429 
16430  // first n-1 elements
16431  auto i = val.m_value.object->cbegin();
16432  for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16433  {
16434  o->write_characters(indent_string.c_str(), new_indent);
16435  o->write_character('\"');
16436  dump_escaped(i->first, ensure_ascii);
16437  o->write_characters("\": ", 3);
16438  dump(i->second, true, ensure_ascii, indent_step, new_indent);
16439  o->write_characters(",\n", 2);
16440  }
16441 
16442  // last element
16443  JSON_ASSERT(i != val.m_value.object->cend());
16444  JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16445  o->write_characters(indent_string.c_str(), new_indent);
16446  o->write_character('\"');
16447  dump_escaped(i->first, ensure_ascii);
16448  o->write_characters("\": ", 3);
16449  dump(i->second, true, ensure_ascii, indent_step, new_indent);
16450 
16451  o->write_character('\n');
16452  o->write_characters(indent_string.c_str(), current_indent);
16453  o->write_character('}');
16454  }
16455  else
16456  {
16457  o->write_character('{');
16458 
16459  // first n-1 elements
16460  auto i = val.m_value.object->cbegin();
16461  for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16462  {
16463  o->write_character('\"');
16464  dump_escaped(i->first, ensure_ascii);
16465  o->write_characters("\":", 2);
16466  dump(i->second, false, ensure_ascii, indent_step, current_indent);
16467  o->write_character(',');
16468  }
16469 
16470  // last element
16471  JSON_ASSERT(i != val.m_value.object->cend());
16472  JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16473  o->write_character('\"');
16474  dump_escaped(i->first, ensure_ascii);
16475  o->write_characters("\":", 2);
16476  dump(i->second, false, ensure_ascii, indent_step, current_indent);
16477 
16478  o->write_character('}');
16479  }
16480 
16481  return;
16482  }
16483 
16484  case value_t::array:
16485  {
16486  if (val.m_value.array->empty())
16487  {
16488  o->write_characters("[]", 2);
16489  return;
16490  }
16491 
16492  if (pretty_print)
16493  {
16494  o->write_characters("[\n", 2);
16495 
16496  // variable to hold indentation for recursive calls
16497  const auto new_indent = current_indent + indent_step;
16498  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16499  {
16500  indent_string.resize(indent_string.size() * 2, ' ');
16501  }
16502 
16503  // first n-1 elements
16504  for (auto i = val.m_value.array->cbegin();
16505  i != val.m_value.array->cend() - 1; ++i)
16506  {
16507  o->write_characters(indent_string.c_str(), new_indent);
16508  dump(*i, true, ensure_ascii, indent_step, new_indent);
16509  o->write_characters(",\n", 2);
16510  }
16511 
16512  // last element
16513  JSON_ASSERT(!val.m_value.array->empty());
16514  o->write_characters(indent_string.c_str(), new_indent);
16515  dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
16516 
16517  o->write_character('\n');
16518  o->write_characters(indent_string.c_str(), current_indent);
16519  o->write_character(']');
16520  }
16521  else
16522  {
16523  o->write_character('[');
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  dump(*i, false, ensure_ascii, indent_step, current_indent);
16530  o->write_character(',');
16531  }
16532 
16533  // last element
16534  JSON_ASSERT(!val.m_value.array->empty());
16535  dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
16536 
16537  o->write_character(']');
16538  }
16539 
16540  return;
16541  }
16542 
16543  case value_t::string:
16544  {
16545  o->write_character('\"');
16546  dump_escaped(*val.m_value.string, ensure_ascii);
16547  o->write_character('\"');
16548  return;
16549  }
16550 
16551  case value_t::binary:
16552  {
16553  if (pretty_print)
16554  {
16555  o->write_characters("{\n", 2);
16556 
16557  // variable to hold indentation for recursive calls
16558  const auto new_indent = current_indent + indent_step;
16559  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16560  {
16561  indent_string.resize(indent_string.size() * 2, ' ');
16562  }
16563 
16564  o->write_characters(indent_string.c_str(), new_indent);
16565 
16566  o->write_characters("\"bytes\": [", 10);
16567 
16568  if (!val.m_value.binary->empty())
16569  {
16570  for (auto i = val.m_value.binary->cbegin();
16571  i != val.m_value.binary->cend() - 1; ++i)
16572  {
16573  dump_integer(*i);
16574  o->write_characters(", ", 2);
16575  }
16576  dump_integer(val.m_value.binary->back());
16577  }
16578 
16579  o->write_characters("],\n", 3);
16580  o->write_characters(indent_string.c_str(), new_indent);
16581 
16582  o->write_characters("\"subtype\": ", 11);
16583  if (val.m_value.binary->has_subtype())
16584  {
16585  dump_integer(val.m_value.binary->subtype());
16586  }
16587  else
16588  {
16589  o->write_characters("null", 4);
16590  }
16591  o->write_character('\n');
16592  o->write_characters(indent_string.c_str(), current_indent);
16593  o->write_character('}');
16594  }
16595  else
16596  {
16597  o->write_characters("{\"bytes\":[", 10);
16598 
16599  if (!val.m_value.binary->empty())
16600  {
16601  for (auto i = val.m_value.binary->cbegin();
16602  i != val.m_value.binary->cend() - 1; ++i)
16603  {
16604  dump_integer(*i);
16605  o->write_character(',');
16606  }
16607  dump_integer(val.m_value.binary->back());
16608  }
16609 
16610  o->write_characters("],\"subtype\":", 12);
16611  if (val.m_value.binary->has_subtype())
16612  {
16613  dump_integer(val.m_value.binary->subtype());
16614  o->write_character('}');
16615  }
16616  else
16617  {
16618  o->write_characters("null}", 5);
16619  }
16620  }
16621  return;
16622  }
16623 
16624  case value_t::boolean:
16625  {
16626  if (val.m_value.boolean)
16627  {
16628  o->write_characters("true", 4);
16629  }
16630  else
16631  {
16632  o->write_characters("false", 5);
16633  }
16634  return;
16635  }
16636 
16637  case value_t::number_integer:
16638  {
16639  dump_integer(val.m_value.number_integer);
16640  return;
16641  }
16642 
16643  case value_t::number_unsigned:
16644  {
16645  dump_integer(val.m_value.number_unsigned);
16646  return;
16647  }
16648 
16649  case value_t::number_float:
16650  {
16651  dump_float(val.m_value.number_float);
16652  return;
16653  }
16654 
16655  case value_t::discarded:
16656  {
16657  o->write_characters("<discarded>", 11);
16658  return;
16659  }
16660 
16661  case value_t::null:
16662  {
16663  o->write_characters("null", 4);
16664  return;
16665  }
16666 
16667  default: // LCOV_EXCL_LINE
16668  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16669  }
16670  }
16671 
16672  JSON_PRIVATE_UNLESS_TESTED:
16687  void dump_escaped(const string_t& s, const bool ensure_ascii)
16688  {
16689  std::uint32_t codepoint{};
16690  std::uint8_t state = UTF8_ACCEPT;
16691  std::size_t bytes = 0; // number of bytes written to string_buffer
16692 
16693  // number of bytes written at the point of the last valid byte
16694  std::size_t bytes_after_last_accept = 0;
16695  std::size_t undumped_chars = 0;
16696 
16697  for (std::size_t i = 0; i < s.size(); ++i)
16698  {
16699  const auto byte = static_cast<std::uint8_t>(s[i]);
16700 
16701  switch (decode(state, codepoint, byte))
16702  {
16703  case UTF8_ACCEPT: // decode found a new code point
16704  {
16705  switch (codepoint)
16706  {
16707  case 0x08: // backspace
16708  {
16709  string_buffer[bytes++] = '\\';
16710  string_buffer[bytes++] = 'b';
16711  break;
16712  }
16713 
16714  case 0x09: // horizontal tab
16715  {
16716  string_buffer[bytes++] = '\\';
16717  string_buffer[bytes++] = 't';
16718  break;
16719  }
16720 
16721  case 0x0A: // newline
16722  {
16723  string_buffer[bytes++] = '\\';
16724  string_buffer[bytes++] = 'n';
16725  break;
16726  }
16727 
16728  case 0x0C: // formfeed
16729  {
16730  string_buffer[bytes++] = '\\';
16731  string_buffer[bytes++] = 'f';
16732  break;
16733  }
16734 
16735  case 0x0D: // carriage return
16736  {
16737  string_buffer[bytes++] = '\\';
16738  string_buffer[bytes++] = 'r';
16739  break;
16740  }
16741 
16742  case 0x22: // quotation mark
16743  {
16744  string_buffer[bytes++] = '\\';
16745  string_buffer[bytes++] = '\"';
16746  break;
16747  }
16748 
16749  case 0x5C: // reverse solidus
16750  {
16751  string_buffer[bytes++] = '\\';
16752  string_buffer[bytes++] = '\\';
16753  break;
16754  }
16755 
16756  default:
16757  {
16758  // escape control characters (0x00..0x1F) or, if
16759  // ensure_ascii parameter is used, non-ASCII characters
16760  if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
16761  {
16762  if (codepoint <= 0xFFFF)
16763  {
16764  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16765  (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
16766  static_cast<std::uint16_t>(codepoint));
16767  bytes += 6;
16768  }
16769  else
16770  {
16771  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16772  (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
16773  static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
16774  static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
16775  bytes += 12;
16776  }
16777  }
16778  else
16779  {
16780  // copy byte to buffer (all previous bytes
16781  // been copied have in default case above)
16782  string_buffer[bytes++] = s[i];
16783  }
16784  break;
16785  }
16786  }
16787 
16788  // write buffer and reset index; there must be 13 bytes
16789  // left, as this is the maximal number of bytes to be
16790  // written ("\uxxxx\uxxxx\0") for one code point
16791  if (string_buffer.size() - bytes < 13)
16792  {
16793  o->write_characters(string_buffer.data(), bytes);
16794  bytes = 0;
16795  }
16796 
16797  // remember the byte position of this accept
16798  bytes_after_last_accept = bytes;
16799  undumped_chars = 0;
16800  break;
16801  }
16802 
16803  case UTF8_REJECT: // decode found invalid UTF-8 byte
16804  {
16805  switch (error_handler)
16806  {
16807  case error_handler_t::strict:
16808  {
16809  std::string sn(9, '\0');
16810  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16811  (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
16812  JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn, BasicJsonType()));
16813  }
16814 
16815  case error_handler_t::ignore:
16816  case error_handler_t::replace:
16817  {
16818  // in case we saw this character the first time, we
16819  // would like to read it again, because the byte
16820  // may be OK for itself, but just not OK for the
16821  // previous sequence
16822  if (undumped_chars > 0)
16823  {
16824  --i;
16825  }
16826 
16827  // reset length buffer to the last accepted index;
16828  // thus removing/ignoring the invalid characters
16829  bytes = bytes_after_last_accept;
16830 
16831  if (error_handler == error_handler_t::replace)
16832  {
16833  // add a replacement character
16834  if (ensure_ascii)
16835  {
16836  string_buffer[bytes++] = '\\';
16837  string_buffer[bytes++] = 'u';
16838  string_buffer[bytes++] = 'f';
16839  string_buffer[bytes++] = 'f';
16840  string_buffer[bytes++] = 'f';
16841  string_buffer[bytes++] = 'd';
16842  }
16843  else
16844  {
16845  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
16846  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
16847  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
16848  }
16849 
16850  // write buffer and reset index; there must be 13 bytes
16851  // left, as this is the maximal number of bytes to be
16852  // written ("\uxxxx\uxxxx\0") for one code point
16853  if (string_buffer.size() - bytes < 13)
16854  {
16855  o->write_characters(string_buffer.data(), bytes);
16856  bytes = 0;
16857  }
16858 
16859  bytes_after_last_accept = bytes;
16860  }
16861 
16862  undumped_chars = 0;
16863 
16864  // continue processing the string
16865  state = UTF8_ACCEPT;
16866  break;
16867  }
16868 
16869  default: // LCOV_EXCL_LINE
16870  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16871  }
16872  break;
16873  }
16874 
16875  default: // decode found yet incomplete multi-byte code point
16876  {
16877  if (!ensure_ascii)
16878  {
16879  // code point will not be escaped - copy byte to buffer
16880  string_buffer[bytes++] = s[i];
16881  }
16882  ++undumped_chars;
16883  break;
16884  }
16885  }
16886  }
16887 
16888  // we finished processing the string
16889  if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
16890  {
16891  // write buffer
16892  if (bytes > 0)
16893  {
16894  o->write_characters(string_buffer.data(), bytes);
16895  }
16896  }
16897  else
16898  {
16899  // we finish reading, but do not accept: string was incomplete
16900  switch (error_handler)
16901  {
16902  case error_handler_t::strict:
16903  {
16904  std::string sn(9, '\0');
16905  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16906  (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
16907  JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn, BasicJsonType()));
16908  }
16909 
16910  case error_handler_t::ignore:
16911  {
16912  // write all accepted bytes
16913  o->write_characters(string_buffer.data(), bytes_after_last_accept);
16914  break;
16915  }
16916 
16917  case error_handler_t::replace:
16918  {
16919  // write all accepted bytes
16920  o->write_characters(string_buffer.data(), bytes_after_last_accept);
16921  // add a replacement character
16922  if (ensure_ascii)
16923  {
16924  o->write_characters("\\ufffd", 6);
16925  }
16926  else
16927  {
16928  o->write_characters("\xEF\xBF\xBD", 3);
16929  }
16930  break;
16931  }
16932 
16933  default: // LCOV_EXCL_LINE
16934  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16935  }
16936  }
16937  }
16938 
16939  private:
16948  inline unsigned int count_digits(number_unsigned_t x) noexcept
16949  {
16950  unsigned int n_digits = 1;
16951  for (;;)
16952  {
16953  if (x < 10)
16954  {
16955  return n_digits;
16956  }
16957  if (x < 100)
16958  {
16959  return n_digits + 1;
16960  }
16961  if (x < 1000)
16962  {
16963  return n_digits + 2;
16964  }
16965  if (x < 10000)
16966  {
16967  return n_digits + 3;
16968  }
16969  x = x / 10000u;
16970  n_digits += 4;
16971  }
16972  }
16973 
16983  template < typename NumberType, detail::enable_if_t <
16984  std::is_integral<NumberType>::value ||
16985  std::is_same<NumberType, number_unsigned_t>::value ||
16986  std::is_same<NumberType, number_integer_t>::value ||
16987  std::is_same<NumberType, binary_char_t>::value,
16988  int > = 0 >
16989  void dump_integer(NumberType x)
16990  {
16991  static constexpr std::array<std::array<char, 2>, 100> digits_to_99
16992  {
16993  {
16994  {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
16995  {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
16996  {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
16997  {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
16998  {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
16999  {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
17000  {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
17001  {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
17002  {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
17003  {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
17004  }
17005  };
17006 
17007  // special case for "0"
17008  if (x == 0)
17009  {
17010  o->write_character('0');
17011  return;
17012  }
17013 
17014  // use a pointer to fill the buffer
17015  auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17016 
17017  const bool is_negative = std::is_signed<NumberType>::value && !(x >= 0); // see issue #755
17018  number_unsigned_t abs_value;
17019 
17020  unsigned int n_chars{};
17021 
17022  if (is_negative)
17023  {
17024  *buffer_ptr = '-';
17025  abs_value = remove_sign(static_cast<number_integer_t>(x));
17026 
17027  // account one more byte for the minus sign
17028  n_chars = 1 + count_digits(abs_value);
17029  }
17030  else
17031  {
17032  abs_value = static_cast<number_unsigned_t>(x);
17033  n_chars = count_digits(abs_value);
17034  }
17035 
17036  // spare 1 byte for '\0'
17037  JSON_ASSERT(n_chars < number_buffer.size() - 1);
17038 
17039  // jump to the end to generate the string from backward
17040  // so we later avoid reversing the result
17041  buffer_ptr += n_chars;
17042 
17043  // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
17044  // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
17045  while (abs_value >= 100)
17046  {
17047  const auto digits_index = static_cast<unsigned>((abs_value % 100));
17048  abs_value /= 100;
17049  *(--buffer_ptr) = digits_to_99[digits_index][1];
17050  *(--buffer_ptr) = digits_to_99[digits_index][0];
17051  }
17052 
17053  if (abs_value >= 10)
17054  {
17055  const auto digits_index = static_cast<unsigned>(abs_value);
17056  *(--buffer_ptr) = digits_to_99[digits_index][1];
17057  *(--buffer_ptr) = digits_to_99[digits_index][0];
17058  }
17059  else
17060  {
17061  *(--buffer_ptr) = static_cast<char>('0' + abs_value);
17062  }
17063 
17064  o->write_characters(number_buffer.data(), n_chars);
17065  }
17066 
17075  void dump_float(number_float_t x)
17076  {
17077  // NaN / inf
17078  if (!std::isfinite(x))
17079  {
17080  o->write_characters("null", 4);
17081  return;
17082  }
17083 
17084  // If number_float_t is an IEEE-754 single or double precision number,
17085  // use the Grisu2 algorithm to produce short numbers which are
17086  // guaranteed to round-trip, using strtof and strtod, resp.
17087  //
17088  // NB: The test below works if <long double> == <double>.
17089  static constexpr bool is_ieee_single_or_double
17090  = (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) ||
17091  (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);
17092 
17093  dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
17094  }
17095 
17096  void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
17097  {
17098  auto* begin = number_buffer.data();
17099  auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
17100 
17101  o->write_characters(begin, static_cast<size_t>(end - begin));
17102  }
17103 
17104  void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
17105  {
17106  // get number of digits for a float -> text -> float round-trip
17107  static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
17108 
17109  // the actual conversion
17110  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17111  std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
17112 
17113  // negative value indicates an error
17114  JSON_ASSERT(len > 0);
17115  // check if buffer was large enough
17116  JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
17117 
17118  // erase thousands separator
17119  if (thousands_sep != '\0')
17120  {
17121  auto* const end = std::remove(number_buffer.begin(),
17122  number_buffer.begin() + len, thousands_sep);
17123  std::fill(end, number_buffer.end(), '\0');
17124  JSON_ASSERT((end - number_buffer.begin()) <= len);
17125  len = (end - number_buffer.begin());
17126  }
17127 
17128  // convert decimal point to '.'
17129  if (decimal_point != '\0' && decimal_point != '.')
17130  {
17131  auto* const dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
17132  if (dec_pos != number_buffer.end())
17133  {
17134  *dec_pos = '.';
17135  }
17136  }
17137 
17138  o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
17139 
17140  // determine if need to append ".0"
17141  const bool value_is_int_like =
17142  std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
17143  [](char c)
17144  {
17145  return c == '.' || c == 'e';
17146  });
17147 
17148  if (value_is_int_like)
17149  {
17150  o->write_characters(".0", 2);
17151  }
17152  }
17153 
17175  static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
17176  {
17177  static const std::array<std::uint8_t, 400> utf8d =
17178  {
17179  {
17180  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
17181  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
17182  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
17183  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
17184  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
17185  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
17186  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
17187  0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
17188  0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
17189  0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
17190  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
17191  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
17192  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
17193  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
17194  }
17195  };
17196 
17197  JSON_ASSERT(byte < utf8d.size());
17198  const std::uint8_t type = utf8d[byte];
17199 
17200  codep = (state != UTF8_ACCEPT)
17201  ? (byte & 0x3fu) | (codep << 6u)
17202  : (0xFFu >> type) & (byte);
17203 
17204  std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
17205  JSON_ASSERT(index < 400);
17206  state = utf8d[index];
17207  return state;
17208  }
17209 
17210  /*
17211  * Overload to make the compiler happy while it is instantiating
17212  * dump_integer for number_unsigned_t.
17213  * Must never be called.
17214  */
17215  number_unsigned_t remove_sign(number_unsigned_t x)
17216  {
17217  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17218  return x; // LCOV_EXCL_LINE
17219  }
17220 
17221  /*
17222  * Helper function for dump_integer
17223  *
17224  * This function takes a negative signed integer and returns its absolute
17225  * value as unsigned integer. The plus/minus shuffling is necessary as we can
17226  * not directly remove the sign of an arbitrary signed integer as the
17227  * absolute values of INT_MIN and INT_MAX are usually not the same. See
17228  * #1708 for details.
17229  */
17230  inline number_unsigned_t remove_sign(number_integer_t x) noexcept
17231  {
17232  JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
17233  return static_cast<number_unsigned_t>(-(x + 1)) + 1;
17234  }
17235 
17236  private:
17238  output_adapter_t<char> o = nullptr;
17239 
17241  std::array<char, 64> number_buffer{{}};
17242 
17244  const std::lconv* loc = nullptr;
17246  const char thousands_sep = '\0';
17248  const char decimal_point = '\0';
17249 
17251  std::array<char, 512> string_buffer{{}};
17252 
17254  const char indent_char;
17256  string_t indent_string;
17257 
17259  const error_handler_t error_handler;
17260 };
17261 } // namespace detail
17262 } // namespace nlohmann
17263 
17264 // #include <nlohmann/detail/value_t.hpp>
17265 
17266 // #include <nlohmann/json_fwd.hpp>
17267 
17268 // #include <nlohmann/ordered_map.hpp>
17269 
17270 
17271 #include <functional> // less
17272 #include <initializer_list> // initializer_list
17273 #include <iterator> // input_iterator_tag, iterator_traits
17274 #include <memory> // allocator
17275 #include <stdexcept> // for out_of_range
17276 #include <type_traits> // enable_if, is_convertible
17277 #include <utility> // pair
17278 #include <vector> // vector
17279 
17280 // #include <nlohmann/detail/macro_scope.hpp>
17281 
17282 
17283 namespace nlohmann
17284 {
17285 
17288 template <class Key, class T, class IgnoredLess = std::less<Key>,
17289  class Allocator = std::allocator<std::pair<const Key, T>>>
17290  struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
17291 {
17292  using key_type = Key;
17293  using mapped_type = T;
17294  using Container = std::vector<std::pair<const Key, T>, Allocator>;
17295  using typename Container::iterator;
17296  using typename Container::const_iterator;
17297  using typename Container::size_type;
17298  using typename Container::value_type;
17299 
17300  // Explicit constructors instead of `using Container::Container`
17301  // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
17302  ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
17303  template <class It>
17304  ordered_map(It first, It last, const Allocator& alloc = Allocator())
17305  : Container{first, last, alloc} {}
17306  ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
17307  : Container{init, alloc} {}
17308 
17309  std::pair<iterator, bool> emplace(const key_type& key, T&& t)
17310  {
17311  for (auto it = this->begin(); it != this->end(); ++it)
17312  {
17313  if (it->first == key)
17314  {
17315  return {it, false};
17316  }
17317  }
17318  Container::emplace_back(key, t);
17319  return {--this->end(), true};
17320  }
17321 
17322  T& operator[](const Key& key)
17323  {
17324  return emplace(key, T{}).first->second;
17325  }
17326 
17327  const T& operator[](const Key& key) const
17328  {
17329  return at(key);
17330  }
17331 
17332  T& at(const Key& key)
17333  {
17334  for (auto it = this->begin(); it != this->end(); ++it)
17335  {
17336  if (it->first == key)
17337  {
17338  return it->second;
17339  }
17340  }
17341 
17342  JSON_THROW(std::out_of_range("key not found"));
17343  }
17344 
17345  const T& at(const Key& key) const
17346  {
17347  for (auto it = this->begin(); it != this->end(); ++it)
17348  {
17349  if (it->first == key)
17350  {
17351  return it->second;
17352  }
17353  }
17354 
17355  JSON_THROW(std::out_of_range("key not found"));
17356  }
17357 
17358  size_type erase(const Key& key)
17359  {
17360  for (auto it = this->begin(); it != this->end(); ++it)
17361  {
17362  if (it->first == key)
17363  {
17364  // Since we cannot move const Keys, re-construct them in place
17365  for (auto next = it; ++next != this->end(); ++it)
17366  {
17367  it->~value_type(); // Destroy but keep allocation
17368  new (&*it) value_type{std::move(*next)};
17369  }
17370  Container::pop_back();
17371  return 1;
17372  }
17373  }
17374  return 0;
17375  }
17376 
17377  iterator erase(iterator pos)
17378  {
17379  auto it = pos;
17380 
17381  // Since we cannot move const Keys, re-construct them in place
17382  for (auto next = it; ++next != this->end(); ++it)
17383  {
17384  it->~value_type(); // Destroy but keep allocation
17385  new (&*it) value_type{std::move(*next)};
17386  }
17387  Container::pop_back();
17388  return pos;
17389  }
17390 
17391  size_type count(const Key& key) const
17392  {
17393  for (auto it = this->begin(); it != this->end(); ++it)
17394  {
17395  if (it->first == key)
17396  {
17397  return 1;
17398  }
17399  }
17400  return 0;
17401  }
17402 
17403  iterator find(const Key& key)
17404  {
17405  for (auto it = this->begin(); it != this->end(); ++it)
17406  {
17407  if (it->first == key)
17408  {
17409  return it;
17410  }
17411  }
17412  return Container::end();
17413  }
17414 
17415  const_iterator find(const Key& key) const
17416  {
17417  for (auto it = this->begin(); it != this->end(); ++it)
17418  {
17419  if (it->first == key)
17420  {
17421  return it;
17422  }
17423  }
17424  return Container::end();
17425  }
17426 
17427  std::pair<iterator, bool> insert( value_type&& value )
17428  {
17429  return emplace(value.first, std::move(value.second));
17430  }
17431 
17432  std::pair<iterator, bool> insert( const value_type& value )
17433  {
17434  for (auto it = this->begin(); it != this->end(); ++it)
17435  {
17436  if (it->first == value.first)
17437  {
17438  return {it, false};
17439  }
17440  }
17441  Container::push_back(value);
17442  return {--this->end(), true};
17443  }
17444 
17445  template<typename InputIt>
17446  using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
17447  std::input_iterator_tag>::value>::type;
17448 
17449  template<typename InputIt, typename = require_input_iter<InputIt>>
17450  void insert(InputIt first, InputIt last)
17451  {
17452  for (auto it = first; it != last; ++it)
17453  {
17454  insert(*it);
17455  }
17456  }
17457 };
17458 
17459 } // namespace nlohmann
17460 
17461 
17462 #if defined(JSON_HAS_CPP_17)
17463  #include <string_view>
17464 #endif
17465 
17471 namespace nlohmann
17472 {
17473 
17558 NLOHMANN_BASIC_JSON_TPL_DECLARATION
17559 class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
17560 {
17561  private:
17562  template<detail::value_t> friend struct detail::external_constructor;
17563  friend ::nlohmann::json_pointer<basic_json>;
17564 
17565  template<typename BasicJsonType, typename InputType>
17566  friend class ::nlohmann::detail::parser;
17567  friend ::nlohmann::detail::serializer<basic_json>;
17568  template<typename BasicJsonType>
17569  friend class ::nlohmann::detail::iter_impl;
17570  template<typename BasicJsonType, typename CharType>
17571  friend class ::nlohmann::detail::binary_writer;
17572  template<typename BasicJsonType, typename InputType, typename SAX>
17573  friend class ::nlohmann::detail::binary_reader;
17574  template<typename BasicJsonType>
17575  friend class ::nlohmann::detail::json_sax_dom_parser;
17576  template<typename BasicJsonType>
17577  friend class ::nlohmann::detail::json_sax_dom_callback_parser;
17578  friend class ::nlohmann::detail::exception;
17579 
17581  using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
17582 
17583  JSON_PRIVATE_UNLESS_TESTED:
17584  // convenience aliases for types residing in namespace detail;
17585  using lexer = ::nlohmann::detail::lexer_base<basic_json>;
17586 
17587  template<typename InputAdapterType>
17588  static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
17589  InputAdapterType adapter,
17590  detail::parser_callback_t<basic_json>cb = nullptr,
17591  const bool allow_exceptions = true,
17592  const bool ignore_comments = false
17593  )
17594  {
17595  return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
17596  std::move(cb), allow_exceptions, ignore_comments);
17597  }
17598 
17599  private:
17600  using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
17601  template<typename BasicJsonType>
17602  using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
17603  template<typename BasicJsonType>
17604  using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
17605  template<typename Iterator>
17606  using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
17607  template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
17608 
17609  template<typename CharType>
17610  using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
17611 
17612  template<typename InputType>
17613  using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
17614  template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
17615 
17616  JSON_PRIVATE_UNLESS_TESTED:
17617  using serializer = ::nlohmann::detail::serializer<basic_json>;
17618 
17619  public:
17620  using value_t = detail::value_t;
17623  template<typename T, typename SFINAE>
17624  using json_serializer = JSONSerializer<T, SFINAE>;
17626  using error_handler_t = detail::error_handler_t;
17628  using cbor_tag_handler_t = detail::cbor_tag_handler_t;
17630  using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
17631 
17632  using input_format_t = detail::input_format_t;
17635 
17637  // exceptions //
17639 
17643 
17645  using exception = detail::exception;
17647  using parse_error = detail::parse_error;
17649  using invalid_iterator = detail::invalid_iterator;
17651  using type_error = detail::type_error;
17653  using out_of_range = detail::out_of_range;
17655  using other_error = detail::other_error;
17656 
17658 
17659 
17661  // container types //
17663 
17668 
17671 
17675  using const_reference = const value_type&;
17676 
17678  using difference_type = std::ptrdiff_t;
17680  using size_type = std::size_t;
17681 
17683  using allocator_type = AllocatorType<basic_json>;
17684 
17686  using pointer = typename std::allocator_traits<allocator_type>::pointer;
17688  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
17689 
17691  using iterator = iter_impl<basic_json>;
17693  using const_iterator = iter_impl<const basic_json>;
17695  using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
17697  using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
17698 
17700 
17701 
17706  {
17707  return allocator_type();
17708  }
17709 
17736 
17737  static basic_json meta()
17738  {
17739  basic_json result;
17740 
17741  result["copyright"] = "(C) 2013-2021 Niels Lohmann";
17742  result["name"] = "JSON for Modern C++";
17743  result["url"] = "https://github.com/nlohmann/json";
17744  result["version"]["string"] =
17745  std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
17746  std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
17747  std::to_string(NLOHMANN_JSON_VERSION_PATCH);
17748  result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
17749  result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
17750  result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
17751 
17752 #ifdef _WIN32
17753  result["platform"] = "win32";
17754 #elif defined __linux__
17755  result["platform"] = "linux";
17756 #elif defined __APPLE__
17757  result["platform"] = "apple";
17758 #elif defined __unix__
17759  result["platform"] = "unix";
17760 #else
17761  result["platform"] = "unknown";
17762 #endif
17763 
17764 #if defined(__ICC) || defined(__INTEL_COMPILER)
17765  result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
17766 #elif defined(__clang__)
17767  result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
17768 #elif defined(__GNUC__) || defined(__GNUG__)
17769  result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
17770 #elif defined(__HP_cc) || defined(__HP_aCC)
17771  result["compiler"] = "hp"
17772 #elif defined(__IBMCPP__)
17773  result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
17774 #elif defined(_MSC_VER)
17775  result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
17776 #elif defined(__PGI)
17777  result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
17778 #elif defined(__SUNPRO_CC)
17779  result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
17780 #else
17781  result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
17782 #endif
17783 
17784 #ifdef __cplusplus
17785  result["compiler"]["c++"] = std::to_string(__cplusplus);
17786 #else
17787  result["compiler"]["c++"] = "unknown";
17788 #endif
17789  return result;
17790  }
17791 
17792 
17794  // JSON value data types //
17796 
17801 
17802 #if defined(JSON_HAS_CPP_14)
17803  // Use transparent comparator if possible, combined with perfect forwarding
17804  // on find() and count() calls prevents unnecessary string construction.
17805  using object_comparator_t = std::less<>;
17806 #else
17807  using object_comparator_t = std::less<StringType>;
17808 #endif
17809 
17893  using object_t = ObjectType<StringType,
17894  basic_json,
17896  AllocatorType<std::pair<const StringType,
17897  basic_json>>>;
17898 
17943  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
17944 
17996  using string_t = StringType;
17997 
18022  using boolean_t = BooleanType;
18023 
18094  using number_integer_t = NumberIntegerType;
18095 
18165  using number_unsigned_t = NumberUnsignedType;
18166 
18233  using number_float_t = NumberFloatType;
18234 
18306 
18307  private:
18308 
18310  template<typename T, typename... Args>
18311 
18312  static T* create(Args&& ... args)
18313  {
18314  AllocatorType<T> alloc;
18315  using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
18316 
18317  auto deleter = [&](T * obj)
18318  {
18319  AllocatorTraits::deallocate(alloc, obj, 1);
18320  };
18321  std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
18322  AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
18323  JSON_ASSERT(obj != nullptr);
18324  return obj.release();
18325  }
18326 
18328  // JSON value storage //
18330 
18331  JSON_PRIVATE_UNLESS_TESTED:
18357  union json_value
18358  {
18360  object_t* object;
18362  array_t* array;
18364  string_t* string;
18366  binary_t* binary;
18368  boolean_t boolean;
18370  number_integer_t number_integer;
18372  number_unsigned_t number_unsigned;
18374  number_float_t number_float;
18375 
18377  json_value() = default;
18379  json_value(boolean_t v) noexcept : boolean(v) {}
18381  json_value(number_integer_t v) noexcept : number_integer(v) {}
18383  json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
18385  json_value(number_float_t v) noexcept : number_float(v) {}
18387  json_value(value_t t)
18388  {
18389  switch (t)
18390  {
18391  case value_t::object:
18392  {
18393  object = create<object_t>();
18394  break;
18395  }
18396 
18397  case value_t::array:
18398  {
18399  array = create<array_t>();
18400  break;
18401  }
18402 
18403  case value_t::string:
18404  {
18405  string = create<string_t>("");
18406  break;
18407  }
18408 
18409  case value_t::binary:
18410  {
18411  binary = create<binary_t>();
18412  break;
18413  }
18414 
18415  case value_t::boolean:
18416  {
18417  boolean = boolean_t(false);
18418  break;
18419  }
18420 
18421  case value_t::number_integer:
18422  {
18423  number_integer = number_integer_t(0);
18424  break;
18425  }
18426 
18427  case value_t::number_unsigned:
18428  {
18429  number_unsigned = number_unsigned_t(0);
18430  break;
18431  }
18432 
18433  case value_t::number_float:
18434  {
18435  number_float = number_float_t(0.0);
18436  break;
18437  }
18438 
18439  case value_t::null:
18440  {
18441  object = nullptr; // silence warning, see #821
18442  break;
18443  }
18444 
18445  case value_t::discarded:
18446  default:
18447  {
18448  object = nullptr; // silence warning, see #821
18449  if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
18450  {
18451  JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.0", basic_json())); // LCOV_EXCL_LINE
18452  }
18453  break;
18454  }
18455  }
18456  }
18457 
18459  json_value(const string_t& value)
18460  {
18461  string = create<string_t>(value);
18462  }
18463 
18465  json_value(string_t&& value)
18466  {
18467  string = create<string_t>(std::move(value));
18468  }
18469 
18471  json_value(const object_t& value)
18472  {
18473  object = create<object_t>(value);
18474  }
18475 
18477  json_value(object_t&& value)
18478  {
18479  object = create<object_t>(std::move(value));
18480  }
18481 
18483  json_value(const array_t& value)
18484  {
18485  array = create<array_t>(value);
18486  }
18487 
18489  json_value(array_t&& value)
18490  {
18491  array = create<array_t>(std::move(value));
18492  }
18493 
18495  json_value(const typename binary_t::container_type& value)
18496  {
18497  binary = create<binary_t>(value);
18498  }
18499 
18501  json_value(typename binary_t::container_type&& value)
18502  {
18503  binary = create<binary_t>(std::move(value));
18504  }
18505 
18507  json_value(const binary_t& value)
18508  {
18509  binary = create<binary_t>(value);
18510  }
18511 
18513  json_value(binary_t&& value)
18514  {
18515  binary = create<binary_t>(std::move(value));
18516  }
18517 
18518  void destroy(value_t t)
18519  {
18520  if (t == value_t::array || t == value_t::object)
18521  {
18522  // flatten the current json_value to a heap-allocated stack
18523  std::vector<basic_json> stack;
18524 
18525  // move the top-level items to stack
18526  if (t == value_t::array)
18527  {
18528  stack.reserve(array->size());
18529  std::move(array->begin(), array->end(), std::back_inserter(stack));
18530  }
18531  else
18532  {
18533  stack.reserve(object->size());
18534  for (auto&& it : *object)
18535  {
18536  stack.push_back(std::move(it.second));
18537  }
18538  }
18539 
18540  while (!stack.empty())
18541  {
18542  // move the last item to local variable to be processed
18543  basic_json current_item(std::move(stack.back()));
18544  stack.pop_back();
18545 
18546  // if current_item is array/object, move
18547  // its children to the stack to be processed later
18548  if (current_item.is_array())
18549  {
18550  std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
18551 
18552  current_item.m_value.array->clear();
18553  }
18554  else if (current_item.is_object())
18555  {
18556  for (auto&& it : *current_item.m_value.object)
18557  {
18558  stack.push_back(std::move(it.second));
18559  }
18560 
18561  current_item.m_value.object->clear();
18562  }
18563 
18564  // it's now safe that current_item get destructed
18565  // since it doesn't have any children
18566  }
18567  }
18568 
18569  switch (t)
18570  {
18571  case value_t::object:
18572  {
18573  AllocatorType<object_t> alloc;
18574  std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
18575  std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
18576  break;
18577  }
18578 
18579  case value_t::array:
18580  {
18581  AllocatorType<array_t> alloc;
18582  std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
18583  std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
18584  break;
18585  }
18586 
18587  case value_t::string:
18588  {
18589  AllocatorType<string_t> alloc;
18590  std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
18591  std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
18592  break;
18593  }
18594 
18595  case value_t::binary:
18596  {
18597  AllocatorType<binary_t> alloc;
18598  std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
18599  std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
18600  break;
18601  }
18602 
18603  case value_t::null:
18604  case value_t::boolean:
18605  case value_t::number_integer:
18606  case value_t::number_unsigned:
18607  case value_t::number_float:
18608  case value_t::discarded:
18609  default:
18610  {
18611  break;
18612  }
18613  }
18614  }
18615  };
18616 
18617  private:
18636  void assert_invariant(bool check_parents = true) const noexcept
18637  {
18638  JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
18639  JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
18640  JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
18641  JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
18642 
18643 #if JSON_DIAGNOSTICS
18644  JSON_TRY
18645  {
18646  // cppcheck-suppress assertWithSideEffect
18647  JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
18648  {
18649  return j.m_parent == this;
18650  }));
18651  }
18652  JSON_CATCH(...) {} // LCOV_EXCL_LINE
18653 #endif
18654  static_cast<void>(check_parents);
18655  }
18656 
18657  void set_parents()
18658  {
18659 #if JSON_DIAGNOSTICS
18660  switch (m_type)
18661  {
18662  case value_t::array:
18663  {
18664  for (auto& element : *m_value.array)
18665  {
18666  element.m_parent = this;
18667  }
18668  break;
18669  }
18670 
18671  case value_t::object:
18672  {
18673  for (auto& element : *m_value.object)
18674  {
18675  element.second.m_parent = this;
18676  }
18677  break;
18678  }
18679 
18680  case value_t::null:
18681  case value_t::string:
18682  case value_t::boolean:
18683  case value_t::number_integer:
18684  case value_t::number_unsigned:
18685  case value_t::number_float:
18686  case value_t::binary:
18687  case value_t::discarded:
18688  default:
18689  break;
18690  }
18691 #endif
18692  }
18693 
18694  iterator set_parents(iterator it, typename iterator::difference_type count)
18695  {
18696 #if JSON_DIAGNOSTICS
18697  for (typename iterator::difference_type i = 0; i < count; ++i)
18698  {
18699  (it + i)->m_parent = this;
18700  }
18701 #else
18702  static_cast<void>(count);
18703 #endif
18704  return it;
18705  }
18706 
18707  reference set_parent(reference j, std::size_t old_capacity = std::size_t(-1))
18708  {
18709 #if JSON_DIAGNOSTICS
18710  if (old_capacity != std::size_t(-1))
18711  {
18712  // see https://github.com/nlohmann/json/issues/2838
18713  JSON_ASSERT(type() == value_t::array);
18714  if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
18715  {
18716  // capacity has changed: update all parents
18717  set_parents();
18718  return j;
18719  }
18720  }
18721 
18722  j.m_parent = this;
18723 #else
18724  static_cast<void>(j);
18725  static_cast<void>(old_capacity);
18726 #endif
18727  return j;
18728  }
18729 
18730  public:
18732  // JSON parser callback //
18734 
18750  using parse_event_t = detail::parse_event_t;
18751 
18801  using parser_callback_t = detail::parser_callback_t<basic_json>;
18802 
18804  // constructors //
18806 
18811 
18842  basic_json(const value_t v)
18843  : m_type(v), m_value(v)
18844  {
18845  assert_invariant();
18846  }
18847 
18866  basic_json(std::nullptr_t = nullptr) noexcept
18867  : basic_json(value_t::null)
18868  {
18869  assert_invariant();
18870  }
18871 
18934  template < typename CompatibleType,
18935  typename U = detail::uncvref_t<CompatibleType>,
18936  detail::enable_if_t <
18937  !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
18938  basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
18939  JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
18940  std::forward<CompatibleType>(val))))
18941  {
18942  JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
18943  set_parents();
18944  assert_invariant();
18945  }
18946 
18973  template < typename BasicJsonType,
18974  detail::enable_if_t <
18975  detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
18976  basic_json(const BasicJsonType& val)
18977  {
18978  using other_boolean_t = typename BasicJsonType::boolean_t;
18979  using other_number_float_t = typename BasicJsonType::number_float_t;
18980  using other_number_integer_t = typename BasicJsonType::number_integer_t;
18981  using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
18982  using other_string_t = typename BasicJsonType::string_t;
18983  using other_object_t = typename BasicJsonType::object_t;
18984  using other_array_t = typename BasicJsonType::array_t;
18985  using other_binary_t = typename BasicJsonType::binary_t;
18986 
18987  switch (val.type())
18988  {
18989  case value_t::boolean:
18990  JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
18991  break;
18992  case value_t::number_float:
18993  JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
18994  break;
18995  case value_t::number_integer:
18996  JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
18997  break;
18998  case value_t::number_unsigned:
18999  JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
19000  break;
19001  case value_t::string:
19002  JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
19003  break;
19004  case value_t::object:
19005  JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
19006  break;
19007  case value_t::array:
19008  JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
19009  break;
19010  case value_t::binary:
19011  JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
19012  break;
19013  case value_t::null:
19014  *this = nullptr;
19015  break;
19016  case value_t::discarded:
19017  m_type = value_t::discarded;
19018  break;
19019  default: // LCOV_EXCL_LINE
19020  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19021  }
19022  set_parents();
19023  assert_invariant();
19024  }
19025 
19101  bool type_deduction = true,
19102  value_t manual_type = value_t::array)
19103  {
19104  // check if each element is an array with two elements whose first
19105  // element is a string
19106  bool is_an_object = std::all_of(init.begin(), init.end(),
19107  [](const detail::json_ref<basic_json>& element_ref)
19108  {
19109  return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
19110  });
19111 
19112  // adjust type if type deduction is not wanted
19113  if (!type_deduction)
19114  {
19115  // if array is wanted, do not create an object though possible
19116  if (manual_type == value_t::array)
19117  {
19118  is_an_object = false;
19119  }
19120 
19121  // if object is wanted but impossible, throw an exception
19122  if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
19123  {
19124  JSON_THROW(type_error::create(301, "cannot create object from initializer list", basic_json()));
19125  }
19126  }
19127 
19128  if (is_an_object)
19129  {
19130  // the initializer list is a list of pairs -> create object
19131  m_type = value_t::object;
19132  m_value = value_t::object;
19133 
19134  for (auto& element_ref : init)
19135  {
19136  auto element = element_ref.moved_or_copied();
19137  m_value.object->emplace(
19138  std::move(*((*element.m_value.array)[0].m_value.string)),
19139  std::move((*element.m_value.array)[1]));
19140  }
19141  }
19142  else
19143  {
19144  // the initializer list describes an array -> create array
19145  m_type = value_t::array;
19146  m_value.array = create<array_t>(init.begin(), init.end());
19147  }
19148 
19149  set_parents();
19150  assert_invariant();
19151  }
19152 
19180 
19181  static basic_json binary(const typename binary_t::container_type& init)
19182  {
19183  auto res = basic_json();
19184  res.m_type = value_t::binary;
19185  res.m_value = init;
19186  return res;
19187  }
19188 
19217 
19218  static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
19219  {
19220  auto res = basic_json();
19221  res.m_type = value_t::binary;
19222  res.m_value = binary_t(init, subtype);
19223  return res;
19224  }
19225 
19227 
19229  {
19230  auto res = basic_json();
19231  res.m_type = value_t::binary;
19232  res.m_value = std::move(init);
19233  return res;
19234  }
19235 
19237 
19238  static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
19239  {
19240  auto res = basic_json();
19241  res.m_type = value_t::binary;
19242  res.m_value = binary_t(std::move(init), subtype);
19243  return res;
19244  }
19245 
19283 
19285  {
19286  return basic_json(init, false, value_t::array);
19287  }
19288 
19327 
19329  {
19330  return basic_json(init, false, value_t::object);
19331  }
19332 
19356  : m_type(value_t::array)
19357  {
19358  m_value.array = create<array_t>(cnt, val);
19359  set_parents();
19360  assert_invariant();
19361  }
19362 
19418  template < class InputIT, typename std::enable_if <
19419  std::is_same<InputIT, typename basic_json_t::iterator>::value ||
19420  std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
19421  basic_json(InputIT first, InputIT last)
19422  {
19423  JSON_ASSERT(first.m_object != nullptr);
19424  JSON_ASSERT(last.m_object != nullptr);
19425 
19426  // make sure iterator fits the current value
19427  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19428  {
19429  JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", basic_json()));
19430  }
19431 
19432  // copy type from first iterator
19433  m_type = first.m_object->m_type;
19434 
19435  // check if iterator range is complete for primitive values
19436  switch (m_type)
19437  {
19438  case value_t::boolean:
19439  case value_t::number_float:
19440  case value_t::number_integer:
19441  case value_t::number_unsigned:
19442  case value_t::string:
19443  {
19444  if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
19445  || !last.m_it.primitive_iterator.is_end()))
19446  {
19447  JSON_THROW(invalid_iterator::create(204, "iterators out of range", *first.m_object));
19448  }
19449  break;
19450  }
19451 
19452  case value_t::null:
19453  case value_t::object:
19454  case value_t::array:
19455  case value_t::binary:
19456  case value_t::discarded:
19457  default:
19458  break;
19459  }
19460 
19461  switch (m_type)
19462  {
19463  case value_t::number_integer:
19464  {
19465  m_value.number_integer = first.m_object->m_value.number_integer;
19466  break;
19467  }
19468 
19469  case value_t::number_unsigned:
19470  {
19471  m_value.number_unsigned = first.m_object->m_value.number_unsigned;
19472  break;
19473  }
19474 
19475  case value_t::number_float:
19476  {
19477  m_value.number_float = first.m_object->m_value.number_float;
19478  break;
19479  }
19480 
19481  case value_t::boolean:
19482  {
19483  m_value.boolean = first.m_object->m_value.boolean;
19484  break;
19485  }
19486 
19487  case value_t::string:
19488  {
19489  m_value = *first.m_object->m_value.string;
19490  break;
19491  }
19492 
19493  case value_t::object:
19494  {
19495  m_value.object = create<object_t>(first.m_it.object_iterator,
19496  last.m_it.object_iterator);
19497  break;
19498  }
19499 
19500  case value_t::array:
19501  {
19502  m_value.array = create<array_t>(first.m_it.array_iterator,
19503  last.m_it.array_iterator);
19504  break;
19505  }
19506 
19507  case value_t::binary:
19508  {
19509  m_value = *first.m_object->m_value.binary;
19510  break;
19511  }
19512 
19513  case value_t::null:
19514  case value_t::discarded:
19515  default:
19516  JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object));
19517  }
19518 
19519  set_parents();
19520  assert_invariant();
19521  }
19522 
19523 
19525  // other constructors and destructor //
19527 
19528  template<typename JsonRef,
19529  detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
19530  std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
19531  basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
19532 
19558  basic_json(const basic_json& other)
19559  : m_type(other.m_type)
19560  {
19561  // check of passed value is valid
19562  other.assert_invariant();
19563 
19564  switch (m_type)
19565  {
19566  case value_t::object:
19567  {
19568  m_value = *other.m_value.object;
19569  break;
19570  }
19571 
19572  case value_t::array:
19573  {
19574  m_value = *other.m_value.array;
19575  break;
19576  }
19577 
19578  case value_t::string:
19579  {
19580  m_value = *other.m_value.string;
19581  break;
19582  }
19583 
19584  case value_t::boolean:
19585  {
19586  m_value = other.m_value.boolean;
19587  break;
19588  }
19589 
19590  case value_t::number_integer:
19591  {
19592  m_value = other.m_value.number_integer;
19593  break;
19594  }
19595 
19596  case value_t::number_unsigned:
19597  {
19598  m_value = other.m_value.number_unsigned;
19599  break;
19600  }
19601 
19602  case value_t::number_float:
19603  {
19604  m_value = other.m_value.number_float;
19605  break;
19606  }
19607 
19608  case value_t::binary:
19609  {
19610  m_value = *other.m_value.binary;
19611  break;
19612  }
19613 
19614  case value_t::null:
19615  case value_t::discarded:
19616  default:
19617  break;
19618  }
19619 
19620  set_parents();
19621  assert_invariant();
19622  }
19623 
19650  basic_json(basic_json&& other) noexcept
19651  : m_type(std::move(other.m_type)),
19652  m_value(std::move(other.m_value))
19653  {
19654  // check that passed value is valid
19655  other.assert_invariant(false);
19656 
19657  // invalidate payload
19658  other.m_type = value_t::null;
19659  other.m_value = {};
19660 
19661  set_parents();
19662  assert_invariant();
19663  }
19664 
19688  basic_json& operator=(basic_json other) noexcept (
19689  std::is_nothrow_move_constructible<value_t>::value&&
19690  std::is_nothrow_move_assignable<value_t>::value&&
19691  std::is_nothrow_move_constructible<json_value>::value&&
19692  std::is_nothrow_move_assignable<json_value>::value
19693  )
19694  {
19695  // check that passed value is valid
19696  other.assert_invariant();
19697 
19698  using std::swap;
19699  swap(m_type, other.m_type);
19700  swap(m_value, other.m_value);
19701 
19702  set_parents();
19703  assert_invariant();
19704  return *this;
19705  }
19706 
19722  ~basic_json() noexcept
19723  {
19724  assert_invariant(false);
19725  m_value.destroy(m_type);
19726  }
19727 
19729 
19730  public:
19732  // object inspection //
19734 
19738 
19786  string_t dump(const int indent = -1,
19787  const char indent_char = ' ',
19788  const bool ensure_ascii = false,
19789  const error_handler_t error_handler = error_handler_t::strict) const
19790  {
19791  string_t result;
19792  serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
19793 
19794  if (indent >= 0)
19795  {
19796  s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
19797  }
19798  else
19799  {
19800  s.dump(*this, false, ensure_ascii, 0);
19801  }
19802 
19803  return result;
19804  }
19805 
19839  constexpr value_t type() const noexcept
19840  {
19841  return m_type;
19842  }
19843 
19870  constexpr bool is_primitive() const noexcept
19871  {
19872  return is_null() || is_string() || is_boolean() || is_number() || is_binary();
19873  }
19874 
19897  constexpr bool is_structured() const noexcept
19898  {
19899  return is_array() || is_object();
19900  }
19901 
19919  constexpr bool is_null() const noexcept
19920  {
19921  return m_type == value_t::null;
19922  }
19923 
19941  constexpr bool is_boolean() const noexcept
19942  {
19943  return m_type == value_t::boolean;
19944  }
19945 
19971  constexpr bool is_number() const noexcept
19972  {
19973  return is_number_integer() || is_number_float();
19974  }
19975 
20000  constexpr bool is_number_integer() const noexcept
20001  {
20002  return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
20003  }
20004 
20028  constexpr bool is_number_unsigned() const noexcept
20029  {
20030  return m_type == value_t::number_unsigned;
20031  }
20032 
20056  constexpr bool is_number_float() const noexcept
20057  {
20058  return m_type == value_t::number_float;
20059  }
20060 
20078  constexpr bool is_object() const noexcept
20079  {
20080  return m_type == value_t::object;
20081  }
20082 
20100  constexpr bool is_array() const noexcept
20101  {
20102  return m_type == value_t::array;
20103  }
20104 
20122  constexpr bool is_string() const noexcept
20123  {
20124  return m_type == value_t::string;
20125  }
20126 
20144  constexpr bool is_binary() const noexcept
20145  {
20146  return m_type == value_t::binary;
20147  }
20148 
20171  constexpr bool is_discarded() const noexcept
20172  {
20173  return m_type == value_t::discarded;
20174  }
20175 
20197  constexpr operator value_t() const noexcept
20198  {
20199  return m_type;
20200  }
20201 
20203 
20204  private:
20206  // value access //
20208 
20210  boolean_t get_impl(boolean_t* /*unused*/) const
20211  {
20212  if (JSON_HEDLEY_LIKELY(is_boolean()))
20213  {
20214  return m_value.boolean;
20215  }
20216 
20217  JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()), *this));
20218  }
20219 
20221  object_t* get_impl_ptr(object_t* /*unused*/) noexcept
20222  {
20223  return is_object() ? m_value.object : nullptr;
20224  }
20225 
20227  constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
20228  {
20229  return is_object() ? m_value.object : nullptr;
20230  }
20231 
20233  array_t* get_impl_ptr(array_t* /*unused*/) noexcept
20234  {
20235  return is_array() ? m_value.array : nullptr;
20236  }
20237 
20239  constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
20240  {
20241  return is_array() ? m_value.array : nullptr;
20242  }
20243 
20245  string_t* get_impl_ptr(string_t* /*unused*/) noexcept
20246  {
20247  return is_string() ? m_value.string : nullptr;
20248  }
20249 
20251  constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
20252  {
20253  return is_string() ? m_value.string : nullptr;
20254  }
20255 
20257  boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
20258  {
20259  return is_boolean() ? &m_value.boolean : nullptr;
20260  }
20261 
20263  constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
20264  {
20265  return is_boolean() ? &m_value.boolean : nullptr;
20266  }
20267 
20269  number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
20270  {
20271  return is_number_integer() ? &m_value.number_integer : nullptr;
20272  }
20273 
20275  constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
20276  {
20277  return is_number_integer() ? &m_value.number_integer : nullptr;
20278  }
20279 
20281  number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
20282  {
20283  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20284  }
20285 
20287  constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
20288  {
20289  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20290  }
20291 
20293  number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
20294  {
20295  return is_number_float() ? &m_value.number_float : nullptr;
20296  }
20297 
20299  constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
20300  {
20301  return is_number_float() ? &m_value.number_float : nullptr;
20302  }
20303 
20305  binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
20306  {
20307  return is_binary() ? m_value.binary : nullptr;
20308  }
20309 
20311  constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
20312  {
20313  return is_binary() ? m_value.binary : nullptr;
20314  }
20315 
20327  template<typename ReferenceType, typename ThisType>
20328  static ReferenceType get_ref_impl(ThisType& obj)
20329  {
20330  // delegate the call to get_ptr<>()
20331  auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
20332 
20333  if (JSON_HEDLEY_LIKELY(ptr != nullptr))
20334  {
20335  return *ptr;
20336  }
20337 
20338  JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()), obj));
20339  }
20340 
20341  public:
20345 
20372  template<typename PointerType, typename std::enable_if<
20373  std::is_pointer<PointerType>::value, int>::type = 0>
20374  auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20375  {
20376  // delegate the call to get_impl_ptr<>()
20377  return get_impl_ptr(static_cast<PointerType>(nullptr));
20378  }
20379 
20384  template < typename PointerType, typename std::enable_if <
20385  std::is_pointer<PointerType>::value&&
20386  std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
20387  constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20388  {
20389  // delegate the call to get_impl_ptr<>() const
20390  return get_impl_ptr(static_cast<PointerType>(nullptr));
20391  }
20392 
20393  private:
20432  template < typename ValueType,
20433  detail::enable_if_t <
20434  detail::is_default_constructible<ValueType>::value&&
20435  detail::has_from_json<basic_json_t, ValueType>::value,
20436  int > = 0 >
20437  ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20438  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20439  {
20440  ValueType ret{};
20441  JSONSerializer<ValueType>::from_json(*this, ret);
20442  return ret;
20443  }
20444 
20475  template < typename ValueType,
20476  detail::enable_if_t <
20477  detail::has_non_default_from_json<basic_json_t, ValueType>::value,
20478  int > = 0 >
20479  ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20480  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20481  {
20482  return JSONSerializer<ValueType>::from_json(*this);
20483  }
20484 
20500  template < typename BasicJsonType,
20501  detail::enable_if_t <
20502  detail::is_basic_json<BasicJsonType>::value,
20503  int > = 0 >
20504  BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20505  {
20506  return *this;
20507  }
20508 
20523  template<typename BasicJsonType,
20524  detail::enable_if_t<
20525  std::is_same<BasicJsonType, basic_json_t>::value,
20526  int> = 0>
20527  basic_json get_impl(detail::priority_tag<3> /*unused*/) const
20528  {
20529  return *this;
20530  }
20531 
20536  template<typename PointerType,
20537  detail::enable_if_t<
20538  std::is_pointer<PointerType>::value,
20539  int> = 0>
20540  constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
20541  -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
20542  {
20543  // delegate the call to get_ptr
20544  return get_ptr<PointerType>();
20545  }
20546 
20547  public:
20571  template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
20572 #if defined(JSON_HAS_CPP_14)
20573  constexpr
20574 #endif
20575  auto get() const noexcept(
20576  noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
20577  -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
20578  {
20579  // we cannot static_assert on ValueTypeCV being non-const, because
20580  // there is support for get<const basic_json_t>(), which is why we
20581  // still need the uncvref
20582  static_assert(!std::is_reference<ValueTypeCV>::value,
20583  "get() cannot be used with reference types, you might want to use get_ref()");
20584  return get_impl<ValueType>(detail::priority_tag<4> {});
20585  }
20586 
20614  template<typename PointerType, typename std::enable_if<
20615  std::is_pointer<PointerType>::value, int>::type = 0>
20616  auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
20617  {
20618  // delegate the call to get_ptr
20619  return get_ptr<PointerType>();
20620  }
20621 
20655  template < typename ValueType,
20656  detail::enable_if_t <
20657  !detail::is_basic_json<ValueType>::value&&
20658  detail::has_from_json<basic_json_t, ValueType>::value,
20659  int > = 0 >
20660  ValueType & get_to(ValueType& v) const noexcept(noexcept(
20661  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
20662  {
20663  JSONSerializer<ValueType>::from_json(*this, v);
20664  return v;
20665  }
20666 
20667  // specialization to allow to call get_to with a basic_json value
20668  // see https://github.com/nlohmann/json/issues/2175
20669  template<typename ValueType,
20670  detail::enable_if_t <
20671  detail::is_basic_json<ValueType>::value,
20672  int> = 0>
20673  ValueType & get_to(ValueType& v) const
20674  {
20675  v = *this;
20676  return v;
20677  }
20678 
20679  template <
20680  typename T, std::size_t N,
20681  typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20682  detail::enable_if_t <
20683  detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
20684  Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20685  noexcept(noexcept(JSONSerializer<Array>::from_json(
20686  std::declval<const basic_json_t&>(), v)))
20687  {
20688  JSONSerializer<Array>::from_json(*this, v);
20689  return v;
20690  }
20691 
20718  template<typename ReferenceType, typename std::enable_if<
20719  std::is_reference<ReferenceType>::value, int>::type = 0>
20720  ReferenceType get_ref()
20721  {
20722  // delegate call to get_ref_impl
20723  return get_ref_impl<ReferenceType>(*this);
20724  }
20725 
20730  template < typename ReferenceType, typename std::enable_if <
20731  std::is_reference<ReferenceType>::value&&
20732  std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
20733  ReferenceType get_ref() const
20734  {
20735  // delegate call to get_ref_impl
20736  return get_ref_impl<ReferenceType>(*this);
20737  }
20738 
20768  template < typename ValueType, typename std::enable_if <
20769  detail::conjunction <
20770  detail::negation<std::is_pointer<ValueType>>,
20771  detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,
20772  detail::negation<std::is_same<ValueType, typename string_t::value_type>>,
20773  detail::negation<detail::is_basic_json<ValueType>>,
20774  detail::negation<std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>>,
20775 
20776 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
20777  detail::negation<std::is_same<ValueType, std::string_view>>,
20778 #endif
20779  detail::is_detected_lazy<detail::get_template_function, const basic_json_t&, ValueType>
20780  >::value, int >::type = 0 >
20781  JSON_EXPLICIT operator ValueType() const
20782  {
20783  // delegate the call to get<>() const
20784  return get<ValueType>();
20785  }
20786 
20797  {
20798  if (!is_binary())
20799  {
20800  JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20801  }
20802 
20803  return *get_ptr<binary_t*>();
20804  }
20805 
20807  const binary_t& get_binary() const
20808  {
20809  if (!is_binary())
20810  {
20811  JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20812  }
20813 
20814  return *get_ptr<const binary_t*>();
20815  }
20816 
20818 
20819 
20821  // element access //
20823 
20827 
20855  {
20856  // at only works for arrays
20857  if (JSON_HEDLEY_LIKELY(is_array()))
20858  {
20859  JSON_TRY
20860  {
20861  return set_parent(m_value.array->at(idx));
20862  }
20863  JSON_CATCH (std::out_of_range&)
20864  {
20865  // create better exception explanation
20866  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
20867  }
20868  }
20869  else
20870  {
20871  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
20872  }
20873  }
20874 
20901  const_reference at(size_type idx) const
20902  {
20903  // at only works for arrays
20904  if (JSON_HEDLEY_LIKELY(is_array()))
20905  {
20906  JSON_TRY
20907  {
20908  return m_value.array->at(idx);
20909  }
20910  JSON_CATCH (std::out_of_range&)
20911  {
20912  // create better exception explanation
20913  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
20914  }
20915  }
20916  else
20917  {
20918  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
20919  }
20920  }
20921 
20952  reference at(const typename object_t::key_type& key)
20953  {
20954  // at only works for objects
20955  if (JSON_HEDLEY_LIKELY(is_object()))
20956  {
20957  JSON_TRY
20958  {
20959  return set_parent(m_value.object->at(key));
20960  }
20961  JSON_CATCH (std::out_of_range&)
20962  {
20963  // create better exception explanation
20964  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
20965  }
20966  }
20967  else
20968  {
20969  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
20970  }
20971  }
20972 
21003  const_reference at(const typename object_t::key_type& key) const
21004  {
21005  // at only works for objects
21006  if (JSON_HEDLEY_LIKELY(is_object()))
21007  {
21008  JSON_TRY
21009  {
21010  return m_value.object->at(key);
21011  }
21012  JSON_CATCH (std::out_of_range&)
21013  {
21014  // create better exception explanation
21015  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21016  }
21017  }
21018  else
21019  {
21020  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21021  }
21022  }
21023 
21050  {
21051  // implicitly convert null value to an empty array
21052  if (is_null())
21053  {
21054  m_type = value_t::array;
21055  m_value.array = create<array_t>();
21056  assert_invariant();
21057  }
21058 
21059  // operator[] only works for arrays
21060  if (JSON_HEDLEY_LIKELY(is_array()))
21061  {
21062  // fill up array with null values if given idx is outside range
21063  if (idx >= m_value.array->size())
21064  {
21065 #if JSON_DIAGNOSTICS
21066  // remember array size before resizing
21067  const auto previous_size = m_value.array->size();
21068 #endif
21069  m_value.array->resize(idx + 1);
21070 
21071 #if JSON_DIAGNOSTICS
21072  // set parent for values added above
21073  set_parents(begin() + static_cast<typename iterator::difference_type>(previous_size), static_cast<typename iterator::difference_type>(idx + 1 - previous_size));
21074 #endif
21075  }
21076 
21077  return m_value.array->operator[](idx);
21078  }
21079 
21080  JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21081  }
21082 
21103  {
21104  // const operator[] only works for arrays
21105  if (JSON_HEDLEY_LIKELY(is_array()))
21106  {
21107  return m_value.array->operator[](idx);
21108  }
21109 
21110  JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21111  }
21140  reference operator[](const typename object_t::key_type& key)
21141  {
21142  // implicitly convert null value to an empty object
21143  if (is_null())
21144  {
21145  m_type = value_t::object;
21146  m_value.object = create<object_t>();
21147  assert_invariant();
21148  }
21149 
21150  // operator[] only works for objects
21151  if (JSON_HEDLEY_LIKELY(is_object()))
21152  {
21153  return set_parent(m_value.object->operator[](key));
21154  }
21155 
21156  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21157  }
21158 
21189  const_reference operator[](const typename object_t::key_type& key) const
21190  {
21191  // const operator[] only works for objects
21192  if (JSON_HEDLEY_LIKELY(is_object()))
21193  {
21194  JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
21195  return m_value.object->find(key)->second;
21196  }
21197 
21198  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21199  }
21200 
21228  template<typename T>
21229  JSON_HEDLEY_NON_NULL(2)
21230  reference operator[](T* key)
21231  {
21232  // implicitly convert null to object
21233  if (is_null())
21234  {
21235  m_type = value_t::object;
21236  m_value = value_t::object;
21237  assert_invariant();
21238  }
21239 
21240  // at only works for objects
21241  if (JSON_HEDLEY_LIKELY(is_object()))
21242  {
21243  return set_parent(m_value.object->operator[](key));
21244  }
21245 
21246  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21247  }
21248 
21279  template<typename T>
21280  JSON_HEDLEY_NON_NULL(2)
21281  const_reference operator[](T* key) const
21282  {
21283  // at only works for objects
21284  if (JSON_HEDLEY_LIKELY(is_object()))
21285  {
21286  JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
21287  return m_value.object->find(key)->second;
21288  }
21289 
21290  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21291  }
21292 
21343  // using std::is_convertible in a std::enable_if will fail when using explicit conversions
21344  template < class ValueType, typename std::enable_if <
21345  detail::is_getable<basic_json_t, ValueType>::value
21346  && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
21347  ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
21348  {
21349  // at only works for objects
21350  if (JSON_HEDLEY_LIKELY(is_object()))
21351  {
21352  // if key is found, return value and given default value otherwise
21353  const auto it = find(key);
21354  if (it != end())
21355  {
21356  return it->template get<ValueType>();
21357  }
21358 
21359  return default_value;
21360  }
21361 
21362  JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21363  }
21364 
21369  string_t value(const typename object_t::key_type& key, const char* default_value) const
21370  {
21371  return value(key, string_t(default_value));
21372  }
21373 
21417  template<class ValueType, typename std::enable_if<
21418  detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
21419  ValueType value(const json_pointer& ptr, const ValueType& default_value) const
21420  {
21421  // at only works for objects
21422  if (JSON_HEDLEY_LIKELY(is_object()))
21423  {
21424  // if pointer resolves a value, return it or use default value
21425  JSON_TRY
21426  {
21427  return ptr.get_checked(this).template get<ValueType>();
21428  }
21429  JSON_INTERNAL_CATCH (out_of_range&)
21430  {
21431  return default_value;
21432  }
21433  }
21434 
21435  JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21436  }
21437 
21442  JSON_HEDLEY_NON_NULL(3)
21443  string_t value(const json_pointer& ptr, const char* default_value) const
21444  {
21445  return value(ptr, string_t(default_value));
21446  }
21447 
21473  reference front()
21474  {
21475  return *begin();
21476  }
21477 
21481  const_reference front() const
21482  {
21483  return *cbegin();
21484  }
21485 
21517  reference back()
21518  {
21519  auto tmp = end();
21520  --tmp;
21521  return *tmp;
21522  }
21523 
21528  {
21529  auto tmp = cend();
21530  --tmp;
21531  return *tmp;
21532  }
21533 
21580  template < class IteratorType, typename std::enable_if <
21581  std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21582  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21583  = 0 >
21584  IteratorType erase(IteratorType pos)
21585  {
21586  // make sure iterator fits the current value
21587  if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21588  {
21589  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
21590  }
21591 
21592  IteratorType result = end();
21593 
21594  switch (m_type)
21595  {
21596  case value_t::boolean:
21597  case value_t::number_float:
21598  case value_t::number_integer:
21599  case value_t::number_unsigned:
21600  case value_t::string:
21601  case value_t::binary:
21602  {
21603  if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
21604  {
21605  JSON_THROW(invalid_iterator::create(205, "iterator out of range", *this));
21606  }
21607 
21608  if (is_string())
21609  {
21610  AllocatorType<string_t> alloc;
21611  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21612  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21613  m_value.string = nullptr;
21614  }
21615  else if (is_binary())
21616  {
21617  AllocatorType<binary_t> alloc;
21618  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21619  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21620  m_value.binary = nullptr;
21621  }
21622 
21623  m_type = value_t::null;
21624  assert_invariant();
21625  break;
21626  }
21627 
21628  case value_t::object:
21629  {
21630  result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
21631  break;
21632  }
21633 
21634  case value_t::array:
21635  {
21636  result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
21637  break;
21638  }
21639 
21640  case value_t::null:
21641  case value_t::discarded:
21642  default:
21643  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21644  }
21645 
21646  return result;
21647  }
21648 
21695  template < class IteratorType, typename std::enable_if <
21696  std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21697  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21698  = 0 >
21699  IteratorType erase(IteratorType first, IteratorType last)
21700  {
21701  // make sure iterator fits the current value
21702  if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
21703  {
21704  JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", *this));
21705  }
21706 
21707  IteratorType result = end();
21708 
21709  switch (m_type)
21710  {
21711  case value_t::boolean:
21712  case value_t::number_float:
21713  case value_t::number_integer:
21714  case value_t::number_unsigned:
21715  case value_t::string:
21716  case value_t::binary:
21717  {
21718  if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
21719  || !last.m_it.primitive_iterator.is_end()))
21720  {
21721  JSON_THROW(invalid_iterator::create(204, "iterators out of range", *this));
21722  }
21723 
21724  if (is_string())
21725  {
21726  AllocatorType<string_t> alloc;
21727  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21728  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21729  m_value.string = nullptr;
21730  }
21731  else if (is_binary())
21732  {
21733  AllocatorType<binary_t> alloc;
21734  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21735  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21736  m_value.binary = nullptr;
21737  }
21738 
21739  m_type = value_t::null;
21740  assert_invariant();
21741  break;
21742  }
21743 
21744  case value_t::object:
21745  {
21746  result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
21747  last.m_it.object_iterator);
21748  break;
21749  }
21750 
21751  case value_t::array:
21752  {
21753  result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
21754  last.m_it.array_iterator);
21755  break;
21756  }
21757 
21758  case value_t::null:
21759  case value_t::discarded:
21760  default:
21761  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21762  }
21763 
21764  return result;
21765  }
21766 
21796  size_type erase(const typename object_t::key_type& key)
21797  {
21798  // this erase only works for objects
21799  if (JSON_HEDLEY_LIKELY(is_object()))
21800  {
21801  return m_value.object->erase(key);
21802  }
21803 
21804  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21805  }
21831  void erase(const size_type idx)
21832  {
21833  // this erase only works for arrays
21834  if (JSON_HEDLEY_LIKELY(is_array()))
21835  {
21836  if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21837  {
21838  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21839  }
21840 
21841  m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
21842  }
21843  else
21844  {
21845  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21846  }
21847  }
21848 
21850 
21851 
21853  // lookup //
21855 
21858 
21883  template<typename KeyT>
21884  iterator find(KeyT&& key)
21885  {
21886  auto result = end();
21887 
21888  if (is_object())
21889  {
21890  result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
21891  }
21892 
21893  return result;
21894  }
21895 
21900  template<typename KeyT>
21901  const_iterator find(KeyT&& key) const
21902  {
21903  auto result = cend();
21904 
21905  if (is_object())
21906  {
21907  result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
21908  }
21909 
21910  return result;
21911  }
21912 
21934  template<typename KeyT>
21935  size_type count(KeyT&& key) const
21936  {
21937  // return 0 for all nonobject types
21938  return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
21939  }
21940 
21966  template < typename KeyT, typename std::enable_if <
21967  !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
21968  bool contains(KeyT && key) const
21969  {
21970  return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
21971  }
21972 
21999  bool contains(const json_pointer& ptr) const
22000  {
22001  return ptr.contains(this);
22002  }
22003 
22005 
22006 
22008  // iterators //
22010 
22013 
22038  iterator begin() noexcept
22039  {
22040  iterator result(this);
22041  result.set_begin();
22042  return result;
22043  }
22044 
22048  const_iterator begin() const noexcept
22049  {
22050  return cbegin();
22051  }
22052 
22078  const_iterator cbegin() const noexcept
22079  {
22080  const_iterator result(this);
22081  result.set_begin();
22082  return result;
22083  }
22084 
22109  iterator end() noexcept
22110  {
22111  iterator result(this);
22112  result.set_end();
22113  return result;
22114  }
22115 
22119  const_iterator end() const noexcept
22120  {
22121  return cend();
22122  }
22123 
22149  const_iterator cend() const noexcept
22150  {
22151  const_iterator result(this);
22152  result.set_end();
22153  return result;
22154  }
22155 
22179  reverse_iterator rbegin() noexcept
22180  {
22181  return reverse_iterator(end());
22182  }
22183 
22187  const_reverse_iterator rbegin() const noexcept
22188  {
22189  return crbegin();
22190  }
22191 
22216  reverse_iterator rend() noexcept
22217  {
22218  return reverse_iterator(begin());
22219  }
22220 
22224  const_reverse_iterator rend() const noexcept
22225  {
22226  return crend();
22227  }
22228 
22253  const_reverse_iterator crbegin() const noexcept
22254  {
22255  return const_reverse_iterator(cend());
22256  }
22257 
22282  const_reverse_iterator crend() const noexcept
22283  {
22284  return const_reverse_iterator(cbegin());
22285  }
22286 
22287  public:
22345  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22346  static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
22347  {
22348  return ref.items();
22349  }
22350 
22354  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22355  static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
22356  {
22357  return ref.items();
22358  }
22359 
22428  iteration_proxy<iterator> items() noexcept
22429  {
22430  return iteration_proxy<iterator>(*this);
22431  }
22432 
22436  iteration_proxy<const_iterator> items() const noexcept
22437  {
22438  return iteration_proxy<const_iterator>(*this);
22439  }
22440 
22442 
22443 
22445  // capacity //
22447 
22450 
22493  bool empty() const noexcept
22494  {
22495  switch (m_type)
22496  {
22497  case value_t::null:
22498  {
22499  // null values are empty
22500  return true;
22501  }
22502 
22503  case value_t::array:
22504  {
22505  // delegate call to array_t::empty()
22506  return m_value.array->empty();
22507  }
22508 
22509  case value_t::object:
22510  {
22511  // delegate call to object_t::empty()
22512  return m_value.object->empty();
22513  }
22514 
22515  case value_t::string:
22516  case value_t::boolean:
22517  case value_t::number_integer:
22518  case value_t::number_unsigned:
22519  case value_t::number_float:
22520  case value_t::binary:
22521  case value_t::discarded:
22522  default:
22523  {
22524  // all other types are nonempty
22525  return false;
22526  }
22527  }
22528  }
22529 
22573  size_type size() const noexcept
22574  {
22575  switch (m_type)
22576  {
22577  case value_t::null:
22578  {
22579  // null values are empty
22580  return 0;
22581  }
22582 
22583  case value_t::array:
22584  {
22585  // delegate call to array_t::size()
22586  return m_value.array->size();
22587  }
22588 
22589  case value_t::object:
22590  {
22591  // delegate call to object_t::size()
22592  return m_value.object->size();
22593  }
22594 
22595  case value_t::string:
22596  case value_t::boolean:
22597  case value_t::number_integer:
22598  case value_t::number_unsigned:
22599  case value_t::number_float:
22600  case value_t::binary:
22601  case value_t::discarded:
22602  default:
22603  {
22604  // all other types have size 1
22605  return 1;
22606  }
22607  }
22608  }
22609 
22651  size_type max_size() const noexcept
22652  {
22653  switch (m_type)
22654  {
22655  case value_t::array:
22656  {
22657  // delegate call to array_t::max_size()
22658  return m_value.array->max_size();
22659  }
22660 
22661  case value_t::object:
22662  {
22663  // delegate call to object_t::max_size()
22664  return m_value.object->max_size();
22665  }
22666 
22667  case value_t::null:
22668  case value_t::string:
22669  case value_t::boolean:
22670  case value_t::number_integer:
22671  case value_t::number_unsigned:
22672  case value_t::number_float:
22673  case value_t::binary:
22674  case value_t::discarded:
22675  default:
22676  {
22677  // all other types have max_size() == size()
22678  return size();
22679  }
22680  }
22681  }
22682 
22684 
22685 
22687  // modifiers //
22689 
22692 
22730  void clear() noexcept
22731  {
22732  switch (m_type)
22733  {
22734  case value_t::number_integer:
22735  {
22736  m_value.number_integer = 0;
22737  break;
22738  }
22739 
22740  case value_t::number_unsigned:
22741  {
22742  m_value.number_unsigned = 0;
22743  break;
22744  }
22745 
22746  case value_t::number_float:
22747  {
22748  m_value.number_float = 0.0;
22749  break;
22750  }
22751 
22752  case value_t::boolean:
22753  {
22754  m_value.boolean = false;
22755  break;
22756  }
22757 
22758  case value_t::string:
22759  {
22760  m_value.string->clear();
22761  break;
22762  }
22763 
22764  case value_t::binary:
22765  {
22766  m_value.binary->clear();
22767  break;
22768  }
22769 
22770  case value_t::array:
22771  {
22772  m_value.array->clear();
22773  break;
22774  }
22775 
22776  case value_t::object:
22777  {
22778  m_value.object->clear();
22779  break;
22780  }
22781 
22782  case value_t::null:
22783  case value_t::discarded:
22784  default:
22785  break;
22786  }
22787  }
22788 
22809  void push_back(basic_json&& val)
22810  {
22811  // push_back only works for null objects or arrays
22812  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22813  {
22814  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22815  }
22816 
22817  // transform null object into an array
22818  if (is_null())
22819  {
22820  m_type = value_t::array;
22821  m_value = value_t::array;
22822  assert_invariant();
22823  }
22824 
22825  // add element to array (move semantics)
22826  const auto old_capacity = m_value.array->capacity();
22827  m_value.array->push_back(std::move(val));
22828  set_parent(m_value.array->back(), old_capacity);
22829  // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
22830  }
22831 
22837  {
22838  push_back(std::move(val));
22839  return *this;
22840  }
22841 
22846  void push_back(const 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
22863  const auto old_capacity = m_value.array->capacity();
22864  m_value.array->push_back(val);
22865  set_parent(m_value.array->back(), old_capacity);
22866  }
22867 
22872  reference operator+=(const basic_json& val)
22873  {
22874  push_back(val);
22875  return *this;
22876  }
22877 
22898  void push_back(const typename object_t::value_type& val)
22899  {
22900  // push_back only works for null objects or objects
22901  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22902  {
22903  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22904  }
22905 
22906  // transform null object into an object
22907  if (is_null())
22908  {
22909  m_type = value_t::object;
22910  m_value = value_t::object;
22911  assert_invariant();
22912  }
22913 
22914  // add element to object
22915  auto res = m_value.object->insert(val);
22916  set_parent(res.first->second);
22917  }
22918 
22923  reference operator+=(const typename object_t::value_type& val)
22924  {
22925  push_back(val);
22926  return *this;
22927  }
22928 
22954  void push_back(initializer_list_t init)
22955  {
22956  if (is_object() && init.size() == 2 && (*init.begin())->is_string())
22957  {
22958  basic_json&& key = init.begin()->moved_or_copied();
22959  push_back(typename object_t::value_type(
22960  std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
22961  }
22962  else
22963  {
22965  }
22966  }
22967 
22973  {
22974  push_back(init);
22975  return *this;
22976  }
22977 
23001  template<class... Args>
23002  reference emplace_back(Args&& ... args)
23003  {
23004  // emplace_back only works for null objects or arrays
23005  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23006  {
23007  JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()), *this));
23008  }
23009 
23010  // transform null object into an array
23011  if (is_null())
23012  {
23013  m_type = value_t::array;
23014  m_value = value_t::array;
23015  assert_invariant();
23016  }
23017 
23018  // add element to array (perfect forwarding)
23019  const auto old_capacity = m_value.array->capacity();
23020  m_value.array->emplace_back(std::forward<Args>(args)...);
23021  return set_parent(m_value.array->back(), old_capacity);
23022  }
23023 
23051  template<class... Args>
23052  std::pair<iterator, bool> emplace(Args&& ... args)
23053  {
23054  // emplace only works for null objects or arrays
23055  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23056  {
23057  JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()), *this));
23058  }
23059 
23060  // transform null object into an object
23061  if (is_null())
23062  {
23063  m_type = value_t::object;
23064  m_value = value_t::object;
23065  assert_invariant();
23066  }
23067 
23068  // add element to array (perfect forwarding)
23069  auto res = m_value.object->emplace(std::forward<Args>(args)...);
23070  set_parent(res.first->second);
23071 
23072  // create result iterator and set iterator to the result of emplace
23073  auto it = begin();
23074  it.m_it.object_iterator = res.first;
23075 
23076  // return pair of iterator and boolean
23077  return {it, res.second};
23078  }
23079 
23083  template<typename... Args>
23084  iterator insert_iterator(const_iterator pos, Args&& ... args)
23085  {
23086  iterator result(this);
23087  JSON_ASSERT(m_value.array != nullptr);
23088 
23089  auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
23090  m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
23091  result.m_it.array_iterator = m_value.array->begin() + insert_pos;
23092 
23093  // This could have been written as:
23094  // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
23095  // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
23096 
23097  set_parents();
23098  return result;
23099  }
23100 
23123  iterator insert(const_iterator pos, const basic_json& val)
23124  {
23125  // insert only works for arrays
23126  if (JSON_HEDLEY_LIKELY(is_array()))
23127  {
23128  // check if iterator pos fits to this JSON value
23129  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23130  {
23131  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23132  }
23134  // insert to array and return iterator
23135  return insert_iterator(pos, val);
23136  }
23137 
23138  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23139  }
23140 
23146  {
23147  return insert(pos, val);
23148  }
23149 
23174  iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
23175  {
23176  // insert only works for arrays
23177  if (JSON_HEDLEY_LIKELY(is_array()))
23178  {
23179  // check if iterator pos fits to this JSON value
23180  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23181  {
23182  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23183  }
23185  // insert to array and return iterator
23186  return insert_iterator(pos, cnt, val);
23187  }
23188 
23189  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23190  }
23191 
23223  {
23224  // insert only works for arrays
23225  if (JSON_HEDLEY_UNLIKELY(!is_array()))
23226  {
23227  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23228  }
23229 
23230  // check if iterator pos fits to this JSON value
23231  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23232  {
23233  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23234  }
23235 
23236  // check if range iterators belong to the same JSON object
23237  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23238  {
23239  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23240  }
23241 
23242  if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
23243  {
23244  JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", *this));
23245  }
23246 
23247  // insert to array and return iterator
23248  return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
23249  }
23250 
23276  {
23277  // insert only works for arrays
23278  if (JSON_HEDLEY_UNLIKELY(!is_array()))
23279  {
23280  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23281  }
23282 
23283  // check if iterator pos fits to this JSON value
23284  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23285  {
23286  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23287  }
23288 
23289  // insert to array and return iterator
23290  return insert_iterator(pos, ilist.begin(), ilist.end());
23291  }
23292 
23316  void insert(const_iterator first, const_iterator last)
23317  {
23318  // insert only works for objects
23319  if (JSON_HEDLEY_UNLIKELY(!is_object()))
23320  {
23321  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23322  }
23323 
23324  // check if range iterators belong to the same JSON object
23325  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23326  {
23327  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23328  }
23329 
23330  // passed iterators must belong to objects
23331  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
23332  {
23333  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23334  }
23335 
23336  m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
23337  }
23338 
23358  void update(const_reference j)
23359  {
23360  // implicitly convert null value to an empty object
23361  if (is_null())
23362  {
23363  m_type = value_t::object;
23364  m_value.object = create<object_t>();
23365  assert_invariant();
23366  }
23367 
23368  if (JSON_HEDLEY_UNLIKELY(!is_object()))
23369  {
23370  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
23371  }
23372  if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
23373  {
23374  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()), *this));
23375  }
23376 
23377  for (auto it = j.cbegin(); it != j.cend(); ++it)
23378  {
23379  m_value.object->operator[](it.key()) = it.value();
23380  }
23381  }
23382 
23409  void update(const_iterator first, const_iterator last)
23410  {
23411  // implicitly convert null value to an empty object
23412  if (is_null())
23413  {
23414  m_type = value_t::object;
23415  m_value.object = create<object_t>();
23416  assert_invariant();
23417  }
23418 
23419  if (JSON_HEDLEY_UNLIKELY(!is_object()))
23420  {
23421  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
23422  }
23423 
23424  // check if range iterators belong to the same JSON object
23425  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23426  {
23427  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23428  }
23429 
23430  // passed iterators must belong to objects
23431  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
23432  || !last.m_object->is_object()))
23433  {
23434  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23435  }
23436 
23437  for (auto it = first; it != last; ++it)
23438  {
23439  m_value.object->operator[](it.key()) = it.value();
23440  }
23441  }
23442 
23460  void swap(reference other) noexcept (
23461  std::is_nothrow_move_constructible<value_t>::value&&
23462  std::is_nothrow_move_assignable<value_t>::value&&
23463  std::is_nothrow_move_constructible<json_value>::value&&
23464  std::is_nothrow_move_assignable<json_value>::value
23465  )
23466  {
23467  std::swap(m_type, other.m_type);
23468  std::swap(m_value, other.m_value);
23469 
23470  set_parents();
23471  other.set_parents();
23472  assert_invariant();
23473  }
23474 
23493  friend void swap(reference left, reference right) noexcept (
23494  std::is_nothrow_move_constructible<value_t>::value&&
23495  std::is_nothrow_move_assignable<value_t>::value&&
23496  std::is_nothrow_move_constructible<json_value>::value&&
23497  std::is_nothrow_move_assignable<json_value>::value
23498  )
23499  {
23500  left.swap(right);
23501  }
23502 
23523  void swap(array_t& other) // NOLINT(bugprone-exception-escape)
23524  {
23525  // swap only works for arrays
23526  if (JSON_HEDLEY_LIKELY(is_array()))
23527  {
23528  std::swap(*(m_value.array), other);
23529  }
23530  else
23531  {
23532  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23533  }
23534  }
23535 
23556  void swap(object_t& other) // NOLINT(bugprone-exception-escape)
23557  {
23558  // swap only works for objects
23559  if (JSON_HEDLEY_LIKELY(is_object()))
23560  {
23561  std::swap(*(m_value.object), other);
23562  }
23563  else
23564  {
23565  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23566  }
23567  }
23568 
23589  void swap(string_t& other) // NOLINT(bugprone-exception-escape)
23590  {
23591  // swap only works for strings
23592  if (JSON_HEDLEY_LIKELY(is_string()))
23593  {
23594  std::swap(*(m_value.string), other);
23595  }
23596  else
23597  {
23598  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23599  }
23600  }
23601 
23622  void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
23623  {
23624  // swap only works for strings
23625  if (JSON_HEDLEY_LIKELY(is_binary()))
23626  {
23627  std::swap(*(m_value.binary), other);
23628  }
23629  else
23630  {
23631  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23632  }
23633  }
23634 
23636  void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
23637  {
23638  // swap only works for strings
23639  if (JSON_HEDLEY_LIKELY(is_binary()))
23640  {
23641  std::swap(*(m_value.binary), other);
23642  }
23643  else
23644  {
23645  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23646  }
23647  }
23648 
23650 
23651  public:
23653  // lexicographical comparison operators //
23655 
23658 
23714  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
23715  {
23716 #ifdef __GNUC__
23717 #pragma GCC diagnostic push
23718 #pragma GCC diagnostic ignored "-Wfloat-equal"
23719 #endif
23720  const auto lhs_type = lhs.type();
23721  const auto rhs_type = rhs.type();
23722 
23723  if (lhs_type == rhs_type)
23724  {
23725  switch (lhs_type)
23726  {
23727  case value_t::array:
23728  return *lhs.m_value.array == *rhs.m_value.array;
23729 
23730  case value_t::object:
23731  return *lhs.m_value.object == *rhs.m_value.object;
23732 
23733  case value_t::null:
23734  return true;
23735 
23736  case value_t::string:
23737  return *lhs.m_value.string == *rhs.m_value.string;
23738 
23739  case value_t::boolean:
23740  return lhs.m_value.boolean == rhs.m_value.boolean;
23741 
23742  case value_t::number_integer:
23743  return lhs.m_value.number_integer == rhs.m_value.number_integer;
23744 
23745  case value_t::number_unsigned:
23746  return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
23747 
23748  case value_t::number_float:
23749  return lhs.m_value.number_float == rhs.m_value.number_float;
23750 
23751  case value_t::binary:
23752  return *lhs.m_value.binary == *rhs.m_value.binary;
23753 
23754  case value_t::discarded:
23755  default:
23756  return false;
23757  }
23758  }
23759  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
23760  {
23761  return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
23762  }
23763  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
23764  {
23765  return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
23766  }
23767  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
23768  {
23769  return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
23770  }
23771  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
23772  {
23773  return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
23774  }
23775  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
23776  {
23777  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
23778  }
23779  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
23780  {
23781  return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
23782  }
23783 
23784  return false;
23785 #ifdef __GNUC__
23786 #pragma GCC diagnostic pop
23787 #endif
23788  }
23789 
23794  template<typename ScalarType, typename std::enable_if<
23795  std::is_scalar<ScalarType>::value, int>::type = 0>
23796  friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
23797  {
23798  return lhs == basic_json(rhs);
23799  }
23800 
23805  template<typename ScalarType, typename std::enable_if<
23806  std::is_scalar<ScalarType>::value, int>::type = 0>
23807  friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
23808  {
23809  return basic_json(lhs) == rhs;
23810  }
23811 
23830  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
23831  {
23832  return !(lhs == rhs);
23833  }
23834 
23839  template<typename ScalarType, typename std::enable_if<
23840  std::is_scalar<ScalarType>::value, int>::type = 0>
23841  friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23842  {
23843  return lhs != basic_json(rhs);
23844  }
23845 
23850  template<typename ScalarType, typename std::enable_if<
23851  std::is_scalar<ScalarType>::value, int>::type = 0>
23852  friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
23853  {
23854  return basic_json(lhs) != rhs;
23855  }
23856 
23883  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
23884  {
23885  const auto lhs_type = lhs.type();
23886  const auto rhs_type = rhs.type();
23887 
23888  if (lhs_type == rhs_type)
23889  {
23890  switch (lhs_type)
23891  {
23892  case value_t::array:
23893  // note parentheses are necessary, see
23894  // https://github.com/nlohmann/json/issues/1530
23895  return (*lhs.m_value.array) < (*rhs.m_value.array);
23896 
23897  case value_t::object:
23898  return (*lhs.m_value.object) < (*rhs.m_value.object);
23899 
23900  case value_t::null:
23901  return false;
23902 
23903  case value_t::string:
23904  return (*lhs.m_value.string) < (*rhs.m_value.string);
23905 
23906  case value_t::boolean:
23907  return (lhs.m_value.boolean) < (rhs.m_value.boolean);
23908 
23909  case value_t::number_integer:
23910  return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
23911 
23912  case value_t::number_unsigned:
23913  return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
23914 
23915  case value_t::number_float:
23916  return (lhs.m_value.number_float) < (rhs.m_value.number_float);
23917 
23918  case value_t::binary:
23919  return (*lhs.m_value.binary) < (*rhs.m_value.binary);
23920 
23921  case value_t::discarded:
23922  default:
23923  return false;
23924  }
23925  }
23926  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
23927  {
23928  return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
23929  }
23930  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
23931  {
23932  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
23933  }
23934  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
23935  {
23936  return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
23937  }
23938  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
23939  {
23940  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
23941  }
23942  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
23943  {
23944  return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
23945  }
23946  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
23947  {
23948  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
23949  }
23950 
23951  // We only reach this line if we cannot compare values. In that case,
23952  // we compare types. Note we have to call the operator explicitly,
23953  // because MSVC has problems otherwise.
23954  return operator<(lhs_type, rhs_type);
23955  }
23956 
23961  template<typename ScalarType, typename std::enable_if<
23962  std::is_scalar<ScalarType>::value, int>::type = 0>
23963  friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
23964  {
23965  return lhs < basic_json(rhs);
23966  }
23967 
23972  template<typename ScalarType, typename std::enable_if<
23973  std::is_scalar<ScalarType>::value, int>::type = 0>
23974  friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
23975  {
23976  return basic_json(lhs) < rhs;
23977  }
23978 
23998  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
23999  {
24000  return !(rhs < lhs);
24001  }
24002 
24007  template<typename ScalarType, typename std::enable_if<
24008  std::is_scalar<ScalarType>::value, int>::type = 0>
24009  friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
24010  {
24011  return lhs <= basic_json(rhs);
24012  }
24013 
24018  template<typename ScalarType, typename std::enable_if<
24019  std::is_scalar<ScalarType>::value, int>::type = 0>
24020  friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
24021  {
24022  return basic_json(lhs) <= rhs;
24023  }
24024 
24044  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
24045  {
24046  return !(lhs <= rhs);
24047  }
24048 
24053  template<typename ScalarType, typename std::enable_if<
24054  std::is_scalar<ScalarType>::value, int>::type = 0>
24055  friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
24056  {
24057  return lhs > basic_json(rhs);
24058  }
24059 
24064  template<typename ScalarType, typename std::enable_if<
24065  std::is_scalar<ScalarType>::value, int>::type = 0>
24066  friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
24067  {
24068  return basic_json(lhs) > rhs;
24069  }
24070 
24090  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
24091  {
24092  return !(lhs < rhs);
24093  }
24094 
24099  template<typename ScalarType, typename std::enable_if<
24100  std::is_scalar<ScalarType>::value, int>::type = 0>
24101  friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
24102  {
24103  return lhs >= basic_json(rhs);
24104  }
24105 
24110  template<typename ScalarType, typename std::enable_if<
24111  std::is_scalar<ScalarType>::value, int>::type = 0>
24112  friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
24113  {
24114  return basic_json(lhs) >= rhs;
24115  }
24116 
24118 
24120  // serialization //
24125 #ifndef JSON_NO_IO
24157  friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
24158  {
24159  // read width member and use it as indentation parameter if nonzero
24160  const bool pretty_print = o.width() > 0;
24161  const auto indentation = pretty_print ? o.width() : 0;
24162 
24163  // reset width to 0 for subsequent calls to this stream
24164  o.width(0);
24165 
24166  // do the actual serialization
24167  serializer s(detail::output_adapter<char>(o), o.fill());
24168  s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
24169  return o;
24170  }
24171 
24180  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
24181  friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
24182  {
24183  return o << j;
24184  }
24185 #endif // JSON_NO_IO
24187 
24188 
24190  // deserialization //
24192 
24195 
24247  template<typename InputType>
24248 
24249  static basic_json parse(InputType&& i,
24250  const parser_callback_t cb = nullptr,
24251  const bool allow_exceptions = true,
24252  const bool ignore_comments = false)
24253  {
24254  basic_json result;
24255  parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
24256  return result;
24257  }
24258 
24285  template<typename IteratorType>
24286 
24287  static basic_json parse(IteratorType first,
24288  IteratorType last,
24289  const parser_callback_t cb = nullptr,
24290  const bool allow_exceptions = true,
24291  const bool ignore_comments = false)
24292  {
24293  basic_json result;
24294  parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
24295  return result;
24296  }
24298 
24299  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
24300  static basic_json parse(detail::span_input_adapter&& i,
24301  const parser_callback_t cb = nullptr,
24302  const bool allow_exceptions = true,
24303  const bool ignore_comments = false)
24304  {
24305  basic_json result;
24306  parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
24307  return result;
24308  }
24309 
24340  template<typename InputType>
24341  static bool accept(InputType&& i,
24342  const bool ignore_comments = false)
24343  {
24344  return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
24345  }
24346 
24347  template<typename IteratorType>
24348  static bool accept(IteratorType first, IteratorType last,
24349  const bool ignore_comments = false)
24350  {
24351  return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
24352  }
24353 
24354 
24355  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
24356  static bool accept(detail::span_input_adapter&& i,
24357  const bool ignore_comments = false)
24358  {
24359  return parser(i.get(), nullptr, false, ignore_comments).accept(true);
24360  }
24361 
24402  template <typename InputType, typename SAX>
24403  JSON_HEDLEY_NON_NULL(2)
24404  static bool sax_parse(InputType&& i, SAX* sax,
24406  const bool strict = true,
24407  const bool ignore_comments = false)
24408  {
24409  auto ia = detail::input_adapter(std::forward<InputType>(i));
24410  return format == input_format_t::json
24411  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24412  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24413  }
24415  template<class IteratorType, class SAX>
24416  JSON_HEDLEY_NON_NULL(3)
24417  static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
24418  input_format_t format = input_format_t::json,
24419  const bool strict = true,
24420  const bool ignore_comments = false)
24421  {
24422  auto ia = detail::input_adapter(std::move(first), std::move(last));
24423  return format == input_format_t::json
24424  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24425  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24426  }
24428  template <typename SAX>
24429  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
24430  JSON_HEDLEY_NON_NULL(2)
24431  static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
24432  input_format_t format = input_format_t::json,
24433  const bool strict = true,
24434  const bool ignore_comments = false)
24435  {
24436  auto ia = i.get();
24437  return format == input_format_t::json
24438  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24439  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24440  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24441  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24442  }
24443 #ifndef JSON_NO_IO
24452  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
24453  friend std::istream& operator<<(basic_json& j, std::istream& i)
24454  {
24455  return operator>>(i, j);
24456  }
24457 
24483  friend std::istream& operator>>(std::istream& i, basic_json& j)
24484  {
24485  parser(detail::input_adapter(i)).parse(false, j);
24486  return i;
24487  }
24488 #endif // JSON_NO_IO
24490 
24492  // convenience functions //
24494 
24526 
24527  const char* type_name() const noexcept
24528  {
24529  {
24530  switch (m_type)
24531  {
24532  case value_t::null:
24533  return "null";
24534  case value_t::object:
24535  return "object";
24536  case value_t::array:
24537  return "array";
24538  case value_t::string:
24539  return "string";
24540  case value_t::boolean:
24541  return "boolean";
24542  case value_t::binary:
24543  return "binary";
24544  case value_t::discarded:
24545  return "discarded";
24546  case value_t::number_integer:
24547  case value_t::number_unsigned:
24548  case value_t::number_float:
24549  default:
24550  return "number";
24551  }
24552  }
24553  }
24554 
24555 
24556  JSON_PRIVATE_UNLESS_TESTED:
24558  // member variables //
24560 
24562  value_t m_type = value_t::null;
24563 
24565  json_value m_value = {};
24567 #if JSON_DIAGNOSTICS
24569  basic_json* m_parent = nullptr;
24570 #endif
24571 
24573  // binary serialization/deserialization //
24578 
24579  public:
24678  static std::vector<std::uint8_t> to_cbor(const basic_json& j)
24679  {
24680  std::vector<std::uint8_t> result;
24681  to_cbor(j, result);
24682  return result;
24683  }
24684 
24685  static void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o)
24686  {
24687  binary_writer<std::uint8_t>(o).write_cbor(j);
24688  }
24689 
24690  static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
24691  {
24692  binary_writer<char>(o).write_cbor(j);
24693  }
24694 
24773  static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
24774  {
24775  std::vector<std::uint8_t> result;
24776  to_msgpack(j, result);
24777  return result;
24778  }
24779 
24780  static void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o)
24781  {
24782  binary_writer<std::uint8_t>(o).write_msgpack(j);
24783  }
24784 
24785  static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
24786  {
24787  binary_writer<char>(o).write_msgpack(j);
24788  }
24789 
24876  static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
24877  const bool use_size = false,
24878  const bool use_type = false)
24879  {
24880  std::vector<std::uint8_t> result;
24881  to_ubjson(j, result, use_size, use_type);
24882  return result;
24883  }
24884 
24885  static void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o,
24886  const bool use_size = false, const bool use_type = false)
24887  {
24888  binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
24889  }
24890 
24891  static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
24892  const bool use_size = false, const bool use_type = false)
24893  {
24894  binary_writer<char>(o).write_ubjson(j, use_size, use_type);
24895  }
24896 
24897 
24954  static std::vector<std::uint8_t> to_bson(const basic_json& j)
24955  {
24956  std::vector<std::uint8_t> result;
24957  to_bson(j, result);
24958  return result;
24959  }
24960 
24969  static void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o)
24970  {
24971  binary_writer<std::uint8_t>(o).write_bson(j);
24972  }
24973 
24977  static void to_bson(const basic_json& j, detail::output_adapter<char> o)
24978  {
24979  binary_writer<char>(o).write_bson(j);
24980  }
24981 
24982 
25085  template<typename InputType>
25086 
25087  static basic_json from_cbor(InputType&& i,
25088  const bool strict = true,
25089  const bool allow_exceptions = true,
25090  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25091  {
25092  basic_json result;
25093  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25094  auto ia = detail::input_adapter(std::forward<InputType>(i));
25095  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25096  return res ? result : basic_json(value_t::discarded);
25097  }
25098 
25102  template<typename IteratorType>
25103 
25104  static basic_json from_cbor(IteratorType first, IteratorType last,
25105  const bool strict = true,
25106  const bool allow_exceptions = true,
25107  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25108  {
25109  basic_json result;
25110  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25111  auto ia = detail::input_adapter(std::move(first), std::move(last));
25112  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25113  return res ? result : basic_json(value_t::discarded);
25114  }
25115 
25116  template<typename T>
25117 
25118  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
25119  static basic_json from_cbor(const T* ptr, std::size_t len,
25120  const bool strict = true,
25121  const bool allow_exceptions = true,
25122  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25123  {
25124  return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
25125  }
25126 
25127 
25128 
25129  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
25130  static basic_json from_cbor(detail::span_input_adapter&& i,
25131  const bool strict = true,
25132  const bool allow_exceptions = true,
25133  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25134  {
25135  basic_json result;
25136  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25137  auto ia = i.get();
25138  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25139  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25140  return res ? result : basic_json(value_t::discarded);
25141  }
25142 
25229  template<typename InputType>
25230 
25231  static basic_json from_msgpack(InputType&& i,
25232  const bool strict = true,
25233  const bool allow_exceptions = true)
25234  {
25235  basic_json result;
25236  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25237  auto ia = detail::input_adapter(std::forward<InputType>(i));
25238  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25239  return res ? result : basic_json(value_t::discarded);
25240  }
25245  template<typename IteratorType>
25246 
25247  static basic_json from_msgpack(IteratorType first, IteratorType last,
25248  const bool strict = true,
25249  const bool allow_exceptions = true)
25250  {
25251  basic_json result;
25252  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25253  auto ia = detail::input_adapter(std::move(first), std::move(last));
25254  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25255  return res ? result : basic_json(value_t::discarded);
25256  }
25258 
25259  template<typename T>
25260 
25261  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
25262  static basic_json from_msgpack(const T* ptr, std::size_t len,
25263  const bool strict = true,
25264  const bool allow_exceptions = true)
25265  {
25266  return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
25267  }
25268 
25269 
25270  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
25271  static basic_json from_msgpack(detail::span_input_adapter&& i,
25272  const bool strict = true,
25273  const bool allow_exceptions = true)
25274  {
25275  basic_json result;
25276  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25277  auto ia = i.get();
25278  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25279  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25280  return res ? result : basic_json(value_t::discarded);
25281  }
25282 
25283 
25346  template<typename InputType>
25347 
25348  static basic_json from_ubjson(InputType&& i,
25349  const bool strict = true,
25350  const bool allow_exceptions = true)
25351  {
25352  basic_json result;
25353  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25354  auto ia = detail::input_adapter(std::forward<InputType>(i));
25355  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25356  return res ? result : basic_json(value_t::discarded);
25357  }
25362  template<typename IteratorType>
25363 
25364  static basic_json from_ubjson(IteratorType first, IteratorType last,
25365  const bool strict = true,
25366  const bool allow_exceptions = true)
25367  {
25368  basic_json result;
25369  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25370  auto ia = detail::input_adapter(std::move(first), std::move(last));
25371  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25372  return res ? result : basic_json(value_t::discarded);
25373  }
25375  template<typename T>
25376 
25377  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
25378  static basic_json from_ubjson(const T* ptr, std::size_t len,
25379  const bool strict = true,
25380  const bool allow_exceptions = true)
25381  {
25382  return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
25383  }
25384 
25385 
25386  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
25387  static basic_json from_ubjson(detail::span_input_adapter&& i,
25388  const bool strict = true,
25389  const bool allow_exceptions = true)
25390  {
25391  basic_json result;
25392  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25393  auto ia = i.get();
25394  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25395  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25396  return res ? result : basic_json(value_t::discarded);
25397  }
25398 
25399 
25460  template<typename InputType>
25461 
25462  static basic_json from_bson(InputType&& i,
25463  const bool strict = true,
25464  const bool allow_exceptions = true)
25465  {
25466  basic_json result;
25467  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25468  auto ia = detail::input_adapter(std::forward<InputType>(i));
25469  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25470  return res ? result : basic_json(value_t::discarded);
25471  }
25476  template<typename IteratorType>
25477 
25478  static basic_json from_bson(IteratorType first, IteratorType last,
25479  const bool strict = true,
25480  const bool allow_exceptions = true)
25481  {
25482  basic_json result;
25483  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25484  auto ia = detail::input_adapter(std::move(first), std::move(last));
25485  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25486  return res ? result : basic_json(value_t::discarded);
25487  }
25489  template<typename T>
25490 
25491  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25492  static basic_json from_bson(const T* ptr, std::size_t len,
25493  const bool strict = true,
25494  const bool allow_exceptions = true)
25495  {
25496  return from_bson(ptr, ptr + len, strict, allow_exceptions);
25497  }
25498 
25499 
25500  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25501  static basic_json from_bson(detail::span_input_adapter&& i,
25502  const bool strict = true,
25503  const bool allow_exceptions = true)
25504  {
25505  basic_json result;
25506  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25507  auto ia = i.get();
25508  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25509  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25510  return res ? result : basic_json(value_t::discarded);
25511  }
25513 
25515  // JSON Pointer support //
25517 
25520 
25554  reference operator[](const json_pointer& ptr)
25555  {
25556  return ptr.get_unchecked(this);
25557  }
25558 
25582  const_reference operator[](const json_pointer& ptr) const
25583  {
25584  return ptr.get_unchecked(this);
25585  }
25586 
25625  reference at(const json_pointer& ptr)
25626  {
25627  return ptr.get_checked(this);
25628  }
25629 
25668  const_reference at(const json_pointer& ptr) const
25669  {
25670  return ptr.get_checked(this);
25671  }
25672 
25695  basic_json flatten() const
25696  {
25697  basic_json result(value_t::object);
25698  json_pointer::flatten("", *this, result);
25699  return result;
25700  }
25701 
25732  basic_json unflatten() const
25733  {
25734  return json_pointer::unflatten(*this);
25735  }
25736 
25738 
25740  // JSON Patch functions //
25745 
25793  basic_json patch(const basic_json& json_patch) const
25794  {
25795  // make a working copy to apply the patch to
25796  basic_json result = *this;
25797 
25798  // the valid JSON Patch operations
25799  enum class patch_operations {add, remove, replace, move, copy, test, invalid};
25800 
25801  const auto get_op = [](const std::string & op)
25802  {
25803  if (op == "add")
25804  {
25805  return patch_operations::add;
25806  }
25807  if (op == "remove")
25808  {
25809  return patch_operations::remove;
25810  }
25811  if (op == "replace")
25812  {
25813  return patch_operations::replace;
25814  }
25815  if (op == "move")
25816  {
25817  return patch_operations::move;
25818  }
25819  if (op == "copy")
25820  {
25821  return patch_operations::copy;
25822  }
25823  if (op == "test")
25824  {
25825  return patch_operations::test;
25826  }
25827 
25828  return patch_operations::invalid;
25829  };
25830 
25831  // wrapper for "add" operation; add value at ptr
25832  const auto operation_add = [&result](json_pointer & ptr, basic_json val)
25833  {
25834  // adding to the root of the target document means replacing it
25835  if (ptr.empty())
25836  {
25837  result = val;
25838  return;
25839  }
25840 
25841  // make sure the top element of the pointer exists
25842  json_pointer top_pointer = ptr.top();
25843  if (top_pointer != ptr)
25844  {
25845  result.at(top_pointer);
25846  }
25847 
25848  // get reference to parent of JSON pointer ptr
25849  const auto last_path = ptr.back();
25850  ptr.pop_back();
25851  basic_json& parent = result[ptr];
25852 
25853  switch (parent.m_type)
25854  {
25855  case value_t::null:
25856  case value_t::object:
25857  {
25858  // use operator[] to add value
25859  parent[last_path] = val;
25860  break;
25861  }
25862 
25863  case value_t::array:
25864  {
25865  if (last_path == "-")
25866  {
25867  // special case: append to back
25868  parent.push_back(val);
25869  }
25870  else
25871  {
25872  const auto idx = json_pointer::array_index(last_path);
25873  if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
25874  {
25875  // avoid undefined behavior
25876  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", parent));
25877  }
25878 
25879  // default case: insert add offset
25880  parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
25881  }
25882  break;
25883  }
25884 
25885  // if there exists a parent it cannot be primitive
25886  case value_t::string: // LCOV_EXCL_LINE
25887  case value_t::boolean: // LCOV_EXCL_LINE
25888  case value_t::number_integer: // LCOV_EXCL_LINE
25889  case value_t::number_unsigned: // LCOV_EXCL_LINE
25890  case value_t::number_float: // LCOV_EXCL_LINE
25891  case value_t::binary: // LCOV_EXCL_LINE
25892  case value_t::discarded: // LCOV_EXCL_LINE
25893  default: // LCOV_EXCL_LINE
25894  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
25895  }
25896  };
25897 
25898  // wrapper for "remove" operation; remove value at ptr
25899  const auto operation_remove = [this, &result](json_pointer & ptr)
25900  {
25901  // get reference to parent of JSON pointer ptr
25902  const auto last_path = ptr.back();
25903  ptr.pop_back();
25904  basic_json& parent = result.at(ptr);
25905 
25906  // remove child
25907  if (parent.is_object())
25908  {
25909  // perform range check
25910  auto it = parent.find(last_path);
25911  if (JSON_HEDLEY_LIKELY(it != parent.end()))
25912  {
25913  parent.erase(it);
25914  }
25915  else
25916  {
25917  JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found", *this));
25918  }
25919  }
25920  else if (parent.is_array())
25921  {
25922  // note erase performs range check
25923  parent.erase(json_pointer::array_index(last_path));
25924  }
25925  };
25926 
25927  // type check: top level value must be an array
25928  if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
25929  {
25930  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", json_patch));
25931  }
25932 
25933  // iterate and apply the operations
25934  for (const auto& val : json_patch)
25935  {
25936  // wrapper to get a value for an operation
25937  const auto get_value = [&val](const std::string & op,
25938  const std::string & member,
25939  bool string_type) -> basic_json &
25940  {
25941  // find value
25942  auto it = val.m_value.object->find(member);
25943 
25944  // context-sensitive error message
25945  const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
25946 
25947  // check if desired value is present
25948  if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
25949  {
25950  // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
25951  JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'", val));
25952  }
25953 
25954  // check if result is of type string
25955  if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
25956  {
25957  // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
25958  JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'", val));
25959  }
25960 
25961  // no error: return value
25962  return it->second;
25963  };
25964 
25965  // type check: every element of the array must be an object
25966  if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
25967  {
25968  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", val));
25969  }
25970 
25971  // collect mandatory members
25972  const auto op = get_value("op", "op", true).template get<std::string>();
25973  const auto path = get_value(op, "path", true).template get<std::string>();
25974  json_pointer ptr(path);
25975 
25976  switch (get_op(op))
25977  {
25978  case patch_operations::add:
25979  {
25980  operation_add(ptr, get_value("add", "value", false));
25981  break;
25982  }
25983 
25984  case patch_operations::remove:
25985  {
25986  operation_remove(ptr);
25987  break;
25988  }
25989 
25990  case patch_operations::replace:
25991  {
25992  // the "path" location must exist - use at()
25993  result.at(ptr) = get_value("replace", "value", false);
25994  break;
25995  }
25996 
25997  case patch_operations::move:
25998  {
25999  const auto from_path = get_value("move", "from", true).template get<std::string>();
26000  json_pointer from_ptr(from_path);
26001 
26002  // the "from" location must exist - use at()
26003  basic_json v = result.at(from_ptr);
26004 
26005  // The move operation is functionally identical to a
26006  // "remove" operation on the "from" location, followed
26007  // immediately by an "add" operation at the target
26008  // location with the value that was just removed.
26009  operation_remove(from_ptr);
26010  operation_add(ptr, v);
26011  break;
26012  }
26013 
26014  case patch_operations::copy:
26015  {
26016  const auto from_path = get_value("copy", "from", true).template get<std::string>();
26017  const json_pointer from_ptr(from_path);
26018 
26019  // the "from" location must exist - use at()
26020  basic_json v = result.at(from_ptr);
26021 
26022  // The copy is functionally identical to an "add"
26023  // operation at the target location using the value
26024  // specified in the "from" member.
26025  operation_add(ptr, v);
26026  break;
26027  }
26028 
26029  case patch_operations::test:
26030  {
26031  bool success = false;
26032  JSON_TRY
26033  {
26034  // check if "value" matches the one at "path"
26035  // the "path" location must exist - use at()
26036  success = (result.at(ptr) == get_value("test", "value", false));
26037  }
26038  JSON_INTERNAL_CATCH (out_of_range&)
26039  {
26040  // ignore out of range errors: success remains false
26041  }
26042 
26043  // throw an exception if test fails
26044  if (JSON_HEDLEY_UNLIKELY(!success))
26045  {
26046  JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump(), val));
26047  }
26048 
26049  break;
26050  }
26051 
26052  case patch_operations::invalid:
26053  default:
26054  {
26055  // op must be "add", "remove", "replace", "move", "copy", or
26056  // "test"
26057  JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid", val));
26058  }
26059  }
26060  }
26061 
26062  return result;
26063  }
26064 
26098 
26099  static basic_json diff(const basic_json& source, const basic_json& target,
26100  const std::string& path = "")
26101  {
26102  // the patch
26103  basic_json result(value_t::array);
26104 
26105  // if the values are the same, return empty patch
26106  if (source == target)
26107  {
26108  return result;
26109  }
26110 
26111  if (source.type() != target.type())
26112  {
26113  // different types: replace value
26114  result.push_back(
26115  {
26116  {"op", "replace"}, {"path", path}, {"value", target}
26117  });
26118  return result;
26119  }
26120 
26121  switch (source.type())
26122  {
26123  case value_t::array:
26124  {
26125  // first pass: traverse common elements
26126  std::size_t i = 0;
26127  while (i < source.size() && i < target.size())
26128  {
26129  // recursive call to compare array values at index i
26130  auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
26131  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
26132  ++i;
26133  }
26134 
26135  // i now reached the end of at least one array
26136  // in a second pass, traverse the remaining elements
26137 
26138  // remove my remaining elements
26139  const auto end_index = static_cast<difference_type>(result.size());
26140  while (i < source.size())
26141  {
26142  // add operations in reverse order to avoid invalid
26143  // indices
26144  result.insert(result.begin() + end_index, object(
26145  {
26146  {"op", "remove"},
26147  {"path", path + "/" + std::to_string(i)}
26148  }));
26149  ++i;
26150  }
26151 
26152  // add other remaining elements
26153  while (i < target.size())
26154  {
26155  result.push_back(
26156  {
26157  {"op", "add"},
26158  {"path", path + "/-"},
26159  {"value", target[i]}
26160  });
26161  ++i;
26162  }
26163 
26164  break;
26165  }
26166 
26167  case value_t::object:
26168  {
26169  // first pass: traverse this object's elements
26170  for (auto it = source.cbegin(); it != source.cend(); ++it)
26171  {
26172  // escape the key name to be used in a JSON patch
26173  const auto path_key = path + "/" + detail::escape(it.key());
26174 
26175  if (target.find(it.key()) != target.end())
26176  {
26177  // recursive call to compare object values at key it
26178  auto temp_diff = diff(it.value(), target[it.key()], path_key);
26179  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
26180  }
26181  else
26182  {
26183  // found a key that is not in o -> remove it
26184  result.push_back(object(
26185  {
26186  {"op", "remove"}, {"path", path_key}
26187  }));
26188  }
26189  }
26190 
26191  // second pass: traverse other object's elements
26192  for (auto it = target.cbegin(); it != target.cend(); ++it)
26193  {
26194  if (source.find(it.key()) == source.end())
26195  {
26196  // found a key that is not in this -> add it
26197  const auto path_key = path + "/" + detail::escape(it.key());
26198  result.push_back(
26199  {
26200  {"op", "add"}, {"path", path_key},
26201  {"value", it.value()}
26202  });
26203  }
26204  }
26205 
26206  break;
26207  }
26208 
26209  case value_t::null:
26210  case value_t::string:
26211  case value_t::boolean:
26212  case value_t::number_integer:
26213  case value_t::number_unsigned:
26214  case value_t::number_float:
26215  case value_t::binary:
26216  case value_t::discarded:
26217  default:
26218  {
26219  // both primitive type: replace value
26220  result.push_back(
26221  {
26222  {"op", "replace"}, {"path", path}, {"value", target}
26223  });
26224  break;
26225  }
26226  }
26227 
26228  return result;
26229  }
26230 
26232 
26234  // JSON Merge Patch functions //
26236 
26239 
26282  void merge_patch(const basic_json& apply_patch)
26283  {
26284  if (apply_patch.is_object())
26285  {
26286  if (!is_object())
26287  {
26288  *this = object();
26289  }
26290  for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
26291  {
26292  if (it.value().is_null())
26293  {
26294  erase(it.key());
26295  }
26296  else
26297  {
26298  operator[](it.key()).merge_patch(it.value());
26299  }
26300  }
26301  }
26302  else
26303  {
26304  *this = apply_patch;
26305  }
26306  }
26307 
26309 };
26310 
26320 NLOHMANN_BASIC_JSON_TPL_DECLARATION
26321 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
26322 {
26323  return j.dump();
26324 }
26325 } // namespace nlohmann
26326 
26328 // nonmember support //
26330 
26331 // specialization of std::swap, and std::hash
26332 namespace std
26333 {
26334 
26336 template<>
26337 struct hash<nlohmann::json>
26338 {
26344  std::size_t operator()(const nlohmann::json& j) const
26345  {
26346  return nlohmann::detail::hash(j);
26347  }
26348 };
26349 
26353 template<>
26354 struct less<::nlohmann::detail::value_t>
26355 {
26360  bool operator()(nlohmann::detail::value_t lhs,
26361  nlohmann::detail::value_t rhs) const noexcept
26362  {
26363  return nlohmann::detail::operator<(lhs, rhs);
26364  }
26365 };
26366 
26367 // C++20 prohibit function specialization in the std namespace.
26368 #ifndef JSON_HAS_CPP_20
26369 
26375 template<>
26376 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
26377  is_nothrow_move_constructible<nlohmann::json>::value&& // NOLINT(misc-redundant-expression)
26378  is_nothrow_move_assignable<nlohmann::json>::value
26379  )
26380 {
26381  j1.swap(j2);
26382 }
26383 
26384 #endif
26385 
26386 } // namespace std
26387 
26401 JSON_HEDLEY_NON_NULL(1)
26402 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
26403 {
26404  return nlohmann::json::parse(s, s + n);
26405 }
26406 
26420 JSON_HEDLEY_NON_NULL(1)
26421 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
26422 {
26423  return nlohmann::json::json_pointer(std::string(s, n));
26424 }
26425 
26426 // #include <nlohmann/detail/macro_unscope.hpp>
26427 
26428 
26429 // restore clang diagnostic settings
26430 #if defined(__clang__)
26431  #pragma clang diagnostic pop
26432 #endif
26433 
26434 // clean up
26435 #undef JSON_ASSERT
26436 #undef JSON_INTERNAL_CATCH
26437 #undef JSON_CATCH
26438 #undef JSON_THROW
26439 #undef JSON_TRY
26440 #undef JSON_PRIVATE_UNLESS_TESTED
26441 #undef JSON_HAS_CPP_11
26442 #undef JSON_HAS_CPP_14
26443 #undef JSON_HAS_CPP_17
26444 #undef JSON_HAS_CPP_20
26445 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
26446 #undef NLOHMANN_BASIC_JSON_TPL
26447 #undef JSON_EXPLICIT
26448 
26449 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
26450 
26451 
26452 #undef JSON_HEDLEY_ALWAYS_INLINE
26453 #undef JSON_HEDLEY_ARM_VERSION
26454 #undef JSON_HEDLEY_ARM_VERSION_CHECK
26455 #undef JSON_HEDLEY_ARRAY_PARAM
26456 #undef JSON_HEDLEY_ASSUME
26457 #undef JSON_HEDLEY_BEGIN_C_DECLS
26458 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
26459 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
26460 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
26461 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
26462 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
26463 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
26464 #undef JSON_HEDLEY_CLANG_HAS_WARNING
26465 #undef JSON_HEDLEY_COMPCERT_VERSION
26466 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
26467 #undef JSON_HEDLEY_CONCAT
26468 #undef JSON_HEDLEY_CONCAT3
26469 #undef JSON_HEDLEY_CONCAT3_EX
26470 #undef JSON_HEDLEY_CONCAT_EX
26471 #undef JSON_HEDLEY_CONST
26472 #undef JSON_HEDLEY_CONSTEXPR
26473 #undef JSON_HEDLEY_CONST_CAST
26474 #undef JSON_HEDLEY_CPP_CAST
26475 #undef JSON_HEDLEY_CRAY_VERSION
26476 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
26477 #undef JSON_HEDLEY_C_DECL
26478 #undef JSON_HEDLEY_DEPRECATED
26479 #undef JSON_HEDLEY_DEPRECATED_FOR
26480 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
26481 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
26482 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
26483 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
26484 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
26485 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
26486 #undef JSON_HEDLEY_DIAGNOSTIC_POP
26487 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
26488 #undef JSON_HEDLEY_DMC_VERSION
26489 #undef JSON_HEDLEY_DMC_VERSION_CHECK
26490 #undef JSON_HEDLEY_EMPTY_BASES
26491 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
26492 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
26493 #undef JSON_HEDLEY_END_C_DECLS
26494 #undef JSON_HEDLEY_FLAGS
26495 #undef JSON_HEDLEY_FLAGS_CAST
26496 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
26497 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
26498 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
26499 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
26500 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
26501 #undef JSON_HEDLEY_GCC_HAS_FEATURE
26502 #undef JSON_HEDLEY_GCC_HAS_WARNING
26503 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
26504 #undef JSON_HEDLEY_GCC_VERSION
26505 #undef JSON_HEDLEY_GCC_VERSION_CHECK
26506 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
26507 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
26508 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
26509 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
26510 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
26511 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
26512 #undef JSON_HEDLEY_GNUC_HAS_WARNING
26513 #undef JSON_HEDLEY_GNUC_VERSION
26514 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
26515 #undef JSON_HEDLEY_HAS_ATTRIBUTE
26516 #undef JSON_HEDLEY_HAS_BUILTIN
26517 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
26518 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
26519 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
26520 #undef JSON_HEDLEY_HAS_EXTENSION
26521 #undef JSON_HEDLEY_HAS_FEATURE
26522 #undef JSON_HEDLEY_HAS_WARNING
26523 #undef JSON_HEDLEY_IAR_VERSION
26524 #undef JSON_HEDLEY_IAR_VERSION_CHECK
26525 #undef JSON_HEDLEY_IBM_VERSION
26526 #undef JSON_HEDLEY_IBM_VERSION_CHECK
26527 #undef JSON_HEDLEY_IMPORT
26528 #undef JSON_HEDLEY_INLINE
26529 #undef JSON_HEDLEY_INTEL_CL_VERSION
26530 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
26531 #undef JSON_HEDLEY_INTEL_VERSION
26532 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
26533 #undef JSON_HEDLEY_IS_CONSTANT
26534 #undef JSON_HEDLEY_IS_CONSTEXPR_
26535 #undef JSON_HEDLEY_LIKELY
26536 #undef JSON_HEDLEY_MALLOC
26537 #undef JSON_HEDLEY_MCST_LCC_VERSION
26538 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
26539 #undef JSON_HEDLEY_MESSAGE
26540 #undef JSON_HEDLEY_MSVC_VERSION
26541 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
26542 #undef JSON_HEDLEY_NEVER_INLINE
26543 #undef JSON_HEDLEY_NON_NULL
26544 #undef JSON_HEDLEY_NO_ESCAPE
26545 #undef JSON_HEDLEY_NO_RETURN
26546 #undef JSON_HEDLEY_NO_THROW
26547 #undef JSON_HEDLEY_NULL
26548 #undef JSON_HEDLEY_PELLES_VERSION
26549 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
26550 #undef JSON_HEDLEY_PGI_VERSION
26551 #undef JSON_HEDLEY_PGI_VERSION_CHECK
26552 #undef JSON_HEDLEY_PREDICT
26553 #undef JSON_HEDLEY_PRINTF_FORMAT
26554 #undef JSON_HEDLEY_PRIVATE
26555 #undef JSON_HEDLEY_PUBLIC
26556 #undef JSON_HEDLEY_PURE
26557 #undef JSON_HEDLEY_REINTERPRET_CAST
26558 #undef JSON_HEDLEY_REQUIRE
26559 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
26560 #undef JSON_HEDLEY_REQUIRE_MSG
26561 #undef JSON_HEDLEY_RESTRICT
26562 #undef
26563 #undef JSON_HEDLEY_SENTINEL
26564 #undef JSON_HEDLEY_STATIC_ASSERT
26565 #undef JSON_HEDLEY_STATIC_CAST
26566 #undef JSON_HEDLEY_STRINGIFY
26567 #undef JSON_HEDLEY_STRINGIFY_EX
26568 #undef JSON_HEDLEY_SUNPRO_VERSION
26569 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
26570 #undef JSON_HEDLEY_TINYC_VERSION
26571 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
26572 #undef JSON_HEDLEY_TI_ARMCL_VERSION
26573 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
26574 #undef JSON_HEDLEY_TI_CL2000_VERSION
26575 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
26576 #undef JSON_HEDLEY_TI_CL430_VERSION
26577 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
26578 #undef JSON_HEDLEY_TI_CL6X_VERSION
26579 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
26580 #undef JSON_HEDLEY_TI_CL7X_VERSION
26581 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
26582 #undef JSON_HEDLEY_TI_CLPRU_VERSION
26583 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
26584 #undef JSON_HEDLEY_TI_VERSION
26585 #undef JSON_HEDLEY_TI_VERSION_CHECK
26586 #undef JSON_HEDLEY_UNAVAILABLE
26587 #undef JSON_HEDLEY_UNLIKELY
26588 #undef JSON_HEDLEY_UNPREDICTABLE
26589 #undef JSON_HEDLEY_UNREACHABLE
26590 #undef JSON_HEDLEY_UNREACHABLE_RETURN
26591 #undef JSON_HEDLEY_VERSION
26592 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
26593 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
26594 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
26595 #undef JSON_HEDLEY_VERSION_ENCODE
26596 #undef JSON_HEDLEY_WARNING
26597 #undef
26598 #undef _MSG
26599 #undef JSON_HEDLEY_FALL_THROUGH
26600 
26601 
26602 
26603 #endif // INCLUDE_NLOHMANN_JSON_HPP_
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:18801
bool contains(KeyT &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:21978
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:22263
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:21357
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:20056
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:18094
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:23724
static bool sax_parse(InputType &&i, SAX *sax, input_format_t format=input_format_t::json, const bool strict=true, const bool ignore_comments=false)
generate SAX events
Definition: json.hpp:24414
detail::exception exception
general exception of the basic_json class
Definition: json.hpp:17645
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:20720
static basic_json parse(InputType &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a compatible input
Definition: json.hpp:24259
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:23012
static basic_json from_cbor(const T *ptr, std::size_t len, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition: json.hpp:25129
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:18842
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:19688
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:22661
static basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition: json.hpp:26109
detail::input_format_t input_format_t
Definition: json.hpp:17632
value_type & reference
the type of an element reference
Definition: json.hpp:17673
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:22292
detail::out_of_range out_of_range
exception indicating access out of the defined range
Definition: json.hpp:17653
static iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition: json.hpp:22356
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:22048
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:19421
basic_json(const JsonRef &ref)
Definition: json.hpp:19531
static std::vector< std::uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:24886
static basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:19284
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:22159
reference back()
access the last element
Definition: json.hpp:21527
static bool accept(InputType &&i, const bool ignore_comments=false)
check if the input is valid JSON
Definition: json.hpp:24351
StringType string_t
a type for a string
Definition: json.hpp:17996
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:22583
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:24191
static basic_json meta()
returns version information on the library
Definition: json.hpp:17737
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:23368
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:17680
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:17678
static basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition: json.hpp:19181
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:22846
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:18976
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:17688
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:17686
static basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:25097
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:18022
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:22964
const char * type_name() const noexcept
return the type as string
Definition: json.hpp:24537
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition: json.hpp:19786
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:21594
static basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
Definition: json.hpp:25472
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:19897
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:20854
static basic_json binary(typename binary_t::container_type &&init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:19238
reference front()
access the first element
Definition: json.hpp:21483
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:19870
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:20028
detail::cbor_tag_handler_t cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:17628
detail::parse_error parse_error
exception indicating a parse error
Definition: json.hpp:17647
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:20078
static std::vector< std::uint8_t > to_bson(const basic_json &j)
Serializes the given JSON object j to BSON and returns a vector containing the corresponding BSON-rep...
Definition: json.hpp:24964
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:19839
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:18233
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:17695
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:24008
bool empty() const noexcept
checks whether the container is empty.
Definition: json.hpp:22503
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:24167
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:19558
~basic_json() noexcept
destructor
Definition: json.hpp:19722
friend struct detail::external_constructor
Definition: json.hpp:17562
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:19650
detail::invalid_iterator invalid_iterator
exception indicating errors with iterators
Definition: json.hpp:17649
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:23840
detail::other_error other_error
exception indicating other library errors
Definition: json.hpp:17655
json_value m_value
the value of the current element
Definition: json.hpp:24575
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:24100
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:22226
static basic_json binary(const typename binary_t::container_type &init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:19218
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:24688
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:20733
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:20616
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:26292
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:20374
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:17943
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition: json.hpp:20684
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:24054
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:19941
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:22438
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:22119
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:23470
void clear() noexcept
clears the contents
Definition: json.hpp:22740
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:20144
static basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:19328
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:21059
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
Definition: json.hpp:20660
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.hpp:17691
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:17697
static basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:25358
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:17622
binary_t & get_binary()
Definition: json.hpp:20796
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:23893
static basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array (without subtype)
Definition: json.hpp:19228
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:20122
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:20100
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.hpp:23094
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:25705
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:17675
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:22819
size_type count(KeyT &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:21945
const binary_t & get_binary() const
Definition: json.hpp:20807
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:19971
std::less< StringType > object_comparator_t
Definition: json.hpp:17807
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:23062
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:20000
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:17630
detail::value_t value_t
Definition: json.hpp:17620
ValueType & get_to(ValueType &v) const
Definition: json.hpp:20673
iterator find(KeyT &&key)
find an element in a JSON object
Definition: json.hpp:21894
detail::type_error type_error
exception indicating executing a member function with a wrong type
Definition: json.hpp:17651
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:18866
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:17683
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:18304
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:17624
static basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:25241
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:25803
basic_json(CompatibleType &&val) noexcept(noexcept(//NOLINT(bugprone-forwarding-reference-overload, bugprone-exception-escape) JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value
Definition: json.hpp:18938
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:25742
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:18165
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:24783
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:22088
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.hpp:19100
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:23133
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.hpp:17693
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:20171
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:19919
ObjectType< StringType, basic_json, object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > >> object_t
a type for an object
Definition: json.hpp:17897
auto get() const noexcept(noexcept(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))) -> decltype(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))
get a (pointer) value (explicit)
Definition: json.hpp:20575
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:19355
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:17705
constexpr auto get_ptr() const noexcept -> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:20387
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:22189
a class to store JSON values
Definition: json.hpp:17560
byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5030
BinaryType container_type
the type of the underlying container
Definition: json.hpp:5014
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5022
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5026
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5048
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:5144
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:5018
byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5036
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:5120
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition: json.hpp:5071
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition: json.hpp:5099
std::uint64_t subtype_type
the type of the subtype
Definition: json.hpp:5016
bool operator==(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5042
an internal type for a backed binary type
Definition: json.hpp:5011
const std::string & back() const
return last reference token
Definition: json.hpp:12610
std::string to_string() const
return a string representation of the JSON pointer
Definition: json.hpp:12404
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for equality
Definition: json.hpp:13302
void pop_back()
remove last reference token
Definition: json.hpp:12586
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:12657
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for inequality
Definition: json.hpp:13319
void push_back(const std::string &token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:12632
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: json.hpp:12436
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition: json.hpp:12482
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.hpp:12386
friend json_pointer operator/(const json_pointer &lhs, const json_pointer &rhs)
create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
Definition: json.hpp:12502
friend json_pointer operator/(const json_pointer &ptr, std::string token)
create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
Definition: json.hpp:12523
json_pointer & operator/=(std::string token)
append an unescaped reference token at the end of this JSON pointer
Definition: json.hpp:12460
void push_back(std::string &&token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:12638
friend json_pointer operator/(const json_pointer &ptr, std::size_t array_idx)
create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
Definition: json.hpp:12543
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:12561
JSON Pointer.
Definition: json.hpp:12359
constexpr const auto & to_json
Definition: json.hpp:4913
constexpr const auto & from_json
Definition: json.hpp:4309
basic_json<> json
default JSON class
Definition: json.hpp:3404
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:26331
namespace for Niels Lohmann
Definition: json.hpp:89
static auto from_json(BasicJsonType &&j, TargetType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), val), void())
convert a JSON value to any value type
Definition: json.hpp:4940
static auto from_json(BasicJsonType &&j) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))
convert a JSON value to any value type
Definition: json.hpp:4960
static auto to_json(BasicJsonType &j, TargetType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< TargetType >(val)))) -> decltype(::nlohmann::to_json(j, std::forward< TargetType >(val)), void())
convert any value type to a JSON value
Definition: json.hpp:4977
default JSONSerializer template argument
Definition: json.hpp:4927
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
virtual bool string(string_t &val)=0
a string was read
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:5821
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:5825
json_sax & operator=(const json_sax &)=default
virtual bool end_array()=0
the end of an array was read
virtual bool key(string_t &val)=0
an object key was read
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:5822
virtual bool binary(binary_t &val)=0
a binary string was read
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:5823
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
json_sax(json_sax &&) noexcept=default
virtual bool boolean(bool val)=0
a boolean value was read
json_sax(const json_sax &)=default
virtual bool end_object()=0
the end of an object was read
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
typename BasicJsonType::string_t string_t
Definition: json.hpp:5824
virtual bool number_float(number_float_t val, const string_t &s)=0
an floating-point number was read
virtual bool number_integer(number_integer_t val)=0
an integer number was read
SAX interface.
Definition: json.hpp:5820
std::pair< iterator, bool > insert(const value_type &value)
Definition: json.hpp:17432
ordered_map(std::initializer_list< T > init, const Allocator &alloc=Allocator())
Definition: json.hpp:17306
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.hpp:17294
iterator find(const Key &key)
Definition: json.hpp:17403
iterator erase(iterator pos)
Definition: json.hpp:17377
void insert(InputIt first, InputIt last)
Definition: json.hpp:17450
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition: json.hpp:17309
const_iterator find(const Key &key) const
Definition: json.hpp:17415
std::pair< iterator, bool > insert(value_type &&value)
Definition: json.hpp:17427
size_type erase(const Key &key)
Definition: json.hpp:17358
const T & operator[](const Key &key) const
Definition: json.hpp:17327
ordered_map(const Allocator &alloc=Allocator())
Definition: json.hpp:17302
typename std::enable_if< std::is_convertible< typename std::iterator_traits< InputIt >::iterator_category, std::input_iterator_tag >::value >::type require_input_iter
Definition: json.hpp:17447
const T & at(const Key &key) const
Definition: json.hpp:17345
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition: json.hpp:17304
T & at(const Key &key)
Definition: json.hpp:17332
T & operator[](const Key &key)
Definition: json.hpp:17322
size_type count(const Key &key) const
Definition: json.hpp:17391