30 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
31 #define INCLUDE_NLOHMANN_JSON_HPP_
33 #define NLOHMANN_JSON_VERSION_MAJOR 3
34 #define NLOHMANN_JSON_VERSION_MINOR 7
35 #define NLOHMANN_JSON_VERSION_PATCH 3
42 #include <initializer_list>
62 #include <forward_list>
67 #include <type_traits>
68 #include <unordered_map>
92 std::size_t chars_read_total = 0;
94 std::size_t chars_read_current_line = 0;
96 std::size_t lines_read = 0;
99 constexpr operator size_t()
const
101 return chars_read_total;
125 #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 11
)
126 #if defined(JSON_HEDLEY_VERSION)
127 #undef JSON_HEDLEY_VERSION
129 #define JSON_HEDLEY_VERSION 11
131 #if defined(JSON_HEDLEY_STRINGIFY_EX)
132 #undef JSON_HEDLEY_STRINGIFY_EX
134 #define JSON_HEDLEY_STRINGIFY_EX(x) #x
136 #if defined(JSON_HEDLEY_STRINGIFY)
137 #undef JSON_HEDLEY_STRINGIFY
139 #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
141 #if defined(JSON_HEDLEY_CONCAT_EX)
142 #undef JSON_HEDLEY_CONCAT_EX
144 #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
146 #if defined(JSON_HEDLEY_CONCAT)
147 #undef JSON_HEDLEY_CONCAT
149 #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
151 #if defined(JSON_HEDLEY_VERSION_ENCODE)
152 #undef JSON_HEDLEY_VERSION_ENCODE
154 #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000
) + ((minor) * 1000
) + (revision))
156 #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
157 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
159 #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000
)
161 #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
162 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
164 #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000
) / 1000
)
166 #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
167 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
169 #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000
)
171 #if defined(JSON_HEDLEY_GNUC_VERSION)
172 #undef JSON_HEDLEY_GNUC_VERSION
174 #if defined(__GNUC__
) && defined(__GNUC_PATCHLEVEL__
)
175 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__
, __GNUC_MINOR__
, __GNUC_PATCHLEVEL__
)
176 #elif defined(__GNUC__)
177 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0
)
180 #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
181 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
183 #if defined(JSON_HEDLEY_GNUC_VERSION
)
184 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
186 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0
)
189 #if defined(JSON_HEDLEY_MSVC_VERSION)
190 #undef JSON_HEDLEY_MSVC_VERSION
192 #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000
)
193 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000
, (_MSC_FULL_VER % 10000000
) / 100000
, (_MSC_FULL_VER % 100000
) / 100
)
194 #elif defined(_MSC_FULL_VER)
195 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000
, (_MSC_FULL_VER % 1000000
) / 10000
, (_MSC_FULL_VER % 10000
) / 10
)
196 #elif defined(_MSC_VER)
197 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100
, _MSC_VER % 100
, 0
)
200 #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
201 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
203 #if !defined(_MSC_VER)
204 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0
)
205 #elif defined(_MSC_VER) && (_MSC_VER >= 1400
)
206 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000
) + (minor * 100000
) + (patch)))
207 #elif defined(_MSC_VER) && (_MSC_VER >= 1200
)
208 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000
) + (minor * 10000
) + (patch)))
210 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100
) + (minor)))
213 #if defined(JSON_HEDLEY_INTEL_VERSION)
214 #undef JSON_HEDLEY_INTEL_VERSION
216 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE)
217 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100
, __INTEL_COMPILER % 100
, __INTEL_COMPILER_UPDATE)
218 #elif defined(__INTEL_COMPILER)
219 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100
, __INTEL_COMPILER % 100
, 0
)
222 #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
223 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
225 #if defined(JSON_HEDLEY_INTEL_VERSION)
226 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
228 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0
)
231 #if defined(JSON_HEDLEY_PGI_VERSION)
232 #undef JSON_HEDLEY_PGI_VERSION
234 #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
235 #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
238 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
239 #undef JSON_HEDLEY_PGI_VERSION_CHECK
241 #if defined(JSON_HEDLEY_PGI_VERSION)
242 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
244 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0
)
247 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
248 #undef JSON_HEDLEY_SUNPRO_VERSION
250 #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000
)
251 #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
)
252 #elif defined(__SUNPRO_C)
253 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8
) & 0xf
, (__SUNPRO_C >> 4
) & 0xf
, (__SUNPRO_C) & 0xf
)
254 #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000
)
255 #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
)
256 #elif defined(__SUNPRO_CC)
257 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8
) & 0xf
, (__SUNPRO_CC >> 4
) & 0xf
, (__SUNPRO_CC) & 0xf
)
260 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
261 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
263 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
264 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
266 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0
)
269 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
270 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
272 #if defined(__EMSCRIPTEN__)
273 #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
276 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
277 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
279 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
280 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
282 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0
)
285 #if defined(JSON_HEDLEY_ARM_VERSION)
286 #undef JSON_HEDLEY_ARM_VERSION
288 #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
289 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000
, (__ARMCOMPILER_VERSION % 1000000
) / 10000
, (__ARMCOMPILER_VERSION % 10000
) / 100
)
290 #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
291 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000
, (__ARMCC_VERSION % 1000000
) / 10000
, (__ARMCC_VERSION % 10000
) / 100
)
294 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
295 #undef JSON_HEDLEY_ARM_VERSION_CHECK
297 #if defined(JSON_HEDLEY_ARM_VERSION)
298 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
300 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0
)
303 #if defined(JSON_HEDLEY_IBM_VERSION)
304 #undef JSON_HEDLEY_IBM_VERSION
306 #if defined(__ibmxl__)
307 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
308 #elif defined(__xlC__) && defined(__xlC_ver__)
309 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8
, __xlC__ & 0xff
, (__xlC_ver__ >> 8
) & 0xff
)
310 #elif defined(__xlC__)
311 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8
, __xlC__ & 0xff
, 0
)
314 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
315 #undef JSON_HEDLEY_IBM_VERSION_CHECK
317 #if defined(JSON_HEDLEY_IBM_VERSION)
318 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
320 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0
)
323 #if defined(JSON_HEDLEY_TI_VERSION)
324 #undef JSON_HEDLEY_TI_VERSION
326 #if defined(__TI_COMPILER_VERSION__)
327 #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000
, (__TI_COMPILER_VERSION__ % 1000000
) / 1000
, (__TI_COMPILER_VERSION__ % 1000
))
330 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
331 #undef JSON_HEDLEY_TI_VERSION_CHECK
333 #if defined(JSON_HEDLEY_TI_VERSION)
334 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
336 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0
)
339 #if defined(JSON_HEDLEY_CRAY_VERSION)
340 #undef JSON_HEDLEY_CRAY_VERSION
343 #if defined(_RELEASE_PATCHLEVEL)
344 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
346 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0
)
350 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
351 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
353 #if defined(JSON_HEDLEY_CRAY_VERSION)
354 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
356 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0
)
359 #if defined(JSON_HEDLEY_IAR_VERSION)
360 #undef JSON_HEDLEY_IAR_VERSION
362 #if defined(__IAR_SYSTEMS_ICC__)
364 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000
), ((__VER__ / 1000
) % 1000
), (__VER__ % 1000
))
366 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(VER / 100
, __VER__ % 100
, 0
)
370 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
371 #undef JSON_HEDLEY_IAR_VERSION_CHECK
373 #if defined(JSON_HEDLEY_IAR_VERSION)
374 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
376 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0
)
379 #if defined(JSON_HEDLEY_TINYC_VERSION)
380 #undef JSON_HEDLEY_TINYC_VERSION
382 #if defined(__TINYC__)
383 #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000
, (__TINYC__ / 100
) % 10
, __TINYC__ % 100
)
386 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
387 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
389 #if defined(JSON_HEDLEY_TINYC_VERSION)
390 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
392 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0
)
395 #if defined(JSON_HEDLEY_DMC_VERSION)
396 #undef JSON_HEDLEY_DMC_VERSION
399 #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8
, (__DMC__ >> 4
) & 0xf
, __DMC__ & 0xf
)
402 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
403 #undef JSON_HEDLEY_DMC_VERSION_CHECK
405 #if defined(JSON_HEDLEY_DMC_VERSION)
406 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
408 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0
)
411 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
412 #undef JSON_HEDLEY_COMPCERT_VERSION
414 #if defined(__COMPCERT_VERSION__)
415 #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000
, (__COMPCERT_VERSION__ / 100
) % 100
, __COMPCERT_VERSION__ % 100
)
418 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
419 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
421 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
422 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
424 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0
)
427 #if defined(JSON_HEDLEY_PELLES_VERSION)
428 #undef JSON_HEDLEY_PELLES_VERSION
430 #if defined(__POCC__)
431 #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100
, __POCC__ % 100
, 0
)
434 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
435 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
437 #if defined(JSON_HEDLEY_PELLES_VERSION)
438 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
440 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0
)
443 #if defined(JSON_HEDLEY_GCC_VERSION)
444 #undef JSON_HEDLEY_GCC_VERSION
447 defined(JSON_HEDLEY_GNUC_VERSION
) &&
448 !defined(__clang__
) &&
449 !defined(JSON_HEDLEY_INTEL_VERSION) &&
450 !defined(JSON_HEDLEY_PGI_VERSION) &&
451 !defined(JSON_HEDLEY_ARM_VERSION) &&
452 !defined(JSON_HEDLEY_TI_VERSION) &&
453 !defined(__COMPCERT__)
454 #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
457 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
458 #undef JSON_HEDLEY_GCC_VERSION_CHECK
460 #if defined(JSON_HEDLEY_GCC_VERSION)
461 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
463 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0
)
466 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
467 #undef JSON_HEDLEY_HAS_ATTRIBUTE
469 #if defined(__has_attribute
)
470 #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
472 #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0
)
475 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
476 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
478 #if defined(__has_attribute
)
479 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
481 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
484 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
485 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
487 #if defined(__has_attribute
)
488 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
490 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
493 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
494 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
497 defined(__has_cpp_attribute
) &&
498 defined(__cplusplus
) &&
500 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
502 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0
)
505 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
506 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
508 #if !defined(__cplusplus
) || !defined(__has_cpp_attribute
)
509 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0
)
511 !defined(JSON_HEDLEY_PGI_VERSION) &&
514 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
516 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0
)
519 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
520 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
522 #if defined(__has_cpp_attribute
) && defined(__cplusplus
)
523 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
525 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
528 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
529 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
531 #if defined(__has_cpp_attribute
) && defined(__cplusplus
)
532 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
534 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
537 #if defined(JSON_HEDLEY_HAS_BUILTIN)
538 #undef JSON_HEDLEY_HAS_BUILTIN
540 #if defined(__has_builtin
)
541 #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
543 #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0
)
546 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
547 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
549 #if defined(__has_builtin
)
550 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
552 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
555 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
556 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
558 #if defined(__has_builtin
)
559 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
561 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
564 #if defined(JSON_HEDLEY_HAS_FEATURE)
565 #undef JSON_HEDLEY_HAS_FEATURE
567 #if defined(__has_feature
)
568 #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
570 #define JSON_HEDLEY_HAS_FEATURE(feature) (0
)
573 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
574 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
576 #if defined(__has_feature
)
577 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
579 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
582 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
583 #undef JSON_HEDLEY_GCC_HAS_FEATURE
585 #if defined(__has_feature
)
586 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
588 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
591 #if defined(JSON_HEDLEY_HAS_EXTENSION)
592 #undef JSON_HEDLEY_HAS_EXTENSION
594 #if defined(__has_extension
)
595 #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
597 #define JSON_HEDLEY_HAS_EXTENSION(extension) (0
)
600 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
601 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
603 #if defined(__has_extension
)
604 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
606 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
609 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
610 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
612 #if defined(__has_extension
)
613 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
615 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
618 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
619 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
621 #if defined(__has_declspec_attribute
)
622 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
624 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0
)
627 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
628 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
630 #if defined(__has_declspec_attribute
)
631 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
633 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
636 #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
637 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
639 #if defined(__has_declspec_attribute
)
640 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
642 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
645 #if defined(JSON_HEDLEY_HAS_WARNING)
646 #undef JSON_HEDLEY_HAS_WARNING
648 #if defined(__has_warning
)
649 #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
651 #define JSON_HEDLEY_HAS_WARNING(warning) (0
)
654 #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
655 #undef JSON_HEDLEY_GNUC_HAS_WARNING
657 #if defined(__has_warning
)
658 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
660 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
663 #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
664 #undef JSON_HEDLEY_GCC_HAS_WARNING
666 #if defined(__has_warning
)
667 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
669 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
674 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
675 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
678 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr)
679 JSON_HEDLEY_DIAGNOSTIC_PUSH
680 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"")
682 JSON_HEDLEY_DIAGNOSTIC_POP
684 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
688 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L
)) ||
689 defined(__clang__
) ||
700 #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
701 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15
,0
,0
)
702 #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
704 #define JSON_HEDLEY_PRAGMA(value)
707 #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
708 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
710 #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
711 #undef JSON_HEDLEY_DIAGNOSTIC_POP
713 #if defined(__clang__
)
714 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
715 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
716 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13
,0
,0
)
717 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
718 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
719 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4
,6
,0
)
720 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
721 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
722 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15
,0
,0
)
723 #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
724 #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
725 #elif JSON_HEDLEY_ARM_VERSION_CHECK(5
,6
,0
)
726 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
727 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
728 #elif JSON_HEDLEY_TI_VERSION_CHECK(8
,1
,0
)
729 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
730 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
731 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2
,90
,0
)
732 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
733 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
735 #define JSON_HEDLEY_DIAGNOSTIC_PUSH
736 #define JSON_HEDLEY_DIAGNOSTIC_POP
739 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
740 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
743 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
744 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13
,0
,0
)
745 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
746 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17
,10
,0
)
747 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
748 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4
,3
,0
)
749 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
750 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15
,0
,0
)
751 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996
))
752 #elif JSON_HEDLEY_TI_VERSION_CHECK(8
,0
,0
)
753 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
754 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5
,13
,0
) && !defined(__cplusplus)
755 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
756 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5
,13
,0
) && defined(__cplusplus)
757 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
758 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8
,0
,0
)
759 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
760 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2
,90
,0
)
761 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
763 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
766 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
767 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
770 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
771 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13
,0
,0
)
772 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
773 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17
,10
,0
)
774 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
775 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4
,3
,0
)
776 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
777 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15
,0
,0
)
778 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068
))
779 #elif JSON_HEDLEY_TI_VERSION_CHECK(8
,0
,0
)
780 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
781 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8
,0
,0
)
782 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
784 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
787 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
788 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
791 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
792 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4
,6
,0
)
793 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
794 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17
,0
,0
)
795 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
796 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19
,0
,0
)
797 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030
))
798 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17
,10
,0
)
799 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
800 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5
,14
,0
) && defined(__cplusplus)
801 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
802 #elif JSON_HEDLEY_TI_VERSION_CHECK(8
,0
,0
)
803 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
805 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
808 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
809 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
812 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
813 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13
,0
,0
)
814 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
815 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3
,0
,0
)
816 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
818 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
821 #if defined(JSON_HEDLEY_DEPRECATED)
822 #undef JSON_HEDLEY_DEPRECATED
824 #if defined(JSON_HEDLEY_DEPRECATED_FOR)
825 #undef JSON_HEDLEY_DEPRECATED_FOR
827 #if defined(__cplusplus
) && (__cplusplus
>= 201402L
)
828 #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
829 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
838 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
839 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
841 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) ||
842 JSON_HEDLEY_GCC_VERSION_CHECK(3
,1
,0
) ||
843 JSON_HEDLEY_ARM_VERSION_CHECK(4
,1
,0
) ||
844 JSON_HEDLEY_TI_VERSION_CHECK(8
,0
,0
) ||
845 (JSON_HEDLEY_TI_VERSION_CHECK(7
,3
,0
) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
846 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
847 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
848 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(14
,0
,0
)
849 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
850 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
852 JSON_HEDLEY_MSVC_VERSION_CHECK(13
,10
,0
) ||
853 JSON_HEDLEY_PELLES_VERSION_CHECK(6
,50
,0
)
854 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
855 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
856 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8
,0
,0
)
857 #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
858 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
860 #define JSON_HEDLEY_DEPRECATED(since)
861 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
864 #if defined(JSON_HEDLEY_UNAVAILABLE)
865 #undef JSON_HEDLEY_UNAVAILABLE
871 #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
873 #define JSON_HEDLEY_UNAVAILABLE(available_since)
879 #if defined(__cplusplus
) && (__cplusplus
>= 201703L
)
880 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
889 #define __attribute__((__warn_unused_result__))
890 #elif defined(_Check_return_)
891 #define _Check_return_
896 #if defined(JSON_HEDLEY_SENTINEL)
897 #undef JSON_HEDLEY_SENTINEL
904 #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
906 #define JSON_HEDLEY_SENTINEL(position)
909 #if defined(JSON_HEDLEY_NO_RETURN)
910 #undef JSON_HEDLEY_NO_RETURN
913 #define JSON_HEDLEY_NO_RETURN __noreturn
915 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
916 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
917 #define JSON_HEDLEY_NO_RETURN _Noreturn
918 #elif defined(__cplusplus
) && (__cplusplus
>= 201103L
)
919 #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
921 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) ||
922 JSON_HEDLEY_GCC_VERSION_CHECK(3
,2
,0
) ||
923 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5
,11
,0
) ||
924 JSON_HEDLEY_ARM_VERSION_CHECK(4
,1
,0
) ||
925 JSON_HEDLEY_IBM_VERSION_CHECK(10
,1
,0
) ||
926 JSON_HEDLEY_TI_VERSION_CHECK(18
,0
,0
) ||
927 (JSON_HEDLEY_TI_VERSION_CHECK(17
,3
,0
) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
928 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
929 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5
,10
,0
)
930 #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
931 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13
,10
,0
)
932 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
933 #elif JSON_HEDLEY_TI_VERSION_CHECK(6
,0
,0
) && defined(__cplusplus)
934 #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
935 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3
,2
,0
)
936 #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
937 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9
,0
,0
)
938 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
940 #define JSON_HEDLEY_NO_RETURN
943 #if defined(JSON_HEDLEY_NO_ESCAPE)
944 #undef JSON_HEDLEY_NO_ESCAPE
947 #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
949 #define JSON_HEDLEY_NO_ESCAPE
952 #if defined(JSON_HEDLEY_UNREACHABLE)
953 #undef JSON_HEDLEY_UNREACHABLE
955 #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
956 #undef JSON_HEDLEY_UNREACHABLE_RETURN
963 #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
964 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13
,10
,0
)
965 #define JSON_HEDLEY_UNREACHABLE() __assume(0
)
966 #elif JSON_HEDLEY_TI_VERSION_CHECK(6
,0
,0
)
967 #if defined(__cplusplus)
968 #define JSON_HEDLEY_UNREACHABLE() std::_nassert(0
)
970 #define JSON_HEDLEY_UNREACHABLE() _nassert(0
)
972 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return value
973 #elif defined(EXIT_FAILURE)
974 #define JSON_HEDLEY_UNREACHABLE() abort()
976 #define JSON_HEDLEY_UNREACHABLE()
977 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return value
979 #if !defined(JSON_HEDLEY_UNREACHABLE_RETURN)
980 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
983 #if defined(JSON_HEDLEY_ASSUME)
984 #undef JSON_HEDLEY_ASSUME
989 #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
991 #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
992 #elif JSON_HEDLEY_TI_VERSION_CHECK(6
,0
,0
)
993 #if defined(__cplusplus)
994 #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
996 #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
999 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && !defined(JSON_HEDLEY_ARM_VERSION)) ||
1000 JSON_HEDLEY_GCC_VERSION_CHECK(4
,5
,0
) ||
1001 JSON_HEDLEY_INTEL_VERSION_CHECK(13
,0
,0
) ||
1002 JSON_HEDLEY_IBM_VERSION_CHECK(13
,1
,5
)
1003 #define JSON_HEDLEY_ASSUME(expr) ((void) ((expr) ? 1
: (__builtin_unreachable(), 1
)))
1005 #define JSON_HEDLEY_ASSUME(expr) ((void) (expr))
1010 #pragma clang diagnostic ignored "-Wpedantic"
1013 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1016 #if defined(__clang__
)
1017 #pragma clang diagnostic ignored "-Wvariadic-macros"
1018 #elif defined(JSON_HEDLEY_GCC_VERSION)
1019 #pragma GCC diagnostic ignored "-Wvariadic-macros"
1022 #if defined(JSON_HEDLEY_NON_NULL)
1023 #undef JSON_HEDLEY_NON_NULL
1030 #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1032 #define JSON_HEDLEY_NON_NULL(...)
1036 #if defined(JSON_HEDLEY_PRINTF_FORMAT)
1037 #undef JSON_HEDLEY_PRINTF_FORMAT
1040 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1042 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1051 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1052 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6
,0
,0
)
1053 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1055 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1058 #if defined(JSON_HEDLEY_CONSTEXPR)
1059 #undef JSON_HEDLEY_CONSTEXPR
1061 #if defined(__cplusplus
)
1062 #if __cplusplus
>= 201103L
1063 #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1067 #define JSON_HEDLEY_CONSTEXPR
1070 #if defined(JSON_HEDLEY_PREDICT)
1071 #undef JSON_HEDLEY_PREDICT
1073 #if defined(JSON_HEDLEY_LIKELY)
1074 #undef JSON_HEDLEY_LIKELY
1076 #if defined(JSON_HEDLEY_UNLIKELY)
1077 #undef JSON_HEDLEY_UNLIKELY
1079 #if defined(JSON_HEDLEY_UNPREDICTABLE)
1080 #undef JSON_HEDLEY_UNPREDICTABLE
1083 #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable(!!(expr))
1088 # define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability(expr, value, probability)
1089 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1
, probability)
1090 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0
, probability)
1091 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1
)
1092 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0
)
1093 #if !defined(JSON_HEDLEY_BUILTIN_UNPREDICTABLE)
1094 #define JSON_HEDLEY_BUILTIN_UNPREDICTABLE(expr) __builtin_expect_with_probability(!!(expr), 1
, 0.5
)
1105 # define JSON_HEDLEY_PREDICT(expr, expected, probability)
1106 (((probability) >= 0.9
) ? __builtin_expect(!!(expr), (expected)) : (((void) (expected)), !!(expr)))
1107 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability)
1109 JSON_HEDLEY_CONSTEXPR double hedley_probability_ = (probability);
1110 ((hedley_probability_ >= 0.9
) ? __builtin_expect(!!(expr), 1
) : ((hedley_probability_ <= 0.1
) ? __builtin_expect(!!(expr), 0
) : !!(expr)));
1112 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability)
1114 JSON_HEDLEY_CONSTEXPR double hedley_probability_ = (probability);
1115 ((hedley_probability_ >= 0.9
) ? __builtin_expect(!!(expr), 0
) : ((hedley_probability_ <= 0.1
) ? __builtin_expect(!!(expr), 1
) : !!(expr)));
1117 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1
)
1118 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0
)
1120 # define JSON_HEDLEY_PREDICT(expr, expected, probability) (((void) (expected)), !!(expr))
1121 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1122 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1123 # define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1124 # define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1127 #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1
, 0.5
)
1130 #if defined(JSON_HEDLEY_MALLOC)
1131 #undef JSON_HEDLEY_MALLOC
1142 #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1143 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5
,10
,0
)
1144 #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1145 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(14
, 0
, 0
)
1146 #define JSON_HEDLEY_MALLOC __declspec(restrict)
1148 #define JSON_HEDLEY_MALLOC
1151 #if defined(JSON_HEDLEY_PURE)
1152 #undef JSON_HEDLEY_PURE
1164 #define JSON_HEDLEY_PURE __attribute__((__pure__))
1165 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5
,10
,0
)
1166 #define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1167 #elif JSON_HEDLEY_TI_VERSION_CHECK(6
,0
,0
) && defined(__cplusplus)
1168 #define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1170 #define JSON_HEDLEY_PURE
1173 #if defined(JSON_HEDLEY_CONST)
1174 #undef JSON_HEDLEY_CONST
1186 #define JSON_HEDLEY_CONST __attribute__((__const__))
1188 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5
,10
,0
)
1189 #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1191 #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1194 #if defined(JSON_HEDLEY_RESTRICT)
1195 #undef JSON_HEDLEY_RESTRICT
1197 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L
) && !defined(__cplusplus
)
1198 #define JSON_HEDLEY_RESTRICT restrict
1210 #define JSON_HEDLEY_RESTRICT __restrict
1211 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5
,3
,0
) && !defined(__cplusplus)
1212 #define JSON_HEDLEY_RESTRICT _Restrict
1214 #define JSON_HEDLEY_RESTRICT
1217 #if defined(JSON_HEDLEY_INLINE)
1218 #undef JSON_HEDLEY_INLINE
1221 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L
)) ||
1222 (defined(__cplusplus
) && (__cplusplus
>= 199711L
))
1223 #define JSON_HEDLEY_INLINE inline
1225 defined(JSON_HEDLEY_GCC_VERSION) ||
1226 JSON_HEDLEY_ARM_VERSION_CHECK(6
,2
,0
)
1227 #define JSON_HEDLEY_INLINE __inline__
1229 JSON_HEDLEY_MSVC_VERSION_CHECK(12
,0
,0
) ||
1230 JSON_HEDLEY_ARM_VERSION_CHECK(4
,1
,0
) ||
1231 JSON_HEDLEY_TI_VERSION_CHECK(8
,0
,0
)
1232 #define JSON_HEDLEY_INLINE __inline
1234 #define JSON_HEDLEY_INLINE
1237 #if defined(JSON_HEDLEY_ALWAYS_INLINE)
1238 #undef JSON_HEDLEY_ALWAYS_INLINE
1249 #define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1250 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(12
,0
,0
)
1251 #define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1252 #elif JSON_HEDLEY_TI_VERSION_CHECK(7
,0
,0
) && defined(__cplusplus)
1253 #define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1254 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8
,0
,0
)
1255 #define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1257 #define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1260 #if defined(JSON_HEDLEY_NEVER_INLINE)
1261 #undef JSON_HEDLEY_NEVER_INLINE
1272 #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1273 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13
,10
,0
)
1274 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1275 #elif JSON_HEDLEY_PGI_VERSION_CHECK(10
,2
,0
)
1276 #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1277 #elif JSON_HEDLEY_TI_VERSION_CHECK(6
,0
,0
) && defined(__cplusplus)
1278 #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1279 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8
,0
,0
)
1280 #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1281 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3
,2
,0
)
1282 #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1283 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9
,0
,0
)
1284 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1286 #define JSON_HEDLEY_NEVER_INLINE
1289 #if defined(JSON_HEDLEY_PRIVATE)
1290 #undef JSON_HEDLEY_PRIVATE
1292 #if defined(JSON_HEDLEY_PUBLIC)
1293 #undef JSON_HEDLEY_PUBLIC
1295 #if defined(JSON_HEDLEY_IMPORT)
1296 #undef JSON_HEDLEY_IMPORT
1298 #if defined(_WIN32) || defined(__CYGWIN__)
1299 #define JSON_HEDLEY_PRIVATE
1300 #define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1301 #define JSON_HEDLEY_IMPORT __declspec(dllimport)
1312 #define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1313 #define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1315 #define JSON_HEDLEY_PRIVATE
1316 #define JSON_HEDLEY_PUBLIC
1318 #define JSON_HEDLEY_IMPORT extern
1321 #if defined(JSON_HEDLEY_NO_THROW)
1322 #undef JSON_HEDLEY_NO_THROW
1328 #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1330 JSON_HEDLEY_MSVC_VERSION_CHECK(13
,1
,0
) ||
1331 JSON_HEDLEY_ARM_VERSION_CHECK(4
,1
,0
)
1332 #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1334 #define JSON_HEDLEY_NO_THROW
1337 #if defined(JSON_HEDLEY_FALL_THROUGH)
1338 #undef JSON_HEDLEY_FALL_THROUGH
1341 #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1342 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1343 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1344 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1345 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1346 #elif defined(__fallthrough)
1347 #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1349 #define JSON_HEDLEY_FALL_THROUGH
1358 #define __attribute__((__returns_nonnull__))
1359 #elif defined(_Ret_notnull_)
1360 #define _Ret_notnull_
1365 #if defined(JSON_HEDLEY_ARRAY_PARAM)
1366 #undef JSON_HEDLEY_ARRAY_PARAM
1369 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L
) &&
1370 !defined(__STDC_NO_VLA__) &&
1371 !defined(__cplusplus
) &&
1372 !defined(JSON_HEDLEY_PGI_VERSION) &&
1373 !defined(JSON_HEDLEY_TINYC_VERSION)
1374 #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1376 #define JSON_HEDLEY_ARRAY_PARAM(name)
1379 #if defined(JSON_HEDLEY_IS_CONSTANT)
1380 #undef JSON_HEDLEY_IS_CONSTANT
1382 #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1383 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1387 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1388 #undef JSON_HEDLEY_IS_CONSTEXPR_
1400 #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1402 #if !defined(__cplusplus
)
1404 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) ||
1405 JSON_HEDLEY_GCC_VERSION_CHECK(3
,4
,0
) ||
1406 JSON_HEDLEY_INTEL_VERSION_CHECK(13
,0
,0
) ||
1407 JSON_HEDLEY_IBM_VERSION_CHECK(13
,1
,0
) ||
1408 JSON_HEDLEY_CRAY_VERSION_CHECK(8
,1
,0
) ||
1409 JSON_HEDLEY_ARM_VERSION_CHECK(5
,4
,0
) ||
1410 JSON_HEDLEY_TINYC_VERSION_CHECK(0
,9
,24
)
1411 #if defined(__INTPTR_TYPE__)
1412 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1
? (void*) ((__INTPTR_TYPE__) ((expr) * 0
)) : (int*) 0
)), int*)
1415 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1
? (void*) ((intptr_t) ((expr) * 0
)) : (int*) 0
)), int*)
1418 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L
) && !defined(JSON_HEDLEY_SUNPRO_VERSION) && !defined(JSON_HEDLEY_PGI_VERSION)) ||
1419 JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) ||
1420 JSON_HEDLEY_GCC_VERSION_CHECK(4
,9
,0
) ||
1421 JSON_HEDLEY_INTEL_VERSION_CHECK(17
,0
,0
) ||
1422 JSON_HEDLEY_IBM_VERSION_CHECK(12
,1
,0
) ||
1423 JSON_HEDLEY_ARM_VERSION_CHECK(5
,3
,0
)
1424 #if defined(__INTPTR_TYPE__)
1425 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1
? (void*) ((__INTPTR_TYPE__) ((expr) * 0
)) : (int*) 0
), int*: 1
, void*: 0
)
1428 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1
? (void*) ((intptr_t) * 0
) : (int*) 0
), int*: 1
, void*: 0
)
1431 defined(JSON_HEDLEY_GCC_VERSION) ||
1432 defined(JSON_HEDLEY_INTEL_VERSION) ||
1433 defined(JSON_HEDLEY_TINYC_VERSION) ||
1434 defined(JSON_HEDLEY_TI_VERSION) ||
1436 # define JSON_HEDLEY_IS_CONSTEXPR_(expr) (
1440 ((void*) ((expr) * 0L
) ) : \
1441 ((struct{ char v[sizeof(void) * 2
]; } *) 1
)
1447 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1448 #if !defined(JSON_HEDLEY_IS_CONSTANT)
1449 #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1451 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1
))
1454 #define JSON_HEDLEY_IS_CONSTANT(expr) (0
)
1456 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
1459 #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
1460 #undef JSON_HEDLEY_BEGIN_C_DECLS
1462 #if defined(JSON_HEDLEY_END_C_DECLS)
1463 #undef JSON_HEDLEY_END_C_DECLS
1465 #if defined(JSON_HEDLEY_C_DECL)
1466 #undef JSON_HEDLEY_C_DECL
1468 #if defined(__cplusplus
)
1469 #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
1470 #define JSON_HEDLEY_END_C_DECLS }
1471 #define JSON_HEDLEY_C_DECL extern "C"
1473 #define JSON_HEDLEY_BEGIN_C_DECLS
1474 #define JSON_HEDLEY_END_C_DECLS
1475 #define JSON_HEDLEY_C_DECL
1478 #if defined(JSON_HEDLEY_STATIC_ASSERT)
1479 #undef JSON_HEDLEY_STATIC_ASSERT
1482 !defined(__cplusplus
) && (
1483 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L
)) ||
1487 defined(_Static_assert)
1489 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
1491 (defined(__cplusplus
) && (__cplusplus
>= 201103L
)) ||
1494 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
1496 # define JSON_HEDLEY_STATIC_ASSERT(expr, message)
1499 #if defined(JSON_HEDLEY_CONST_CAST)
1500 #undef JSON_HEDLEY_CONST_CAST
1502 #if defined(__cplusplus
)
1503 # define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1505 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") ||
1506 JSON_HEDLEY_GCC_VERSION_CHECK(4
,6
,0
) ||
1507 JSON_HEDLEY_INTEL_VERSION_CHECK(13
,0
,0
)
1508 # define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({
1509 JSON_HEDLEY_DIAGNOSTIC_PUSH
1510 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1512 JSON_HEDLEY_DIAGNOSTIC_POP
1515 # define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1518 #if defined(JSON_HEDLEY_REINTERPRET_CAST)
1519 #undef JSON_HEDLEY_REINTERPRET_CAST
1521 #if defined(__cplusplus
)
1522 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1524 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (*((T*) &(expr)))
1527 #if defined(JSON_HEDLEY_STATIC_CAST)
1528 #undef JSON_HEDLEY_STATIC_CAST
1530 #if defined(__cplusplus
)
1531 #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1533 #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1536 #if defined(JSON_HEDLEY_CPP_CAST)
1537 #undef JSON_HEDLEY_CPP_CAST
1539 #if defined(__cplusplus
)
1540 #define JSON_HEDLEY_CPP_CAST(T, expr) static_cast<T>(expr)
1542 #define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1545 #if defined(JSON_HEDLEY_NULL)
1546 #undef JSON_HEDLEY_NULL
1548 #if defined(__cplusplus
)
1549 #if __cplusplus
>= 201103L
1550 #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
1552 #define JSON_HEDLEY_NULL NULL
1554 #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0
)
1557 #define JSON_HEDLEY_NULL NULL
1559 #define JSON_HEDLEY_NULL ((void*) 0
)
1562 #if defined(JSON_HEDLEY_MESSAGE)
1563 #undef JSON_HEDLEY_MESSAGE
1566 # define JSON_HEDLEY_MESSAGE(msg)
1567 JSON_HEDLEY_DIAGNOSTIC_PUSH
1568 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1570 JSON_HEDLEY_DIAGNOSTIC_POP
1572 JSON_HEDLEY_GCC_VERSION_CHECK(4
,4
,0
) ||
1573 JSON_HEDLEY_INTEL_VERSION_CHECK(13
,0
,0
)
1574 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
1575 #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5
,0
,0
)
1576 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
1577 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8
,0
,0
)
1578 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1579 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2
,0
,0
)
1580 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1582 # define JSON_HEDLEY_MESSAGE(msg)
1585 #if defined(JSON_HEDLEY_WARNING)
1586 #undef JSON_HEDLEY_WARNING
1589 # define JSON_HEDLEY_WARNING(msg)
1590 JSON_HEDLEY_DIAGNOSTIC_PUSH
1591 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1593 JSON_HEDLEY_DIAGNOSTIC_POP
1595 JSON_HEDLEY_GCC_VERSION_CHECK(4
,8
,0
) ||
1596 JSON_HEDLEY_PGI_VERSION_CHECK(18
,4
,0
)
1597 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
1598 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15
,0
,0
)
1599 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
1601 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
1604 #if defined(JSON_HEDLEY_REQUIRE)
1605 #undef JSON_HEDLEY_REQUIRE
1607 #if defined(JSON_HEDLEY_REQUIRE_MSG)
1608 #undef JSON_HEDLEY_REQUIRE_MSG
1612 # define JSON_HEDLEY_REQUIRE(expr)
1613 JSON_HEDLEY_DIAGNOSTIC_PUSH
1614 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"")
1615 __attribute__((diagnose_if(!(expr), #expr, "error")))
1616 JSON_HEDLEY_DIAGNOSTIC_POP
1617 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
1618 JSON_HEDLEY_DIAGNOSTIC_PUSH
1619 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"")
1620 __attribute__((diagnose_if(!(expr), msg, "error")))
1621 JSON_HEDLEY_DIAGNOSTIC_POP
1623 # define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
1624 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
1627 # define JSON_HEDLEY_REQUIRE(expr)
1628 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
1631 #if defined(JSON_HEDLEY_FLAGS)
1632 #undef JSON_HEDLEY_FLAGS
1635 #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
1638 #if defined(JSON_HEDLEY_FLAGS_CAST)
1639 #undef JSON_HEDLEY_FLAGS_CAST
1642 # define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({
1643 JSON_HEDLEY_DIAGNOSTIC_PUSH
1644 _Pragma("warning(disable:188)")
1646 JSON_HEDLEY_DIAGNOSTIC_POP
1649 # define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
1652 #if defined(JSON_HEDLEY_EMPTY_BASES)
1653 #undef JSON_HEDLEY_EMPTY_BASES
1656 #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
1658 #define JSON_HEDLEY_EMPTY_BASES
1663 #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
1664 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
1666 #if defined(__clang__
)
1667 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0
)
1669 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1672 #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
1673 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
1675 #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
1677 #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
1678 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
1680 #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
1682 #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
1683 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
1685 #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
1687 #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
1688 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
1690 #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
1692 #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
1693 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
1695 #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
1697 #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
1698 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
1700 #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
1702 #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
1703 #undef JSON_HEDLEY_CLANG_HAS_WARNING
1705 #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
1714 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
1715 #if defined(__clang__
)
1716 #if (__clang_major__
* 10000
+ __clang_minor__
* 100
+ __clang_patchlevel__
) < 30400
1717 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
1719 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
1720 #if (__GNUC__ * 10000
+ __GNUC_MINOR__ * 100
+ __GNUC_PATCHLEVEL__) < 40800
1721 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
1727 #if (defined(__cplusplus
) && __cplusplus
>= 201703L
) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1
)
1728 #define JSON_HAS_CPP_17
1729 #define JSON_HAS_CPP_14
1730 #elif (defined(__cplusplus
) && __cplusplus
>= 201402L
) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1
)
1731 #define JSON_HAS_CPP_14
1735 #if defined(__clang__
) || defined(__GNUC__
) || defined(__GNUG__
)
1736 #pragma GCC diagnostic push
1737 #pragma GCC diagnostic ignored "-Wfloat-equal"
1741 #if defined(__clang__
)
1742 #pragma GCC diagnostic push
1743 #pragma GCC diagnostic ignored "-Wdocumentation"
1747 #if (defined(__cpp_exceptions
) || defined(__EXCEPTIONS
) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
1748 #define JSON_THROW(exception) throw exception
1749 #define JSON_TRY try
1750 #define JSON_CATCH(exception) catch(exception)
1751 #define JSON_INTERNAL_CATCH(exception) catch(exception)
1754 #define JSON_THROW(exception) std::abort()
1755 #define JSON_TRY if(true)
1756 #define JSON_CATCH(exception) if(false)
1757 #define JSON_INTERNAL_CATCH(exception) if(false)
1761 #if defined(JSON_THROW_USER)
1763 #define JSON_THROW JSON_THROW_USER
1765 #if defined(JSON_TRY_USER)
1767 #define JSON_TRY JSON_TRY_USER
1769 #if defined(JSON_CATCH_USER)
1771 #define JSON_CATCH JSON_CATCH_USER
1772 #undef JSON_INTERNAL_CATCH
1773 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
1775 #if defined(JSON_INTERNAL_CATCH_USER)
1776 #undef JSON_INTERNAL_CATCH
1777 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
1785 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...)
1786 template<typename BasicJsonType>
1787 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e)
1789 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");
1790 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;
1791 auto it = std::find_if(std::begin(m), std::end(m),
1792 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool
1794 return ej_pair.first == e;
1796 j = ((it != std::end(m)) ? it : std::begin(m))->second;
1798 template<typename BasicJsonType>
1799 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e)
1801 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");
1802 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;
1803 auto it = std::find_if(std::begin(m), std::end(m),
1804 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool
1806 return ej_pair.second == j;
1808 e = ((it != std::end(m)) ? it : std::begin(m))->first;
1814 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION
1815 template<template<typename, typename, typename...> class ObjectType,
1816 template<typename, typename...> class ArrayType,
1817 class StringType, class BooleanType, class NumberIntegerType,
1818 class NumberUnsignedType, class NumberFloatType,
1819 template<typename> class AllocatorType,
1820 template<typename, typename = void> class JSONSerializer>
1822 #define NLOHMANN_BASIC_JSON_TPL
1823 basic_json<ObjectType, ArrayType, StringType, BooleanType,
1824 NumberIntegerType, NumberUnsignedType, NumberFloatType,
1825 AllocatorType, JSONSerializer>
1864 class exception :
public std::exception
1869 const char* what()
const noexcept override
1879 exception(
int id_,
const char* what_arg) : id(id_), m(what_arg) {}
1881 static std::string name(
const std::string& ename,
int id_)
1883 return "[json.exception." + ename +
"." + std::to_string(id_) +
"] ";
1888 std::runtime_error m;
1935 class parse_error :
public exception
1947 static parse_error create(
int id_,
const position_t& pos,
const std::string& what_arg)
1949 std::string w = exception::name(
"parse_error", id_) +
"parse error" +
1950 position_string(pos) +
": " + what_arg;
1951 return parse_error(id_, pos.chars_read_total, w.c_str());
1954 static parse_error create(
int id_, std::size_t byte_,
const std::string& what_arg)
1956 std::string w = exception::name(
"parse_error", id_) +
"parse error" +
1957 (byte_ != 0 ? (
" at byte " + std::to_string(byte_)) :
"") +
1959 return parse_error(id_, byte_, w.c_str());
1971 const std::size_t byte;
1974 parse_error(
int id_, std::size_t byte_,
const char* what_arg)
1975 : exception(id_, what_arg), byte(byte_) {}
1977 static std::string position_string(
const position_t& pos)
1979 return " at line " + std::to_string(pos.lines_read + 1) +
1980 ", column " + std::to_string(pos.chars_read_current_line);
2021 class invalid_iterator :
public exception
2024 static invalid_iterator create(
int id_,
const std::string& what_arg)
2026 std::string w = exception::name(
"invalid_iterator", id_) + what_arg;
2027 return invalid_iterator(id_, w.c_str());
2032 invalid_iterator(
int id_,
const char* what_arg)
2033 : exception(id_, what_arg) {}
2075 class type_error :
public exception
2078 static type_error create(
int id_,
const std::string& what_arg)
2080 std::string w = exception::name(
"type_error", id_) + what_arg;
2081 return type_error(id_, w.c_str());
2086 type_error(
int id_,
const char* what_arg) : exception(id_, what_arg) {}
2122 class out_of_range :
public exception
2125 static out_of_range create(
int id_,
const std::string& what_arg)
2127 std::string w = exception::name(
"out_of_range", id_) + what_arg;
2128 return out_of_range(id_, w.c_str());
2133 out_of_range(
int id_,
const char* what_arg) : exception(id_, what_arg) {}
2160 class other_error :
public exception
2163 static other_error create(
int id_,
const std::string& what_arg)
2165 std::string w = exception::name(
"other_error", id_) + what_arg;
2166 return other_error(id_, w.c_str());
2171 other_error(
int id_,
const char* what_arg) : exception(id_, what_arg) {}
2183 #include <type_traits>
2190 template<
bool B,
typename T =
void>
2191 using enable_if_t =
typename std::enable_if<B, T>::type;
2193 template<
typename T>
2194 using uncvref_t =
typename std::remove_cv<
typename std::remove_reference<T>::type>::type;
2198 template<std::size_t... Ints>
2199 struct index_sequence
2201 using type = index_sequence;
2202 using value_type = std::size_t;
2203 static constexpr std::size_t size()
noexcept
2205 return sizeof...(Ints);
2209 template<
class Sequence1,
class Sequence2>
2210 struct merge_and_renumber;
2212 template<std::size_t... I1, std::size_t... I2>
2213 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
2214 : index_sequence < I1..., (
sizeof...(I1) + I2)... > {};
2216 template<std::size_t N>
2217 struct make_index_sequence
2218 : merge_and_renumber <
typename make_index_sequence < N / 2 >::type,
2219 typename make_index_sequence < N - N / 2 >::type > {};
2221 template<>
struct make_index_sequence<0> : index_sequence<> {};
2222 template<>
struct make_index_sequence<1> : index_sequence<0> {};
2224 template<
typename... Ts>
2225 using index_sequence_for = make_index_sequence<
sizeof...(Ts)>;
2228 template<
unsigned N>
struct priority_tag : priority_tag < N - 1 > {};
2229 template<>
struct priority_tag<0> {};
2232 template<
typename T>
2235 static constexpr T value{};
2238 template<
typename T>
2239 constexpr T static_const<T>::value;
2248 #include <type_traits>
2263 template <
typename ...Ts>
struct make_void
2267 template <
typename ...Ts>
using void_t =
typename make_void<Ts...>::type;
2278 template <
typename It,
typename =
void>
2279 struct iterator_types {};
2281 template <
typename It>
2282 struct iterator_types <
2284 void_t<
typename It::difference_type,
typename It::value_type,
typename It::pointer,
2285 typename It::reference,
typename It::iterator_category >>
2287 using difference_type =
typename It::difference_type;
2288 using value_type =
typename It::value_type;
2289 using pointer =
typename It::pointer;
2290 using reference =
typename It::reference;
2291 using iterator_category =
typename It::iterator_category;
2296 template <
typename T,
typename =
void>
2297 struct iterator_traits
2301 template <
typename T>
2302 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
2307 template <
typename T>
2308 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
2310 using iterator_category = std::random_access_iterator_tag;
2311 using value_type = T;
2312 using difference_type = ptrdiff_t;
2314 using reference = T&;
2326 #include <type_traits>
2338 nonesuch() =
delete;
2339 ~nonesuch() =
delete;
2340 nonesuch(nonesuch
const&) =
delete;
2341 nonesuch(nonesuch
const&&) =
delete;
2342 void operator=(nonesuch
const&) =
delete;
2343 void operator=(nonesuch&&) =
delete;
2346 template <
class Default,
2348 template <
class...>
class Op,
2352 using value_t = std::false_type;
2353 using type = Default;
2356 template <
class Default,
template <
class...>
class Op,
class... Args>
2357 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2359 using value_t = std::true_type;
2360 using type = Op<Args...>;
2363 template <
template <
class...>
class Op,
class... Args>
2364 using is_detected =
typename detector<nonesuch,
void, Op, Args...>::value_t;
2366 template <
template <
class...>
class Op,
class... Args>
2367 using detected_t =
typename detector<nonesuch,
void, Op, Args...>::type;
2369 template <
class Default,
template <
class...>
class Op,
class... Args>
2370 using detected_or = detector<Default,
void, Op, Args...>;
2372 template <
class Default,
template <
class...>
class Op,
class... Args>
2373 using detected_or_t =
typename detected_or<Default, Op, Args...>::type;
2375 template <
class Expected,
template <
class...>
class Op,
class... Args>
2376 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2378 template <
class To,
template <
class...>
class Op,
class... Args>
2379 using is_detected_convertible =
2380 std::is_convertible<detected_t<Op, Args...>, To>;
2385 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
2386 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
2408 template<
typename T =
void,
typename SFINAE =
void>
2409 struct adl_serializer;
2411 template<
template<
typename U,
typename V,
typename... Args>
class ObjectType =
2413 template<
typename U,
typename... Args>
class ArrayType = std::vector,
2414 class StringType = std::string,
class BooleanType =
bool,
2415 class NumberIntegerType = std::int64_t,
2416 class NumberUnsignedType = std::uint64_t,
2417 class NumberFloatType =
double,
2418 template<
typename U>
class AllocatorType = std::allocator,
2419 template<
typename T,
typename SFINAE =
void>
class JSONSerializer =
2434 template<
typename BasicJsonType>
2445 using json = basic_json<>;
2476 template<
typename>
struct is_basic_json : std::false_type {};
2485 template <
typename T>
2486 using mapped_type_t =
typename T::mapped_type;
2488 template <
typename T>
2489 using key_type_t =
typename T::key_type;
2491 template <
typename T>
2492 using value_type_t =
typename T::value_type;
2494 template <
typename T>
2495 using difference_type_t =
typename T::difference_type;
2497 template <
typename T>
2498 using pointer_t =
typename T::pointer;
2500 template <
typename T>
2501 using reference_t =
typename T::reference;
2503 template <
typename T>
2504 using iterator_category_t =
typename T::iterator_category;
2506 template <
typename T>
2507 using iterator_t =
typename T::iterator;
2509 template <
typename T,
typename... Args>
2510 using to_json_function =
decltype(T::to_json(std::declval<Args>()...));
2512 template <
typename T,
typename... Args>
2513 using from_json_function =
decltype(T::from_json(std::declval<Args>()...));
2515 template <
typename T,
typename U>
2516 using get_template_function =
decltype(std::declval<T>().
template get<U>());
2519 template <
typename BasicJsonType,
typename T,
typename =
void>
2520 struct has_from_json : std::false_type {};
2522 template <
typename BasicJsonType,
typename T>
2523 struct has_from_json<BasicJsonType, T,
2524 enable_if_t<
not is_basic_json<T>::value>>
2526 using serializer =
typename BasicJsonType::
template json_serializer<T,
void>;
2528 static constexpr bool value =
2529 is_detected_exact<
void, from_json_function, serializer,
2530 const BasicJsonType&, T&>::value;
2535 template <
typename BasicJsonType,
typename T,
typename =
void>
2536 struct has_non_default_from_json : std::false_type {};
2538 template<
typename BasicJsonType,
typename T>
2539 struct has_non_default_from_json<BasicJsonType, T, enable_if_t<
not is_basic_json<T>::value>>
2541 using serializer =
typename BasicJsonType::
template json_serializer<T,
void>;
2543 static constexpr bool value =
2544 is_detected_exact<T, from_json_function, serializer,
2545 const BasicJsonType&>::value;
2550 template <
typename BasicJsonType,
typename T,
typename =
void>
2551 struct has_to_json : std::false_type {};
2553 template <
typename BasicJsonType,
typename T>
2554 struct has_to_json<BasicJsonType, T, enable_if_t<
not is_basic_json<T>::value>>
2556 using serializer =
typename BasicJsonType::
template json_serializer<T,
void>;
2558 static constexpr bool value =
2559 is_detected_exact<
void, to_json_function, serializer, BasicJsonType&,
2568 template <
typename T,
typename =
void>
2569 struct is_iterator_traits : std::false_type {};
2571 template <
typename T>
2572 struct is_iterator_traits<iterator_traits<T>>
2575 using traits = iterator_traits<T>;
2578 static constexpr auto value =
2579 is_detected<value_type_t, traits>::value &&
2580 is_detected<difference_type_t, traits>::value &&
2581 is_detected<pointer_t, traits>::value &&
2582 is_detected<iterator_category_t, traits>::value &&
2583 is_detected<reference_t, traits>::value;
2588 template <
typename T,
typename =
void>
2589 struct is_complete_type : std::false_type {};
2591 template <
typename T>
2592 struct is_complete_type<T,
decltype(
void(
sizeof(T)))> : std::true_type {};
2594 template <
typename BasicJsonType,
typename CompatibleObjectType,
2596 struct is_compatible_object_type_impl : std::false_type {};
2598 template <
typename BasicJsonType,
typename CompatibleObjectType>
2599 struct is_compatible_object_type_impl <
2600 BasicJsonType, CompatibleObjectType,
2601 enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value
and
2602 is_detected<key_type_t, CompatibleObjectType>::value >>
2605 using object_t =
typename BasicJsonType::object_t;
2608 static constexpr bool value =
2609 std::is_constructible<
typename object_t::key_type,
2610 typename CompatibleObjectType::key_type>::value
and
2611 std::is_constructible<
typename object_t::mapped_type,
2612 typename CompatibleObjectType::mapped_type>::value;
2615 template <
typename BasicJsonType,
typename CompatibleObjectType>
2616 struct is_compatible_object_type
2617 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
2619 template <
typename BasicJsonType,
typename ConstructibleObjectType,
2621 struct is_constructible_object_type_impl : std::false_type {};
2623 template <
typename BasicJsonType,
typename ConstructibleObjectType>
2624 struct is_constructible_object_type_impl <
2625 BasicJsonType, ConstructibleObjectType,
2626 enable_if_t<is_detected<mapped_type_t, ConstructibleObjectType>::value
and
2627 is_detected<key_type_t, ConstructibleObjectType>::value >>
2629 using object_t =
typename BasicJsonType::object_t;
2631 static constexpr bool value =
2632 (std::is_default_constructible<ConstructibleObjectType>::value
and
2633 (std::is_move_assignable<ConstructibleObjectType>::value
or
2634 std::is_copy_assignable<ConstructibleObjectType>::value)
and
2635 (std::is_constructible<
typename ConstructibleObjectType::key_type,
2636 typename object_t::key_type>::value
and
2638 typename object_t::mapped_type,
2639 typename ConstructibleObjectType::mapped_type >::value))
or
2640 (has_from_json<BasicJsonType,
2641 typename ConstructibleObjectType::mapped_type>::value
or
2642 has_non_default_from_json <
2644 typename ConstructibleObjectType::mapped_type >::value);
2647 template <
typename BasicJsonType,
typename ConstructibleObjectType>
2648 struct is_constructible_object_type
2649 : is_constructible_object_type_impl<BasicJsonType,
2650 ConstructibleObjectType> {};
2652 template <
typename BasicJsonType,
typename CompatibleStringType,
2654 struct is_compatible_string_type_impl : std::false_type {};
2656 template <
typename BasicJsonType,
typename CompatibleStringType>
2657 struct is_compatible_string_type_impl <
2658 BasicJsonType, CompatibleStringType,
2659 enable_if_t<is_detected_exact<
typename BasicJsonType::string_t::value_type,
2660 value_type_t, CompatibleStringType>::value >>
2662 static constexpr auto value =
2663 std::is_constructible<
typename BasicJsonType::string_t, CompatibleStringType>::value;
2666 template <
typename BasicJsonType,
typename ConstructibleStringType>
2667 struct is_compatible_string_type
2668 : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
2670 template <
typename BasicJsonType,
typename ConstructibleStringType,
2672 struct is_constructible_string_type_impl : std::false_type {};
2674 template <
typename BasicJsonType,
typename ConstructibleStringType>
2675 struct is_constructible_string_type_impl <
2676 BasicJsonType, ConstructibleStringType,
2677 enable_if_t<is_detected_exact<
typename BasicJsonType::string_t::value_type,
2678 value_type_t, ConstructibleStringType>::value >>
2680 static constexpr auto value =
2681 std::is_constructible<ConstructibleStringType,
2682 typename BasicJsonType::string_t>::value;
2685 template <
typename BasicJsonType,
typename ConstructibleStringType>
2686 struct is_constructible_string_type
2687 : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
2689 template <
typename BasicJsonType,
typename CompatibleArrayType,
typename =
void>
2690 struct is_compatible_array_type_impl : std::false_type {};
2692 template <
typename BasicJsonType,
typename CompatibleArrayType>
2693 struct is_compatible_array_type_impl <
2694 BasicJsonType, CompatibleArrayType,
2695 enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value
and
2696 is_detected<iterator_t, CompatibleArrayType>::value
and
2700 not is_iterator_traits<
2701 iterator_traits<CompatibleArrayType>>::value >>
2703 static constexpr bool value =
2704 std::is_constructible<BasicJsonType,
2705 typename CompatibleArrayType::value_type>::value;
2708 template <
typename BasicJsonType,
typename CompatibleArrayType>
2709 struct is_compatible_array_type
2710 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
2712 template <
typename BasicJsonType,
typename ConstructibleArrayType,
typename =
void>
2713 struct is_constructible_array_type_impl : std::false_type {};
2715 template <
typename BasicJsonType,
typename ConstructibleArrayType>
2716 struct is_constructible_array_type_impl <
2717 BasicJsonType, ConstructibleArrayType,
2718 enable_if_t<std::is_same<ConstructibleArrayType,
2719 typename BasicJsonType::value_type>::value >>
2720 : std::true_type {};
2722 template <
typename BasicJsonType,
typename ConstructibleArrayType>
2723 struct is_constructible_array_type_impl <
2724 BasicJsonType, ConstructibleArrayType,
2725 enable_if_t<
not std::is_same<ConstructibleArrayType,
2726 typename BasicJsonType::value_type>::value
and
2727 std::is_default_constructible<ConstructibleArrayType>::value
and
2728 (std::is_move_assignable<ConstructibleArrayType>::value
or
2729 std::is_copy_assignable<ConstructibleArrayType>::value)
and
2730 is_detected<value_type_t, ConstructibleArrayType>::value
and
2731 is_detected<iterator_t, ConstructibleArrayType>::value
and
2733 detected_t<value_type_t, ConstructibleArrayType>>::value >>
2735 static constexpr bool value =
2741 not is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value
and
2743 (std::is_same<
typename ConstructibleArrayType::value_type,
2744 typename BasicJsonType::array_t::value_type>::value
or
2745 has_from_json<BasicJsonType,
2746 typename ConstructibleArrayType::value_type>::value
or
2747 has_non_default_from_json <
2748 BasicJsonType,
typename ConstructibleArrayType::value_type >::value);
2751 template <
typename BasicJsonType,
typename ConstructibleArrayType>
2752 struct is_constructible_array_type
2753 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
2755 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType,
2757 struct is_compatible_integer_type_impl : std::false_type {};
2759 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType>
2760 struct is_compatible_integer_type_impl <
2761 RealIntegerType, CompatibleNumberIntegerType,
2762 enable_if_t<std::is_integral<RealIntegerType>::value
and
2763 std::is_integral<CompatibleNumberIntegerType>::value
and
2764 not std::is_same<
bool, CompatibleNumberIntegerType>::value >>
2767 using RealLimits = std::numeric_limits<RealIntegerType>;
2768 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
2770 static constexpr auto value =
2771 std::is_constructible<RealIntegerType,
2772 CompatibleNumberIntegerType>::value
and
2773 CompatibleLimits::is_integer
and
2774 RealLimits::is_signed == CompatibleLimits::is_signed;
2777 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType>
2778 struct is_compatible_integer_type
2779 : is_compatible_integer_type_impl<RealIntegerType,
2780 CompatibleNumberIntegerType> {};
2782 template <
typename BasicJsonType,
typename CompatibleType,
typename =
void>
2783 struct is_compatible_type_impl: std::false_type {};
2785 template <
typename BasicJsonType,
typename CompatibleType>
2786 struct is_compatible_type_impl <
2787 BasicJsonType, CompatibleType,
2788 enable_if_t<is_complete_type<CompatibleType>::value >>
2790 static constexpr bool value =
2791 has_to_json<BasicJsonType, CompatibleType>::value;
2794 template <
typename BasicJsonType,
typename CompatibleType>
2795 struct is_compatible_type
2796 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
2799 template<
class...>
struct conjunction : std::true_type { };
2800 template<
class B1>
struct conjunction<B1> : B1 { };
2801 template<
class B1,
class... Bn>
2802 struct conjunction<B1, Bn...>
2803 : std::conditional<
bool(B1::value), conjunction<Bn...>, B1>::type {};
2805 template <
typename T1,
typename T2>
2806 struct is_constructible_tuple : std::false_type {};
2808 template <
typename T1,
typename... Args>
2809 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<std::is_constructible<T1, Args>...> {};
2854 enum class value_t : std::uint8_t
2877 inline bool operator<(
const value_t lhs,
const value_t rhs)
noexcept
2879 static constexpr std::array<std::uint8_t, 8> order = {{
2885 const auto l_index =
static_cast<std::size_t>(lhs);
2886 const auto r_index =
static_cast<std::size_t>(rhs);
2887 return l_index < order.size()
and r_index < order.size()
and order[l_index] < order[r_index];
2897 template<
typename BasicJsonType>
2898 void from_json(
const BasicJsonType& j,
typename std::nullptr_t& n)
2902 JSON_THROW(type_error::create(302,
"type must be null, but is " + std::string(j.type_name())));
2908 template<
typename BasicJsonType,
typename ArithmeticType,
2909 enable_if_t<std::is_arithmetic<ArithmeticType>::value
and
2910 not std::is_same<ArithmeticType,
typename BasicJsonType::boolean_t>::value,
2912 void get_arithmetic_value(
const BasicJsonType& j, ArithmeticType& val)
2914 switch (
static_cast<value_t>(j))
2916 case value_t::number_unsigned:
2918 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_unsigned_t*>());
2921 case value_t::number_integer:
2923 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_integer_t*>());
2926 case value_t::number_float:
2928 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_float_t*>());
2933 JSON_THROW(type_error::create(302,
"type must be number, but is " + std::string(j.type_name())));
2937 template<
typename BasicJsonType>
2938 void from_json(
const BasicJsonType& j,
typename BasicJsonType::boolean_t& b)
2942 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(j.type_name())));
2944 b = *j.
template get_ptr<
const typename BasicJsonType::boolean_t*>();
2947 template<
typename BasicJsonType>
2948 void from_json(
const BasicJsonType& j,
typename BasicJsonType::string_t& s)
2952 JSON_THROW(type_error::create(302,
"type must be string, but is " + std::string(j.type_name())));
2954 s = *j.
template get_ptr<
const typename BasicJsonType::string_t*>();
2958 typename BasicJsonType,
typename ConstructibleStringType,
2960 is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value
and
2961 not std::is_same<
typename BasicJsonType::string_t,
2962 ConstructibleStringType>::value,
2964 void from_json(
const BasicJsonType& j, ConstructibleStringType& s)
2968 JSON_THROW(type_error::create(302,
"type must be string, but is " + std::string(j.type_name())));
2971 s = *j.
template get_ptr<
const typename BasicJsonType::string_t*>();
2974 template<
typename BasicJsonType>
2975 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_float_t& val)
2977 get_arithmetic_value(j, val);
2980 template<
typename BasicJsonType>
2981 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_unsigned_t& val)
2983 get_arithmetic_value(j, val);
2986 template<
typename BasicJsonType>
2987 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_integer_t& val)
2989 get_arithmetic_value(j, val);
2992 template<
typename BasicJsonType,
typename EnumType,
2993 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
2994 void from_json(
const BasicJsonType& j, EnumType& e)
2996 typename std::underlying_type<EnumType>::type val;
2997 get_arithmetic_value(j, val);
2998 e =
static_cast<EnumType>(val);
3002 template<
typename BasicJsonType,
typename T,
typename Allocator,
3003 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
3004 void from_json(
const BasicJsonType& j, std::forward_list<T, Allocator>& l)
3008 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
3011 std::transform(j.rbegin(), j.rend(),
3012 std::front_inserter(l), [](
const BasicJsonType & i)
3014 return i.
template get<T>();
3019 template<
typename BasicJsonType,
typename T,
3020 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
3021 void from_json(
const BasicJsonType& j, std::valarray<T>& l)
3025 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
3028 std::copy(j.begin(), j.end(), std::begin(l));
3031 template <
typename BasicJsonType,
typename T, std::size_t N>
3032 auto from_json(
const BasicJsonType& j, T (&arr)[N])
3033 ->
decltype(j.
template get<T>(),
void())
3035 for (std::size_t i = 0; i < N; ++i)
3037 arr[i] = j.at(i).
template get<T>();
3041 template<
typename BasicJsonType>
3042 void from_json_array_impl(
const BasicJsonType& j,
typename BasicJsonType::array_t& arr, priority_tag<3> )
3044 arr = *j.
template get_ptr<
const typename BasicJsonType::array_t*>();
3047 template <
typename BasicJsonType,
typename T, std::size_t N>
3048 auto from_json_array_impl(
const BasicJsonType& j, std::array<T, N>& arr,
3050 ->
decltype(j.
template get<T>(),
void())
3052 for (std::size_t i = 0; i < N; ++i)
3054 arr[i] = j.at(i).
template get<T>();
3058 template<
typename BasicJsonType,
typename ConstructibleArrayType>
3059 auto from_json_array_impl(
const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> )
3061 arr.reserve(std::declval<
typename ConstructibleArrayType::size_type>()),
3062 j.
template get<
typename ConstructibleArrayType::value_type>(),
3067 ConstructibleArrayType ret;
3068 ret.reserve(j.size());
3069 std::transform(j.begin(), j.end(),
3070 std::inserter(ret, end(ret)), [](
const BasicJsonType & i)
3074 return i.
template get<
typename ConstructibleArrayType::value_type>();
3076 arr = std::move(ret);
3079 template <
typename BasicJsonType,
typename ConstructibleArrayType>
3080 void from_json_array_impl(
const BasicJsonType& j, ConstructibleArrayType& arr,
3085 ConstructibleArrayType ret;
3087 j.begin(), j.end(), std::inserter(ret, end(ret)),
3088 [](
const BasicJsonType & i)
3092 return i.
template get<
typename ConstructibleArrayType::value_type>();
3094 arr = std::move(ret);
3097 template <
typename BasicJsonType,
typename ConstructibleArrayType,
3099 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value
and
3100 not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value
and
3101 not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value
and
3102 not is_basic_json<ConstructibleArrayType>::value,
3105 auto from_json(
const BasicJsonType& j, ConstructibleArrayType& arr)
3106 ->
decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
3107 j.
template get<
typename ConstructibleArrayType::value_type>(),
3112 JSON_THROW(type_error::create(302,
"type must be array, but is " +
3113 std::string(j.type_name())));
3116 from_json_array_impl(j, arr, priority_tag<3> {});
3119 template<
typename BasicJsonType,
typename ConstructibleObjectType,
3120 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value,
int> = 0>
3121 void from_json(
const BasicJsonType& j, ConstructibleObjectType& obj)
3125 JSON_THROW(type_error::create(302,
"type must be object, but is " + std::string(j.type_name())));
3128 ConstructibleObjectType ret;
3129 auto inner_object = j.
template get_ptr<
const typename BasicJsonType::object_t*>();
3130 using value_type =
typename ConstructibleObjectType::value_type;
3132 inner_object->begin(), inner_object->end(),
3133 std::inserter(ret, ret.begin()),
3134 [](
typename BasicJsonType::object_t::value_type
const & p)
3136 return value_type(p.first, p.second.
template get<
typename ConstructibleObjectType::mapped_type>());
3138 obj = std::move(ret);
3145 template<
typename BasicJsonType,
typename ArithmeticType,
3147 std::is_arithmetic<ArithmeticType>::value
and
3148 not std::is_same<ArithmeticType,
typename BasicJsonType::number_unsigned_t>::value
and
3149 not std::is_same<ArithmeticType,
typename BasicJsonType::number_integer_t>::value
and
3150 not std::is_same<ArithmeticType,
typename BasicJsonType::number_float_t>::value
and
3151 not std::is_same<ArithmeticType,
typename BasicJsonType::boolean_t>::value,
3153 void from_json(
const BasicJsonType& j, ArithmeticType& val)
3155 switch (
static_cast<value_t>(j))
3157 case value_t::number_unsigned:
3159 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_unsigned_t*>());
3162 case value_t::number_integer:
3164 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_integer_t*>());
3167 case value_t::number_float:
3169 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::number_float_t*>());
3172 case value_t::boolean:
3174 val =
static_cast<ArithmeticType>(*j.
template get_ptr<
const typename BasicJsonType::boolean_t*>());
3179 JSON_THROW(type_error::create(302,
"type must be number, but is " + std::string(j.type_name())));
3183 template<
typename BasicJsonType,
typename A1,
typename A2>
3184 void from_json(
const BasicJsonType& j, std::pair<A1, A2>& p)
3186 p = {j.at(0).
template get<A1>(), j.at(1).
template get<A2>()};
3189 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
3190 void from_json_tuple_impl(
const BasicJsonType& j, Tuple& t, index_sequence<Idx...> )
3192 t = std::make_tuple(j.at(Idx).
template get<
typename std::tuple_element<Idx, Tuple>::type>()...);
3195 template<
typename BasicJsonType,
typename... Args>
3196 void from_json(
const BasicJsonType& j, std::tuple<Args...>& t)
3198 from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
3201 template <
typename BasicJsonType,
typename Key,
typename Value,
typename Compare,
typename Allocator,
3202 typename = enable_if_t<
not std::is_constructible<
3203 typename BasicJsonType::string_t, Key>::value>>
3204 void from_json(
const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
3208 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
3211 for (
const auto& p : j)
3215 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(p.type_name())));
3217 m.emplace(p.at(0).
template get<Key>(), p.at(1).
template get<Value>());
3221 template <
typename BasicJsonType,
typename Key,
typename Value,
typename Hash,
typename KeyEqual,
typename Allocator,
3222 typename = enable_if_t<
not std::is_constructible<
3223 typename BasicJsonType::string_t, Key>::value>>
3224 void from_json(
const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
3228 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
3231 for (
const auto& p : j)
3235 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(p.type_name())));
3237 m.emplace(p.at(0).
template get<Key>(), p.at(1).
template get<Value>());
3243 template<
typename BasicJsonType,
typename T>
3244 auto operator()(
const BasicJsonType& j, T& val)
const
3245 noexcept(
noexcept(from_json(j, val)))
3246 ->
decltype(from_json(j, val),
void())
3248 return from_json(j, val);
3258 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
3265 #include <algorithm>
3270 #include <type_traits>
3292 template<
typename string_type>
3293 void int_to_string( string_type& target, std::size_t value )
3295 target = std::to_string(value);
3297 template <
typename IteratorType>
class iteration_proxy_value
3300 using difference_type = std::ptrdiff_t;
3301 using value_type = iteration_proxy_value;
3302 using pointer = value_type * ;
3303 using reference = value_type & ;
3304 using iterator_category = std::input_iterator_tag;
3305 using string_type =
typename std::remove_cv<
typename std::remove_reference<
decltype( std::declval<IteratorType>().key() ) >::type >::type;
3309 IteratorType anchor;
3311 std::size_t array_index = 0;
3313 mutable std::size_t array_index_last = 0;
3315 mutable string_type array_index_str =
"0";
3317 const string_type empty_str =
"";
3320 explicit iteration_proxy_value(IteratorType it)
noexcept : anchor(it) {}
3323 iteration_proxy_value& operator*()
3329 iteration_proxy_value& operator++()
3338 bool operator==(
const iteration_proxy_value& o)
const
3340 return anchor == o.anchor;
3344 bool operator!=(
const iteration_proxy_value& o)
const
3346 return anchor != o.anchor;
3350 const string_type& key()
const
3352 assert(anchor.m_object !=
nullptr);
3354 switch (anchor.m_object->type())
3357 case value_t::array:
3359 if (array_index != array_index_last)
3361 int_to_string( array_index_str, array_index );
3362 array_index_last = array_index;
3364 return array_index_str;
3368 case value_t::object:
3369 return anchor.key();
3378 typename IteratorType::reference value()
const
3380 return anchor.value();
3385 template<
typename IteratorType>
class iteration_proxy
3389 typename IteratorType::reference container;
3393 explicit iteration_proxy(
typename IteratorType::reference cont)
noexcept
3394 : container(cont) {}
3397 iteration_proxy_value<IteratorType> begin()
noexcept
3399 return iteration_proxy_value<IteratorType>(container.begin());
3403 iteration_proxy_value<IteratorType> end()
noexcept
3405 return iteration_proxy_value<IteratorType>(container.end());
3411 template <std::size_t N,
typename IteratorType, enable_if_t<N == 0,
int> = 0>
3412 auto get(
const nlohmann::detail::iteration_proxy_value<IteratorType>& i) ->
decltype(i.key())
3419 template <std::size_t N,
typename IteratorType, enable_if_t<N == 1,
int> = 0>
3420 auto get(
const nlohmann::detail::iteration_proxy_value<IteratorType>& i) ->
decltype(i.value())
3433 #if defined(__clang__
)
3435 #pragma clang diagnostic push
3436 #pragma clang diagnostic ignored "-Wmismatched-tags"
3438 template <
typename IteratorType>
3439 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
3440 :
public std::integral_constant<std::size_t, 2> {};
3442 template <std::size_t N,
typename IteratorType>
3443 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
3446 using type =
decltype(
3447 get<N>(std::declval <
3448 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
3450 #if defined(__clang__
)
3451 #pragma clang diagnostic pop
3470 template<value_t>
struct external_constructor;
3473 struct external_constructor<value_t::boolean>
3475 template<
typename BasicJsonType>
3476 static void construct(BasicJsonType& j,
typename BasicJsonType::boolean_t b)
noexcept
3478 j.m_type = value_t::boolean;
3480 j.assert_invariant();
3485 struct external_constructor<value_t::string>
3487 template<
typename BasicJsonType>
3488 static void construct(BasicJsonType& j,
const typename BasicJsonType::string_t& s)
3490 j.m_type = value_t::string;
3492 j.assert_invariant();
3495 template<
typename BasicJsonType>
3496 static void construct(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
3498 j.m_type = value_t::string;
3499 j.m_value = std::move(s);
3500 j.assert_invariant();
3503 template<
typename BasicJsonType,
typename CompatibleStringType,
3504 enable_if_t<
not std::is_same<CompatibleStringType,
typename BasicJsonType::string_t>::value,
3506 static void construct(BasicJsonType& j,
const CompatibleStringType& str)
3508 j.m_type = value_t::string;
3509 j.m_value.string = j.
template create<
typename BasicJsonType::string_t>(str);
3510 j.assert_invariant();
3515 struct external_constructor<value_t::number_float>
3517 template<
typename BasicJsonType>
3518 static void construct(BasicJsonType& j,
typename BasicJsonType::number_float_t val)
noexcept
3520 j.m_type = value_t::number_float;
3522 j.assert_invariant();
3527 struct external_constructor<value_t::number_unsigned>
3529 template<
typename BasicJsonType>
3530 static void construct(BasicJsonType& j,
typename BasicJsonType::number_unsigned_t val)
noexcept
3532 j.m_type = value_t::number_unsigned;
3534 j.assert_invariant();
3539 struct external_constructor<value_t::number_integer>
3541 template<
typename BasicJsonType>
3542 static void construct(BasicJsonType& j,
typename BasicJsonType::number_integer_t val)
noexcept
3544 j.m_type = value_t::number_integer;
3546 j.assert_invariant();
3551 struct external_constructor<value_t::array>
3553 template<
typename BasicJsonType>
3554 static void construct(BasicJsonType& j,
const typename BasicJsonType::array_t& arr)
3556 j.m_type = value_t::array;
3558 j.assert_invariant();
3561 template<
typename BasicJsonType>
3562 static void construct(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
3564 j.m_type = value_t::array;
3565 j.m_value = std::move(arr);
3566 j.assert_invariant();
3569 template<
typename BasicJsonType,
typename CompatibleArrayType,
3570 enable_if_t<
not std::is_same<CompatibleArrayType,
typename BasicJsonType::array_t>::value,
3572 static void construct(BasicJsonType& j,
const CompatibleArrayType& arr)
3576 j.m_type = value_t::array;
3577 j.m_value.array = j.
template create<
typename BasicJsonType::array_t>(begin(arr), end(arr));
3578 j.assert_invariant();
3581 template<
typename BasicJsonType>
3582 static void construct(BasicJsonType& j,
const std::vector<
bool>& arr)
3584 j.m_type = value_t::array;
3585 j.m_value = value_t::array;
3586 j.m_value.array->reserve(arr.size());
3587 for (
const bool x : arr)
3589 j.m_value.array->push_back(x);
3591 j.assert_invariant();
3594 template<
typename BasicJsonType,
typename T,
3595 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
3596 static void construct(BasicJsonType& j,
const std::valarray<T>& arr)
3598 j.m_type = value_t::array;
3599 j.m_value = value_t::array;
3600 j.m_value.array->resize(arr.size());
3603 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
3605 j.assert_invariant();
3610 struct external_constructor<value_t::object>
3612 template<
typename BasicJsonType>
3613 static void construct(BasicJsonType& j,
const typename BasicJsonType::object_t& obj)
3615 j.m_type = value_t::object;
3617 j.assert_invariant();
3620 template<
typename BasicJsonType>
3621 static void construct(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
3623 j.m_type = value_t::object;
3624 j.m_value = std::move(obj);
3625 j.assert_invariant();
3628 template<
typename BasicJsonType,
typename CompatibleObjectType,
3629 enable_if_t<
not std::is_same<CompatibleObjectType,
typename BasicJsonType::object_t>::value,
int> = 0>
3630 static void construct(BasicJsonType& j,
const CompatibleObjectType& obj)
3635 j.m_type = value_t::object;
3636 j.m_value.object = j.
template create<
typename BasicJsonType::object_t>(begin(obj), end(obj));
3637 j.assert_invariant();
3645 template<
typename BasicJsonType,
typename T,
3646 enable_if_t<std::is_same<T,
typename BasicJsonType::boolean_t>::value,
int> = 0>
3647 void to_json(BasicJsonType& j, T b)
noexcept
3649 external_constructor<value_t::boolean>::construct(j, b);
3652 template<
typename BasicJsonType,
typename CompatibleString,
3653 enable_if_t<std::is_constructible<
typename BasicJsonType::string_t, CompatibleString>::value,
int> = 0>
3654 void to_json(BasicJsonType& j,
const CompatibleString& s)
3656 external_constructor<value_t::string>::construct(j, s);
3659 template<
typename BasicJsonType>
3660 void to_json(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
3662 external_constructor<value_t::string>::construct(j, std::move(s));
3665 template<
typename BasicJsonType,
typename FloatType,
3666 enable_if_t<std::is_floating_point<FloatType>::value,
int> = 0>
3667 void to_json(BasicJsonType& j, FloatType val)
noexcept
3669 external_constructor<value_t::number_float>::construct(j,
static_cast<
typename BasicJsonType::number_float_t>(val));
3672 template<
typename BasicJsonType,
typename CompatibleNumberUnsignedType,
3673 enable_if_t<is_compatible_integer_type<
typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value,
int> = 0>
3674 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val)
noexcept
3676 external_constructor<value_t::number_unsigned>::construct(j,
static_cast<
typename BasicJsonType::number_unsigned_t>(val));
3679 template<
typename BasicJsonType,
typename CompatibleNumberIntegerType,
3680 enable_if_t<is_compatible_integer_type<
typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value,
int> = 0>
3681 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val)
noexcept
3683 external_constructor<value_t::number_integer>::construct(j,
static_cast<
typename BasicJsonType::number_integer_t>(val));
3686 template<
typename BasicJsonType,
typename EnumType,
3687 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
3688 void to_json(BasicJsonType& j, EnumType e)
noexcept
3690 using underlying_type =
typename std::underlying_type<EnumType>::type;
3691 external_constructor<value_t::number_integer>::construct(j,
static_cast<underlying_type>(e));
3694 template<
typename BasicJsonType>
3695 void to_json(BasicJsonType& j,
const std::vector<
bool>& e)
3697 external_constructor<value_t::array>::construct(j, e);
3700 template <
typename BasicJsonType,
typename CompatibleArrayType,
3701 enable_if_t<is_compatible_array_type<BasicJsonType,
3702 CompatibleArrayType>::value
and
3703 not is_compatible_object_type<
3704 BasicJsonType, CompatibleArrayType>::value
and
3705 not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value
and
3706 not is_basic_json<CompatibleArrayType>::value,
3708 void to_json(BasicJsonType& j,
const CompatibleArrayType& arr)
3710 external_constructor<value_t::array>::construct(j, arr);
3713 template<
typename BasicJsonType,
typename T,
3714 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
3715 void to_json(BasicJsonType& j,
const std::valarray<T>& arr)
3717 external_constructor<value_t::array>::construct(j, std::move(arr));
3720 template<
typename BasicJsonType>
3721 void to_json(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
3723 external_constructor<value_t::array>::construct(j, std::move(arr));
3726 template<
typename BasicJsonType,
typename CompatibleObjectType,
3727 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value
and not is_basic_json<CompatibleObjectType>::value,
int> = 0>
3728 void to_json(BasicJsonType& j,
const CompatibleObjectType& obj)
3730 external_constructor<value_t::object>::construct(j, obj);
3733 template<
typename BasicJsonType>
3734 void to_json(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
3736 external_constructor<value_t::object>::construct(j, std::move(obj));
3740 typename BasicJsonType,
typename T, std::size_t N,
3741 enable_if_t<
not std::is_constructible<
typename BasicJsonType::string_t,
3742 const T(&)[N]>::value,
3744 void to_json(BasicJsonType& j,
const T(&arr)[N])
3746 external_constructor<value_t::array>::construct(j, arr);
3749 template <
typename BasicJsonType,
typename T1,
typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value,
int > = 0 >
3750 void to_json(BasicJsonType& j,
const std::pair<T1, T2>& p)
3752 j = { p.first, p.second };
3756 template <
typename BasicJsonType,
typename T,
3757 enable_if_t<std::is_same<T, iteration_proxy_value<
typename BasicJsonType::iterator>>::value,
int> = 0>
3758 void to_json(BasicJsonType& j,
const T& b)
3760 j = { {b.key(), b.value()} };
3763 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
3764 void to_json_tuple_impl(BasicJsonType& j,
const Tuple& t, index_sequence<Idx...> )
3766 j = { std::get<Idx>(t)... };
3769 template<
typename BasicJsonType,
typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value,
int > = 0>
3770 void to_json(BasicJsonType& j,
const T& t)
3772 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
3777 template<
typename BasicJsonType,
typename T>
3778 auto operator()(BasicJsonType& j, T&& val)
const noexcept(
noexcept(to_json(j, std::forward<T>(val))))
3779 ->
decltype(to_json(j, std::forward<T>(val)),
void())
3781 return to_json(j, std::forward<T>(val));
3789 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
3797 template<
typename,
typename>
3798 struct adl_serializer
3809 template<
typename BasicJsonType,
typename ValueType>
3810 static auto from_json(BasicJsonType&& j, ValueType& val)
noexcept(
3811 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
3812 ->
decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val),
void())
3814 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
3826 template <
typename BasicJsonType,
typename ValueType>
3827 static auto to_json(BasicJsonType& j, ValueType&& val)
noexcept(
3828 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
3829 ->
decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)),
void())
3831 ::nlohmann::to_json(j, std::forward<ValueType>(val));
3846 #include <algorithm>
3874 #include <type_traits>
3887 enum class input_format_t { json, cbor, msgpack, ubjson, bson };
3904 struct input_adapter_protocol
3907 virtual std::char_traits<
char>::int_type get_character() = 0;
3908 virtual ~input_adapter_protocol() =
default;
3912 using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
3918 class file_input_adapter :
public input_adapter_protocol
3922 explicit file_input_adapter(std::FILE* f)
noexcept
3927 file_input_adapter(
const file_input_adapter&) =
delete;
3928 file_input_adapter(file_input_adapter&&) =
default;
3929 file_input_adapter& operator=(
const file_input_adapter&) =
delete;
3930 file_input_adapter& operator=(file_input_adapter&&) =
default;
3931 ~file_input_adapter() override =
default;
3933 std::char_traits<
char>::int_type get_character()
noexcept override
3935 return std::fgetc(m_file);
3953 class input_stream_adapter :
public input_adapter_protocol
3956 ~input_stream_adapter() override
3960 is.clear(is.rdstate() & std::ios::eofbit);
3963 explicit input_stream_adapter(std::istream& i)
3964 : is(i), sb(*i.rdbuf())
3968 input_stream_adapter(
const input_stream_adapter&) =
delete;
3969 input_stream_adapter& operator=(input_stream_adapter&) =
delete;
3970 input_stream_adapter(input_stream_adapter&&) =
delete;
3971 input_stream_adapter& operator=(input_stream_adapter&&) =
delete;
3976 std::char_traits<
char>::int_type get_character() override
3978 auto res = sb.sbumpc();
3982 is.clear(is.rdstate() | std::ios::eofbit);
3994 class input_buffer_adapter :
public input_adapter_protocol
3997 input_buffer_adapter(
const char* b,
const std::size_t l)
noexcept
3998 : cursor(b), limit(b ==
nullptr ?
nullptr : (b + l))
4002 input_buffer_adapter(
const input_buffer_adapter&) =
delete;
4003 input_buffer_adapter& operator=(input_buffer_adapter&) =
delete;
4004 input_buffer_adapter(input_buffer_adapter&&) =
delete;
4005 input_buffer_adapter& operator=(input_buffer_adapter&&) =
delete;
4006 ~input_buffer_adapter() override =
default;
4008 std::char_traits<
char>::int_type get_character()
noexcept override
4012 assert(cursor !=
nullptr and limit !=
nullptr);
4013 return std::char_traits<
char>::to_int_type(*(cursor++));
4016 return std::char_traits<
char>::eof();
4023 const char*
const limit;
4026 template<
typename WideStringType, size_t T>
4027 struct wide_string_input_helper
4030 static void fill_buffer(
const WideStringType& str,
4031 size_t& current_wchar,
4032 std::array<std::char_traits<
char>::int_type, 4>& utf8_bytes,
4033 size_t& utf8_bytes_index,
4034 size_t& utf8_bytes_filled)
4036 utf8_bytes_index = 0;
4038 if (current_wchar == str.size())
4040 utf8_bytes[0] = std::char_traits<
char>::eof();
4041 utf8_bytes_filled = 1;
4046 const auto wc =
static_cast<
unsigned int>(str[current_wchar++]);
4051 utf8_bytes[0] =
static_cast<std::char_traits<
char>::int_type>(wc);
4052 utf8_bytes_filled = 1;
4054 else if (wc <= 0x7FF)
4056 utf8_bytes[0] =
static_cast<std::char_traits<
char>::int_type>(0xC0u | ((wc >> 6u) & 0x1Fu));
4057 utf8_bytes[1] =
static_cast<std::char_traits<
char>::int_type>(0x80u | (wc & 0x3Fu));
4058 utf8_bytes_filled = 2;
4060 else if (wc <= 0xFFFF)
4062 utf8_bytes[0] =
static_cast<std::char_traits<
char>::int_type>(0xE0u | ((wc >> 12u) & 0x0Fu));
4063 utf8_bytes[1] =
static_cast<std::char_traits<
char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
4064 utf8_bytes[2] =
static_cast<std::char_traits<
char>::int_type>(0x80u | (wc & 0x3Fu));
4065 utf8_bytes_filled = 3;
4067 else if (wc <= 0x10FFFF)
4069 utf8_bytes[0] =
static_cast<std::char_traits<
char>::int_type>(0xF0u | ((wc >> 18u) & 0x07u));
4070 utf8_bytes[1] =
static_cast<std::char_traits<
char>::int_type>(0x80u | ((wc >> 12u) & 0x3Fu));
4071 utf8_bytes[2] =
static_cast<std::char_traits<
char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
4072 utf8_bytes[3] =
static_cast<std::char_traits<
char>::int_type>(0x80u | (wc & 0x3Fu));
4073 utf8_bytes_filled = 4;
4078 utf8_bytes[0] =
static_cast<std::char_traits<
char>::int_type>(wc);
4079 utf8_bytes_filled = 1;
4085 template<
typename WideStringType>
4086 struct wide_string_input_helper<WideStringType, 2>
4089 static void fill_buffer(
const WideStringType& str,
4090 size_t& current_wchar,
4091 std::array<std::char_traits<
char>::int_type, 4>& utf8_bytes,
4092 size_t& utf8_bytes_index,
4093 size_t& utf8_bytes_filled)
4095 utf8_bytes_index = 0;
4097 if (current_wchar == str.size())
4099 utf8_bytes[0] = std::char_traits<
char>::eof();
4100 utf8_bytes_filled = 1;
4105 const auto wc =
static_cast<
unsigned int>(str[current_wchar++]);
4110 utf8_bytes[0] =
static_cast<std::char_traits<
char>::int_type>(wc);
4111 utf8_bytes_filled = 1;
4113 else if (wc <= 0x7FF)
4115 utf8_bytes[0] =
static_cast<std::char_traits<
char>::int_type>(0xC0u | ((wc >> 6u)));
4116 utf8_bytes[1] =
static_cast<std::char_traits<
char>::int_type>(0x80u | (wc & 0x3Fu));
4117 utf8_bytes_filled = 2;
4119 else if (0xD800 > wc
or wc >= 0xE000)
4121 utf8_bytes[0] =
static_cast<std::char_traits<
char>::int_type>(0xE0u | ((wc >> 12u)));
4122 utf8_bytes[1] =
static_cast<std::char_traits<
char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
4123 utf8_bytes[2] =
static_cast<std::char_traits<
char>::int_type>(0x80u | (wc & 0x3Fu));
4124 utf8_bytes_filled = 3;
4128 if (current_wchar < str.size())
4130 const auto wc2 =
static_cast<
unsigned int>(str[current_wchar++]);
4131 const auto charcode = 0x10000u + (((wc & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
4132 utf8_bytes[0] =
static_cast<std::char_traits<
char>::int_type>(0xF0u | (charcode >> 18u));
4133 utf8_bytes[1] =
static_cast<std::char_traits<
char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
4134 utf8_bytes[2] =
static_cast<std::char_traits<
char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
4135 utf8_bytes[3] =
static_cast<std::char_traits<
char>::int_type>(0x80u | (charcode & 0x3Fu));
4136 utf8_bytes_filled = 4;
4142 utf8_bytes[0] =
static_cast<std::char_traits<
char>::int_type>(wc);
4143 utf8_bytes_filled = 1;
4150 template<
typename WideStringType>
4151 class wide_string_input_adapter :
public input_adapter_protocol
4154 explicit wide_string_input_adapter(
const WideStringType& w)
noexcept
4158 std::char_traits<
char>::int_type get_character()
noexcept override
4161 if (utf8_bytes_index == utf8_bytes_filled)
4163 fill_buffer<
sizeof(
typename WideStringType::value_type)>();
4165 assert(utf8_bytes_filled > 0);
4166 assert(utf8_bytes_index == 0);
4170 assert(utf8_bytes_filled > 0);
4171 assert(utf8_bytes_index < utf8_bytes_filled);
4172 return utf8_bytes[utf8_bytes_index++];
4179 wide_string_input_helper<WideStringType, T>::fill_buffer(str, current_wchar, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
4183 const WideStringType& str;
4186 std::size_t current_wchar = 0;
4189 std::array<std::char_traits<
char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
4192 std::size_t utf8_bytes_index = 0;
4194 std::size_t utf8_bytes_filled = 0;
4202 input_adapter(std::FILE* file)
4203 : ia(std::make_shared<file_input_adapter>(file)) {}
4205 input_adapter(std::istream& i)
4206 : ia(std::make_shared<input_stream_adapter>(i)) {}
4209 input_adapter(std::istream&& i)
4210 : ia(std::make_shared<input_stream_adapter>(i)) {}
4212 input_adapter(
const std::wstring& ws)
4213 : ia(std::make_shared<wide_string_input_adapter<std::wstring>>(ws)) {}
4215 input_adapter(
const std::u16string& ws)
4216 : ia(std::make_shared<wide_string_input_adapter<std::u16string>>(ws)) {}
4218 input_adapter(
const std::u32string& ws)
4219 : ia(std::make_shared<wide_string_input_adapter<std::u32string>>(ws)) {}
4222 template<
typename CharT,
4223 typename std::enable_if<
4224 std::is_pointer<CharT>::value
and
4225 std::is_integral<
typename std::remove_pointer<CharT>::type>::value
and
4226 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
4228 input_adapter(CharT b, std::size_t l)
4229 : ia(std::make_shared<input_buffer_adapter>(
reinterpret_cast<
const char*>(b), l)) {}
4234 template<
typename CharT,
4235 typename std::enable_if<
4236 std::is_pointer<CharT>::value
and
4237 std::is_integral<
typename std::remove_pointer<CharT>::type>::value
and
4238 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
4240 input_adapter(CharT b)
4241 : input_adapter(
reinterpret_cast<
const char*>(b),
4242 std::strlen(
reinterpret_cast<
const char*>(b))) {}
4245 template<
class IteratorType,
4246 typename std::enable_if<
4247 std::is_same<
typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
4249 input_adapter(IteratorType first, IteratorType last)
4254 const auto is_contiguous = std::accumulate(
4255 first, last, std::pair<
bool,
int>(
true, 0),
4256 [&first](std::pair<
bool,
int> res,
decltype(*first) val)
4258 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
4261 assert(is_contiguous);
4266 sizeof(
typename iterator_traits<IteratorType>::value_type) == 1,
4267 "each element in the iterator range must have the size of 1 byte");
4269 const auto len =
static_cast<size_t>(std::distance(first, last));
4273 ia = std::make_shared<input_buffer_adapter>(
reinterpret_cast<
const char*>(&(*first)), len);
4278 ia = std::make_shared<input_buffer_adapter>(
nullptr, len);
4283 template<
class T, std::size_t N>
4284 input_adapter(T (&array)[N])
4285 : input_adapter(std::begin(array), std::end(array)) {}
4288 template<
class ContiguousContainer,
typename
4289 std::enable_if<
not std::is_pointer<ContiguousContainer>::value
and
4290 std::is_base_of<std::random_access_iterator_tag,
typename iterator_traits<
decltype(std::begin(std::declval<ContiguousContainer
const>()))>::iterator_category>::value,
4292 input_adapter(
const ContiguousContainer& c)
4293 : input_adapter(std::begin(c), std::end(c)) {}
4295 operator input_adapter_t()
4302 input_adapter_t ia =
nullptr;
4332 template<
typename BasicJsonType>
4336 using number_integer_t =
typename BasicJsonType::number_integer_t;
4338 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
4340 using number_float_t =
typename BasicJsonType::number_float_t;
4342 using string_t =
typename BasicJsonType::string_t;
4348 virtual bool null() = 0;
4355 virtual bool boolean(
bool val) = 0;
4362 virtual bool number_integer(number_integer_t val) = 0;
4369 virtual bool number_unsigned(number_unsigned_t val) = 0;
4377 virtual bool number_float(number_float_t val,
const string_t& s) = 0;
4385 virtual bool string(string_t& val) = 0;
4393 virtual bool start_object(std::size_t elements) = 0;
4401 virtual bool key(string_t& val) = 0;
4407 virtual bool end_object() = 0;
4415 virtual bool start_array(std::size_t elements) = 0;
4421 virtual bool end_array() = 0;
4430 virtual bool parse_error(std::size_t position,
4431 const std::string& last_token,
4432 const detail::exception& ex) = 0;
4434 virtual ~json_sax() =
default;
4453 template<
typename BasicJsonType>
4454 class json_sax_dom_parser
4457 using number_integer_t =
typename BasicJsonType::number_integer_t;
4458 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
4459 using number_float_t =
typename BasicJsonType::number_float_t;
4460 using string_t =
typename BasicJsonType::string_t;
4467 explicit json_sax_dom_parser(BasicJsonType& r,
const bool allow_exceptions_ =
true)
4468 : root(r), allow_exceptions(allow_exceptions_)
4472 json_sax_dom_parser(
const json_sax_dom_parser&) =
delete;
4473 json_sax_dom_parser(json_sax_dom_parser&&) =
default;
4474 json_sax_dom_parser& operator=(
const json_sax_dom_parser&) =
delete;
4475 json_sax_dom_parser& operator=(json_sax_dom_parser&&) =
default;
4476 ~json_sax_dom_parser() =
default;
4480 handle_value(
nullptr);
4484 bool boolean(
bool val)
4490 bool number_integer(number_integer_t val)
4496 bool number_unsigned(number_unsigned_t val)
4502 bool number_float(number_float_t val,
const string_t& )
4508 bool string(string_t& val)
4514 bool start_object(std::size_t len)
4516 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
4521 "excessive object size: " + std::to_string(len)));
4527 bool key(string_t& val)
4530 object_element = &(ref_stack.back()->m_value.object->operator[](val));
4536 ref_stack.pop_back();
4540 bool start_array(std::size_t len)
4542 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
4547 "excessive array size: " + std::to_string(len)));
4555 ref_stack.pop_back();
4559 bool parse_error(std::size_t ,
const std::string& ,
4560 const detail::exception& ex)
4563 if (allow_exceptions)
4566 switch ((ex.id / 100) % 100)
4569 JSON_THROW(*
static_cast<
const detail::parse_error*>(&ex));
4571 JSON_THROW(*
static_cast<
const detail::out_of_range*>(&ex));
4574 JSON_THROW(*
static_cast<
const detail::invalid_iterator*>(&ex));
4576 JSON_THROW(*
static_cast<
const detail::type_error*>(&ex));
4578 JSON_THROW(*
static_cast<
const detail::other_error*>(&ex));
4587 constexpr bool is_errored()
const
4599 template<
typename Value>
4601 BasicJsonType* handle_value(Value&& v)
4603 if (ref_stack.empty())
4605 root = BasicJsonType(std::forward<Value>(v));
4609 assert(ref_stack.back()->is_array()
or ref_stack.back()->is_object());
4611 if (ref_stack.back()->is_array())
4613 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
4614 return &(ref_stack.back()->m_value.array->back());
4617 assert(ref_stack.back()->is_object());
4618 assert(object_element);
4619 *object_element = BasicJsonType(std::forward<Value>(v));
4620 return object_element;
4624 BasicJsonType& root;
4626 std::vector<BasicJsonType*> ref_stack {};
4628 BasicJsonType* object_element =
nullptr;
4630 bool errored =
false;
4632 const bool allow_exceptions =
true;
4635 template<
typename BasicJsonType>
4636 class json_sax_dom_callback_parser
4639 using number_integer_t =
typename BasicJsonType::number_integer_t;
4640 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
4641 using number_float_t =
typename BasicJsonType::number_float_t;
4642 using string_t =
typename BasicJsonType::string_t;
4643 using parser_callback_t =
typename BasicJsonType::parser_callback_t;
4644 using parse_event_t =
typename BasicJsonType::parse_event_t;
4646 json_sax_dom_callback_parser(BasicJsonType& r,
4647 const parser_callback_t cb,
4648 const bool allow_exceptions_ =
true)
4649 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
4651 keep_stack.push_back(
true);
4655 json_sax_dom_callback_parser(
const json_sax_dom_callback_parser&) =
delete;
4656 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) =
default;
4657 json_sax_dom_callback_parser& operator=(
const json_sax_dom_callback_parser&) =
delete;
4658 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) =
default;
4659 ~json_sax_dom_callback_parser() =
default;
4663 handle_value(
nullptr);
4667 bool boolean(
bool val)
4673 bool number_integer(number_integer_t val)
4679 bool number_unsigned(number_unsigned_t val)
4685 bool number_float(number_float_t val,
const string_t& )
4691 bool string(string_t& val)
4697 bool start_object(std::size_t len)
4700 const bool keep = callback(
static_cast<
int>(ref_stack.size()), parse_event_t::object_start, discarded);
4701 keep_stack.push_back(keep);
4703 auto val = handle_value(BasicJsonType::value_t::object,
true);
4704 ref_stack.push_back(val.second);
4707 if (ref_stack.back()
and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1)
and len > ref_stack.back()->max_size()))
4709 JSON_THROW(out_of_range::create(408,
"excessive object size: " + std::to_string(len)));
4715 bool key(string_t& val)
4717 BasicJsonType k = BasicJsonType(val);
4720 const bool keep = callback(
static_cast<
int>(ref_stack.size()), parse_event_t::key, k);
4721 key_keep_stack.push_back(keep);
4724 if (keep
and ref_stack.back())
4726 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
4734 if (ref_stack.back()
and not callback(
static_cast<
int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
4737 *ref_stack.back() = discarded;
4740 assert(
not ref_stack.empty());
4741 assert(
not keep_stack.empty());
4742 ref_stack.pop_back();
4743 keep_stack.pop_back();
4745 if (
not ref_stack.empty()
and ref_stack.back()
and ref_stack.back()->is_object())
4748 for (
auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
4750 if (it->is_discarded())
4752 ref_stack.back()->erase(it);
4761 bool start_array(std::size_t len)
4763 const bool keep = callback(
static_cast<
int>(ref_stack.size()), parse_event_t::array_start, discarded);
4764 keep_stack.push_back(keep);
4766 auto val = handle_value(BasicJsonType::value_t::array,
true);
4767 ref_stack.push_back(val.second);
4770 if (ref_stack.back()
and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1)
and len > ref_stack.back()->max_size()))
4772 JSON_THROW(out_of_range::create(408,
"excessive array size: " + std::to_string(len)));
4782 if (ref_stack.back())
4784 keep = callback(
static_cast<
int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
4788 *ref_stack.back() = discarded;
4792 assert(
not ref_stack.empty());
4793 assert(
not keep_stack.empty());
4794 ref_stack.pop_back();
4795 keep_stack.pop_back();
4798 if (
not keep
and not ref_stack.empty()
and ref_stack.back()->is_array())
4800 ref_stack.back()->m_value.array->pop_back();
4806 bool parse_error(std::size_t ,
const std::string& ,
4807 const detail::exception& ex)
4810 if (allow_exceptions)
4813 switch ((ex.id / 100) % 100)
4816 JSON_THROW(*
static_cast<
const detail::parse_error*>(&ex));
4818 JSON_THROW(*
static_cast<
const detail::out_of_range*>(&ex));
4821 JSON_THROW(*
static_cast<
const detail::invalid_iterator*>(&ex));
4823 JSON_THROW(*
static_cast<
const detail::type_error*>(&ex));
4825 JSON_THROW(*
static_cast<
const detail::other_error*>(&ex));
4834 constexpr bool is_errored()
const
4855 template<
typename Value>
4856 std::pair<
bool, BasicJsonType*> handle_value(Value&& v,
const bool skip_callback =
false)
4858 assert(
not keep_stack.empty());
4862 if (
not keep_stack.back())
4864 return {
false,
nullptr};
4868 auto value = BasicJsonType(std::forward<Value>(v));
4871 const bool keep = skip_callback
or callback(
static_cast<
int>(ref_stack.size()), parse_event_t::value, value);
4876 return {
false,
nullptr};
4879 if (ref_stack.empty())
4881 root = std::move(value);
4882 return {
true, &root};
4887 if (
not ref_stack.back())
4889 return {
false,
nullptr};
4893 assert(ref_stack.back()->is_array()
or ref_stack.back()->is_object());
4896 if (ref_stack.back()->is_array())
4898 ref_stack.back()->m_value.array->push_back(std::move(value));
4899 return {
true, &(ref_stack.back()->m_value.array->back())};
4903 assert(ref_stack.back()->is_object());
4905 assert(
not key_keep_stack.empty());
4906 const bool store_element = key_keep_stack.back();
4907 key_keep_stack.pop_back();
4909 if (
not store_element)
4911 return {
false,
nullptr};
4914 assert(object_element);
4915 *object_element = std::move(value);
4916 return {
true, object_element};
4920 BasicJsonType& root;
4922 std::vector<BasicJsonType*> ref_stack {};
4924 std::vector<
bool> keep_stack {};
4926 std::vector<
bool> key_keep_stack {};
4928 BasicJsonType* object_element =
nullptr;
4930 bool errored =
false;
4932 const parser_callback_t callback =
nullptr;
4934 const bool allow_exceptions =
true;
4936 BasicJsonType discarded = BasicJsonType::value_t::discarded;
4939 template<
typename BasicJsonType>
4940 class json_sax_acceptor
4943 using number_integer_t =
typename BasicJsonType::number_integer_t;
4944 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
4945 using number_float_t =
typename BasicJsonType::number_float_t;
4946 using string_t =
typename BasicJsonType::string_t;
4958 bool number_integer(number_integer_t )
4963 bool number_unsigned(number_unsigned_t )
4968 bool number_float(number_float_t ,
const string_t& )
4973 bool string(string_t& )
4978 bool start_object(std::size_t = std::size_t(-1))
4983 bool key(string_t& )
4993 bool start_array(std::size_t = std::size_t(-1))
5003 bool parse_error(std::size_t ,
const std::string& ,
const detail::exception& )
5030 template <
typename T>
5031 using null_function_t =
decltype(std::declval<T&>().null());
5033 template <
typename T>
5034 using boolean_function_t =
5035 decltype(std::declval<T&>().boolean(std::declval<
bool>()));
5037 template <
typename T,
typename Integer>
5038 using number_integer_function_t =
5039 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
5041 template <
typename T,
typename Unsigned>
5042 using number_unsigned_function_t =
5043 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
5045 template <
typename T,
typename Float,
typename String>
5046 using number_float_function_t =
decltype(std::declval<T&>().number_float(
5047 std::declval<Float>(), std::declval<
const String&>()));
5049 template <
typename T,
typename String>
5050 using string_function_t =
5051 decltype(std::declval<T&>().string(std::declval<String&>()));
5053 template <
typename T>
5054 using start_object_function_t =
5055 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
5057 template <
typename T,
typename String>
5058 using key_function_t =
5059 decltype(std::declval<T&>().key(std::declval<String&>()));
5061 template <
typename T>
5062 using end_object_function_t =
decltype(std::declval<T&>().end_object());
5064 template <
typename T>
5065 using start_array_function_t =
5066 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
5068 template <
typename T>
5069 using end_array_function_t =
decltype(std::declval<T&>().end_array());
5071 template <
typename T,
typename Exception>
5072 using parse_error_function_t =
decltype(std::declval<T&>().parse_error(
5073 std::declval<std::size_t>(), std::declval<
const std::string&>(),
5074 std::declval<
const Exception&>()));
5076 template <
typename SAX,
typename BasicJsonType>
5080 static_assert(is_basic_json<BasicJsonType>::value,
5081 "BasicJsonType must be of type basic_json<...>");
5083 using number_integer_t =
typename BasicJsonType::number_integer_t;
5084 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
5085 using number_float_t =
typename BasicJsonType::number_float_t;
5086 using string_t =
typename BasicJsonType::string_t;
5087 using exception_t =
typename BasicJsonType::exception;
5090 static constexpr bool value =
5091 is_detected_exact<
bool, null_function_t, SAX>::value &&
5092 is_detected_exact<
bool, boolean_function_t, SAX>::value &&
5093 is_detected_exact<
bool, number_integer_function_t, SAX,
5094 number_integer_t>::value &&
5095 is_detected_exact<
bool, number_unsigned_function_t, SAX,
5096 number_unsigned_t>::value &&
5097 is_detected_exact<
bool, number_float_function_t, SAX, number_float_t,
5099 is_detected_exact<
bool, string_function_t, SAX, string_t>::value &&
5100 is_detected_exact<
bool, start_object_function_t, SAX>::value &&
5101 is_detected_exact<
bool, key_function_t, SAX, string_t>::value &&
5102 is_detected_exact<
bool, end_object_function_t, SAX>::value &&
5103 is_detected_exact<
bool, start_array_function_t, SAX>::value &&
5104 is_detected_exact<
bool, end_array_function_t, SAX>::value &&
5105 is_detected_exact<
bool, parse_error_function_t, SAX, exception_t>::value;
5108 template <
typename SAX,
typename BasicJsonType>
5109 struct is_sax_static_asserts
5112 static_assert(is_basic_json<BasicJsonType>::value,
5113 "BasicJsonType must be of type basic_json<...>");
5115 using number_integer_t =
typename BasicJsonType::number_integer_t;
5116 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
5117 using number_float_t =
typename BasicJsonType::number_float_t;
5118 using string_t =
typename BasicJsonType::string_t;
5119 using exception_t =
typename BasicJsonType::exception;
5122 static_assert(is_detected_exact<
bool, null_function_t, SAX>::value,
5123 "Missing/invalid function: bool null()");
5124 static_assert(is_detected_exact<
bool, boolean_function_t, SAX>::value,
5125 "Missing/invalid function: bool boolean(bool)");
5126 static_assert(is_detected_exact<
bool, boolean_function_t, SAX>::value,
5127 "Missing/invalid function: bool boolean(bool)");
5129 is_detected_exact<
bool, number_integer_function_t, SAX,
5130 number_integer_t>::value,
5131 "Missing/invalid function: bool number_integer(number_integer_t)");
5133 is_detected_exact<
bool, number_unsigned_function_t, SAX,
5134 number_unsigned_t>::value,
5135 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
5136 static_assert(is_detected_exact<
bool, number_float_function_t, SAX,
5137 number_float_t, string_t>::value,
5138 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
5140 is_detected_exact<
bool, string_function_t, SAX, string_t>::value,
5141 "Missing/invalid function: bool string(string_t&)");
5142 static_assert(is_detected_exact<
bool, start_object_function_t, SAX>::value,
5143 "Missing/invalid function: bool start_object(std::size_t)");
5144 static_assert(is_detected_exact<
bool, key_function_t, SAX, string_t>::value,
5145 "Missing/invalid function: bool key(string_t&)");
5146 static_assert(is_detected_exact<
bool, end_object_function_t, SAX>::value,
5147 "Missing/invalid function: bool end_object()");
5148 static_assert(is_detected_exact<
bool, start_array_function_t, SAX>::value,
5149 "Missing/invalid function: bool start_array(std::size_t)");
5150 static_assert(is_detected_exact<
bool, end_array_function_t, SAX>::value,
5151 "Missing/invalid function: bool end_array()");
5153 is_detected_exact<
bool, parse_error_function_t, SAX, exception_t>::value,
5154 "Missing/invalid function: bool parse_error(std::size_t, const "
5155 "std::string&, const exception&)");
5174 template<
typename BasicJsonType,
typename SAX = json_sax_dom_parser<BasicJsonType>>
5177 using number_integer_t =
typename BasicJsonType::number_integer_t;
5178 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
5179 using number_float_t =
typename BasicJsonType::number_float_t;
5180 using string_t =
typename BasicJsonType::string_t;
5181 using json_sax_t = SAX;
5189 explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
5191 (
void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
5196 binary_reader(
const binary_reader&) =
delete;
5197 binary_reader(binary_reader&&) =
default;
5198 binary_reader& operator=(
const binary_reader&) =
delete;
5199 binary_reader& operator=(binary_reader&&) =
default;
5200 ~binary_reader() =
default;
5210 bool sax_parse(
const input_format_t format,
5212 const bool strict =
true)
5215 bool result =
false;
5219 case input_format_t::bson:
5220 result = parse_bson_internal();
5223 case input_format_t::cbor:
5224 result = parse_cbor_internal();
5227 case input_format_t::msgpack:
5228 result = parse_msgpack_internal();
5231 case input_format_t::ubjson:
5232 result = parse_ubjson_internal();
5240 if (result
and strict)
5242 if (format == input_format_t::ubjson)
5253 return sax->parse_error(chars_read, get_token_string(),
5254 parse_error::create(110, chars_read, exception_message(format,
"expected end of input; last byte: 0x" + get_token_string(),
"value")));
5268 static constexpr bool little_endianess(
int num = 1)
noexcept
5270 return *
reinterpret_cast<
char*>(&num) == 1;
5282 bool parse_bson_internal()
5284 std::int32_t document_size;
5285 get_number<std::int32_t,
true>(input_format_t::bson, document_size);
5297 return sax->end_object();
5307 bool get_bson_cstr(string_t& result)
5309 auto out = std::back_inserter(result);
5317 if (current == 0x00)
5321 *out++ =
static_cast<
char>(current);
5338 template<
typename NumberType>
5339 bool get_bson_string(
const NumberType len, string_t& result)
5343 auto last_token = get_token_string();
5344 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")));
5347 return get_string(input_format_t::bson, len -
static_cast<NumberType>(1), result)
and get() != std::char_traits<
char>::eof();
5360 bool parse_bson_element_internal(
const int element_type,
5361 const std::size_t element_type_parse_position)
5363 switch (element_type)
5368 return get_number<
double,
true>(input_format_t::bson, number)
and sax->number_float(
static_cast<number_float_t>(number),
"");
5375 return get_number<std::int32_t,
true>(input_format_t::bson, len)
and get_bson_string(len, value)
and sax->string(value);
5380 return parse_bson_internal();
5385 return parse_bson_array();
5390 return sax->boolean(get() != 0);
5401 return get_number<std::int32_t,
true>(input_format_t::bson, value)
and sax->number_integer(value);
5407 return get_number<std::int64_t,
true>(input_format_t::bson, value)
and sax->number_integer(value);
5412 std::array<
char, 3> cr{{}};
5413 (std::snprintf)(cr.data(), cr.size(),
"%.2hhX",
static_cast<
unsigned char>(element_type));
5414 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())));
5431 bool parse_bson_element_list(
const bool is_array)
5434 while (
int element_type = get())
5441 const std::size_t element_type_parse_position = chars_read;
5447 if (
not is_array
and not sax->key(key))
5452 if (
JSON_HEDLEY_UNLIKELY(
not parse_bson_element_internal(element_type, element_type_parse_position)))
5468 bool parse_bson_array()
5470 std::int32_t document_size;
5471 get_number<std::int32_t,
true>(input_format_t::bson, document_size);
5483 return sax->end_array();
5497 bool parse_cbor_internal(
const bool get_char =
true)
5499 switch (get_char ? get() : current)
5502 case std::char_traits<
char>::eof():
5503 return unexpect_eof(input_format_t::cbor,
"value");
5530 return sax->number_unsigned(
static_cast<number_unsigned_t>(current));
5534 std::uint8_t number;
5535 return get_number(input_format_t::cbor, number)
and sax->number_unsigned(number);
5540 std::uint16_t number;
5541 return get_number(input_format_t::cbor, number)
and sax->number_unsigned(number);
5546 std::uint32_t number;
5547 return get_number(input_format_t::cbor, number)
and sax->number_unsigned(number);
5552 std::uint64_t number;
5553 return get_number(input_format_t::cbor, number)
and sax->number_unsigned(number);
5581 return sax->number_integer(
static_cast<std::int8_t>(0x20 - 1 - current));
5585 std::uint8_t number;
5586 return get_number(input_format_t::cbor, number)
and sax->number_integer(
static_cast<number_integer_t>(-1) - number);
5591 std::uint16_t number;
5592 return get_number(input_format_t::cbor, number)
and sax->number_integer(
static_cast<number_integer_t>(-1) - number);
5597 std::uint32_t number;
5598 return get_number(input_format_t::cbor, number)
and sax->number_integer(
static_cast<number_integer_t>(-1) - number);
5603 std::uint64_t number;
5604 return get_number(input_format_t::cbor, number)
and sax->number_integer(
static_cast<number_integer_t>(-1)
5605 -
static_cast<number_integer_t>(number));
5640 return get_cbor_string(s)
and sax->string(s);
5668 return get_cbor_array(
static_cast<std::size_t>(
static_cast<
unsigned int>(current) & 0x1Fu));
5673 return get_number(input_format_t::cbor, len)
and get_cbor_array(
static_cast<std::size_t>(len));
5679 return get_number(input_format_t::cbor, len)
and get_cbor_array(
static_cast<std::size_t>(len));
5685 return get_number(input_format_t::cbor, len)
and get_cbor_array(
static_cast<std::size_t>(len));
5691 return get_number(input_format_t::cbor, len)
and get_cbor_array(
static_cast<std::size_t>(len));
5695 return get_cbor_array(std::size_t(-1));
5722 return get_cbor_object(
static_cast<std::size_t>(
static_cast<
unsigned int>(current) & 0x1Fu));
5727 return get_number(input_format_t::cbor, len)
and get_cbor_object(
static_cast<std::size_t>(len));
5733 return get_number(input_format_t::cbor, len)
and get_cbor_object(
static_cast<std::size_t>(len));
5739 return get_number(input_format_t::cbor, len)
and get_cbor_object(
static_cast<std::size_t>(len));
5745 return get_number(input_format_t::cbor, len)
and get_cbor_object(
static_cast<std::size_t>(len));
5749 return get_cbor_object(std::size_t(-1));
5752 return sax->boolean(
false);
5755 return sax->boolean(
true);
5762 const int byte1_raw = get();
5767 const int byte2_raw = get();
5773 const auto byte1 =
static_cast<
unsigned char>(byte1_raw);
5774 const auto byte2 =
static_cast<
unsigned char>(byte2_raw);
5784 const auto half =
static_cast<
unsigned int>((byte1 << 8u) + byte2);
5785 const double val = [&half]
5787 const int exp = (half >> 10u) & 0x1Fu;
5788 const unsigned int mant = half & 0x3FFu;
5789 assert(0 <= exp
and exp <= 32);
5790 assert(mant <= 1024);
5794 return std::ldexp(mant, -24);
5797 ? std::numeric_limits<
double>::infinity()
5798 : std::numeric_limits<
double>::quiet_NaN();
5800 return std::ldexp(mant + 1024, exp - 25);
5803 return sax->number_float((half & 0x8000u) != 0
5804 ?
static_cast<number_float_t>(-val)
5805 :
static_cast<number_float_t>(val),
"");
5811 return get_number(input_format_t::cbor, number)
and sax->number_float(
static_cast<number_float_t>(number),
"");
5817 return get_number(input_format_t::cbor, number)
and sax->number_float(
static_cast<number_float_t>(number),
"");
5822 auto last_token = get_token_string();
5823 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")));
5839 bool get_cbor_string(string_t& result)
5874 return get_string(input_format_t::cbor,
static_cast<
unsigned int>(current) & 0x1Fu, result);
5880 return get_number(input_format_t::cbor, len)
and get_string(input_format_t::cbor, len, result);
5886 return get_number(input_format_t::cbor, len)
and get_string(input_format_t::cbor, len, result);
5892 return get_number(input_format_t::cbor, len)
and get_string(input_format_t::cbor, len, result);
5898 return get_number(input_format_t::cbor, len)
and get_string(input_format_t::cbor, len, result);
5903 while (get() != 0xFF)
5906 if (
not get_cbor_string(chunk))
5910 result.append(chunk);
5917 auto last_token = get_token_string();
5918 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")));
5928 bool get_cbor_array(
const std::size_t len)
5935 if (len != std::size_t(-1))
5937 for (std::size_t i = 0; i < len; ++i)
5947 while (get() != 0xFF)
5956 return sax->end_array();
5964 bool get_cbor_object(
const std::size_t len)
5972 if (len != std::size_t(-1))
5974 for (std::size_t i = 0; i < len; ++i)
5991 while (get() != 0xFF)
6006 return sax->end_object();
6016 bool parse_msgpack_internal()
6021 case std::char_traits<
char>::eof():
6022 return unexpect_eof(input_format_t::msgpack,
"value");
6153 return sax->number_unsigned(
static_cast<number_unsigned_t>(current));
6172 return get_msgpack_object(
static_cast<std::size_t>(
static_cast<
unsigned int>(current) & 0x0Fu));
6191 return get_msgpack_array(
static_cast<std::size_t>(
static_cast<
unsigned int>(current) & 0x0Fu));
6231 return get_msgpack_string(s)
and sax->string(s);
6238 return sax->boolean(
false);
6241 return sax->boolean(
true);
6246 return get_number(input_format_t::msgpack, number)
and sax->number_float(
static_cast<number_float_t>(number),
"");
6252 return get_number(input_format_t::msgpack, number)
and sax->number_float(
static_cast<number_float_t>(number),
"");
6257 std::uint8_t number;
6258 return get_number(input_format_t::msgpack, number)
and sax->number_unsigned(number);
6263 std::uint16_t number;
6264 return get_number(input_format_t::msgpack, number)
and sax->number_unsigned(number);
6269 std::uint32_t number;
6270 return get_number(input_format_t::msgpack, number)
and sax->number_unsigned(number);
6275 std::uint64_t number;
6276 return get_number(input_format_t::msgpack, number)
and sax->number_unsigned(number);
6282 return get_number(input_format_t::msgpack, number)
and sax->number_integer(number);
6287 std::int16_t number;
6288 return get_number(input_format_t::msgpack, number)
and sax->number_integer(number);
6293 std::int32_t number;
6294 return get_number(input_format_t::msgpack, number)
and sax->number_integer(number);
6299 std::int64_t number;
6300 return get_number(input_format_t::msgpack, number)
and sax->number_integer(number);
6306 return get_number(input_format_t::msgpack, len)
and get_msgpack_array(
static_cast<std::size_t>(len));
6312 return get_number(input_format_t::msgpack, len)
and get_msgpack_array(
static_cast<std::size_t>(len));
6318 return get_number(input_format_t::msgpack, len)
and get_msgpack_object(
static_cast<std::size_t>(len));
6324 return get_number(input_format_t::msgpack, len)
and get_msgpack_object(
static_cast<std::size_t>(len));
6360 return sax->number_integer(
static_cast<std::int8_t>(current));
6364 auto last_token = get_token_string();
6365 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")));
6380 bool get_msgpack_string(string_t& result)
6423 return get_string(input_format_t::msgpack,
static_cast<
unsigned int>(current) & 0x1Fu, result);
6429 return get_number(input_format_t::msgpack, len)
and get_string(input_format_t::msgpack, len, result);
6435 return get_number(input_format_t::msgpack, len)
and get_string(input_format_t::msgpack, len, result);
6441 return get_number(input_format_t::msgpack, len)
and get_string(input_format_t::msgpack, len, result);
6446 auto last_token = get_token_string();
6447 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")));
6456 bool get_msgpack_array(
const std::size_t len)
6463 for (std::size_t i = 0; i < len; ++i)
6471 return sax->end_array();
6478 bool get_msgpack_object(
const std::size_t len)
6486 for (std::size_t i = 0; i < len; ++i)
6501 return sax->end_object();
6515 bool parse_ubjson_internal(
const bool get_char =
true)
6517 return get_ubjson_value(get_char ? get_ignore_noop() : current);
6534 bool get_ubjson_string(string_t& result,
const bool get_char =
true)
6551 return get_number(input_format_t::ubjson, len)
and get_string(input_format_t::ubjson, len, result);
6557 return get_number(input_format_t::ubjson, len)
and get_string(input_format_t::ubjson, len, result);
6563 return get_number(input_format_t::ubjson, len)
and get_string(input_format_t::ubjson, len, result);
6569 return get_number(input_format_t::ubjson, len)
and get_string(input_format_t::ubjson, len, result);
6575 return get_number(input_format_t::ubjson, len)
and get_string(input_format_t::ubjson, len, result);
6579 auto last_token = get_token_string();
6580 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")));
6588 bool get_ubjson_size_value(std::size_t& result)
6590 switch (get_ignore_noop())
6594 std::uint8_t number;
6599 result =
static_cast<std::size_t>(number);
6610 result =
static_cast<std::size_t>(number);
6616 std::int16_t number;
6621 result =
static_cast<std::size_t>(number);
6627 std::int32_t number;
6632 result =
static_cast<std::size_t>(number);
6638 std::int64_t number;
6643 result =
static_cast<std::size_t>(number);
6649 auto last_token = get_token_string();
6650 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")));
6665 bool get_ubjson_size_type(std::pair<std::size_t,
int>& result)
6667 result.first = string_t::npos;
6674 result.second = get();
6687 auto last_token = get_token_string();
6688 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")));
6691 return get_ubjson_size_value(result.first);
6696 return get_ubjson_size_value(result.first);
6706 bool get_ubjson_value(
const int prefix)
6710 case std::char_traits<
char>::eof():
6711 return unexpect_eof(input_format_t::ubjson,
"value");
6714 return sax->boolean(
true);
6716 return sax->boolean(
false);
6723 std::uint8_t number;
6724 return get_number(input_format_t::ubjson, number)
and sax->number_unsigned(number);
6730 return get_number(input_format_t::ubjson, number)
and sax->number_integer(number);
6735 std::int16_t number;
6736 return get_number(input_format_t::ubjson, number)
and sax->number_integer(number);
6741 std::int32_t number;
6742 return get_number(input_format_t::ubjson, number)
and sax->number_integer(number);
6747 std::int64_t number;
6748 return get_number(input_format_t::ubjson, number)
and sax->number_integer(number);
6754 return get_number(input_format_t::ubjson, number)
and sax->number_float(
static_cast<number_float_t>(number),
"");
6760 return get_number(input_format_t::ubjson, number)
and sax->number_float(
static_cast<number_float_t>(number),
"");
6772 auto last_token = get_token_string();
6773 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")));
6775 string_t s(1,
static_cast<
char>(current));
6776 return sax->string(s);
6782 return get_ubjson_string(s)
and sax->string(s);
6786 return get_ubjson_array();
6789 return get_ubjson_object();
6793 auto last_token = get_token_string();
6794 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")));
6802 bool get_ubjson_array()
6804 std::pair<std::size_t,
int> size_and_type;
6810 if (size_and_type.first != string_t::npos)
6817 if (size_and_type.second != 0)
6819 if (size_and_type.second !=
'N')
6821 for (std::size_t i = 0; i < size_and_type.first; ++i)
6832 for (std::size_t i = 0; i < size_and_type.first; ++i)
6848 while (current !=
']')
6858 return sax->end_array();
6864 bool get_ubjson_object()
6866 std::pair<std::size_t,
int> size_and_type;
6873 if (size_and_type.first != string_t::npos)
6880 if (size_and_type.second != 0)
6882 for (std::size_t i = 0; i < size_and_type.first; ++i)
6897 for (std::size_t i = 0; i < size_and_type.first; ++i)
6918 while (current !=
'}')
6933 return sax->end_object();
6952 return current = ia->get_character();
6958 int get_ignore_noop()
6964 while (current ==
'N');
6982 template<
typename NumberType,
bool InputIsLittleEndian =
false>
6983 bool get_number(
const input_format_t format, NumberType& result)
6986 std::array<std::uint8_t,
sizeof(NumberType)> vec;
6987 for (std::size_t i = 0; i <
sizeof(NumberType); ++i)
6996 if (is_little_endian != InputIsLittleEndian)
6998 vec[
sizeof(NumberType) - i - 1] =
static_cast<std::uint8_t>(current);
7002 vec[i] =
static_cast<std::uint8_t>(current);
7007 std::memcpy(&result, vec.data(),
sizeof(NumberType));
7025 template<
typename NumberType>
7026 bool get_string(
const input_format_t format,
7027 const NumberType len,
7030 bool success =
true;
7031 std::generate_n(std::back_inserter(result), len, [
this, &success, &format]()
7038 return static_cast<
char>(current);
7049 bool unexpect_eof(
const input_format_t format,
const char* context)
const
7053 return sax->parse_error(chars_read,
"<end of file>",
7054 parse_error::create(110, chars_read, exception_message(format,
"unexpected end of input", context)));
7062 std::string get_token_string()
const
7064 std::array<
char, 3> cr{{}};
7065 (std::snprintf)(cr.data(), cr.size(),
"%.2hhX",
static_cast<
unsigned char>(current));
7066 return std::string{cr.data()};
7075 std::string exception_message(
const input_format_t format,
7076 const std::string& detail,
7077 const std::string& context)
const
7079 std::string error_msg =
"syntax error while parsing ";
7083 case input_format_t::cbor:
7084 error_msg +=
"CBOR";
7087 case input_format_t::msgpack:
7088 error_msg +=
"MessagePack";
7091 case input_format_t::ubjson:
7092 error_msg +=
"UBJSON";
7095 case input_format_t::bson:
7096 error_msg +=
"BSON";
7103 return error_msg +
" " + context +
": " + detail;
7108 input_adapter_t ia =
nullptr;
7111 int current = std::char_traits<
char>::eof();
7114 std::size_t chars_read = 0;
7117 const bool is_little_endian = little_endianess();
7120 json_sax_t* sax =
nullptr;
7135 #include <initializer_list>
7160 template<
typename BasicJsonType>
7163 using number_integer_t =
typename BasicJsonType::number_integer_t;
7164 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
7165 using number_float_t =
typename BasicJsonType::number_float_t;
7166 using string_t =
typename BasicJsonType::string_t;
7170 enum class token_type
7194 static const char* token_type_name(
const token_type t)
noexcept
7198 case token_type::uninitialized:
7199 return "<uninitialized>";
7200 case token_type::literal_true:
7201 return "true literal";
7202 case token_type::literal_false:
7203 return "false literal";
7204 case token_type::literal_null:
7205 return "null literal";
7206 case token_type::value_string:
7207 return "string literal";
7208 case lexer::token_type::value_unsigned:
7209 case lexer::token_type::value_integer:
7210 case lexer::token_type::value_float:
7211 return "number literal";
7212 case token_type::begin_array:
7214 case token_type::begin_object:
7216 case token_type::end_array:
7218 case token_type::end_object:
7220 case token_type::name_separator:
7222 case token_type::value_separator:
7224 case token_type::parse_error:
7225 return "<parse error>";
7226 case token_type::end_of_input:
7227 return "end of input";
7228 case token_type::literal_or_value:
7229 return "'[', '{', or a literal";
7232 return "unknown token";
7237 explicit lexer(detail::input_adapter_t&& adapter)
7238 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
7241 lexer(
const lexer&) =
delete;
7242 lexer(lexer&&) =
delete;
7243 lexer& operator=(lexer&) =
delete;
7244 lexer& operator=(lexer&&) =
delete;
7254 static char get_decimal_point()
noexcept
7256 const auto loc = localeconv();
7257 assert(loc !=
nullptr);
7258 return (loc->decimal_point ==
nullptr) ?
'.' : *(loc->decimal_point);
7283 assert(current ==
'u');
7286 const auto factors = { 12u, 8u, 4u, 0u };
7287 for (
const auto factor : factors)
7291 if (current >=
'0' and current <=
'9')
7293 codepoint +=
static_cast<
int>((
static_cast<
unsigned int>(current) - 0x30u) << factor);
7295 else if (current >=
'A' and current <=
'F')
7297 codepoint +=
static_cast<
int>((
static_cast<
unsigned int>(current) - 0x37u) << factor);
7299 else if (current >=
'a' and current <=
'f')
7301 codepoint +=
static_cast<
int>((
static_cast<
unsigned int>(current) - 0x57u) << factor);
7309 assert(0x0000 <= codepoint
and codepoint <= 0xFFFF);
7328 bool next_byte_in_range(std::initializer_list<
int> ranges)
7330 assert(ranges.size() == 2
or ranges.size() == 4
or ranges.size() == 6);
7333 for (
auto range = ranges.begin(); range != ranges.end(); ++range)
7342 error_message =
"invalid string: ill-formed UTF-8 byte";
7365 token_type scan_string()
7371 assert(current ==
'\"');
7379 case std::char_traits<
char>::eof():
7381 error_message =
"invalid string: missing closing quote";
7382 return token_type::parse_error;
7388 return token_type::value_string;
7432 const int codepoint1 = get_codepoint();
7433 int codepoint = codepoint1;
7437 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
7438 return token_type::parse_error;
7442 if (0xD800 <= codepoint1
and codepoint1 <= 0xDBFF)
7447 const int codepoint2 = get_codepoint();
7451 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
7452 return token_type::parse_error;
7459 codepoint =
static_cast<
int>(
7461 (
static_cast<
unsigned int>(codepoint1) << 10u)
7463 +
static_cast<
unsigned int>(codepoint2)
7471 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
7472 return token_type::parse_error;
7477 error_message =
"invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
7478 return token_type::parse_error;
7485 error_message =
"invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
7486 return token_type::parse_error;
7491 assert(0x00 <= codepoint
and codepoint <= 0x10FFFF);
7494 if (codepoint < 0x80)
7499 else if (codepoint <= 0x7FF)
7502 add(
static_cast<
int>(0xC0u | (
static_cast<
unsigned int>(codepoint) >> 6u)));
7503 add(
static_cast<
int>(0x80u | (
static_cast<
unsigned int>(codepoint) & 0x3Fu)));
7505 else if (codepoint <= 0xFFFF)
7508 add(
static_cast<
int>(0xE0u | (
static_cast<
unsigned int>(codepoint) >> 12u)));
7509 add(
static_cast<
int>(0x80u | ((
static_cast<
unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7510 add(
static_cast<
int>(0x80u | (
static_cast<
unsigned int>(codepoint) & 0x3Fu)));
7515 add(
static_cast<
int>(0xF0u | (
static_cast<
unsigned int>(codepoint) >> 18u)));
7516 add(
static_cast<
int>(0x80u | ((
static_cast<
unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7517 add(
static_cast<
int>(0x80u | ((
static_cast<
unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7518 add(
static_cast<
int>(0x80u | (
static_cast<
unsigned int>(codepoint) & 0x3Fu)));
7526 error_message =
"invalid string: forbidden character after backslash";
7527 return token_type::parse_error;
7536 error_message =
"invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7537 return token_type::parse_error;
7542 error_message =
"invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7543 return token_type::parse_error;
7548 error_message =
"invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7549 return token_type::parse_error;
7554 error_message =
"invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7555 return token_type::parse_error;
7560 error_message =
"invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7561 return token_type::parse_error;
7566 error_message =
"invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7567 return token_type::parse_error;
7572 error_message =
"invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7573 return token_type::parse_error;
7578 error_message =
"invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7579 return token_type::parse_error;
7584 error_message =
"invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7585 return token_type::parse_error;
7590 error_message =
"invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7591 return token_type::parse_error;
7596 error_message =
"invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7597 return token_type::parse_error;
7602 error_message =
"invalid string: control character U+000B (VT) must be escaped to \\u000B";
7603 return token_type::parse_error;
7608 error_message =
"invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7609 return token_type::parse_error;
7614 error_message =
"invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7615 return token_type::parse_error;
7620 error_message =
"invalid string: control character U+000E (SO) must be escaped to \\u000E";
7621 return token_type::parse_error;
7626 error_message =
"invalid string: control character U+000F (SI) must be escaped to \\u000F";
7627 return token_type::parse_error;
7632 error_message =
"invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7633 return token_type::parse_error;
7638 error_message =
"invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7639 return token_type::parse_error;
7644 error_message =
"invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7645 return token_type::parse_error;
7650 error_message =
"invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7651 return token_type::parse_error;
7656 error_message =
"invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7657 return token_type::parse_error;
7662 error_message =
"invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7663 return token_type::parse_error;
7668 error_message =
"invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7669 return token_type::parse_error;
7674 error_message =
"invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7675 return token_type::parse_error;
7680 error_message =
"invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7681 return token_type::parse_error;
7686 error_message =
"invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7687 return token_type::parse_error;
7692 error_message =
"invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7693 return token_type::parse_error;
7698 error_message =
"invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7699 return token_type::parse_error;
7704 error_message =
"invalid string: control character U+001C (FS) must be escaped to \\u001C";
7705 return token_type::parse_error;
7710 error_message =
"invalid string: control character U+001D (GS) must be escaped to \\u001D";
7711 return token_type::parse_error;
7716 error_message =
"invalid string: control character U+001E (RS) must be escaped to \\u001E";
7717 return token_type::parse_error;
7722 error_message =
"invalid string: control character U+001F (US) must be escaped to \\u001F";
7723 return token_type::parse_error;
7860 return token_type::parse_error;
7870 return token_type::parse_error;
7894 return token_type::parse_error;
7904 return token_type::parse_error;
7914 return token_type::parse_error;
7926 return token_type::parse_error;
7936 return token_type::parse_error;
7944 error_message =
"invalid string: ill-formed UTF-8 byte";
7945 return token_type::parse_error;
7952 static void strtof(
float& f,
const char* str,
char** endptr)
noexcept
7954 f = std::strtof(str, endptr);
7958 static void strtof(
double& f,
const char* str,
char** endptr)
noexcept
7960 f = std::strtod(str, endptr);
7964 static void strtof(
long double& f,
const char* str,
char** endptr)
noexcept
7966 f = std::strtold(str, endptr);
8009 token_type scan_number()
8016 token_type number_type = token_type::value_unsigned;
8024 goto scan_number_minus;
8030 goto scan_number_zero;
8044 goto scan_number_any1;
8054 number_type = token_type::value_integer;
8060 goto scan_number_zero;
8074 goto scan_number_any1;
8079 error_message =
"invalid number; expected digit after '-'";
8080 return token_type::parse_error;
8090 add(decimal_point_char);
8091 goto scan_number_decimal1;
8098 goto scan_number_exponent;
8102 goto scan_number_done;
8121 goto scan_number_any1;
8126 add(decimal_point_char);
8127 goto scan_number_decimal1;
8134 goto scan_number_exponent;
8138 goto scan_number_done;
8141 scan_number_decimal1:
8143 number_type = token_type::value_float;
8158 goto scan_number_decimal2;
8163 error_message =
"invalid number; expected digit after '.'";
8164 return token_type::parse_error;
8168 scan_number_decimal2:
8184 goto scan_number_decimal2;
8191 goto scan_number_exponent;
8195 goto scan_number_done;
8198 scan_number_exponent:
8200 number_type = token_type::value_float;
8207 goto scan_number_sign;
8222 goto scan_number_any2;
8228 "invalid number; expected '+', '-', or digit after exponent";
8229 return token_type::parse_error;
8249 goto scan_number_any2;
8254 error_message =
"invalid number; expected digit after exponent sign";
8255 return token_type::parse_error;
8275 goto scan_number_any2;
8279 goto scan_number_done;
8287 char* endptr =
nullptr;
8291 if (number_type == token_type::value_unsigned)
8293 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
8296 assert(endptr == token_buffer.data() + token_buffer.size());
8300 value_unsigned =
static_cast<number_unsigned_t>(x);
8301 if (value_unsigned == x)
8303 return token_type::value_unsigned;
8307 else if (number_type == token_type::value_integer)
8309 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
8312 assert(endptr == token_buffer.data() + token_buffer.size());
8316 value_integer =
static_cast<number_integer_t>(x);
8317 if (value_integer == x)
8319 return token_type::value_integer;
8326 strtof(value_float, token_buffer.data(), &endptr);
8329 assert(endptr == token_buffer.data() + token_buffer.size());
8331 return token_type::value_float;
8340 token_type scan_literal(
const char* literal_text,
const std::size_t length,
8341 token_type return_type)
8343 assert(current == literal_text[0]);
8344 for (std::size_t i = 1; i < length; ++i)
8348 error_message =
"invalid literal";
8349 return token_type::parse_error;
8360 void reset()
noexcept
8362 token_buffer.clear();
8363 token_string.clear();
8364 token_string.push_back(std::char_traits<
char>::to_char_type(current));
8377 std::char_traits<
char>::int_type get()
8379 ++position.chars_read_total;
8380 ++position.chars_read_current_line;
8389 current = ia->get_character();
8394 token_string.push_back(std::char_traits<
char>::to_char_type(current));
8397 if (current ==
'\n')
8399 ++position.lines_read;
8400 position.chars_read_current_line = 0;
8418 --position.chars_read_total;
8421 if (position.chars_read_current_line == 0)
8423 if (position.lines_read > 0)
8425 --position.lines_read;
8430 --position.chars_read_current_line;
8435 assert(
not token_string.empty());
8436 token_string.pop_back();
8443 token_buffer.push_back(std::char_traits<
char>::to_char_type(c));
8452 constexpr number_integer_t get_number_integer()
const noexcept
8454 return value_integer;
8458 constexpr number_unsigned_t get_number_unsigned()
const noexcept
8460 return value_unsigned;
8464 constexpr number_float_t get_number_float()
const noexcept
8470 string_t& get_string()
8472 return token_buffer;
8480 constexpr position_t get_position()
const noexcept
8488 std::string get_token_string()
const
8492 for (
const auto c : token_string)
8494 if (
'\x00' <= c
and c <=
'\x1F')
8497 std::array<
char, 9> cs{{}};
8498 (std::snprintf)(cs.data(), cs.size(),
"<U+%.4X>",
static_cast<
unsigned char>(c));
8499 result += cs.data();
8504 result.push_back(c);
8513 constexpr const char* get_error_message()
const noexcept
8515 return error_message;
8531 return get() == 0xBB
and get() == 0xBF;
8543 if (position.chars_read_total == 0
and not skip_bom())
8545 error_message =
"invalid BOM; must be 0xEF 0xBB 0xBF if given";
8546 return token_type::parse_error;
8554 while (current ==
' ' or current ==
'\t' or current ==
'\n' or current ==
'\r');
8560 return token_type::begin_array;
8562 return token_type::end_array;
8564 return token_type::begin_object;
8566 return token_type::end_object;
8568 return token_type::name_separator;
8570 return token_type::value_separator;
8574 return scan_literal(
"true", 4, token_type::literal_true);
8576 return scan_literal(
"false", 5, token_type::literal_false);
8578 return scan_literal(
"null", 4, token_type::literal_null);
8582 return scan_string();
8596 return scan_number();
8601 case std::char_traits<
char>::eof():
8602 return token_type::end_of_input;
8606 error_message =
"invalid literal";
8607 return token_type::parse_error;
8613 detail::input_adapter_t ia =
nullptr;
8616 std::char_traits<
char>::int_type current = std::char_traits<
char>::eof();
8619 bool next_unget =
false;
8622 position_t position {};
8625 std::vector<
char> token_string {};
8628 string_t token_buffer {};
8631 const char* error_message =
"";
8634 number_integer_t value_integer = 0;
8635 number_unsigned_t value_unsigned = 0;
8636 number_float_t value_float = 0;
8639 const char decimal_point_char =
'.';
8650 #include <functional>
8683 template<
typename BasicJsonType>
8686 using number_integer_t =
typename BasicJsonType::number_integer_t;
8687 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
8688 using number_float_t =
typename BasicJsonType::number_float_t;
8689 using string_t =
typename BasicJsonType::string_t;
8690 using lexer_t = lexer<BasicJsonType>;
8691 using token_type =
typename lexer_t::token_type;
8694 enum class parse_event_t : uint8_t
8710 using parser_callback_t =
8711 std::function<
bool(
int depth, parse_event_t event, BasicJsonType& parsed)>;
8714 explicit parser(detail::input_adapter_t&& adapter,
8715 const parser_callback_t cb =
nullptr,
8716 const bool allow_exceptions_ =
true)
8717 : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
8733 void parse(
const bool strict, BasicJsonType& result)
8737 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
8738 sax_parse_internal(&sdp);
8739 result.assert_invariant();
8742 if (strict
and (get_token() != token_type::end_of_input))
8744 sdp.parse_error(m_lexer.get_position(),
8745 m_lexer.get_token_string(),
8746 parse_error::create(101, m_lexer.get_position(),
8747 exception_message(token_type::end_of_input,
"value")));
8751 if (sdp.is_errored())
8753 result = value_t::discarded;
8759 if (result.is_discarded())
8766 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
8767 sax_parse_internal(&sdp);
8768 result.assert_invariant();
8771 if (strict
and (get_token() != token_type::end_of_input))
8773 sdp.parse_error(m_lexer.get_position(),
8774 m_lexer.get_token_string(),
8775 parse_error::create(101, m_lexer.get_position(),
8776 exception_message(token_type::end_of_input,
"value")));
8780 if (sdp.is_errored())
8782 result = value_t::discarded;
8794 bool accept(
const bool strict =
true)
8796 json_sax_acceptor<BasicJsonType> sax_acceptor;
8797 return sax_parse(&sax_acceptor, strict);
8800 template <
typename SAX>
8802 bool sax_parse(SAX* sax,
const bool strict =
true)
8804 (
void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
8805 const bool result = sax_parse_internal(sax);
8808 if (result
and strict
and (get_token() != token_type::end_of_input))
8810 return sax->parse_error(m_lexer.get_position(),
8811 m_lexer.get_token_string(),
8812 parse_error::create(101, m_lexer.get_position(),
8813 exception_message(token_type::end_of_input,
"value")));
8820 template <
typename SAX>
8822 bool sax_parse_internal(SAX* sax)
8826 std::vector<
bool> states;
8828 bool skip_to_state_evaluation =
false;
8832 if (
not skip_to_state_evaluation)
8837 case token_type::begin_object:
8845 if (get_token() == token_type::end_object)
8857 return sax->parse_error(m_lexer.get_position(),
8858 m_lexer.get_token_string(),
8859 parse_error::create(101, m_lexer.get_position(),
8860 exception_message(token_type::value_string,
"object key")));
8870 return sax->parse_error(m_lexer.get_position(),
8871 m_lexer.get_token_string(),
8872 parse_error::create(101, m_lexer.get_position(),
8873 exception_message(token_type::name_separator,
"object separator")));
8877 states.push_back(
false);
8884 case token_type::begin_array:
8892 if (get_token() == token_type::end_array)
8902 states.push_back(
true);
8908 case token_type::value_float:
8910 const auto res = m_lexer.get_number_float();
8914 return sax->parse_error(m_lexer.get_position(),
8915 m_lexer.get_token_string(),
8916 out_of_range::create(406,
"number overflow parsing '" + m_lexer.get_token_string() +
"'"));
8927 case token_type::literal_false:
8936 case token_type::literal_null:
8945 case token_type::literal_true:
8954 case token_type::value_integer:
8963 case token_type::value_string:
8972 case token_type::value_unsigned:
8981 case token_type::parse_error:
8984 return sax->parse_error(m_lexer.get_position(),
8985 m_lexer.get_token_string(),
8986 parse_error::create(101, m_lexer.get_position(),
8987 exception_message(token_type::uninitialized,
"value")));
8992 return sax->parse_error(m_lexer.get_position(),
8993 m_lexer.get_token_string(),
8994 parse_error::create(101, m_lexer.get_position(),
8995 exception_message(token_type::literal_or_value,
"value")));
9001 skip_to_state_evaluation =
false;
9014 if (get_token() == token_type::value_separator)
9033 assert(
not states.empty());
9035 skip_to_state_evaluation =
true;
9039 return sax->parse_error(m_lexer.get_position(),
9040 m_lexer.get_token_string(),
9041 parse_error::create(101, m_lexer.get_position(),
9042 exception_message(token_type::end_array,
"array")));
9047 if (get_token() == token_type::value_separator)
9052 return sax->parse_error(m_lexer.get_position(),
9053 m_lexer.get_token_string(),
9054 parse_error::create(101, m_lexer.get_position(),
9055 exception_message(token_type::value_string,
"object key")));
9066 return sax->parse_error(m_lexer.get_position(),
9067 m_lexer.get_token_string(),
9068 parse_error::create(101, m_lexer.get_position(),
9069 exception_message(token_type::name_separator,
"object separator")));
9089 assert(
not states.empty());
9091 skip_to_state_evaluation =
true;
9095 return sax->parse_error(m_lexer.get_position(),
9096 m_lexer.get_token_string(),
9097 parse_error::create(101, m_lexer.get_position(),
9098 exception_message(token_type::end_object,
"object")));
9104 token_type get_token()
9106 return last_token = m_lexer.scan();
9109 std::string exception_message(
const token_type expected,
const std::string& context)
9111 std::string error_msg =
"syntax error ";
9113 if (
not context.empty())
9115 error_msg +=
"while parsing " + context +
" ";
9120 if (last_token == token_type::parse_error)
9122 error_msg += std::string(m_lexer.get_error_message()) +
"; last read: '" +
9123 m_lexer.get_token_string() +
"'";
9127 error_msg +=
"unexpected " + std::string(lexer_t::token_type_name(last_token));
9130 if (expected != token_type::uninitialized)
9132 error_msg +=
"; expected " + std::string(lexer_t::token_type_name(expected));
9140 const parser_callback_t callback =
nullptr;
9142 token_type last_token = token_type::uninitialized;
9146 const bool allow_exceptions =
true;
9173 class primitive_iterator_t
9176 using difference_type = std::ptrdiff_t;
9177 static constexpr difference_type begin_value = 0;
9178 static constexpr difference_type end_value = begin_value + 1;
9181 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
9184 constexpr difference_type get_value()
const noexcept
9190 void set_begin()
noexcept
9196 void set_end()
noexcept
9202 constexpr bool is_begin()
const noexcept
9204 return m_it == begin_value;
9208 constexpr bool is_end()
const noexcept
9210 return m_it == end_value;
9213 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs)
noexcept
9215 return lhs.m_it == rhs.m_it;
9218 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs)
noexcept
9220 return lhs.m_it < rhs.m_it;
9223 primitive_iterator_t operator+(difference_type n)
noexcept
9225 auto result = *
this;
9230 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs)
noexcept
9232 return lhs.m_it - rhs.m_it;
9235 primitive_iterator_t& operator++()
noexcept
9241 primitive_iterator_t
const operator++(
int)
noexcept
9243 auto result = *
this;
9248 primitive_iterator_t& operator--()
noexcept
9254 primitive_iterator_t
const operator--(
int)
noexcept
9256 auto result = *
this;
9261 primitive_iterator_t& operator+=(difference_type n)
noexcept
9267 primitive_iterator_t& operator-=(difference_type n)
noexcept
9287 template<
typename BasicJsonType>
struct internal_iterator
9290 typename BasicJsonType::object_t::iterator object_iterator {};
9292 typename BasicJsonType::array_t::iterator array_iterator {};
9294 primitive_iterator_t primitive_iterator {};
9304 #include <type_traits>
9326 template<
typename IteratorType>
class iteration_proxy;
9327 template<
typename IteratorType>
class iteration_proxy_value;
9345 template<
typename BasicJsonType>
9349 friend iter_impl<
typename std::conditional<std::is_const<BasicJsonType>::value,
typename std::remove_const<BasicJsonType>::type,
const BasicJsonType>::type>;
9350 friend BasicJsonType;
9351 friend iteration_proxy<iter_impl>;
9352 friend iteration_proxy_value<iter_impl>;
9354 using object_t =
typename BasicJsonType::object_t;
9355 using array_t =
typename BasicJsonType::array_t;
9357 static_assert(is_basic_json<
typename std::remove_const<BasicJsonType>::type>::value,
9358 "iter_impl only accepts (const) basic_json");
9367 using iterator_category = std::bidirectional_iterator_tag;
9370 using value_type =
typename BasicJsonType::value_type;
9372 using difference_type =
typename BasicJsonType::difference_type;
9374 using pointer =
typename std::conditional<std::is_const<BasicJsonType>::value,
9375 typename BasicJsonType::const_pointer,
9376 typename BasicJsonType::pointer>::type;
9379 typename std::conditional<std::is_const<BasicJsonType>::value,
9380 typename BasicJsonType::const_reference,
9381 typename BasicJsonType::reference>::type;
9384 iter_impl() =
default;
9392 explicit iter_impl(pointer object)
noexcept : m_object(object)
9394 assert(m_object !=
nullptr);
9396 switch (m_object->m_type)
9398 case value_t::object:
9400 m_it.object_iterator =
typename object_t::iterator();
9404 case value_t::array:
9406 m_it.array_iterator =
typename array_t::iterator();
9412 m_it.primitive_iterator = primitive_iterator_t();
9434 iter_impl(
const iter_impl<
const BasicJsonType>& other)
noexcept
9435 : m_object(other.m_object), m_it(other.m_it)
9444 iter_impl& operator=(
const iter_impl<
const BasicJsonType>& other)
noexcept
9446 m_object = other.m_object;
9456 iter_impl(
const iter_impl<
typename std::remove_const<BasicJsonType>::type>& other)
noexcept
9457 : m_object(other.m_object), m_it(other.m_it)
9466 iter_impl& operator=(
const iter_impl<
typename std::remove_const<BasicJsonType>::type>& other)
noexcept
9468 m_object = other.m_object;
9478 void set_begin()
noexcept
9480 assert(m_object !=
nullptr);
9482 switch (m_object->m_type)
9484 case value_t::object:
9486 m_it.object_iterator = m_object->m_value.object->begin();
9490 case value_t::array:
9492 m_it.array_iterator = m_object->m_value.array->begin();
9499 m_it.primitive_iterator.set_end();
9505 m_it.primitive_iterator.set_begin();
9515 void set_end()
noexcept
9517 assert(m_object !=
nullptr);
9519 switch (m_object->m_type)
9521 case value_t::object:
9523 m_it.object_iterator = m_object->m_value.object->end();
9527 case value_t::array:
9529 m_it.array_iterator = m_object->m_value.array->end();
9535 m_it.primitive_iterator.set_end();
9546 reference operator*()
const
9548 assert(m_object !=
nullptr);
9550 switch (m_object->m_type)
9552 case value_t::object:
9554 assert(m_it.object_iterator != m_object->m_value.object->end());
9555 return m_it.object_iterator->second;
9558 case value_t::array:
9560 assert(m_it.array_iterator != m_object->m_value.array->end());
9561 return *m_it.array_iterator;
9565 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
9574 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
9583 pointer operator->()
const
9585 assert(m_object !=
nullptr);
9587 switch (m_object->m_type)
9589 case value_t::object:
9591 assert(m_it.object_iterator != m_object->m_value.object->end());
9592 return &(m_it.object_iterator->second);
9595 case value_t::array:
9597 assert(m_it.array_iterator != m_object->m_value.array->end());
9598 return &*m_it.array_iterator;
9608 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
9617 iter_impl
const operator++(
int)
9619 auto result = *
this;
9628 iter_impl& operator++()
9630 assert(m_object !=
nullptr);
9632 switch (m_object->m_type)
9634 case value_t::object:
9636 std::advance(m_it.object_iterator, 1);
9640 case value_t::array:
9642 std::advance(m_it.array_iterator, 1);
9648 ++m_it.primitive_iterator;
9660 iter_impl
const operator--(
int)
9662 auto result = *
this;
9671 iter_impl& operator--()
9673 assert(m_object !=
nullptr);
9675 switch (m_object->m_type)
9677 case value_t::object:
9679 std::advance(m_it.object_iterator, -1);
9683 case value_t::array:
9685 std::advance(m_it.array_iterator, -1);
9691 --m_it.primitive_iterator;
9703 bool operator==(
const iter_impl& other)
const
9708 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
9711 assert(m_object !=
nullptr);
9713 switch (m_object->m_type)
9715 case value_t::object:
9716 return (m_it.object_iterator == other.m_it.object_iterator);
9718 case value_t::array:
9719 return (m_it.array_iterator == other.m_it.array_iterator);
9722 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
9730 bool operator!=(
const iter_impl& other)
const
9732 return not operator==(other);
9739 bool operator<(
const iter_impl& other)
const
9744 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
9747 assert(m_object !=
nullptr);
9749 switch (m_object->m_type)
9751 case value_t::object:
9752 JSON_THROW(invalid_iterator::create(213,
"cannot compare order of object iterators"));
9754 case value_t::array:
9755 return (m_it.array_iterator < other.m_it.array_iterator);
9758 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
9766 bool operator<=(
const iter_impl& other)
const
9768 return not other.operator < (*
this);
9775 bool operator>(
const iter_impl& other)
const
9777 return not operator<=(other);
9784 bool operator>=(
const iter_impl& other)
const
9786 return not operator<(other);
9793 iter_impl& operator+=(difference_type i)
9795 assert(m_object !=
nullptr);
9797 switch (m_object->m_type)
9799 case value_t::object:
9800 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
9802 case value_t::array:
9804 std::advance(m_it.array_iterator, i);
9810 m_it.primitive_iterator += i;
9822 iter_impl& operator-=(difference_type i)
9824 return operator+=(-i);
9831 iter_impl operator+(difference_type i)
const
9833 auto result = *
this;
9842 friend iter_impl operator+(difference_type i,
const iter_impl& it)
9853 iter_impl operator-(difference_type i)
const
9855 auto result = *
this;
9864 difference_type operator-(
const iter_impl& other)
const
9866 assert(m_object !=
nullptr);
9868 switch (m_object->m_type)
9870 case value_t::object:
9871 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
9873 case value_t::array:
9874 return m_it.array_iterator - other.m_it.array_iterator;
9877 return m_it.primitive_iterator - other.m_it.primitive_iterator;
9885 reference operator[](difference_type n)
const
9887 assert(m_object !=
nullptr);
9889 switch (m_object->m_type)
9891 case value_t::object:
9892 JSON_THROW(invalid_iterator::create(208,
"cannot use operator[] for object iterators"));
9894 case value_t::array:
9895 return *std::next(m_it.array_iterator, n);
9898 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
9907 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
9916 const typename object_t::key_type& key()
const
9918 assert(m_object !=
nullptr);
9922 return m_it.object_iterator->first;
9925 JSON_THROW(invalid_iterator::create(207,
"cannot use key() for non-object iterators"));
9932 reference value()
const
9939 pointer m_object =
nullptr;
9941 internal_iterator<
typename std::remove_const<BasicJsonType>::type> m_it {};
9981 template<
typename Base>
9982 class json_reverse_iterator :
public std::reverse_iterator<Base>
9985 using difference_type = std::ptrdiff_t;
9987 using base_iterator = std::reverse_iterator<Base>;
9989 using reference =
typename Base::reference;
9992 explicit json_reverse_iterator(
const typename base_iterator::iterator_type& it)
noexcept
9993 : base_iterator(it) {}
9996 explicit json_reverse_iterator(
const base_iterator& it)
noexcept : base_iterator(it) {}
9999 json_reverse_iterator
const operator++(
int)
10001 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
10005 json_reverse_iterator& operator++()
10007 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
10011 json_reverse_iterator
const operator--(
int)
10013 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
10017 json_reverse_iterator& operator--()
10019 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
10023 json_reverse_iterator& operator+=(difference_type i)
10025 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
10029 json_reverse_iterator operator+(difference_type i)
const
10031 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
10035 json_reverse_iterator operator-(difference_type i)
const
10037 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
10041 difference_type operator-(
const json_reverse_iterator& other)
const
10043 return base_iterator(*
this) - base_iterator(other);
10047 reference operator[](difference_type n)
const
10049 return *(
this->operator+(n));
10053 auto key()
const ->
decltype(std::declval<Base>().key())
10055 auto it = --
this->base();
10060 reference value()
const
10062 auto it = --
this->base();
10063 return it.operator * ();
10074 #include <algorithm>
10091 template<
typename BasicJsonType>
10096 friend class basic_json;
10120 explicit json_pointer(
const std::string& s =
"")
10121 : reference_tokens(split(s))
10138 std::string to_string()
const
10140 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
10142 [](
const std::string & a,
const std::string & b)
10144 return a +
"/" + escape(b);
10149 operator std::string()
const
10151 return to_string();
10170 json_pointer& operator/=(
const json_pointer& ptr)
10172 reference_tokens.insert(reference_tokens.end(),
10173 ptr.reference_tokens.begin(),
10174 ptr.reference_tokens.end());
10194 json_pointer& operator/=(std::string token)
10196 push_back(std::move(token));
10216 json_pointer& operator/=(std::size_t array_index)
10218 return *
this /= std::to_string(array_index);
10236 friend json_pointer operator/(
const json_pointer& lhs,
10237 const json_pointer& rhs)
10239 return json_pointer(lhs) /= rhs;
10257 friend json_pointer operator/(
const json_pointer& ptr, std::string token)
10259 return json_pointer(ptr) /= std::move(token);
10277 friend json_pointer operator/(
const json_pointer& ptr, std::size_t array_index)
10279 return json_pointer(ptr) /= array_index;
10295 json_pointer parent_pointer()
const
10302 json_pointer res = *
this;
10324 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
10327 reference_tokens.pop_back();
10344 const std::string& back()
const
10348 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
10351 return reference_tokens.back();
10366 void push_back(
const std::string& token)
10368 reference_tokens.push_back(token);
10372 void push_back(std::string&& token)
10374 reference_tokens.push_back(std::move(token));
10391 bool empty()
const noexcept
10393 return reference_tokens.empty();
10404 static int array_index(
const std::string& s)
10406 std::size_t processed_chars = 0;
10407 const int res = std::stoi(s, &processed_chars);
10412 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + s +
"'"));
10418 json_pointer top()
const
10422 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
10425 json_pointer result = *
this;
10426 result.reference_tokens = {reference_tokens[0]};
10438 BasicJsonType& get_and_create(BasicJsonType& j)
const
10440 using size_type =
typename BasicJsonType::size_type;
10445 for (
const auto& reference_token : reference_tokens)
10447 switch (result->type())
10449 case detail::value_t::null:
10451 if (reference_token ==
"0")
10454 result = &result->operator[](0);
10459 result = &result->operator[](reference_token);
10464 case detail::value_t::object:
10467 result = &result->operator[](reference_token);
10471 case detail::value_t::array:
10476 result = &result->operator[](
static_cast<size_type>(array_index(reference_token)));
10480 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
10492 JSON_THROW(detail::type_error::create(313,
"invalid value to unflatten"));
10518 BasicJsonType& get_unchecked(BasicJsonType* ptr)
const
10520 using size_type =
typename BasicJsonType::size_type;
10521 for (
const auto& reference_token : reference_tokens)
10524 if (ptr->is_null())
10528 std::all_of(reference_token.begin(), reference_token.end(),
10529 [](
const unsigned char x)
10531 return std::isdigit(x);
10535 *ptr = (nums
or reference_token ==
"-")
10536 ? detail::value_t::array
10537 : detail::value_t::object;
10540 switch (ptr->type())
10542 case detail::value_t::object:
10545 ptr = &ptr->operator[](reference_token);
10549 case detail::value_t::array:
10554 JSON_THROW(detail::parse_error::create(106, 0,
10555 "array index '" + reference_token +
10556 "' must not begin with '0'"));
10559 if (reference_token ==
"-")
10562 ptr = &ptr->operator[](ptr->m_value.array->size());
10569 ptr = &ptr->operator[](
10570 static_cast<size_type>(array_index(reference_token)));
10574 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
10581 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
10594 BasicJsonType& get_checked(BasicJsonType* ptr)
const
10596 using size_type =
typename BasicJsonType::size_type;
10597 for (
const auto& reference_token : reference_tokens)
10599 switch (ptr->type())
10601 case detail::value_t::object:
10604 ptr = &ptr->at(reference_token);
10608 case detail::value_t::array:
10613 JSON_THROW(detail::out_of_range::create(402,
10614 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
10615 ") is out of range"));
10621 JSON_THROW(detail::parse_error::create(106, 0,
10622 "array index '" + reference_token +
10623 "' must not begin with '0'"));
10629 ptr = &ptr->at(
static_cast<size_type>(array_index(reference_token)));
10633 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
10639 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
10659 const BasicJsonType& get_unchecked(
const BasicJsonType* ptr)
const
10661 using size_type =
typename BasicJsonType::size_type;
10662 for (
const auto& reference_token : reference_tokens)
10664 switch (ptr->type())
10666 case detail::value_t::object:
10669 ptr = &ptr->operator[](reference_token);
10673 case detail::value_t::array:
10678 JSON_THROW(detail::out_of_range::create(402,
10679 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
10680 ") is out of range"));
10686 JSON_THROW(detail::parse_error::create(106, 0,
10687 "array index '" + reference_token +
10688 "' must not begin with '0'"));
10694 ptr = &ptr->operator[](
10695 static_cast<size_type>(array_index(reference_token)));
10699 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
10705 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
10718 const BasicJsonType& get_checked(
const BasicJsonType* ptr)
const
10720 using size_type =
typename BasicJsonType::size_type;
10721 for (
const auto& reference_token : reference_tokens)
10723 switch (ptr->type())
10725 case detail::value_t::object:
10728 ptr = &ptr->at(reference_token);
10732 case detail::value_t::array:
10737 JSON_THROW(detail::out_of_range::create(402,
10738 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
10739 ") is out of range"));
10745 JSON_THROW(detail::parse_error::create(106, 0,
10746 "array index '" + reference_token +
10747 "' must not begin with '0'"));
10753 ptr = &ptr->at(
static_cast<size_type>(array_index(reference_token)));
10757 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
10763 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
10774 bool contains(
const BasicJsonType* ptr)
const
10776 using size_type =
typename BasicJsonType::size_type;
10777 for (
const auto& reference_token : reference_tokens)
10779 switch (ptr->type())
10781 case detail::value_t::object:
10783 if (
not ptr->contains(reference_token))
10789 ptr = &ptr->operator[](reference_token);
10793 case detail::value_t::array:
10804 JSON_THROW(detail::parse_error::create(106, 0,
10805 "array index '" + reference_token +
10806 "' must not begin with '0'"));
10811 const auto idx =
static_cast<size_type>(array_index(reference_token));
10812 if (idx >= ptr->size())
10818 ptr = &ptr->operator[](idx);
10823 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + reference_token +
"' is not a number"));
10850 static std::vector<std::string> split(
const std::string& reference_string)
10852 std::vector<std::string> result;
10855 if (reference_string.empty())
10863 JSON_THROW(detail::parse_error::create(107, 1,
10864 "JSON pointer must be empty or begin with '/' - was: '" +
10865 reference_string +
"'"));
10873 std::size_t slash = reference_string.find_first_of(
'/', 1),
10880 start = (slash == std::string::npos) ? 0 : slash + 1,
10882 slash = reference_string.find_first_of(
'/', start))
10886 auto reference_token = reference_string.substr(start, slash - start);
10889 for (std::size_t pos = reference_token.find_first_of(
'~');
10890 pos != std::string::npos;
10891 pos = reference_token.find_first_of(
'~', pos + 1))
10893 assert(reference_token[pos] ==
'~');
10897 (reference_token[pos + 1] !=
'0' and
10898 reference_token[pos + 1] !=
'1')))
10900 JSON_THROW(detail::parse_error::create(108, 0,
"escape character '~' must be followed with '0' or '1'"));
10905 unescape(reference_token);
10906 result.push_back(reference_token);
10925 static void replace_substring(std::string& s,
const std::string& f,
10926 const std::string& t)
10928 assert(
not f.empty());
10929 for (
auto pos = s.find(f);
10930 pos != std::string::npos;
10931 s.replace(pos, f.size(), t),
10932 pos = s.find(f, pos + t.size()))
10937 static std::string escape(std::string s)
10939 replace_substring(s,
"~",
"~0");
10940 replace_substring(s,
"/",
"~1");
10945 static void unescape(std::string& s)
10947 replace_substring(s,
"~1",
"/");
10948 replace_substring(s,
"~0",
"~");
10958 static void flatten(
const std::string& reference_string,
10959 const BasicJsonType& value,
10960 BasicJsonType& result)
10962 switch (value.type())
10964 case detail::value_t::array:
10966 if (value.m_value.array->empty())
10969 result[reference_string] =
nullptr;
10974 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
10976 flatten(reference_string +
"/" + std::to_string(i),
10977 value.m_value.array->operator[](i), result);
10983 case detail::value_t::object:
10985 if (value.m_value.object->empty())
10988 result[reference_string] =
nullptr;
10993 for (
const auto& element : *value.m_value.object)
10995 flatten(reference_string +
"/" + escape(element.first), element.second, result);
11004 result[reference_string] = value;
11020 static BasicJsonType
11021 unflatten(
const BasicJsonType& value)
11025 JSON_THROW(detail::type_error::create(314,
"only objects can be unflattened"));
11028 BasicJsonType result;
11031 for (
const auto& element : *value.m_value.object)
11035 JSON_THROW(detail::type_error::create(315,
"values in object must be primitive"));
11042 json_pointer(element.first).get_and_create(result) = element.second;
11059 friend bool operator==(json_pointer
const& lhs,
11060 json_pointer
const& rhs)
noexcept
11062 return lhs.reference_tokens == rhs.reference_tokens;
11076 friend bool operator!=(json_pointer
const& lhs,
11077 json_pointer
const& rhs)
noexcept
11079 return not (lhs == rhs);
11083 std::vector<std::string> reference_tokens;
11090 #include <initializer_list>
11100 template<
typename BasicJsonType>
11104 using value_type = BasicJsonType;
11106 json_ref(value_type&& value)
11107 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(
true)
11110 json_ref(
const value_type& value)
11111 : value_ref(
const_cast<value_type*>(&value)), is_rvalue(
false)
11114 json_ref(std::initializer_list<json_ref> init)
11115 : owned_value(init), value_ref(&owned_value), is_rvalue(
true)
11120 enable_if_t<std::is_constructible<value_type, Args...>::value,
int> = 0 >
11121 json_ref(Args && ... args)
11122 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value),
11126 json_ref(json_ref&&) =
default;
11127 json_ref(
const json_ref&) =
delete;
11128 json_ref& operator=(
const json_ref&) =
delete;
11129 json_ref& operator=(json_ref&&) =
delete;
11130 ~json_ref() =
default;
11132 value_type moved_or_copied()
const
11136 return std::move(*value_ref);
11141 value_type
const& operator*()
const
11143 return *
static_cast<value_type
const*>(value_ref);
11146 value_type
const* operator->()
const
11148 return static_cast<value_type
const*>(value_ref);
11152 mutable value_type owned_value =
nullptr;
11153 value_type* value_ref =
nullptr;
11154 const bool is_rvalue;
11168 #include <algorithm>
11182 #include <algorithm>
11185 #include <iterator>
11198 template<
typename CharType>
struct output_adapter_protocol
11200 virtual void write_character(CharType c) = 0;
11201 virtual void write_characters(
const CharType* s, std::size_t length) = 0;
11202 virtual ~output_adapter_protocol() =
default;
11206 template<
typename CharType>
11207 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
11210 template<
typename CharType>
11211 class output_vector_adapter :
public output_adapter_protocol<CharType>
11214 explicit output_vector_adapter(std::vector<CharType>& vec)
noexcept
11218 void write_character(CharType c) override
11224 void write_characters(
const CharType* s, std::size_t length) override
11226 std::copy(s, s + length, std::back_inserter(v));
11230 std::vector<CharType>& v;
11234 template<
typename CharType>
11235 class output_stream_adapter :
public output_adapter_protocol<CharType>
11238 explicit output_stream_adapter(std::basic_ostream<CharType>& s)
noexcept
11242 void write_character(CharType c) override
11248 void write_characters(
const CharType* s, std::size_t length) override
11250 stream.write(s,
static_cast<std::streamsize>(length));
11254 std::basic_ostream<CharType>& stream;
11258 template<
typename CharType,
typename StringType = std::basic_string<CharType>>
11259 class output_string_adapter :
public output_adapter_protocol<CharType>
11262 explicit output_string_adapter(StringType& s)
noexcept
11266 void write_character(CharType c) override
11272 void write_characters(
const CharType* s, std::size_t length) override
11274 str.append(s, length);
11281 template<
typename CharType,
typename StringType = std::basic_string<CharType>>
11282 class output_adapter
11285 output_adapter(std::vector<CharType>& vec)
11286 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
11288 output_adapter(std::basic_ostream<CharType>& s)
11289 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
11291 output_adapter(StringType& s)
11292 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
11294 operator output_adapter_t<CharType>()
11300 output_adapter_t<CharType> oa =
nullptr;
11317 template<
typename BasicJsonType,
typename CharType>
11318 class binary_writer
11320 using string_t =
typename BasicJsonType::string_t;
11328 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
11337 void write_bson(
const BasicJsonType& j)
11341 case value_t::object:
11343 write_bson_object(*j.m_value.object);
11349 JSON_THROW(type_error::create(317,
"to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
11357 void write_cbor(
const BasicJsonType& j)
11361 case value_t::null:
11363 oa->write_character(to_char_type(0xF6));
11367 case value_t::boolean:
11369 oa->write_character(j.m_value.boolean
11370 ? to_char_type(0xF5)
11371 : to_char_type(0xF4));
11375 case value_t::number_integer:
11377 if (j.m_value.number_integer >= 0)
11382 if (j.m_value.number_integer <= 0x17)
11384 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
11386 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
11388 oa->write_character(to_char_type(0x18));
11389 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
11391 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
11393 oa->write_character(to_char_type(0x19));
11394 write_number(
static_cast<std::uint16_t>(j.m_value.number_integer));
11396 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
11398 oa->write_character(to_char_type(0x1A));
11399 write_number(
static_cast<std::uint32_t>(j.m_value.number_integer));
11403 oa->write_character(to_char_type(0x1B));
11404 write_number(
static_cast<std::uint64_t>(j.m_value.number_integer));
11411 const auto positive_number = -1 - j.m_value.number_integer;
11412 if (j.m_value.number_integer >= -24)
11414 write_number(
static_cast<std::uint8_t>(0x20 + positive_number));
11416 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
11418 oa->write_character(to_char_type(0x38));
11419 write_number(
static_cast<std::uint8_t>(positive_number));
11421 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
11423 oa->write_character(to_char_type(0x39));
11424 write_number(
static_cast<std::uint16_t>(positive_number));
11426 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
11428 oa->write_character(to_char_type(0x3A));
11429 write_number(
static_cast<std::uint32_t>(positive_number));
11433 oa->write_character(to_char_type(0x3B));
11434 write_number(
static_cast<std::uint64_t>(positive_number));
11440 case value_t::number_unsigned:
11442 if (j.m_value.number_unsigned <= 0x17)
11444 write_number(
static_cast<std::uint8_t>(j.m_value.number_unsigned));
11446 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
11448 oa->write_character(to_char_type(0x18));
11449 write_number(
static_cast<std::uint8_t>(j.m_value.number_unsigned));
11451 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
11453 oa->write_character(to_char_type(0x19));
11454 write_number(
static_cast<std::uint16_t>(j.m_value.number_unsigned));
11456 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
11458 oa->write_character(to_char_type(0x1A));
11459 write_number(
static_cast<std::uint32_t>(j.m_value.number_unsigned));
11463 oa->write_character(to_char_type(0x1B));
11464 write_number(
static_cast<std::uint64_t>(j.m_value.number_unsigned));
11469 case value_t::number_float:
11471 oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
11472 write_number(j.m_value.number_float);
11476 case value_t::string:
11479 const auto N = j.m_value.string->size();
11482 write_number(
static_cast<std::uint8_t>(0x60 + N));
11484 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
11486 oa->write_character(to_char_type(0x78));
11487 write_number(
static_cast<std::uint8_t>(N));
11489 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
11491 oa->write_character(to_char_type(0x79));
11492 write_number(
static_cast<std::uint16_t>(N));
11494 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
11496 oa->write_character(to_char_type(0x7A));
11497 write_number(
static_cast<std::uint32_t>(N));
11500 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
11502 oa->write_character(to_char_type(0x7B));
11503 write_number(
static_cast<std::uint64_t>(N));
11508 oa->write_characters(
11509 reinterpret_cast<
const CharType*>(j.m_value.string->c_str()),
11510 j.m_value.string->size());
11514 case value_t::array:
11517 const auto N = j.m_value.array->size();
11520 write_number(
static_cast<std::uint8_t>(0x80 + N));
11522 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
11524 oa->write_character(to_char_type(0x98));
11525 write_number(
static_cast<std::uint8_t>(N));
11527 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
11529 oa->write_character(to_char_type(0x99));
11530 write_number(
static_cast<std::uint16_t>(N));
11532 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
11534 oa->write_character(to_char_type(0x9A));
11535 write_number(
static_cast<std::uint32_t>(N));
11538 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
11540 oa->write_character(to_char_type(0x9B));
11541 write_number(
static_cast<std::uint64_t>(N));
11546 for (
const auto& el : *j.m_value.array)
11553 case value_t::object:
11556 const auto N = j.m_value.object->size();
11559 write_number(
static_cast<std::uint8_t>(0xA0 + N));
11561 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
11563 oa->write_character(to_char_type(0xB8));
11564 write_number(
static_cast<std::uint8_t>(N));
11566 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
11568 oa->write_character(to_char_type(0xB9));
11569 write_number(
static_cast<std::uint16_t>(N));
11571 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
11573 oa->write_character(to_char_type(0xBA));
11574 write_number(
static_cast<std::uint32_t>(N));
11577 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
11579 oa->write_character(to_char_type(0xBB));
11580 write_number(
static_cast<std::uint64_t>(N));
11585 for (
const auto& el : *j.m_value.object)
11587 write_cbor(el.first);
11588 write_cbor(el.second);
11601 void write_msgpack(
const BasicJsonType& j)
11605 case value_t::null:
11607 oa->write_character(to_char_type(0xC0));
11611 case value_t::boolean:
11613 oa->write_character(j.m_value.boolean
11614 ? to_char_type(0xC3)
11615 : to_char_type(0xC2));
11619 case value_t::number_integer:
11621 if (j.m_value.number_integer >= 0)
11626 if (j.m_value.number_unsigned < 128)
11629 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
11631 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
11634 oa->write_character(to_char_type(0xCC));
11635 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
11637 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
11640 oa->write_character(to_char_type(0xCD));
11641 write_number(
static_cast<std::uint16_t>(j.m_value.number_integer));
11643 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
11646 oa->write_character(to_char_type(0xCE));
11647 write_number(
static_cast<std::uint32_t>(j.m_value.number_integer));
11649 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
11652 oa->write_character(to_char_type(0xCF));
11653 write_number(
static_cast<std::uint64_t>(j.m_value.number_integer));
11658 if (j.m_value.number_integer >= -32)
11661 write_number(
static_cast<std::int8_t>(j.m_value.number_integer));
11663 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)()
and
11664 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
11667 oa->write_character(to_char_type(0xD0));
11668 write_number(
static_cast<std::int8_t>(j.m_value.number_integer));
11670 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)()
and
11671 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
11674 oa->write_character(to_char_type(0xD1));
11675 write_number(
static_cast<std::int16_t>(j.m_value.number_integer));
11677 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)()
and
11678 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
11681 oa->write_character(to_char_type(0xD2));
11682 write_number(
static_cast<std::int32_t>(j.m_value.number_integer));
11684 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)()
and
11685 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
11688 oa->write_character(to_char_type(0xD3));
11689 write_number(
static_cast<std::int64_t>(j.m_value.number_integer));
11695 case value_t::number_unsigned:
11697 if (j.m_value.number_unsigned < 128)
11700 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
11702 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
11705 oa->write_character(to_char_type(0xCC));
11706 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
11708 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
11711 oa->write_character(to_char_type(0xCD));
11712 write_number(
static_cast<std::uint16_t>(j.m_value.number_integer));
11714 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
11717 oa->write_character(to_char_type(0xCE));
11718 write_number(
static_cast<std::uint32_t>(j.m_value.number_integer));
11720 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
11723 oa->write_character(to_char_type(0xCF));
11724 write_number(
static_cast<std::uint64_t>(j.m_value.number_integer));
11729 case value_t::number_float:
11731 oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
11732 write_number(j.m_value.number_float);
11736 case value_t::string:
11739 const auto N = j.m_value.string->size();
11743 write_number(
static_cast<std::uint8_t>(0xA0 | N));
11745 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
11748 oa->write_character(to_char_type(0xD9));
11749 write_number(
static_cast<std::uint8_t>(N));
11751 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
11754 oa->write_character(to_char_type(0xDA));
11755 write_number(
static_cast<std::uint16_t>(N));
11757 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
11760 oa->write_character(to_char_type(0xDB));
11761 write_number(
static_cast<std::uint32_t>(N));
11765 oa->write_characters(
11766 reinterpret_cast<
const CharType*>(j.m_value.string->c_str()),
11767 j.m_value.string->size());
11771 case value_t::array:
11774 const auto N = j.m_value.array->size();
11778 write_number(
static_cast<std::uint8_t>(0x90 | N));
11780 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
11783 oa->write_character(to_char_type(0xDC));
11784 write_number(
static_cast<std::uint16_t>(N));
11786 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
11789 oa->write_character(to_char_type(0xDD));
11790 write_number(
static_cast<std::uint32_t>(N));
11794 for (
const auto& el : *j.m_value.array)
11801 case value_t::object:
11804 const auto N = j.m_value.object->size();
11808 write_number(
static_cast<std::uint8_t>(0x80 | (N & 0xF)));
11810 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
11813 oa->write_character(to_char_type(0xDE));
11814 write_number(
static_cast<std::uint16_t>(N));
11816 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
11819 oa->write_character(to_char_type(0xDF));
11820 write_number(
static_cast<std::uint32_t>(N));
11824 for (
const auto& el : *j.m_value.object)
11826 write_msgpack(el.first);
11827 write_msgpack(el.second);
11843 void write_ubjson(
const BasicJsonType& j,
const bool use_count,
11844 const bool use_type,
const bool add_prefix =
true)
11848 case value_t::null:
11852 oa->write_character(to_char_type(
'Z'));
11857 case value_t::boolean:
11861 oa->write_character(j.m_value.boolean
11862 ? to_char_type(
'T')
11863 : to_char_type(
'F'));
11868 case value_t::number_integer:
11870 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
11874 case value_t::number_unsigned:
11876 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
11880 case value_t::number_float:
11882 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
11886 case value_t::string:
11890 oa->write_character(to_char_type(
'S'));
11892 write_number_with_ubjson_prefix(j.m_value.string->size(),
true);
11893 oa->write_characters(
11894 reinterpret_cast<
const CharType*>(j.m_value.string->c_str()),
11895 j.m_value.string->size());
11899 case value_t::array:
11903 oa->write_character(to_char_type(
'['));
11906 bool prefix_required =
true;
11907 if (use_type
and not j.m_value.array->empty())
11910 const CharType first_prefix = ubjson_prefix(j.front());
11911 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
11912 [
this, first_prefix](
const BasicJsonType & v)
11914 return ubjson_prefix(v) == first_prefix;
11919 prefix_required =
false;
11920 oa->write_character(to_char_type(
'$'));
11921 oa->write_character(first_prefix);
11927 oa->write_character(to_char_type(
'#'));
11928 write_number_with_ubjson_prefix(j.m_value.array->size(),
true);
11931 for (
const auto& el : *j.m_value.array)
11933 write_ubjson(el, use_count, use_type, prefix_required);
11938 oa->write_character(to_char_type(
']'));
11944 case value_t::object:
11948 oa->write_character(to_char_type(
'{'));
11951 bool prefix_required =
true;
11952 if (use_type
and not j.m_value.object->empty())
11955 const CharType first_prefix = ubjson_prefix(j.front());
11956 const bool same_prefix = std::all_of(j.begin(), j.end(),
11957 [
this, first_prefix](
const BasicJsonType & v)
11959 return ubjson_prefix(v) == first_prefix;
11964 prefix_required =
false;
11965 oa->write_character(to_char_type(
'$'));
11966 oa->write_character(first_prefix);
11972 oa->write_character(to_char_type(
'#'));
11973 write_number_with_ubjson_prefix(j.m_value.object->size(),
true);
11976 for (
const auto& el : *j.m_value.object)
11978 write_number_with_ubjson_prefix(el.first.size(),
true);
11979 oa->write_characters(
11980 reinterpret_cast<
const CharType*>(el.first.c_str()),
11982 write_ubjson(el.second, use_count, use_type, prefix_required);
11987 oa->write_character(to_char_type(
'}'));
12007 static std::size_t calc_bson_entry_header_size(
const string_t& name)
12009 const auto it = name.find(
static_cast<
typename string_t::value_type>(0));
12013 "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) +
")"));
12016 return 1ul + name.size() + 1u;
12022 void write_bson_entry_header(
const string_t& name,
12023 const std::uint8_t element_type)
12025 oa->write_character(to_char_type(element_type));
12026 oa->write_characters(
12027 reinterpret_cast<
const CharType*>(name.c_str()),
12034 void write_bson_boolean(
const string_t& name,
12037 write_bson_entry_header(name, 0x08);
12038 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
12044 void write_bson_double(
const string_t& name,
12045 const double value)
12047 write_bson_entry_header(name, 0x01);
12048 write_number<
double,
true>(value);
12054 static std::size_t calc_bson_string_size(
const string_t& value)
12056 return sizeof(std::int32_t) + value.size() + 1ul;
12062 void write_bson_string(
const string_t& name,
12063 const string_t& value)
12065 write_bson_entry_header(name, 0x02);
12067 write_number<std::int32_t,
true>(
static_cast<std::int32_t>(value.size() + 1ul));
12068 oa->write_characters(
12069 reinterpret_cast<
const CharType*>(value.c_str()),
12076 void write_bson_null(
const string_t& name)
12078 write_bson_entry_header(name, 0x0A);
12084 static std::size_t calc_bson_integer_size(
const std::int64_t value)
12086 return (std::numeric_limits<std::int32_t>::min)() <= value
and value <= (std::numeric_limits<std::int32_t>::max)()
12087 ?
sizeof(std::int32_t)
12088 :
sizeof(std::int64_t);
12094 void write_bson_integer(
const string_t& name,
12095 const std::int64_t value)
12097 if ((std::numeric_limits<std::int32_t>::min)() <= value
and value <= (std::numeric_limits<std::int32_t>::max)())
12099 write_bson_entry_header(name, 0x10);
12100 write_number<std::int32_t,
true>(
static_cast<std::int32_t>(value));
12104 write_bson_entry_header(name, 0x12);
12105 write_number<std::int64_t,
true>(
static_cast<std::int64_t>(value));
12112 static constexpr std::size_t calc_bson_unsigned_size(
const std::uint64_t value)
noexcept
12114 return (value <=
static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
12115 ?
sizeof(std::int32_t)
12116 :
sizeof(std::int64_t);
12122 void write_bson_unsigned(
const string_t& name,
12123 const std::uint64_t value)
12125 if (value <=
static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
12127 write_bson_entry_header(name, 0x10 );
12128 write_number<std::int32_t,
true>(
static_cast<std::int32_t>(value));
12130 else if (value <=
static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
12132 write_bson_entry_header(name, 0x12 );
12133 write_number<std::int64_t,
true>(
static_cast<std::int64_t>(value));
12137 JSON_THROW(out_of_range::create(407,
"integer number " + std::to_string(value) +
" cannot be represented by BSON as it does not fit int64"));
12144 void write_bson_object_entry(
const string_t& name,
12145 const typename BasicJsonType::object_t& value)
12147 write_bson_entry_header(name, 0x03);
12148 write_bson_object(value);
12154 static std::size_t calc_bson_array_size(
const typename BasicJsonType::array_t& value)
12156 std::size_t array_index = 0ul;
12158 const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), 0ul, [&array_index](std::size_t result,
const typename BasicJsonType::array_t::value_type & el)
12160 return result + calc_bson_element_size(std::to_string(array_index++), el);
12163 return sizeof(std::int32_t) + embedded_document_size + 1ul;
12169 void write_bson_array(
const string_t& name,
12170 const typename BasicJsonType::array_t& value)
12172 write_bson_entry_header(name, 0x04);
12173 write_number<std::int32_t,
true>(
static_cast<std::int32_t>(calc_bson_array_size(value)));
12175 std::size_t array_index = 0ul;
12177 for (
const auto& el : value)
12179 write_bson_element(std::to_string(array_index++), el);
12182 oa->write_character(to_char_type(0x00));
12189 static std::size_t calc_bson_element_size(
const string_t& name,
12190 const BasicJsonType& j)
12192 const auto header_size = calc_bson_entry_header_size(name);
12195 case value_t::object:
12196 return header_size + calc_bson_object_size(*j.m_value.object);
12198 case value_t::array:
12199 return header_size + calc_bson_array_size(*j.m_value.array);
12201 case value_t::boolean:
12202 return header_size + 1ul;
12204 case value_t::number_float:
12205 return header_size + 8ul;
12207 case value_t::number_integer:
12208 return header_size + calc_bson_integer_size(j.m_value.number_integer);
12210 case value_t::number_unsigned:
12211 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
12213 case value_t::string:
12214 return header_size + calc_bson_string_size(*j.m_value.string);
12216 case value_t::null:
12217 return header_size + 0ul;
12234 void write_bson_element(
const string_t& name,
12235 const BasicJsonType& j)
12239 case value_t::object:
12240 return write_bson_object_entry(name, *j.m_value.object);
12242 case value_t::array:
12243 return write_bson_array(name, *j.m_value.array);
12245 case value_t::boolean:
12246 return write_bson_boolean(name, j.m_value.boolean);
12248 case value_t::number_float:
12249 return write_bson_double(name, j.m_value.number_float);
12251 case value_t::number_integer:
12252 return write_bson_integer(name, j.m_value.number_integer);
12254 case value_t::number_unsigned:
12255 return write_bson_unsigned(name, j.m_value.number_unsigned);
12257 case value_t::string:
12258 return write_bson_string(name, *j.m_value.string);
12260 case value_t::null:
12261 return write_bson_null(name);
12277 static std::size_t calc_bson_object_size(
const typename BasicJsonType::object_t& value)
12279 std::size_t document_size = std::accumulate(value.begin(), value.end(), 0ul,
12280 [](size_t result,
const typename BasicJsonType::object_t::value_type & el)
12282 return result += calc_bson_element_size(el.first, el.second);
12285 return sizeof(std::int32_t) + document_size + 1ul;
12292 void write_bson_object(
const typename BasicJsonType::object_t& value)
12294 write_number<std::int32_t,
true>(
static_cast<std::int32_t>(calc_bson_object_size(value)));
12296 for (
const auto& el : value)
12298 write_bson_element(el.first, el.second);
12301 oa->write_character(to_char_type(0x00));
12308 static constexpr CharType get_cbor_float_prefix(
float )
12310 return to_char_type(0xFA);
12313 static constexpr CharType get_cbor_float_prefix(
double )
12315 return to_char_type(0xFB);
12322 static constexpr CharType get_msgpack_float_prefix(
float )
12324 return to_char_type(0xCA);
12327 static constexpr CharType get_msgpack_float_prefix(
double )
12329 return to_char_type(0xCB);
12337 template<
typename NumberType,
typename std::enable_if<
12338 std::is_floating_point<NumberType>::value,
int>::type = 0>
12339 void write_number_with_ubjson_prefix(
const NumberType n,
12340 const bool add_prefix)
12344 oa->write_character(get_ubjson_float_prefix(n));
12350 template<
typename NumberType,
typename std::enable_if<
12351 std::is_unsigned<NumberType>::value,
int>::type = 0>
12352 void write_number_with_ubjson_prefix(
const NumberType n,
12353 const bool add_prefix)
12355 if (n <=
static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
12359 oa->write_character(to_char_type(
'i'));
12361 write_number(
static_cast<std::uint8_t>(n));
12363 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
12367 oa->write_character(to_char_type(
'U'));
12369 write_number(
static_cast<std::uint8_t>(n));
12371 else if (n <=
static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
12375 oa->write_character(to_char_type(
'I'));
12377 write_number(
static_cast<std::int16_t>(n));
12379 else if (n <=
static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
12383 oa->write_character(to_char_type(
'l'));
12385 write_number(
static_cast<std::int32_t>(n));
12387 else if (n <=
static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
12391 oa->write_character(to_char_type(
'L'));
12393 write_number(
static_cast<std::int64_t>(n));
12397 JSON_THROW(out_of_range::create(407,
"integer number " + std::to_string(n) +
" cannot be represented by UBJSON as it does not fit int64"));
12402 template<
typename NumberType,
typename std::enable_if<
12403 std::is_signed<NumberType>::value
and
12404 not std::is_floating_point<NumberType>::value,
int>::type = 0>
12405 void write_number_with_ubjson_prefix(
const NumberType n,
12406 const bool add_prefix)
12408 if ((std::numeric_limits<std::int8_t>::min)() <= n
and n <= (std::numeric_limits<std::int8_t>::max)())
12412 oa->write_character(to_char_type(
'i'));
12414 write_number(
static_cast<std::int8_t>(n));
12416 else if (
static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n
and n <=
static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
12420 oa->write_character(to_char_type(
'U'));
12422 write_number(
static_cast<std::uint8_t>(n));
12424 else if ((std::numeric_limits<std::int16_t>::min)() <= n
and n <= (std::numeric_limits<std::int16_t>::max)())
12428 oa->write_character(to_char_type(
'I'));
12430 write_number(
static_cast<std::int16_t>(n));
12432 else if ((std::numeric_limits<std::int32_t>::min)() <= n
and n <= (std::numeric_limits<std::int32_t>::max)())
12436 oa->write_character(to_char_type(
'l'));
12438 write_number(
static_cast<std::int32_t>(n));
12440 else if ((std::numeric_limits<std::int64_t>::min)() <= n
and n <= (std::numeric_limits<std::int64_t>::max)())
12444 oa->write_character(to_char_type(
'L'));
12446 write_number(
static_cast<std::int64_t>(n));
12451 JSON_THROW(out_of_range::create(407,
"integer number " + std::to_string(n) +
" cannot be represented by UBJSON as it does not fit int64"));
12465 CharType ubjson_prefix(
const BasicJsonType& j)
const noexcept
12469 case value_t::null:
12472 case value_t::boolean:
12473 return j.m_value.boolean ?
'T' :
'F';
12475 case value_t::number_integer:
12477 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer
and j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
12481 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer
and j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
12485 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer
and j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
12489 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer
and j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
12497 case value_t::number_unsigned:
12499 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
12503 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
12507 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
12511 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
12519 case value_t::number_float:
12520 return get_ubjson_float_prefix(j.m_value.number_float);
12522 case value_t::string:
12525 case value_t::array:
12528 case value_t::object:
12536 static constexpr CharType get_ubjson_float_prefix(
float )
12541 static constexpr CharType get_ubjson_float_prefix(
double )
12561 template<
typename NumberType,
bool OutputIsLittleEndian =
false>
12562 void write_number(
const NumberType n)
12565 std::array<CharType,
sizeof(NumberType)> vec;
12566 std::memcpy(vec.data(), &n,
sizeof(NumberType));
12569 if (is_little_endian != OutputIsLittleEndian)
12572 std::reverse(vec.begin(), vec.end());
12575 oa->write_characters(vec.data(),
sizeof(NumberType));
12583 template <
typename C = CharType,
12584 enable_if_t < std::is_signed<C>::value
and std::is_signed<
char>::value > * =
nullptr >
12585 static constexpr CharType to_char_type(std::uint8_t x)
noexcept
12587 return *
reinterpret_cast<
char*>(&x);
12590 template <
typename C = CharType,
12591 enable_if_t < std::is_signed<C>::value
and std::is_unsigned<
char>::value > * =
nullptr >
12592 static CharType to_char_type(std::uint8_t x)
noexcept
12594 static_assert(
sizeof(std::uint8_t) ==
sizeof(CharType),
"size of CharType must be equal to std::uint8_t");
12595 static_assert(std::is_pod<CharType>::value,
"CharType must be POD");
12597 std::memcpy(&result, &x,
sizeof(x));
12601 template<
typename C = CharType,
12602 enable_if_t<std::is_unsigned<C>::value>* =
nullptr>
12603 static constexpr CharType to_char_type(std::uint8_t x)
noexcept
12608 template <
typename InputCharType,
typename C = CharType,
12610 std::is_signed<C>::value
and
12611 std::is_signed<
char>::value
and
12612 std::is_same<
char,
typename std::remove_cv<InputCharType>::type>::value
12614 static constexpr CharType to_char_type(InputCharType x)
noexcept
12621 const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
12624 output_adapter_t<CharType> oa =
nullptr;
12634 #include <algorithm>
12645 #include <type_traits>
12658 #include <type_traits>
12686 namespace dtoa_impl
12689 template <
typename Target,
typename Source>
12690 Target reinterpret_bits(
const Source source)
12692 static_assert(
sizeof(Target) ==
sizeof(Source),
"size mismatch");
12695 std::memcpy(&target, &source,
sizeof(Source));
12701 static constexpr int kPrecision = 64;
12703 std::uint64_t f = 0;
12706 constexpr diyfp(std::uint64_t f_,
int e_)
noexcept : f(f_), e(e_) {}
12712 static diyfp sub(
const diyfp& x,
const diyfp& y)
noexcept
12714 assert(x.e == y.e);
12715 assert(x.f >= y.f);
12717 return {x.f - y.f, x.e};
12724 static diyfp mul(
const diyfp& x,
const diyfp& y)
noexcept
12726 static_assert(kPrecision == 64,
"internal error");
12751 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
12752 const std::uint64_t u_hi = x.f >> 32u;
12753 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
12754 const std::uint64_t v_hi = y.f >> 32u;
12756 const std::uint64_t p0 = u_lo * v_lo;
12757 const std::uint64_t p1 = u_lo * v_hi;
12758 const std::uint64_t p2 = u_hi * v_lo;
12759 const std::uint64_t p3 = u_hi * v_hi;
12761 const std::uint64_t p0_hi = p0 >> 32u;
12762 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
12763 const std::uint64_t p1_hi = p1 >> 32u;
12764 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
12765 const std::uint64_t p2_hi = p2 >> 32u;
12767 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
12778 Q += std::uint64_t{1} << (64u - 32u - 1u);
12780 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
12782 return {h, x.e + y.e + 64};
12789 static diyfp normalize(diyfp x)
noexcept
12793 while ((x.f >> 63u) == 0)
12806 static diyfp normalize_to(
const diyfp& x,
const int target_exponent)
noexcept
12808 const int delta = x.e - target_exponent;
12810 assert(delta >= 0);
12811 assert(((x.f << delta) >> delta) == x.f);
12813 return {x.f << delta, target_exponent};
12830 template <
typename FloatType>
12831 boundaries compute_boundaries(FloatType value)
12833 assert(std::isfinite(value));
12843 static_assert(std::numeric_limits<FloatType>::is_iec559,
12844 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
12846 constexpr int kPrecision = std::numeric_limits<FloatType>::digits;
12847 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
12848 constexpr int kMinExp = 1 - kBias;
12849 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1);
12851 using bits_type =
typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
12853 const std::uint64_t bits = reinterpret_bits<bits_type>(value);
12854 const std::uint64_t E = bits >> (kPrecision - 1);
12855 const std::uint64_t F = bits & (kHiddenBit - 1);
12857 const bool is_denormal = E == 0;
12858 const diyfp v = is_denormal
12859 ? diyfp(F, kMinExp)
12860 : diyfp(F + kHiddenBit,
static_cast<
int>(E) - kBias);
12883 const bool lower_boundary_is_closer = F == 0
and E > 1;
12884 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
12885 const diyfp m_minus = lower_boundary_is_closer
12886 ? diyfp(4 * v.f - 1, v.e - 2)
12887 : diyfp(2 * v.f - 1, v.e - 1);
12890 const diyfp w_plus = diyfp::normalize(m_plus);
12893 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
12895 return {diyfp::normalize(v), w_minus, w_plus};
12953 constexpr int kAlpha = -60;
12954 constexpr int kGamma = -32;
12956 struct cached_power
12970 inline cached_power get_cached_power_for_binary_exponent(
int e)
13022 constexpr int kCachedPowersMinDecExp = -300;
13023 constexpr int kCachedPowersDecStep = 8;
13025 static constexpr std::array<cached_power, 79> kCachedPowers =
13028 { 0xAB70FE17C79AC6CA, -1060, -300 },
13029 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
13030 { 0xBE5691EF416BD60C, -1007, -284 },
13031 { 0x8DD01FAD907FFC3C, -980, -276 },
13032 { 0xD3515C2831559A83, -954, -268 },
13033 { 0x9D71AC8FADA6C9B5, -927, -260 },
13034 { 0xEA9C227723EE8BCB, -901, -252 },
13035 { 0xAECC49914078536D, -874, -244 },
13036 { 0x823C12795DB6CE57, -847, -236 },
13037 { 0xC21094364DFB5637, -821, -228 },
13038 { 0x9096EA6F3848984F, -794, -220 },
13039 { 0xD77485CB25823AC7, -768, -212 },
13040 { 0xA086CFCD97BF97F4, -741, -204 },
13041 { 0xEF340A98172AACE5, -715, -196 },
13042 { 0xB23867FB2A35B28E, -688, -188 },
13043 { 0x84C8D4DFD2C63F3B, -661, -180 },
13044 { 0xC5DD44271AD3CDBA, -635, -172 },
13045 { 0x936B9FCEBB25C996, -608, -164 },
13046 { 0xDBAC6C247D62A584, -582, -156 },
13047 { 0xA3AB66580D5FDAF6, -555, -148 },
13048 { 0xF3E2F893DEC3F126, -529, -140 },
13049 { 0xB5B5ADA8AAFF80B8, -502, -132 },
13050 { 0x87625F056C7C4A8B, -475, -124 },
13051 { 0xC9BCFF6034C13053, -449, -116 },
13052 { 0x964E858C91BA2655, -422, -108 },
13053 { 0xDFF9772470297EBD, -396, -100 },
13054 { 0xA6DFBD9FB8E5B88F, -369, -92 },
13055 { 0xF8A95FCF88747D94, -343, -84 },
13056 { 0xB94470938FA89BCF, -316, -76 },
13057 { 0x8A08F0F8BF0F156B, -289, -68 },
13058 { 0xCDB02555653131B6, -263, -60 },
13059 { 0x993FE2C6D07B7FAC, -236, -52 },
13060 { 0xE45C10C42A2B3B06, -210, -44 },
13061 { 0xAA242499697392D3, -183, -36 },
13062 { 0xFD87B5F28300CA0E, -157, -28 },
13063 { 0xBCE5086492111AEB, -130, -20 },
13064 { 0x8CBCCC096F5088CC, -103, -12 },
13065 { 0xD1B71758E219652C, -77, -4 },
13066 { 0x9C40000000000000, -50, 4 },
13067 { 0xE8D4A51000000000, -24, 12 },
13068 { 0xAD78EBC5AC620000, 3, 20 },
13069 { 0x813F3978F8940984, 30, 28 },
13070 { 0xC097CE7BC90715B3, 56, 36 },
13071 { 0x8F7E32CE7BEA5C70, 83, 44 },
13072 { 0xD5D238A4ABE98068, 109, 52 },
13073 { 0x9F4F2726179A2245, 136, 60 },
13074 { 0xED63A231D4C4FB27, 162, 68 },
13075 { 0xB0DE65388CC8ADA8, 189, 76 },
13076 { 0x83C7088E1AAB65DB, 216, 84 },
13077 { 0xC45D1DF942711D9A, 242, 92 },
13078 { 0x924D692CA61BE758, 269, 100 },
13079 { 0xDA01EE641A708DEA, 295, 108 },
13080 { 0xA26DA3999AEF774A, 322, 116 },
13081 { 0xF209787BB47D6B85, 348, 124 },
13082 { 0xB454E4A179DD1877, 375, 132 },
13083 { 0x865B86925B9BC5C2, 402, 140 },
13084 { 0xC83553C5C8965D3D, 428, 148 },
13085 { 0x952AB45CFA97A0B3, 455, 156 },
13086 { 0xDE469FBD99A05FE3, 481, 164 },
13087 { 0xA59BC234DB398C25, 508, 172 },
13088 { 0xF6C69A72A3989F5C, 534, 180 },
13089 { 0xB7DCBF5354E9BECE, 561, 188 },
13090 { 0x88FCF317F22241E2, 588, 196 },
13091 { 0xCC20CE9BD35C78A5, 614, 204 },
13092 { 0x98165AF37B2153DF, 641, 212 },
13093 { 0xE2A0B5DC971F303A, 667, 220 },
13094 { 0xA8D9D1535CE3B396, 694, 228 },
13095 { 0xFB9B7CD9A4A7443C, 720, 236 },
13096 { 0xBB764C4CA7A44410, 747, 244 },
13097 { 0x8BAB8EEFB6409C1A, 774, 252 },
13098 { 0xD01FEF10A657842C, 800, 260 },
13099 { 0x9B10A4E5E9913129, 827, 268 },
13100 { 0xE7109BFBA19C0C9D, 853, 276 },
13101 { 0xAC2820D9623BF429, 880, 284 },
13102 { 0x80444B5E7AA7CF85, 907, 292 },
13103 { 0xBF21E44003ACDD2D, 933, 300 },
13104 { 0x8E679C2F5E44FF8F, 960, 308 },
13105 { 0xD433179D9C8CB841, 986, 316 },
13106 { 0x9E19DB92B4E31BA9, 1013, 324 },
13114 assert(e >= -1500);
13116 const int f = kAlpha - e - 1;
13117 const int k = (f * 78913) / (1 << 18) +
static_cast<
int>(f > 0);
13119 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
13120 assert(index >= 0);
13121 assert(
static_cast<std::size_t>(index) < kCachedPowers.size());
13123 const cached_power cached = kCachedPowers[
static_cast<std::size_t>(index)];
13124 assert(kAlpha <= cached.e + e + 64);
13125 assert(kGamma >= cached.e + e + 64);
13134 inline int find_largest_pow10(
const std::uint32_t n, std::uint32_t& pow10)
13137 if (n >= 1000000000)
13139 pow10 = 1000000000;
13143 else if (n >= 100000000)
13148 else if (n >= 10000000)
13153 else if (n >= 1000000)
13158 else if (n >= 100000)
13163 else if (n >= 10000)
13168 else if (n >= 1000)
13190 inline void grisu2_round(
char* buf,
int len, std::uint64_t dist, std::uint64_t delta,
13191 std::uint64_t rest, std::uint64_t ten_k)
13194 assert(dist <= delta);
13195 assert(rest <= delta);
13218 and delta - rest >= ten_k
13219 and (rest + ten_k < dist
or dist - rest > rest + ten_k - dist))
13221 assert(buf[len - 1] !=
'0');
13231 inline void grisu2_digit_gen(
char* buffer,
int& length,
int& decimal_exponent,
13232 diyfp M_minus, diyfp w, diyfp M_plus)
13234 static_assert(kAlpha >= -60,
"internal error");
13235 static_assert(kGamma <= -32,
"internal error");
13249 assert(M_plus.e >= kAlpha);
13250 assert(M_plus.e <= kGamma);
13252 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f;
13253 std::uint64_t dist = diyfp::sub(M_plus, w ).f;
13262 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
13264 auto p1 =
static_cast<std::uint32_t>(M_plus.f >> -one.e);
13265 std::uint64_t p2 = M_plus.f & (one.f - 1);
13273 std::uint32_t pow10;
13274 const int k = find_largest_pow10(p1, pow10);
13301 const std::uint32_t d = p1 / pow10;
13302 const std::uint32_t r = p1 % pow10;
13308 buffer[length++] =
static_cast<
char>(
'0' + d);
13327 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
13332 decimal_exponent += n;
13343 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
13344 grisu2_round(buffer, length, dist, delta, rest, ten_n);
13394 assert(p2 > delta);
13405 assert(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
13407 const std::uint64_t d = p2 >> -one.e;
13408 const std::uint64_t r = p2 & (one.f - 1);
13415 buffer[length++] =
static_cast<
char>(
'0' + d);
13440 decimal_exponent -= m;
13448 const std::uint64_t ten_m = one.f;
13449 grisu2_round(buffer, length, dist, delta, p2, ten_m);
13472 inline void grisu2(
char* buf,
int& len,
int& decimal_exponent,
13473 diyfp m_minus, diyfp v, diyfp m_plus)
13475 assert(m_plus.e == m_minus.e);
13476 assert(m_plus.e == v.e);
13487 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
13489 const diyfp c_minus_k(cached.f, cached.e);
13492 const diyfp w = diyfp::mul(v, c_minus_k);
13493 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
13494 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
13517 const diyfp M_minus(w_minus.f + 1, w_minus.e);
13518 const diyfp M_plus (w_plus.f - 1, w_plus.e );
13520 decimal_exponent = -cached.k;
13522 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
13530 template <
typename FloatType>
13532 void grisu2(
char* buf,
int& len,
int& decimal_exponent, FloatType value)
13534 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
13535 "internal error: not enough precision");
13537 assert(std::isfinite(value));
13557 const boundaries w = compute_boundaries(
static_cast<
double>(value));
13559 const boundaries w = compute_boundaries(value);
13562 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
13572 inline char* append_exponent(
char* buf,
int e)
13587 auto k =
static_cast<std::uint32_t>(e);
13593 *buf++ =
static_cast<
char>(
'0' + k);
13597 *buf++ =
static_cast<
char>(
'0' + k / 10);
13599 *buf++ =
static_cast<
char>(
'0' + k);
13603 *buf++ =
static_cast<
char>(
'0' + k / 100);
13605 *buf++ =
static_cast<
char>(
'0' + k / 10);
13607 *buf++ =
static_cast<
char>(
'0' + k);
13624 inline char* format_buffer(
char* buf,
int len,
int decimal_exponent,
13625 int min_exp,
int max_exp)
13627 assert(min_exp < 0);
13628 assert(max_exp > 0);
13631 const int n = len + decimal_exponent;
13637 if (k <= n
and n <= max_exp)
13642 std::memset(buf + k,
'0',
static_cast<size_t>(n - k));
13646 return buf + (n + 2);
13649 if (0 < n
and n <= max_exp)
13656 std::memmove(buf + (n + 1), buf + n,
static_cast<size_t>(k - n));
13658 return buf + (k + 1);
13661 if (min_exp < n
and n <= 0)
13666 std::memmove(buf + (2 + -n), buf,
static_cast<size_t>(k));
13669 std::memset(buf + 2,
'0',
static_cast<size_t>(-n));
13670 return buf + (2 + (-n) + k);
13685 std::memmove(buf + 2, buf + 1,
static_cast<size_t>(k - 1));
13691 return append_exponent(buf, n - 1);
13706 template <
typename FloatType>
13709 char* to_chars(
char* first,
const char* last, FloatType value)
13711 static_cast<
void>(last);
13712 assert(std::isfinite(value));
13715 if (std::signbit(value))
13730 assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
13737 int decimal_exponent = 0;
13738 dtoa_impl::grisu2(first, len, decimal_exponent, value);
13740 assert(len <= std::numeric_limits<FloatType>::max_digits10);
13743 constexpr int kMinExp = -4;
13745 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
13747 assert(last - first >= kMaxExp + 2);
13748 assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
13749 assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
13751 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
13779 enum class error_handler_t
13786 template<
typename BasicJsonType>
13789 using string_t =
typename BasicJsonType::string_t;
13790 using number_float_t =
typename BasicJsonType::number_float_t;
13791 using number_integer_t =
typename BasicJsonType::number_integer_t;
13792 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
13793 static constexpr std::uint8_t UTF8_ACCEPT = 0;
13794 static constexpr std::uint8_t UTF8_REJECT = 1;
13802 serializer(output_adapter_t<
char> s,
const char ichar,
13803 error_handler_t error_handler_ = error_handler_t::strict)
13805 , loc(std::localeconv())
13806 , thousands_sep(loc->thousands_sep ==
nullptr ?
'\0' : * (loc->thousands_sep))
13807 , decimal_point(loc->decimal_point ==
nullptr ?
'\0' : * (loc->decimal_point))
13808 , indent_char(ichar)
13809 , indent_string(512, indent_char)
13810 , error_handler(error_handler_)
13814 serializer(
const serializer&) =
delete;
13815 serializer& operator=(
const serializer&) =
delete;
13816 serializer(serializer&&) =
delete;
13817 serializer& operator=(serializer&&) =
delete;
13818 ~serializer() =
default;
13837 void dump(
const BasicJsonType& val,
const bool pretty_print,
13838 const bool ensure_ascii,
13839 const unsigned int indent_step,
13840 const unsigned int current_indent = 0)
13842 switch (val.m_type)
13844 case value_t::object:
13846 if (val.m_value.object->empty())
13848 o->write_characters(
"{}", 2);
13854 o->write_characters(
"{\n", 2);
13857 const auto new_indent = current_indent + indent_step;
13860 indent_string.resize(indent_string.size() * 2,
' ');
13864 auto i = val.m_value.object->cbegin();
13865 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
13867 o->write_characters(indent_string.c_str(), new_indent);
13868 o->write_character(
'\"');
13869 dump_escaped(i->first, ensure_ascii);
13870 o->write_characters(
"\": ", 3);
13871 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
13872 o->write_characters(
",\n", 2);
13876 assert(i != val.m_value.object->cend());
13877 assert(std::next(i) == val.m_value.object->cend());
13878 o->write_characters(indent_string.c_str(), new_indent);
13879 o->write_character(
'\"');
13880 dump_escaped(i->first, ensure_ascii);
13881 o->write_characters(
"\": ", 3);
13882 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
13884 o->write_character(
'\n');
13885 o->write_characters(indent_string.c_str(), current_indent);
13886 o->write_character(
'}');
13890 o->write_character(
'{');
13893 auto i = val.m_value.object->cbegin();
13894 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
13896 o->write_character(
'\"');
13897 dump_escaped(i->first, ensure_ascii);
13898 o->write_characters(
"\":", 2);
13899 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
13900 o->write_character(
',');
13904 assert(i != val.m_value.object->cend());
13905 assert(std::next(i) == val.m_value.object->cend());
13906 o->write_character(
'\"');
13907 dump_escaped(i->first, ensure_ascii);
13908 o->write_characters(
"\":", 2);
13909 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
13911 o->write_character(
'}');
13917 case value_t::array:
13919 if (val.m_value.array->empty())
13921 o->write_characters(
"[]", 2);
13927 o->write_characters(
"[\n", 2);
13930 const auto new_indent = current_indent + indent_step;
13933 indent_string.resize(indent_string.size() * 2,
' ');
13937 for (
auto i = val.m_value.array->cbegin();
13938 i != val.m_value.array->cend() - 1; ++i)
13940 o->write_characters(indent_string.c_str(), new_indent);
13941 dump(*i,
true, ensure_ascii, indent_step, new_indent);
13942 o->write_characters(
",\n", 2);
13946 assert(
not val.m_value.array->empty());
13947 o->write_characters(indent_string.c_str(), new_indent);
13948 dump(val.m_value.array->back(),
true, ensure_ascii, indent_step, new_indent);
13950 o->write_character(
'\n');
13951 o->write_characters(indent_string.c_str(), current_indent);
13952 o->write_character(
']');
13956 o->write_character(
'[');
13959 for (
auto i = val.m_value.array->cbegin();
13960 i != val.m_value.array->cend() - 1; ++i)
13962 dump(*i,
false, ensure_ascii, indent_step, current_indent);
13963 o->write_character(
',');
13967 assert(
not val.m_value.array->empty());
13968 dump(val.m_value.array->back(),
false, ensure_ascii, indent_step, current_indent);
13970 o->write_character(
']');
13976 case value_t::string:
13978 o->write_character(
'\"');
13979 dump_escaped(*val.m_value.string, ensure_ascii);
13980 o->write_character(
'\"');
13984 case value_t::boolean:
13986 if (val.m_value.boolean)
13988 o->write_characters(
"true", 4);
13992 o->write_characters(
"false", 5);
13997 case value_t::number_integer:
13999 dump_integer(val.m_value.number_integer);
14003 case value_t::number_unsigned:
14005 dump_integer(val.m_value.number_unsigned);
14009 case value_t::number_float:
14011 dump_float(val.m_value.number_float);
14015 case value_t::discarded:
14017 o->write_characters(
"<discarded>", 11);
14021 case value_t::null:
14023 o->write_characters(
"null", 4);
14047 void dump_escaped(
const string_t& s,
const bool ensure_ascii)
14049 std::uint32_t codepoint;
14050 std::uint8_t state = UTF8_ACCEPT;
14051 std::size_t bytes = 0;
14054 std::size_t bytes_after_last_accept = 0;
14055 std::size_t undumped_chars = 0;
14057 for (std::size_t i = 0; i < s.size(); ++i)
14059 const auto byte =
static_cast<uint8_t>(s[i]);
14061 switch (decode(state, codepoint, byte))
14069 string_buffer[bytes++] =
'\\';
14070 string_buffer[bytes++] =
'b';
14076 string_buffer[bytes++] =
'\\';
14077 string_buffer[bytes++] =
't';
14083 string_buffer[bytes++] =
'\\';
14084 string_buffer[bytes++] =
'n';
14090 string_buffer[bytes++] =
'\\';
14091 string_buffer[bytes++] =
'f';
14097 string_buffer[bytes++] =
'\\';
14098 string_buffer[bytes++] =
'r';
14104 string_buffer[bytes++] =
'\\';
14105 string_buffer[bytes++] =
'\"';
14111 string_buffer[bytes++] =
'\\';
14112 string_buffer[bytes++] =
'\\';
14120 if ((codepoint <= 0x1F)
or (ensure_ascii
and (codepoint >= 0x7F)))
14122 if (codepoint <= 0xFFFF)
14124 (std::snprintf)(string_buffer.data() + bytes, 7,
"\\u%04x",
14125 static_cast<std::uint16_t>(codepoint));
14130 (std::snprintf)(string_buffer.data() + bytes, 13,
"\\u%04x\\u%04x",
14131 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
14132 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
14140 string_buffer[bytes++] = s[i];
14149 if (string_buffer.size() - bytes < 13)
14151 o->write_characters(string_buffer.data(), bytes);
14156 bytes_after_last_accept = bytes;
14157 undumped_chars = 0;
14163 switch (error_handler)
14165 case error_handler_t::strict:
14167 std::string sn(3,
'\0');
14168 (std::snprintf)(&sn[0], sn.size(),
"%.2X", byte);
14169 JSON_THROW(type_error::create(316,
"invalid UTF-8 byte at index " + std::to_string(i) +
": 0x" + sn));
14172 case error_handler_t::ignore:
14173 case error_handler_t::replace:
14179 if (undumped_chars > 0)
14186 bytes = bytes_after_last_accept;
14188 if (error_handler == error_handler_t::replace)
14193 string_buffer[bytes++] =
'\\';
14194 string_buffer[bytes++] =
'u';
14195 string_buffer[bytes++] =
'f';
14196 string_buffer[bytes++] =
'f';
14197 string_buffer[bytes++] =
'f';
14198 string_buffer[bytes++] =
'd';
14202 string_buffer[bytes++] = detail::binary_writer<BasicJsonType,
char>::to_char_type(
'\xEF');
14203 string_buffer[bytes++] = detail::binary_writer<BasicJsonType,
char>::to_char_type(
'\xBF');
14204 string_buffer[bytes++] = detail::binary_writer<BasicJsonType,
char>::to_char_type(
'\xBD');
14210 if (string_buffer.size() - bytes < 13)
14212 o->write_characters(string_buffer.data(), bytes);
14216 bytes_after_last_accept = bytes;
14219 undumped_chars = 0;
14222 state = UTF8_ACCEPT;
14234 if (
not ensure_ascii)
14237 string_buffer[bytes++] = s[i];
14251 o->write_characters(string_buffer.data(), bytes);
14257 switch (error_handler)
14259 case error_handler_t::strict:
14261 std::string sn(3,
'\0');
14262 (std::snprintf)(&sn[0], sn.size(),
"%.2X",
static_cast<std::uint8_t>(s.back()));
14263 JSON_THROW(type_error::create(316,
"incomplete UTF-8 string; last byte: 0x" + sn));
14266 case error_handler_t::ignore:
14269 o->write_characters(string_buffer.data(), bytes_after_last_accept);
14273 case error_handler_t::replace:
14276 o->write_characters(string_buffer.data(), bytes_after_last_accept);
14280 o->write_characters(
"\\ufffd", 6);
14284 o->write_characters(
"\xEF\xBF\xBD", 3);
14303 inline unsigned int count_digits(number_unsigned_t x)
noexcept
14305 unsigned int n_digits = 1;
14314 return n_digits + 1;
14318 return n_digits + 2;
14322 return n_digits + 3;
14338 template<
typename NumberType, detail::enable_if_t<
14339 std::is_same<NumberType, number_unsigned_t>::value
or
14340 std::is_same<NumberType, number_integer_t>::value,
14342 void dump_integer(NumberType x)
14344 static constexpr std::array<std::array<
char, 2>, 100> digits_to_99
14347 {{
'0',
'0'}}, {{
'0',
'1'}}, {{
'0',
'2'}}, {{
'0',
'3'}}, {{
'0',
'4'}}, {{
'0',
'5'}}, {{
'0',
'6'}}, {{
'0',
'7'}}, {{
'0',
'8'}}, {{
'0',
'9'}},
14348 {{
'1',
'0'}}, {{
'1',
'1'}}, {{
'1',
'2'}}, {{
'1',
'3'}}, {{
'1',
'4'}}, {{
'1',
'5'}}, {{
'1',
'6'}}, {{
'1',
'7'}}, {{
'1',
'8'}}, {{
'1',
'9'}},
14349 {{
'2',
'0'}}, {{
'2',
'1'}}, {{
'2',
'2'}}, {{
'2',
'3'}}, {{
'2',
'4'}}, {{
'2',
'5'}}, {{
'2',
'6'}}, {{
'2',
'7'}}, {{
'2',
'8'}}, {{
'2',
'9'}},
14350 {{
'3',
'0'}}, {{
'3',
'1'}}, {{
'3',
'2'}}, {{
'3',
'3'}}, {{
'3',
'4'}}, {{
'3',
'5'}}, {{
'3',
'6'}}, {{
'3',
'7'}}, {{
'3',
'8'}}, {{
'3',
'9'}},
14351 {{
'4',
'0'}}, {{
'4',
'1'}}, {{
'4',
'2'}}, {{
'4',
'3'}}, {{
'4',
'4'}}, {{
'4',
'5'}}, {{
'4',
'6'}}, {{
'4',
'7'}}, {{
'4',
'8'}}, {{
'4',
'9'}},
14352 {{
'5',
'0'}}, {{
'5',
'1'}}, {{
'5',
'2'}}, {{
'5',
'3'}}, {{
'5',
'4'}}, {{
'5',
'5'}}, {{
'5',
'6'}}, {{
'5',
'7'}}, {{
'5',
'8'}}, {{
'5',
'9'}},
14353 {{
'6',
'0'}}, {{
'6',
'1'}}, {{
'6',
'2'}}, {{
'6',
'3'}}, {{
'6',
'4'}}, {{
'6',
'5'}}, {{
'6',
'6'}}, {{
'6',
'7'}}, {{
'6',
'8'}}, {{
'6',
'9'}},
14354 {{
'7',
'0'}}, {{
'7',
'1'}}, {{
'7',
'2'}}, {{
'7',
'3'}}, {{
'7',
'4'}}, {{
'7',
'5'}}, {{
'7',
'6'}}, {{
'7',
'7'}}, {{
'7',
'8'}}, {{
'7',
'9'}},
14355 {{
'8',
'0'}}, {{
'8',
'1'}}, {{
'8',
'2'}}, {{
'8',
'3'}}, {{
'8',
'4'}}, {{
'8',
'5'}}, {{
'8',
'6'}}, {{
'8',
'7'}}, {{
'8',
'8'}}, {{
'8',
'9'}},
14356 {{
'9',
'0'}}, {{
'9',
'1'}}, {{
'9',
'2'}}, {{
'9',
'3'}}, {{
'9',
'4'}}, {{
'9',
'5'}}, {{
'9',
'6'}}, {{
'9',
'7'}}, {{
'9',
'8'}}, {{
'9',
'9'}},
14363 o->write_character(
'0');
14368 auto buffer_ptr = number_buffer.begin();
14370 const bool is_negative = std::is_same<NumberType, number_integer_t>::value
and not(x >= 0);
14371 number_unsigned_t abs_value;
14373 unsigned int n_chars;
14378 abs_value = remove_sign(x);
14381 n_chars = 1 + count_digits(abs_value);
14385 abs_value =
static_cast<number_unsigned_t>(x);
14386 n_chars = count_digits(abs_value);
14390 assert(n_chars < number_buffer.size() - 1);
14394 buffer_ptr += n_chars;
14398 while (abs_value >= 100)
14400 const auto digits_index =
static_cast<
unsigned>((abs_value % 100));
14402 *(--buffer_ptr) = digits_to_99[digits_index][1];
14403 *(--buffer_ptr) = digits_to_99[digits_index][0];
14406 if (abs_value >= 10)
14408 const auto digits_index =
static_cast<
unsigned>(abs_value);
14409 *(--buffer_ptr) = digits_to_99[digits_index][1];
14410 *(--buffer_ptr) = digits_to_99[digits_index][0];
14414 *(--buffer_ptr) =
static_cast<
char>(
'0' + abs_value);
14417 o->write_characters(number_buffer.data(), n_chars);
14428 void dump_float(number_float_t x)
14431 if (
not std::isfinite(x))
14433 o->write_characters(
"null", 4);
14442 static constexpr bool is_ieee_single_or_double
14443 = (std::numeric_limits<number_float_t>::is_iec559
and std::numeric_limits<number_float_t>::digits == 24
and std::numeric_limits<number_float_t>::max_exponent == 128)
or
14444 (std::numeric_limits<number_float_t>::is_iec559
and std::numeric_limits<number_float_t>::digits == 53
and std::numeric_limits<number_float_t>::max_exponent == 1024);
14446 dump_float(x, std::integral_constant<
bool, is_ieee_single_or_double>());
14449 void dump_float(number_float_t x, std::true_type )
14451 char* begin = number_buffer.data();
14452 char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
14454 o->write_characters(begin,
static_cast<size_t>(end - begin));
14457 void dump_float(number_float_t x, std::false_type )
14460 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
14463 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(),
"%.*g", d, x);
14468 assert(
static_cast<std::size_t>(len) < number_buffer.size());
14471 if (thousands_sep !=
'\0')
14473 const auto end = std::remove(number_buffer.begin(),
14474 number_buffer.begin() + len, thousands_sep);
14475 std::fill(end, number_buffer.end(),
'\0');
14476 assert((end - number_buffer.begin()) <= len);
14477 len = (end - number_buffer.begin());
14481 if (decimal_point !=
'\0' and decimal_point !=
'.')
14483 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
14484 if (dec_pos != number_buffer.end())
14490 o->write_characters(number_buffer.data(),
static_cast<std::size_t>(len));
14493 const bool value_is_int_like =
14494 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
14497 return c ==
'.' or c ==
'e';
14500 if (value_is_int_like)
14502 o->write_characters(
".0", 2);
14527 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep,
const std::uint8_t byte)
noexcept
14529 static const std::array<std::uint8_t, 400> utf8d =
14532 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,
14533 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,
14534 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,
14535 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,
14536 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,
14537 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,
14538 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,
14539 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3,
14540 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
14541 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1,
14542 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,
14543 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,
14544 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,
14545 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
14549 const std::uint8_t type = utf8d[byte];
14551 codep = (state != UTF8_ACCEPT)
14552 ? (byte & 0x3fu) | (codep << 6u)
14553 : (0xFFu >> type) & (byte);
14555 state = utf8d[256u + state * 16u + type];
14564 number_unsigned_t remove_sign(number_unsigned_t x)
14579 inline number_unsigned_t remove_sign(number_integer_t x)
noexcept
14581 assert(x < 0
and x < (std::numeric_limits<number_integer_t>::max)());
14582 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
14587 output_adapter_t<
char> o =
nullptr;
14590 std::array<
char, 64> number_buffer{{}};
14593 const std::lconv* loc =
nullptr;
14595 const char thousands_sep =
'\0';
14597 const char decimal_point =
'\0';
14600 std::array<
char, 512> string_buffer{{}};
14603 const char indent_char;
14605 string_t indent_string;
14608 const error_handler_t error_handler;
14711 template<detail::value_t>
friend struct detail::external_constructor;
14712 friend ::nlohmann::json_pointer<basic_json>;
14713 friend ::nlohmann::detail::parser<basic_json>;
14714 friend ::nlohmann::detail::serializer<basic_json>;
14715 template<
typename BasicJsonType>
14716 friend class ::nlohmann::detail::iter_impl;
14717 template<
typename BasicJsonType,
typename CharType>
14718 friend class ::nlohmann::detail::binary_writer;
14719 template<
typename BasicJsonType,
typename SAX>
14720 friend class ::nlohmann::detail::binary_reader;
14721 template<
typename BasicJsonType>
14722 friend class ::nlohmann::detail::json_sax_dom_parser;
14723 template<
typename BasicJsonType>
14724 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
14730 using lexer = ::nlohmann::detail::lexer<basic_json>;
14731 using parser = ::nlohmann::detail::parser<basic_json>;
14733 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
14734 template<
typename BasicJsonType>
14735 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
14736 template<
typename BasicJsonType>
14737 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
14738 template<
typename Iterator>
14739 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
14740 template<
typename Base>
using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
14742 template<
typename CharType>
14743 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
14745 using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
14746 template<
typename CharType>
using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
14748 using serializer = ::nlohmann::detail::serializer<basic_json>;
14751 using value_t = detail::value_t;
14753 using json_pointer = ::nlohmann::json_pointer<basic_json>;
14754 template<
typename T,
typename SFINAE>
14755 using json_serializer = JSONSerializer<T, SFINAE>;
14757 using error_handler_t = detail::error_handler_t;
14759 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
14761 using input_format_t = detail::input_format_t;
14763 using json_sax_t = json_sax<basic_json>;
14774 using exception = detail::exception;
14776 using parse_error = detail::parse_error;
14778 using invalid_iterator = detail::invalid_iterator;
14780 using type_error = detail::type_error;
14782 using out_of_range = detail::out_of_range;
14784 using other_error = detail::other_error;
14799 using value_type = basic_json;
14802 using reference = value_type&;
14804 using const_reference =
const value_type&;
14807 using difference_type = std::ptrdiff_t;
14809 using size_type = std::size_t;
14812 using allocator_type = AllocatorType<basic_json>;
14815 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
14817 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
14820 using iterator = iter_impl<basic_json>;
14822 using const_iterator = iter_impl<
const basic_json>;
14824 using reverse_iterator = json_reverse_iterator<
typename basic_json::iterator>;
14826 using const_reverse_iterator = json_reverse_iterator<
typename basic_json::const_iterator>;
14834 static allocator_type get_allocator()
14836 return allocator_type();
14866 static basic_json meta()
14870 result[
"copyright"] =
"(C) 2013-2017 Niels Lohmann";
14871 result[
"name"] =
"JSON for Modern C++";
14872 result[
"url"] =
"https://github.com/nlohmann/json";
14873 result[
"version"][
"string"] =
14882 result[
"platform"] =
"win32";
14883 #elif defined __linux__
14884 result[
"platform"] =
"linux";
14885 #elif defined __APPLE__
14886 result[
"platform"] =
"apple";
14887 #elif defined __unix__
14888 result[
"platform"] =
"unix";
14890 result[
"platform"] =
"unknown";
14893 #if defined(__ICC) || defined(__INTEL_COMPILER)
14894 result[
"compiler"] = {{
"family",
"icc"}, {
"version", __INTEL_COMPILER}};
14895 #elif defined(__clang__
)
14896 result[
"compiler"] = {{
"family",
"clang"}, {
"version", __clang_version__}};
14897 #elif defined(__GNUC__) || defined(__GNUG__)
14898 result[
"compiler"] = {{
"family",
"gcc"}, {
"version", std::to_string(__GNUC__) +
"." + std::to_string(__GNUC_MINOR__) +
"." + std::to_string(__GNUC_PATCHLEVEL__)}};
14899 #elif defined(__HP_cc) || defined(__HP_aCC)
14900 result[
"compiler"] =
"hp"
14901 #elif defined(__IBMCPP__)
14902 result[
"compiler"] = {{
"family",
"ilecpp"}, {
"version", __IBMCPP__}};
14903 #elif defined(_MSC_VER)
14904 result[
"compiler"] = {{
"family",
"msvc"}, {
"version", _MSC_VER}};
14905 #elif defined(__PGI)
14906 result[
"compiler"] = {{
"family",
"pgcpp"}, {
"version", __PGI}};
14907 #elif defined(__SUNPRO_CC)
14908 result[
"compiler"] = {{
"family",
"sunpro"}, {
"version", __SUNPRO_CC}};
14910 result[
"compiler"] = {{
"family",
"unknown"}, {
"version",
"unknown"}};
14914 result[
"compiler"][
"c++"] = std::to_string(__cplusplus);
14916 result[
"compiler"][
"c++"] =
"unknown";
14931 #if defined(JSON_HAS_CPP_14)
14934 using object_comparator_t = std::less<>;
14936 using object_comparator_t = std::less<StringType>;
15022 using object_t = ObjectType<StringType,
15024 object_comparator_t,
15025 AllocatorType<std::pair<
const StringType,
15072 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
15125 using string_t = StringType;
15151 using boolean_t = BooleanType;
15223 using number_integer_t = NumberIntegerType;
15294 using number_unsigned_t = NumberUnsignedType;
15362 using number_float_t = NumberFloatType;
15369 template<
typename T,
typename... Args>
15371 static T* create(Args&& ... args)
15373 AllocatorType<T> alloc;
15374 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
15376 auto deleter = [&](T * object)
15378 AllocatorTraits::deallocate(alloc, object, 1);
15380 std::unique_ptr<T,
decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
15381 AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
15382 assert(object !=
nullptr);
15383 return object.release();
15425 number_integer_t number_integer;
15427 number_unsigned_t number_unsigned;
15429 number_float_t number_float;
15432 json_value() =
default;
15434 json_value(boolean_t v)
noexcept : boolean(v) {}
15436 json_value(number_integer_t v)
noexcept : number_integer(v) {}
15438 json_value(number_unsigned_t v)
noexcept : number_unsigned(v) {}
15440 json_value(number_float_t v)
noexcept : number_float(v) {}
15442 json_value(value_t t)
15446 case value_t::object:
15448 object = create<object_t>();
15452 case value_t::array:
15454 array = create<array_t>();
15458 case value_t::string:
15460 string = create<string_t>(
"");
15464 case value_t::boolean:
15466 boolean = boolean_t(
false);
15470 case value_t::number_integer:
15472 number_integer = number_integer_t(0);
15476 case value_t::number_unsigned:
15478 number_unsigned = number_unsigned_t(0);
15482 case value_t::number_float:
15484 number_float = number_float_t(0.0);
15488 case value_t::null:
15499 JSON_THROW(other_error::create(500,
"961c151d2e87f2686a955a9be24d316f1362bf21 3.7.3"));
15507 json_value(
const string_t& value)
15509 string = create<string_t>(value);
15513 json_value(string_t&& value)
15515 string = create<string_t>(std::move(value));
15519 json_value(
const object_t& value)
15521 object = create<object_t>(value);
15525 json_value(object_t&& value)
15527 object = create<object_t>(std::move(value));
15531 json_value(
const array_t& value)
15533 array = create<array_t>(value);
15537 json_value(array_t&& value)
15539 array = create<array_t>(std::move(value));
15542 void destroy(value_t t)
noexcept
15545 std::vector<basic_json> stack;
15548 if (t == value_t::array)
15550 stack.reserve(array->size());
15551 std::move(array->begin(), array->end(), std::back_inserter(stack));
15553 else if (t == value_t::object)
15555 stack.reserve(object->size());
15556 for (
auto&& it : *object)
15558 stack.push_back(std::move(it.second));
15562 while (
not stack.empty())
15565 basic_json current_item(std::move(stack.back()));
15570 if (current_item.is_array())
15572 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
15573 std::back_inserter(stack));
15575 current_item.m_value.array->clear();
15577 else if (current_item.is_object())
15579 for (
auto&& it : *current_item.m_value.object)
15581 stack.push_back(std::move(it.second));
15584 current_item.m_value.object->clear();
15593 case value_t::object:
15595 AllocatorType<object_t> alloc;
15596 std::allocator_traits<
decltype(alloc)>::destroy(alloc, object);
15597 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, object, 1);
15601 case value_t::array:
15603 AllocatorType<array_t> alloc;
15604 std::allocator_traits<
decltype(alloc)>::destroy(alloc, array);
15605 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, array, 1);
15609 case value_t::string:
15611 AllocatorType<string_t> alloc;
15612 std::allocator_traits<
decltype(alloc)>::destroy(alloc, string);
15613 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, string, 1);
15634 void assert_invariant()
const noexcept
15636 assert(m_type != value_t::object
or m_value.object !=
nullptr);
15637 assert(m_type != value_t::array
or m_value.array !=
nullptr);
15638 assert(m_type != value_t::string
or m_value.string !=
nullptr);
15661 using parse_event_t =
typename parser::parse_event_t;
15712 using parser_callback_t =
typename parser::parser_callback_t;
15752 basic_json(
const value_t v)
15753 : m_type(v), m_value(v)
15755 assert_invariant();
15776 basic_json(std::nullptr_t =
nullptr)
noexcept
15777 : basic_json(value_t::null)
15779 assert_invariant();
15839 template <
typename CompatibleType,
15840 typename U = detail::uncvref_t<CompatibleType>,
15841 detail::enable_if_t<
15842 not detail::is_basic_json<U>::value
and detail::is_compatible_type<basic_json_t, U>::value,
int> = 0>
15843 basic_json(CompatibleType && val)
noexcept(
noexcept(
15844 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
15845 std::forward<CompatibleType>(val))))
15847 JSONSerializer<U>::to_json(*
this, std::forward<CompatibleType>(val));
15848 assert_invariant();
15877 template <
typename BasicJsonType,
15878 detail::enable_if_t<
15879 detail::is_basic_json<BasicJsonType>::value
and not std::is_same<basic_json, BasicJsonType>::value,
int> = 0>
15880 basic_json(
const BasicJsonType& val)
15882 using other_boolean_t =
typename BasicJsonType::boolean_t;
15883 using other_number_float_t =
typename BasicJsonType::number_float_t;
15884 using other_number_integer_t =
typename BasicJsonType::number_integer_t;
15885 using other_number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
15886 using other_string_t =
typename BasicJsonType::string_t;
15887 using other_object_t =
typename BasicJsonType::object_t;
15888 using other_array_t =
typename BasicJsonType::array_t;
15890 switch (val.type())
15892 case value_t::boolean:
15893 JSONSerializer<other_boolean_t>::to_json(*
this, val.
template get<other_boolean_t>());
15895 case value_t::number_float:
15896 JSONSerializer<other_number_float_t>::to_json(*
this, val.
template get<other_number_float_t>());
15898 case value_t::number_integer:
15899 JSONSerializer<other_number_integer_t>::to_json(*
this, val.
template get<other_number_integer_t>());
15901 case value_t::number_unsigned:
15902 JSONSerializer<other_number_unsigned_t>::to_json(*
this, val.
template get<other_number_unsigned_t>());
15904 case value_t::string:
15905 JSONSerializer<other_string_t>::to_json(*
this, val.
template get_ref<
const other_string_t&>());
15907 case value_t::object:
15908 JSONSerializer<other_object_t>::to_json(*
this, val.
template get_ref<
const other_object_t&>());
15910 case value_t::array:
15911 JSONSerializer<other_array_t>::to_json(*
this, val.
template get_ref<
const other_array_t&>());
15913 case value_t::null:
15916 case value_t::discarded:
15917 m_type = value_t::discarded;
15922 assert_invariant();
15999 basic_json(initializer_list_t init,
16000 bool type_deduction =
true,
16001 value_t manual_type = value_t::array)
16005 bool is_an_object = std::all_of(init.begin(), init.end(),
16006 [](
const detail::json_ref<basic_json>& element_ref)
16008 return element_ref->is_array()
and element_ref->size() == 2
and (*element_ref)[0].is_string();
16012 if (
not type_deduction)
16015 if (manual_type == value_t::array)
16017 is_an_object =
false;
16023 JSON_THROW(type_error::create(301,
"cannot create object from initializer list"));
16030 m_type = value_t::object;
16031 m_value = value_t::object;
16033 std::for_each(init.begin(), init.end(), [
this](
const detail::json_ref<basic_json>& element_ref)
16035 auto element = element_ref.moved_or_copied();
16036 m_value.object->emplace(
16037 std::move(*((*element.m_value.array)[0].m_value.string)),
16038 std::move((*element.m_value.array)[1]));
16044 m_type = value_t::array;
16045 m_value.array = create<array_t>(init.begin(), init.end());
16048 assert_invariant();
16089 static basic_json array(initializer_list_t init = {})
16091 return basic_json(init,
false, value_t::array);
16133 static basic_json object(initializer_list_t init = {})
16135 return basic_json(init,
false, value_t::object);
16160 basic_json(size_type cnt,
const basic_json& val)
16161 : m_type(value_t::array)
16163 m_value.array = create<array_t>(cnt, val);
16164 assert_invariant();
16222 template<
class InputIT,
typename std::enable_if<
16223 std::is_same<InputIT,
typename basic_json_t::iterator>::value
or
16224 std::is_same<InputIT,
typename basic_json_t::const_iterator>::value,
int>::type = 0>
16225 basic_json(InputIT first, InputIT last)
16227 assert(first.m_object !=
nullptr);
16228 assert(last.m_object !=
nullptr);
16233 JSON_THROW(invalid_iterator::create(201,
"iterators are not compatible"));
16237 m_type = first.m_object->m_type;
16242 case value_t::boolean:
16243 case value_t::number_float:
16244 case value_t::number_integer:
16245 case value_t::number_unsigned:
16246 case value_t::string:
16249 or not last.m_it.primitive_iterator.is_end()))
16251 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
16262 case value_t::number_integer:
16264 m_value.number_integer = first.m_object->m_value.number_integer;
16268 case value_t::number_unsigned:
16270 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
16274 case value_t::number_float:
16276 m_value.number_float = first.m_object->m_value.number_float;
16280 case value_t::boolean:
16282 m_value.boolean = first.m_object->m_value.boolean;
16286 case value_t::string:
16288 m_value = *first.m_object->m_value.string;
16292 case value_t::object:
16294 m_value.object = create<object_t>(first.m_it.object_iterator,
16295 last.m_it.object_iterator);
16299 case value_t::array:
16301 m_value.array = create<array_t>(first.m_it.array_iterator,
16302 last.m_it.array_iterator);
16307 JSON_THROW(invalid_iterator::create(206,
"cannot construct with iterators from " +
16308 std::string(first.m_object->type_name())));
16311 assert_invariant();
16320 basic_json(
const detail::json_ref<basic_json>& ref)
16321 : basic_json(ref.moved_or_copied())
16349 basic_json(
const basic_json& other)
16350 : m_type(other.m_type)
16353 other.assert_invariant();
16357 case value_t::object:
16359 m_value = *other.m_value.object;
16363 case value_t::array:
16365 m_value = *other.m_value.array;
16369 case value_t::string:
16371 m_value = *other.m_value.string;
16375 case value_t::boolean:
16377 m_value = other.m_value.boolean;
16381 case value_t::number_integer:
16383 m_value = other.m_value.number_integer;
16387 case value_t::number_unsigned:
16389 m_value = other.m_value.number_unsigned;
16393 case value_t::number_float:
16395 m_value = other.m_value.number_float;
16403 assert_invariant();
16432 basic_json(basic_json&& other)
noexcept
16433 : m_type(std::move(other.m_type)),
16434 m_value(std::move(other.m_value))
16437 other.assert_invariant();
16440 other.m_type = value_t::null;
16441 other.m_value = {};
16443 assert_invariant();
16469 basic_json& operator=(basic_json other)
noexcept (
16470 std::is_nothrow_move_constructible<value_t>::value
and
16471 std::is_nothrow_move_assignable<value_t>::value
and
16472 std::is_nothrow_move_constructible<json_value>::value
and
16473 std::is_nothrow_move_assignable<json_value>::value
16477 other.assert_invariant();
16480 swap(m_type, other.m_type);
16481 swap(m_value, other.m_value);
16483 assert_invariant();
16502 ~basic_json()
noexcept
16504 assert_invariant();
16505 m_value.destroy(m_type);
16560 string_t dump(
const int indent = -1,
16561 const char indent_char =
' ',
16562 const bool ensure_ascii =
false,
16563 const error_handler_t error_handler = error_handler_t::strict)
const
16566 serializer s(detail::output_adapter<
char, string_t>(result), indent_char, error_handler);
16570 s.dump(*
this,
true, ensure_ascii,
static_cast<
unsigned int>(indent));
16574 s.dump(*
this,
false, ensure_ascii, 0);
16612 constexpr value_t type()
const noexcept
16642 constexpr bool is_primitive()
const noexcept
16644 return is_null()
or is_string()
or is_boolean()
or is_number();
16669 constexpr bool is_structured()
const noexcept
16671 return is_array()
or is_object();
16691 constexpr bool is_null()
const noexcept
16693 return m_type == value_t::null;
16713 constexpr bool is_boolean()
const noexcept
16715 return m_type == value_t::boolean;
16743 constexpr bool is_number()
const noexcept
16745 return is_number_integer()
or is_number_float();
16772 constexpr bool is_number_integer()
const noexcept
16774 return m_type == value_t::number_integer
or m_type == value_t::number_unsigned;
16800 constexpr bool is_number_unsigned()
const noexcept
16802 return m_type == value_t::number_unsigned;
16828 constexpr bool is_number_float()
const noexcept
16830 return m_type == value_t::number_float;
16850 constexpr bool is_object()
const noexcept
16852 return m_type == value_t::object;
16872 constexpr bool is_array()
const noexcept
16874 return m_type == value_t::array;
16894 constexpr bool is_string()
const noexcept
16896 return m_type == value_t::string;
16921 constexpr bool is_discarded()
const noexcept
16923 return m_type == value_t::discarded;
16947 constexpr operator value_t()
const noexcept
16960 boolean_t get_impl(boolean_t* )
const
16964 return m_value.boolean;
16967 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(type_name())));
16971 object_t* get_impl_ptr(object_t* )
noexcept
16973 return is_object() ? m_value.object :
nullptr;
16977 constexpr const object_t* get_impl_ptr(
const object_t* )
const noexcept
16979 return is_object() ? m_value.object :
nullptr;
16983 array_t* get_impl_ptr(array_t* )
noexcept
16985 return is_array() ? m_value.array :
nullptr;
16989 constexpr const array_t* get_impl_ptr(
const array_t* )
const noexcept
16991 return is_array() ? m_value.array :
nullptr;
16995 string_t* get_impl_ptr(string_t* )
noexcept
16997 return is_string() ? m_value.string :
nullptr;
17001 constexpr const string_t* get_impl_ptr(
const string_t* )
const noexcept
17003 return is_string() ? m_value.string :
nullptr;
17007 boolean_t* get_impl_ptr(boolean_t* )
noexcept
17009 return is_boolean() ? &m_value.boolean :
nullptr;
17013 constexpr const boolean_t* get_impl_ptr(
const boolean_t* )
const noexcept
17015 return is_boolean() ? &m_value.boolean :
nullptr;
17019 number_integer_t* get_impl_ptr(number_integer_t* )
noexcept
17021 return is_number_integer() ? &m_value.number_integer :
nullptr;
17025 constexpr const number_integer_t* get_impl_ptr(
const number_integer_t* )
const noexcept
17027 return is_number_integer() ? &m_value.number_integer :
nullptr;
17031 number_unsigned_t* get_impl_ptr(number_unsigned_t* )
noexcept
17033 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
17037 constexpr const number_unsigned_t* get_impl_ptr(
const number_unsigned_t* )
const noexcept
17039 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
17043 number_float_t* get_impl_ptr(number_float_t* )
noexcept
17045 return is_number_float() ? &m_value.number_float :
nullptr;
17049 constexpr const number_float_t* get_impl_ptr(
const number_float_t* )
const noexcept
17051 return is_number_float() ? &m_value.number_float :
nullptr;
17065 template<
typename ReferenceType,
typename ThisType>
17066 static ReferenceType get_ref_impl(ThisType& obj)
17069 auto ptr = obj.
template get_ptr<
typename std::add_pointer<ReferenceType>::type>();
17076 JSON_THROW(type_error::create(303,
"incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
17098 template<
typename BasicJsonType, detail::enable_if_t<
17099 std::is_same<
typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
17101 basic_json get()
const
17121 template<
typename BasicJsonType, detail::enable_if_t<
17122 not std::is_same<BasicJsonType, basic_json>::value
and
17123 detail::is_basic_json<BasicJsonType>::value,
int> = 0>
17124 BasicJsonType get()
const
17168 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
17169 detail::enable_if_t <
17170 not detail::is_basic_json<ValueType>::value
and
17171 detail::has_from_json<basic_json_t, ValueType>::value
and
17172 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
17174 ValueType get()
const noexcept(
noexcept(
17175 JSONSerializer<ValueType>::from_json(std::declval<
const basic_json_t&>(), std::declval<ValueType&>())))
17180 static_assert(
not std::is_reference<ValueTypeCV>::value,
17181 "get() cannot be used with reference types, you might want to use get_ref()");
17182 static_assert(std::is_default_constructible<ValueType>::value,
17183 "types must be DefaultConstructible when used with get()");
17186 JSONSerializer<ValueType>::from_json(*
this, ret);
17221 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
17222 detail::enable_if_t<
not std::is_same<basic_json_t, ValueType>::value
and
17223 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
17225 ValueType get()
const noexcept(
noexcept(
17226 JSONSerializer<ValueType>::from_json(std::declval<
const basic_json_t&>())))
17228 static_assert(
not std::is_reference<ValueTypeCV>::value,
17229 "get() cannot be used with reference types, you might want to use get_ref()");
17230 return JSONSerializer<ValueType>::from_json(*
this);
17266 template<
typename ValueType,
17267 detail::enable_if_t <
17268 not detail::is_basic_json<ValueType>::value
and
17269 detail::has_from_json<basic_json_t, ValueType>::value,
17271 ValueType & get_to(ValueType& v)
const noexcept(
noexcept(
17272 JSONSerializer<ValueType>::from_json(std::declval<
const basic_json_t&>(), v)))
17274 JSONSerializer<ValueType>::from_json(*
this, v);
17279 typename T, std::size_t N,
17280 typename Array = T (&)[N],
17281 detail::enable_if_t <
17282 detail::has_from_json<basic_json_t, Array>::value,
int > = 0 >
17283 Array get_to(T (&v)[N])
const
17284 noexcept(
noexcept(JSONSerializer<Array>::from_json(
17285 std::declval<
const basic_json_t&>(), v)))
17287 JSONSerializer<Array>::from_json(*
this, v);
17318 template<
typename PointerType,
typename std::enable_if<
17319 std::is_pointer<PointerType>::value,
int>::type = 0>
17320 auto get_ptr()
noexcept ->
decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
17323 return get_impl_ptr(
static_cast<PointerType>(
nullptr));
17330 template<
typename PointerType,
typename std::enable_if<
17331 std::is_pointer<PointerType>::value
and
17332 std::is_const<
typename std::remove_pointer<PointerType>::type>::value,
int>::type = 0>
17333 constexpr auto get_ptr()
const noexcept ->
decltype(std::declval<
const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
17336 return get_impl_ptr(
static_cast<PointerType>(
nullptr));
17366 template<
typename PointerType,
typename std::enable_if<
17367 std::is_pointer<PointerType>::value,
int>::type = 0>
17368 auto get()
noexcept ->
decltype(std::declval<basic_json_t&>().
template get_ptr<PointerType>())
17371 return get_ptr<PointerType>();
17378 template<
typename PointerType,
typename std::enable_if<
17379 std::is_pointer<PointerType>::value,
int>::type = 0>
17380 constexpr auto get()
const noexcept ->
decltype(std::declval<
const basic_json_t&>().
template get_ptr<PointerType>())
17383 return get_ptr<PointerType>();
17412 template<
typename ReferenceType,
typename std::enable_if<
17413 std::is_reference<ReferenceType>::value,
int>::type = 0>
17414 ReferenceType get_ref()
17417 return get_ref_impl<ReferenceType>(*
this);
17424 template<
typename ReferenceType,
typename std::enable_if<
17425 std::is_reference<ReferenceType>::value
and
17426 std::is_const<
typename std::remove_reference<ReferenceType>::type>::value,
int>::type = 0>
17427 ReferenceType get_ref()
const
17430 return get_ref_impl<ReferenceType>(*
this);
17462 template <
typename ValueType,
typename std::enable_if <
17463 not std::is_pointer<ValueType>::value
and
17464 not std::is_same<ValueType, detail::json_ref<basic_json>>::value
and
17465 not std::is_same<ValueType,
typename string_t::value_type>::value
and
17466 not detail::is_basic_json<ValueType>::value
17469 and not std::is_same<ValueType, std::initializer_list<
typename string_t::value_type>>::value
17470 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__
) || (defined(_MSC_VER) and _MSC_VER <= 1914
))
17471 and not std::is_same<ValueType,
typename std::string_view>::value
17474 and detail::is_detected<detail::get_template_function,
const basic_json_t&, ValueType>::value
17475 ,
int >::type = 0 >
17476 operator ValueType()
const
17479 return get<ValueType>();
17519 reference at(size_type idx)
17526 return m_value.array->at(idx);
17531 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
17536 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
17566 const_reference at(size_type idx)
const
17573 return m_value.array->at(idx);
17578 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
17583 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
17617 reference at(
const typename object_t::key_type& key)
17624 return m_value.object->at(key);
17629 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
17634 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
17668 const_reference at(
const typename object_t::key_type& key)
const
17675 return m_value.object->at(key);
17680 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
17685 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(type_name())));
17714 reference operator[](size_type idx)
17719 m_type = value_t::array;
17720 m_value.array = create<array_t>();
17721 assert_invariant();
17728 if (idx >= m_value.array->size())
17730 m_value.array->insert(m_value.array->end(),
17731 idx - m_value.array->size() + 1,
17735 return m_value.array->operator[](idx);
17738 JSON_THROW(type_error::create(305,
"cannot use operator[] with a numeric argument with " + std::string(type_name())));
17760 const_reference operator[](size_type idx)
const
17765 return m_value.array->operator[](idx);
17768 JSON_THROW(type_error::create(305,
"cannot use operator[] with a numeric argument with " + std::string(type_name())));
17798 reference operator[](
const typename object_t::key_type& key)
17803 m_type = value_t::object;
17804 m_value.object = create<object_t>();
17805 assert_invariant();
17811 return m_value.object->operator[](key);
17814 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(type_name())));
17847 const_reference operator[](
const typename object_t::key_type& key)
const
17852 assert(m_value.object->find(key) != m_value.object->end());
17853 return m_value.object->find(key)->second;
17856 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(type_name())));
17886 template<
typename T>
17888 reference operator[](T* key)
17893 m_type = value_t::object;
17894 m_value = value_t::object;
17895 assert_invariant();
17901 return m_value.object->operator[](key);
17904 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(type_name())));
17937 template<
typename T>
17939 const_reference operator[](T* key)
const
17944 assert(m_value.object->find(key) != m_value.object->end());
17945 return m_value.object->find(key)->second;
17948 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(type_name())));
18001 template<
class ValueType,
typename std::enable_if<
18002 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
18003 ValueType value(
const typename object_t::key_type& key,
const ValueType& default_value)
const
18009 const auto it = find(key);
18015 return default_value;
18018 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(type_name())));
18025 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const
18027 return value(key, string_t(default_value));
18073 template<
class ValueType,
typename std::enable_if<
18074 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
18075 ValueType value(
const json_pointer& ptr,
const ValueType& default_value)
const
18083 return ptr.get_checked(
this);
18087 return default_value;
18091 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(type_name())));
18099 string_t value(
const json_pointer& ptr,
const char* default_value)
const
18101 return value(ptr, string_t(default_value));
18137 const_reference front()
const
18183 const_reference back()
const
18236 template<
class IteratorType,
typename std::enable_if<
18237 std::is_same<IteratorType,
typename basic_json_t::iterator>::value
or
18238 std::is_same<IteratorType,
typename basic_json_t::const_iterator>::value,
int>::type
18240 IteratorType erase(IteratorType pos)
18245 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
18248 IteratorType result = end();
18252 case value_t::boolean:
18253 case value_t::number_float:
18254 case value_t::number_integer:
18255 case value_t::number_unsigned:
18256 case value_t::string:
18260 JSON_THROW(invalid_iterator::create(205,
"iterator out of range"));
18265 AllocatorType<string_t> alloc;
18266 std::allocator_traits<
decltype(alloc)>::destroy(alloc, m_value.string);
18267 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, m_value.string, 1);
18268 m_value.string =
nullptr;
18271 m_type = value_t::null;
18272 assert_invariant();
18276 case value_t::object:
18278 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
18282 case value_t::array:
18284 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
18289 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
18341 template<
class IteratorType,
typename std::enable_if<
18342 std::is_same<IteratorType,
typename basic_json_t::iterator>::value
or
18343 std::is_same<IteratorType,
typename basic_json_t::const_iterator>::value,
int>::type
18345 IteratorType erase(IteratorType first, IteratorType last)
18350 JSON_THROW(invalid_iterator::create(203,
"iterators do not fit current value"));
18353 IteratorType result = end();
18357 case value_t::boolean:
18358 case value_t::number_float:
18359 case value_t::number_integer:
18360 case value_t::number_unsigned:
18361 case value_t::string:
18364 or not last.m_it.primitive_iterator.is_end()))
18366 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
18371 AllocatorType<string_t> alloc;
18372 std::allocator_traits<
decltype(alloc)>::destroy(alloc, m_value.string);
18373 std::allocator_traits<
decltype(alloc)>::deallocate(alloc, m_value.string, 1);
18374 m_value.string =
nullptr;
18377 m_type = value_t::null;
18378 assert_invariant();
18382 case value_t::object:
18384 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
18385 last.m_it.object_iterator);
18389 case value_t::array:
18391 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
18392 last.m_it.array_iterator);
18397 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
18432 size_type erase(
const typename object_t::key_type& key)
18437 return m_value.object->erase(key);
18440 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
18467 void erase(
const size_type idx)
18474 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
18477 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
18481 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(type_name())));
18519 template<
typename KeyT>
18520 iterator find(KeyT&& key)
18522 auto result = end();
18526 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
18536 template<
typename KeyT>
18537 const_iterator find(KeyT&& key)
const
18539 auto result = cend();
18543 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
18570 template<
typename KeyT>
18571 size_type count(KeyT&& key)
const
18574 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
18602 template<
typename KeyT,
typename std::enable_if<
18603 not std::is_same<
typename std::decay<KeyT>::type, json_pointer>::value,
int>::type = 0>
18604 bool contains(KeyT && key)
const
18606 return is_object()
and m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
18635 bool contains(
const json_pointer& ptr)
const
18637 return ptr.contains(
this);
18674 iterator begin()
noexcept
18676 iterator result(
this);
18677 result.set_begin();
18684 const_iterator begin()
const noexcept
18714 const_iterator cbegin()
const noexcept
18716 const_iterator result(
this);
18717 result.set_begin();
18745 iterator end()
noexcept
18747 iterator result(
this);
18755 const_iterator end()
const noexcept
18785 const_iterator cend()
const noexcept
18787 const_iterator result(
this);
18815 reverse_iterator rbegin()
noexcept
18817 return reverse_iterator(end());
18823 const_reverse_iterator rbegin()
const noexcept
18852 reverse_iterator rend()
noexcept
18854 return reverse_iterator(begin());
18860 const_reverse_iterator rend()
const noexcept
18889 const_reverse_iterator crbegin()
const noexcept
18891 return const_reverse_iterator(cend());
18918 const_reverse_iterator crend()
const noexcept
18920 return const_reverse_iterator(cbegin());
18982 static iteration_proxy<iterator> iterator_wrapper(reference ref)
noexcept
18984 return ref.items();
18991 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref)
noexcept
18993 return ref.items();
19059 iteration_proxy<iterator> items()
noexcept
19061 return iteration_proxy<iterator>(*
this);
19067 iteration_proxy<const_iterator> items()
const noexcept
19069 return iteration_proxy<const_iterator>(*
this);
19123 bool empty()
const noexcept
19127 case value_t::null:
19133 case value_t::array:
19136 return m_value.array->empty();
19139 case value_t::object:
19142 return m_value.object->empty();
19195 size_type size()
const noexcept
19199 case value_t::null:
19205 case value_t::array:
19208 return m_value.array->size();
19211 case value_t::object:
19214 return m_value.object->size();
19265 size_type max_size()
const noexcept
19269 case value_t::array:
19272 return m_value.array->max_size();
19275 case value_t::object:
19278 return m_value.object->max_size();
19335 void clear()
noexcept
19339 case value_t::number_integer:
19341 m_value.number_integer = 0;
19345 case value_t::number_unsigned:
19347 m_value.number_unsigned = 0;
19351 case value_t::number_float:
19353 m_value.number_float = 0.0;
19357 case value_t::boolean:
19359 m_value.boolean =
false;
19363 case value_t::string:
19365 m_value.string->clear();
19369 case value_t::array:
19371 m_value.array->clear();
19375 case value_t::object:
19377 m_value.object->clear();
19406 void push_back(basic_json&& val)
19411 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
19417 m_type = value_t::array;
19418 m_value = value_t::array;
19419 assert_invariant();
19423 m_value.array->push_back(std::move(val));
19426 val.m_type = value_t::null;
19433 reference operator+=(basic_json&& val)
19435 push_back(std::move(val));
19443 void push_back(
const basic_json& val)
19448 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
19454 m_type = value_t::array;
19455 m_value = value_t::array;
19456 assert_invariant();
19460 m_value.array->push_back(val);
19467 reference operator+=(
const basic_json& val)
19493 void push_back(
const typename object_t::value_type& val)
19498 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(type_name())));
19504 m_type = value_t::object;
19505 m_value = value_t::object;
19506 assert_invariant();
19510 m_value.object->insert(val);
19517 reference operator+=(
const typename object_t::value_type& val)
19548 void push_back(initializer_list_t init)
19550 if (is_object()
and init.size() == 2
and (*init.begin())->is_string())
19552 basic_json&& key = init.begin()->moved_or_copied();
19553 push_back(
typename object_t::value_type(
19554 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
19558 push_back(basic_json(init));
19566 reference operator+=(initializer_list_t init)
19595 template<
class... Args>
19596 reference emplace_back(Args&& ... args)
19601 JSON_THROW(type_error::create(311,
"cannot use emplace_back() with " + std::string(type_name())));
19607 m_type = value_t::array;
19608 m_value = value_t::array;
19609 assert_invariant();
19613 #ifdef JSON_HAS_CPP_17
19614 return m_value.array->emplace_back(std::forward<Args>(args)...);
19616 m_value.array->emplace_back(std::forward<Args>(args)...);
19617 return m_value.array->back();
19648 template<
class... Args>
19649 std::pair<iterator,
bool> emplace(Args&& ... args)
19654 JSON_THROW(type_error::create(311,
"cannot use emplace() with " + std::string(type_name())));
19660 m_type = value_t::object;
19661 m_value = value_t::object;
19662 assert_invariant();
19666 auto res = m_value.object->emplace(std::forward<Args>(args)...);
19669 it.m_it.object_iterator = res.first;
19672 return {it, res.second};
19678 template<
typename... Args>
19679 iterator insert_iterator(const_iterator pos, Args&& ... args)
19681 iterator result(
this);
19682 assert(m_value.array !=
nullptr);
19684 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
19685 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
19686 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
19717 iterator insert(const_iterator pos,
const basic_json& val)
19725 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
19729 return insert_iterator(pos, val);
19732 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
19739 iterator insert(const_iterator pos, basic_json&& val)
19741 return insert(pos, val);
19768 iterator insert(const_iterator pos, size_type cnt,
const basic_json& val)
19776 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
19780 return insert_iterator(pos, cnt, val);
19783 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
19816 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
19821 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
19827 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
19833 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
19838 JSON_THROW(invalid_iterator::create(211,
"passed iterators may not belong to container"));
19842 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
19869 iterator insert(const_iterator pos, initializer_list_t ilist)
19874 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
19880 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
19884 return insert_iterator(pos, ilist.begin(), ilist.end());
19910 void insert(const_iterator first, const_iterator last)
19915 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(type_name())));
19921 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
19927 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
19930 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
19952 void update(const_reference j)
19957 m_type = value_t::object;
19958 m_value.object = create<object_t>();
19959 assert_invariant();
19964 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
19968 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(j.type_name())));
19971 for (
auto it = j.cbegin(); it != j.cend(); ++it)
19973 m_value.object->operator[](it.key()) = it.value();
20003 void update(const_iterator first, const_iterator last)
20008 m_type = value_t::object;
20009 m_value.object = create<object_t>();
20010 assert_invariant();
20015 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(type_name())));
20021 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
20026 or not last.m_object->is_object()))
20028 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
20031 for (
auto it = first; it != last; ++it)
20033 m_value.object->operator[](it.key()) = it.value();
20054 void swap(reference other)
noexcept (
20055 std::is_nothrow_move_constructible<value_t>::value
and
20056 std::is_nothrow_move_assignable<value_t>::value
and
20057 std::is_nothrow_move_constructible<json_value>::value
and
20058 std::is_nothrow_move_assignable<json_value>::value
20061 std::swap(m_type, other.m_type);
20062 std::swap(m_value, other.m_value);
20063 assert_invariant();
20086 void swap(array_t& other)
20091 std::swap(*(m_value.array), other);
20095 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
20119 void swap(object_t& other)
20124 std::swap(*(m_value.object), other);
20128 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
20152 void swap(string_t& other)
20157 std::swap(*(m_value.string), other);
20161 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(type_name())));
20214 friend bool operator==(const_reference lhs, const_reference rhs)
noexcept
20216 const auto lhs_type = lhs.type();
20217 const auto rhs_type = rhs.type();
20219 if (lhs_type == rhs_type)
20223 case value_t::array:
20224 return *lhs.m_value.array == *rhs.m_value.array;
20226 case value_t::object:
20227 return *lhs.m_value.object == *rhs.m_value.object;
20229 case value_t::null:
20232 case value_t::string:
20233 return *lhs.m_value.string == *rhs.m_value.string;
20235 case value_t::boolean:
20236 return lhs.m_value.boolean == rhs.m_value.boolean;
20238 case value_t::number_integer:
20239 return lhs.m_value.number_integer == rhs.m_value.number_integer;
20241 case value_t::number_unsigned:
20242 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
20244 case value_t::number_float:
20245 return lhs.m_value.number_float == rhs.m_value.number_float;
20251 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_float)
20253 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
20255 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_integer)
20257 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer);
20259 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_float)
20261 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
20263 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_unsigned)
20265 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned);
20267 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_integer)
20269 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
20271 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_unsigned)
20273 return lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
20283 template<
typename ScalarType,
typename std::enable_if<
20284 std::is_scalar<ScalarType>::value,
int>::type = 0>
20285 friend bool operator==(const_reference lhs,
const ScalarType rhs)
noexcept
20287 return lhs == basic_json(rhs);
20294 template<
typename ScalarType,
typename std::enable_if<
20295 std::is_scalar<ScalarType>::value,
int>::type = 0>
20296 friend bool operator==(
const ScalarType lhs, const_reference rhs)
noexcept
20298 return basic_json(lhs) == rhs;
20319 friend bool operator!=(const_reference lhs, const_reference rhs)
noexcept
20321 return not (lhs == rhs);
20328 template<
typename ScalarType,
typename std::enable_if<
20329 std::is_scalar<ScalarType>::value,
int>::type = 0>
20330 friend bool operator!=(const_reference lhs,
const ScalarType rhs)
noexcept
20332 return lhs != basic_json(rhs);
20339 template<
typename ScalarType,
typename std::enable_if<
20340 std::is_scalar<ScalarType>::value,
int>::type = 0>
20341 friend bool operator!=(
const ScalarType lhs, const_reference rhs)
noexcept
20343 return basic_json(lhs) != rhs;
20372 friend bool operator<(const_reference lhs, const_reference rhs)
noexcept
20374 const auto lhs_type = lhs.type();
20375 const auto rhs_type = rhs.type();
20377 if (lhs_type == rhs_type)
20381 case value_t::array:
20384 return (*lhs.m_value.array) < (*rhs.m_value.array);
20386 case value_t::object:
20387 return (*lhs.m_value.object) < (*rhs.m_value.object);
20389 case value_t::null:
20392 case value_t::string:
20393 return (*lhs.m_value.string) < (*rhs.m_value.string);
20395 case value_t::boolean:
20396 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
20398 case value_t::number_integer:
20399 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
20401 case value_t::number_unsigned:
20402 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
20404 case value_t::number_float:
20405 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
20411 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_float)
20413 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
20415 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_integer)
20417 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
20419 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_float)
20421 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
20423 else if (lhs_type == value_t::number_float
and rhs_type == value_t::number_unsigned)
20425 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
20427 else if (lhs_type == value_t::number_integer
and rhs_type == value_t::number_unsigned)
20429 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
20431 else if (lhs_type == value_t::number_unsigned
and rhs_type == value_t::number_integer)
20433 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
20439 return operator<(lhs_type, rhs_type);
20446 template<
typename ScalarType,
typename std::enable_if<
20447 std::is_scalar<ScalarType>::value,
int>::type = 0>
20448 friend bool operator<(const_reference lhs,
const ScalarType rhs)
noexcept
20450 return lhs < basic_json(rhs);
20457 template<
typename ScalarType,
typename std::enable_if<
20458 std::is_scalar<ScalarType>::value,
int>::type = 0>
20459 friend bool operator<(
const ScalarType lhs, const_reference rhs)
noexcept
20461 return basic_json(lhs) < rhs;
20483 friend bool operator<=(const_reference lhs, const_reference rhs)
noexcept
20485 return not (rhs < lhs);
20492 template<
typename ScalarType,
typename std::enable_if<
20493 std::is_scalar<ScalarType>::value,
int>::type = 0>
20494 friend bool operator<=(const_reference lhs,
const ScalarType rhs)
noexcept
20496 return lhs <= basic_json(rhs);
20503 template<
typename ScalarType,
typename std::enable_if<
20504 std::is_scalar<ScalarType>::value,
int>::type = 0>
20505 friend bool operator<=(
const ScalarType lhs, const_reference rhs)
noexcept
20507 return basic_json(lhs) <= rhs;
20529 friend bool operator>(const_reference lhs, const_reference rhs)
noexcept
20531 return not (lhs <= rhs);
20538 template<
typename ScalarType,
typename std::enable_if<
20539 std::is_scalar<ScalarType>::value,
int>::type = 0>
20540 friend bool operator>(const_reference lhs,
const ScalarType rhs)
noexcept
20542 return lhs > basic_json(rhs);
20549 template<
typename ScalarType,
typename std::enable_if<
20550 std::is_scalar<ScalarType>::value,
int>::type = 0>
20551 friend bool operator>(
const ScalarType lhs, const_reference rhs)
noexcept
20553 return basic_json(lhs) > rhs;
20575 friend bool operator>=(const_reference lhs, const_reference rhs)
noexcept
20577 return not (lhs < rhs);
20584 template<
typename ScalarType,
typename std::enable_if<
20585 std::is_scalar<ScalarType>::value,
int>::type = 0>
20586 friend bool operator>=(const_reference lhs,
const ScalarType rhs)
noexcept
20588 return lhs >= basic_json(rhs);
20595 template<
typename ScalarType,
typename std::enable_if<
20596 std::is_scalar<ScalarType>::value,
int>::type = 0>
20597 friend bool operator>=(
const ScalarType lhs, const_reference rhs)
noexcept
20599 return basic_json(lhs) >= rhs;
20642 friend std::ostream& operator<<(std::ostream& o,
const basic_json& j)
20645 const bool pretty_print = o.width() > 0;
20646 const auto indentation = pretty_print ? o.width() : 0;
20652 serializer s(detail::output_adapter<
char>(o), o.fill());
20653 s.dump(j, pretty_print,
false,
static_cast<
unsigned int>(indentation));
20666 friend std::ostream& operator>>(
const basic_json& j, std::ostream& o)
20745 static basic_json parse(detail::input_adapter&& i,
20746 const parser_callback_t cb =
nullptr,
20747 const bool allow_exceptions =
true)
20750 parser(i, cb, allow_exceptions).parse(
true, result);
20754 static bool accept(detail::input_adapter&& i)
20756 return parser(i).accept(
true);
20812 template <
typename SAX>
20814 static bool sax_parse(detail::input_adapter&& i, SAX* sax,
20815 input_format_t format = input_format_t::json,
20816 const bool strict =
true)
20819 return format == input_format_t::json
20820 ? parser(std::move(i)).sax_parse(sax, strict)
20821 : detail::binary_reader<basic_json, SAX>(std::move(i)).sax_parse(format, sax, strict);
20873 template<
class IteratorType,
typename std::enable_if<
20875 std::random_access_iterator_tag,
20876 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
20877 static basic_json parse(IteratorType first, IteratorType last,
20878 const parser_callback_t cb =
nullptr,
20879 const bool allow_exceptions =
true)
20882 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(
true, result);
20886 template<
class IteratorType,
typename std::enable_if<
20888 std::random_access_iterator_tag,
20889 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
20890 static bool accept(IteratorType first, IteratorType last)
20892 return parser(detail::input_adapter(first, last)).accept(
true);
20895 template<
class IteratorType,
class SAX,
typename std::enable_if<
20897 std::random_access_iterator_tag,
20898 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
20900 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
20902 return parser(detail::input_adapter(first, last)).sax_parse(sax);
20914 friend std::istream& operator<<(basic_json& j, std::istream& i)
20916 return operator>>(i, j);
20944 friend std::istream& operator>>(std::istream& i, basic_json& j)
20946 parser(detail::input_adapter(i)).parse(
false, j);
20987 const char* type_name()
const noexcept
20992 case value_t::null:
20994 case value_t::object:
20996 case value_t::array:
20998 case value_t::string:
21000 case value_t::boolean:
21002 case value_t::discarded:
21003 return "discarded";
21017 value_t m_type = value_t::null;
21020 json_value m_value = {};
21118 static std::vector<uint8_t> to_cbor(
const basic_json& j)
21120 std::vector<uint8_t> result;
21121 to_cbor(j, result);
21125 static void to_cbor(
const basic_json& j, detail::output_adapter<uint8_t> o)
21127 binary_writer<uint8_t>(o).write_cbor(j);
21130 static void to_cbor(
const basic_json& j, detail::output_adapter<
char> o)
21132 binary_writer<
char>(o).write_cbor(j);
21214 static std::vector<uint8_t> to_msgpack(
const basic_json& j)
21216 std::vector<uint8_t> result;
21217 to_msgpack(j, result);
21221 static void to_msgpack(
const basic_json& j, detail::output_adapter<uint8_t> o)
21223 binary_writer<uint8_t>(o).write_msgpack(j);
21226 static void to_msgpack(
const basic_json& j, detail::output_adapter<
char> o)
21228 binary_writer<
char>(o).write_msgpack(j);
21311 static std::vector<uint8_t> to_ubjson(
const basic_json& j,
21312 const bool use_size =
false,
21313 const bool use_type =
false)
21315 std::vector<uint8_t> result;
21316 to_ubjson(j, result, use_size, use_type);
21320 static void to_ubjson(
const basic_json& j, detail::output_adapter<uint8_t> o,
21321 const bool use_size =
false,
const bool use_type =
false)
21323 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
21326 static void to_ubjson(
const basic_json& j, detail::output_adapter<
char> o,
21327 const bool use_size =
false,
const bool use_type =
false)
21329 binary_writer<
char>(o).write_ubjson(j, use_size, use_type);
21388 static std::vector<uint8_t> to_bson(
const basic_json& j)
21390 std::vector<uint8_t> result;
21391 to_bson(j, result);
21403 static void to_bson(
const basic_json& j, detail::output_adapter<uint8_t> o)
21405 binary_writer<uint8_t>(o).write_bson(j);
21411 static void to_bson(
const basic_json& j, detail::output_adapter<
char> o)
21413 binary_writer<
char>(o).write_bson(j);
21517 static basic_json from_cbor(detail::input_adapter&& i,
21518 const bool strict =
true,
21519 const bool allow_exceptions =
true)
21522 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21523 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::cbor, &sdp, strict);
21524 return res ? result : basic_json(value_t::discarded);
21530 template<
typename A1,
typename A2,
21531 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
21533 static basic_json from_cbor(A1 && a1, A2 && a2,
21534 const bool strict =
true,
21535 const bool allow_exceptions =
true)
21538 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21539 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::cbor, &sdp, strict);
21540 return res ? result : basic_json(value_t::discarded);
21626 static basic_json from_msgpack(detail::input_adapter&& i,
21627 const bool strict =
true,
21628 const bool allow_exceptions =
true)
21631 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21632 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::msgpack, &sdp, strict);
21633 return res ? result : basic_json(value_t::discarded);
21639 template<
typename A1,
typename A2,
21640 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
21642 static basic_json from_msgpack(A1 && a1, A2 && a2,
21643 const bool strict =
true,
21644 const bool allow_exceptions =
true)
21647 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21648 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::msgpack, &sdp, strict);
21649 return res ? result : basic_json(value_t::discarded);
21714 static basic_json from_ubjson(detail::input_adapter&& i,
21715 const bool strict =
true,
21716 const bool allow_exceptions =
true)
21719 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21720 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::ubjson, &sdp, strict);
21721 return res ? result : basic_json(value_t::discarded);
21727 template<
typename A1,
typename A2,
21728 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
21730 static basic_json from_ubjson(A1 && a1, A2 && a2,
21731 const bool strict =
true,
21732 const bool allow_exceptions =
true)
21735 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21736 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::ubjson, &sdp, strict);
21737 return res ? result : basic_json(value_t::discarded);
21801 static basic_json from_bson(detail::input_adapter&& i,
21802 const bool strict =
true,
21803 const bool allow_exceptions =
true)
21806 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21807 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::bson, &sdp, strict);
21808 return res ? result : basic_json(value_t::discarded);
21814 template<
typename A1,
typename A2,
21815 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value,
int> = 0>
21817 static basic_json from_bson(A1 && a1, A2 && a2,
21818 const bool strict =
true,
21819 const bool allow_exceptions =
true)
21822 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21823 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::bson, &sdp, strict);
21824 return res ? result : basic_json(value_t::discarded);
21871 reference operator[](
const json_pointer& ptr)
21873 return ptr.get_unchecked(
this);
21899 const_reference operator[](
const json_pointer& ptr)
const
21901 return ptr.get_unchecked(
this);
21942 reference at(
const json_pointer& ptr)
21944 return ptr.get_checked(
this);
21985 const_reference at(
const json_pointer& ptr)
const
21987 return ptr.get_checked(
this);
22012 basic_json flatten()
const
22014 basic_json result(value_t::object);
22015 json_pointer::flatten(
"", *
this, result);
22049 basic_json unflatten()
const
22051 return json_pointer::unflatten(*
this);
22110 basic_json patch(
const basic_json& json_patch)
const
22113 basic_json result = *
this;
22116 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
22118 const auto get_op = [](
const std::string & op)
22122 return patch_operations::add;
22124 if (op ==
"remove")
22126 return patch_operations::remove;
22128 if (op ==
"replace")
22130 return patch_operations::replace;
22134 return patch_operations::move;
22138 return patch_operations::copy;
22142 return patch_operations::test;
22145 return patch_operations::invalid;
22149 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
22159 json_pointer top_pointer = ptr.top();
22160 if (top_pointer != ptr)
22162 result.at(top_pointer);
22166 const auto last_path = ptr.back();
22168 basic_json& parent = result[ptr];
22170 switch (parent.m_type)
22172 case value_t::null:
22173 case value_t::object:
22176 parent[last_path] = val;
22180 case value_t::array:
22182 if (last_path ==
"-")
22185 parent.push_back(val);
22189 const auto idx = json_pointer::array_index(last_path);
22193 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
22197 parent.insert(parent.begin() +
static_cast<difference_type>(idx), val);
22209 const auto operation_remove = [&result](json_pointer & ptr)
22212 const auto last_path = ptr.back();
22214 basic_json& parent = result.at(ptr);
22217 if (parent.is_object())
22220 auto it = parent.find(last_path);
22227 JSON_THROW(out_of_range::create(403,
"key '" + last_path +
"' not found"));
22230 else if (parent.is_array())
22233 parent.erase(
static_cast<size_type>(json_pointer::array_index(last_path)));
22240 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
22244 for (
const auto& val : json_patch)
22247 const auto get_value = [&val](
const std::string & op,
22248 const std::string & member,
22249 bool string_type) -> basic_json &
22252 auto it = val.m_value.object->find(member);
22255 const auto error_msg = (op ==
"op") ?
"operation" :
"operation '" + op +
"'";
22260 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have member '" + member +
"'"));
22266 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have string member '" + member +
"'"));
22276 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
22280 const std::string op = get_value(
"op",
"op",
true);
22281 const std::string path = get_value(op,
"path",
true);
22282 json_pointer ptr(path);
22284 switch (get_op(op))
22286 case patch_operations::add:
22288 operation_add(ptr, get_value(
"add",
"value",
false));
22292 case patch_operations::remove:
22294 operation_remove(ptr);
22298 case patch_operations::replace:
22301 result.at(ptr) = get_value(
"replace",
"value",
false);
22305 case patch_operations::move:
22307 const std::string from_path = get_value(
"move",
"from",
true);
22308 json_pointer from_ptr(from_path);
22311 basic_json v = result.at(from_ptr);
22317 operation_remove(from_ptr);
22318 operation_add(ptr, v);
22322 case patch_operations::copy:
22324 const std::string from_path = get_value(
"copy",
"from",
true);
22325 const json_pointer from_ptr(from_path);
22328 basic_json v = result.at(from_ptr);
22333 operation_add(ptr, v);
22337 case patch_operations::test:
22339 bool success =
false;
22344 success = (result.at(ptr) == get_value(
"test",
"value",
false));
22354 JSON_THROW(other_error::create(501,
"unsuccessful: " + val.dump()));
22364 JSON_THROW(parse_error::create(105, 0,
"operation value '" + op +
"' is invalid"));
22406 static basic_json diff(
const basic_json& source,
const basic_json& target,
22407 const std::string& path =
"")
22410 basic_json result(value_t::array);
22413 if (source == target)
22418 if (source.type() != target.type())
22423 {
"op",
"replace"}, {
"path", path}, {
"value", target}
22428 switch (source.type())
22430 case value_t::array:
22434 while (i < source.size()
and i < target.size())
22437 auto temp_diff = diff(source[i], target[i], path +
"/" + std::to_string(i));
22438 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
22446 const auto end_index =
static_cast<difference_type>(result.size());
22447 while (i < source.size())
22451 result.insert(result.begin() + end_index, object(
22454 {
"path", path +
"/" + std::to_string(i)}
22460 while (i < target.size())
22465 {
"path", path +
"/" + std::to_string(i)},
22466 {
"value", target[i]}
22474 case value_t::object:
22477 for (
auto it = source.cbegin(); it != source.cend(); ++it)
22480 const auto key = json_pointer::escape(it.key());
22482 if (target.find(it.key()) != target.end())
22485 auto temp_diff = diff(it.value(), target[it.key()], path +
"/" + key);
22486 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
22491 result.push_back(object(
22493 {
"op",
"remove"}, {
"path", path +
"/" + key}
22499 for (
auto it = target.cbegin(); it != target.cend(); ++it)
22501 if (source.find(it.key()) == source.end())
22504 const auto key = json_pointer::escape(it.key());
22507 {
"op",
"add"}, {
"path", path +
"/" + key},
22508 {
"value", it.value()}
22521 {
"op",
"replace"}, {
"path", path}, {
"value", target}
22581 void merge_patch(
const basic_json& apply_patch)
22583 if (apply_patch.is_object())
22585 if (
not is_object())
22589 for (
auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
22591 if (it.value().is_null())
22597 operator[](it.key()).merge_patch(it.value());
22603 *
this = apply_patch;
22636 struct hash<nlohmann::json>
22643 std::size_t operator()(
const nlohmann::json& j)
const
22646 const auto& h = hash<nlohmann::json::string_t>();
22647 return h(j.dump());
22655 struct less<::nlohmann::detail::value_t>
22661 bool operator()(nlohmann::detail::value_t lhs,
22662 nlohmann::detail::value_t rhs)
const noexcept
22664 return nlohmann::detail::operator<(lhs, rhs);
22674 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2)
noexcept(
22675 is_nothrow_move_constructible<nlohmann::json>::value
and
22676 is_nothrow_move_assignable<nlohmann::json>::value
22698 inline nlohmann::json operator
"" _json(
const char* s, std::size_t n)
22700 return nlohmann::json::parse(s, s + n);
22717 inline nlohmann::json::json_pointer operator
"" _json_pointer(
const char* s, std::size_t n)
22719 return nlohmann::json::json_pointer(std::string(s, n));
22726 #if defined(__clang__
) || defined(__GNUC__
) || defined(__GNUG__
)
22727 #pragma GCC diagnostic pop
22729 #if defined(__clang__
)
22730 #pragma GCC diagnostic pop
22734 #undef JSON_INTERNAL_CATCH
22738 #undef JSON_HAS_CPP_14
22739 #undef JSON_HAS_CPP_17
22740 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
22741 #undef NLOHMANN_BASIC_JSON_TPL
22744 #undef JSON_HEDLEY_ALWAYS_INLINE
22745 #undef JSON_HEDLEY_ARM_VERSION
22746 #undef JSON_HEDLEY_ARM_VERSION_CHECK
22747 #undef JSON_HEDLEY_ARRAY_PARAM
22748 #undef JSON_HEDLEY_ASSUME
22749 #undef JSON_HEDLEY_BEGIN_C_DECLS
22750 #undef JSON_HEDLEY_C_DECL
22751 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
22752 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
22753 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
22754 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
22755 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
22756 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
22757 #undef JSON_HEDLEY_CLANG_HAS_WARNING
22758 #undef JSON_HEDLEY_COMPCERT_VERSION
22759 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
22760 #undef JSON_HEDLEY_CONCAT
22761 #undef JSON_HEDLEY_CONCAT_EX
22762 #undef JSON_HEDLEY_CONST
22763 #undef JSON_HEDLEY_CONST_CAST
22764 #undef JSON_HEDLEY_CONSTEXPR
22765 #undef JSON_HEDLEY_CPP_CAST
22766 #undef JSON_HEDLEY_CRAY_VERSION
22767 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
22768 #undef JSON_HEDLEY_DEPRECATED
22769 #undef JSON_HEDLEY_DEPRECATED_FOR
22770 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
22771 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
22772 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
22773 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
22774 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
22775 #undef JSON_HEDLEY_DIAGNOSTIC_POP
22776 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
22777 #undef JSON_HEDLEY_DMC_VERSION
22778 #undef JSON_HEDLEY_DMC_VERSION_CHECK
22779 #undef JSON_HEDLEY_EMPTY_BASES
22780 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
22781 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
22782 #undef JSON_HEDLEY_END_C_DECLS
22783 #undef JSON_HEDLEY_FALL_THROUGH
22784 #undef JSON_HEDLEY_FLAGS
22785 #undef JSON_HEDLEY_FLAGS_CAST
22786 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
22787 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
22788 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
22789 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
22790 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
22791 #undef JSON_HEDLEY_GCC_HAS_FEATURE
22792 #undef JSON_HEDLEY_GCC_HAS_WARNING
22793 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
22794 #undef JSON_HEDLEY_GCC_VERSION
22795 #undef JSON_HEDLEY_GCC_VERSION_CHECK
22796 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
22797 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
22798 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
22799 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
22800 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
22801 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
22802 #undef JSON_HEDLEY_GNUC_HAS_WARNING
22803 #undef JSON_HEDLEY_GNUC_VERSION
22804 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
22805 #undef JSON_HEDLEY_HAS_ATTRIBUTE
22806 #undef JSON_HEDLEY_HAS_BUILTIN
22807 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
22808 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
22809 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
22810 #undef JSON_HEDLEY_HAS_EXTENSION
22811 #undef JSON_HEDLEY_HAS_FEATURE
22812 #undef JSON_HEDLEY_HAS_WARNING
22813 #undef JSON_HEDLEY_IAR_VERSION
22814 #undef JSON_HEDLEY_IAR_VERSION_CHECK
22815 #undef JSON_HEDLEY_IBM_VERSION
22816 #undef JSON_HEDLEY_IBM_VERSION_CHECK
22817 #undef JSON_HEDLEY_IMPORT
22818 #undef JSON_HEDLEY_INLINE
22819 #undef JSON_HEDLEY_INTEL_VERSION
22820 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
22821 #undef JSON_HEDLEY_IS_CONSTANT
22822 #undef JSON_HEDLEY_IS_CONSTEXPR_
22823 #undef JSON_HEDLEY_LIKELY
22824 #undef JSON_HEDLEY_MALLOC
22825 #undef JSON_HEDLEY_MESSAGE
22826 #undef JSON_HEDLEY_MSVC_VERSION
22827 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
22828 #undef JSON_HEDLEY_NEVER_INLINE
22829 #undef JSON_HEDLEY_NO_ESCAPE
22830 #undef JSON_HEDLEY_NON_NULL
22831 #undef JSON_HEDLEY_NO_RETURN
22832 #undef JSON_HEDLEY_NO_THROW
22833 #undef JSON_HEDLEY_NULL
22834 #undef JSON_HEDLEY_PELLES_VERSION
22835 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
22836 #undef JSON_HEDLEY_PGI_VERSION
22837 #undef JSON_HEDLEY_PGI_VERSION_CHECK
22838 #undef JSON_HEDLEY_PREDICT
22839 #undef JSON_HEDLEY_PRINTF_FORMAT
22840 #undef JSON_HEDLEY_PRIVATE
22841 #undef JSON_HEDLEY_PUBLIC
22842 #undef JSON_HEDLEY_PURE
22843 #undef JSON_HEDLEY_REINTERPRET_CAST
22844 #undef JSON_HEDLEY_REQUIRE
22845 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
22846 #undef JSON_HEDLEY_REQUIRE_MSG
22847 #undef JSON_HEDLEY_RESTRICT
22849 #undef JSON_HEDLEY_SENTINEL
22850 #undef JSON_HEDLEY_STATIC_ASSERT
22851 #undef JSON_HEDLEY_STATIC_CAST
22852 #undef JSON_HEDLEY_STRINGIFY
22853 #undef JSON_HEDLEY_STRINGIFY_EX
22854 #undef JSON_HEDLEY_SUNPRO_VERSION
22855 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
22856 #undef JSON_HEDLEY_TINYC_VERSION
22857 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
22858 #undef JSON_HEDLEY_TI_VERSION
22859 #undef JSON_HEDLEY_TI_VERSION_CHECK
22860 #undef JSON_HEDLEY_UNAVAILABLE
22861 #undef JSON_HEDLEY_UNLIKELY
22862 #undef JSON_HEDLEY_UNPREDICTABLE
22863 #undef JSON_HEDLEY_UNREACHABLE
22864 #undef JSON_HEDLEY_UNREACHABLE_RETURN
22865 #undef JSON_HEDLEY_VERSION
22866 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
22867 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
22868 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
22869 #undef JSON_HEDLEY_VERSION_ENCODE
22870 #undef JSON_HEDLEY_WARNING