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 8
35 #define NLOHMANN_JSON_VERSION_PATCH 0
41 #include <initializer_list>
60 #include <forward_list>
65 #include <type_traits>
66 #include <unordered_map>
76 #if __cplusplus <= 201703L
100 std::size_t chars_read_total = 0;
102 std::size_t chars_read_current_line = 0;
104 std::size_t lines_read = 0;
107 constexpr
operator size_t()
const
109 return chars_read_total;
133 #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 13)
134 #if defined(JSON_HEDLEY_VERSION)
135 #undef JSON_HEDLEY_VERSION
137 #define JSON_HEDLEY_VERSION 13
139 #if defined(JSON_HEDLEY_STRINGIFY_EX)
140 #undef JSON_HEDLEY_STRINGIFY_EX
142 #define JSON_HEDLEY_STRINGIFY_EX(x) #x
144 #if defined(JSON_HEDLEY_STRINGIFY)
145 #undef JSON_HEDLEY_STRINGIFY
147 #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
149 #if defined(JSON_HEDLEY_CONCAT_EX)
150 #undef JSON_HEDLEY_CONCAT_EX
152 #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
154 #if defined(JSON_HEDLEY_CONCAT)
155 #undef JSON_HEDLEY_CONCAT
157 #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
159 #if defined(JSON_HEDLEY_CONCAT3_EX)
160 #undef JSON_HEDLEY_CONCAT3_EX
162 #define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
164 #if defined(JSON_HEDLEY_CONCAT3)
165 #undef JSON_HEDLEY_CONCAT3
167 #define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
169 #if defined(JSON_HEDLEY_VERSION_ENCODE)
170 #undef JSON_HEDLEY_VERSION_ENCODE
172 #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
174 #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
175 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
177 #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
179 #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
180 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
182 #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
184 #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
185 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
187 #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
189 #if defined(JSON_HEDLEY_GNUC_VERSION)
190 #undef JSON_HEDLEY_GNUC_VERSION
192 #if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
193 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
194 #elif defined(__GNUC__)
195 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
198 #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
199 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
201 #if defined(JSON_HEDLEY_GNUC_VERSION)
202 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
204 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
207 #if defined(JSON_HEDLEY_MSVC_VERSION)
208 #undef JSON_HEDLEY_MSVC_VERSION
210 #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000)
211 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
212 #elif defined(_MSC_FULL_VER)
213 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
214 #elif defined(_MSC_VER)
215 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
218 #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
219 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
221 #if !defined(_MSC_VER)
222 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
223 #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
224 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
225 #elif defined(_MSC_VER) && (_MSC_VER >= 1200)
226 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
228 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
231 #if defined(JSON_HEDLEY_INTEL_VERSION)
232 #undef JSON_HEDLEY_INTEL_VERSION
234 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE)
235 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
236 #elif defined(__INTEL_COMPILER)
237 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
240 #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
241 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
243 #if defined(JSON_HEDLEY_INTEL_VERSION)
244 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
246 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
249 #if defined(JSON_HEDLEY_PGI_VERSION)
250 #undef JSON_HEDLEY_PGI_VERSION
252 #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
253 #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
256 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
257 #undef JSON_HEDLEY_PGI_VERSION_CHECK
259 #if defined(JSON_HEDLEY_PGI_VERSION)
260 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
262 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
265 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
266 #undef JSON_HEDLEY_SUNPRO_VERSION
268 #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
269 #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)
270 #elif defined(__SUNPRO_C)
271 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
272 #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
273 #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)
274 #elif defined(__SUNPRO_CC)
275 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
278 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
279 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
281 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
282 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
284 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
287 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
288 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
290 #if defined(__EMSCRIPTEN__)
291 #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
294 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
295 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
297 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
298 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
300 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
303 #if defined(JSON_HEDLEY_ARM_VERSION)
304 #undef JSON_HEDLEY_ARM_VERSION
306 #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
307 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
308 #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
309 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
312 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
313 #undef JSON_HEDLEY_ARM_VERSION_CHECK
315 #if defined(JSON_HEDLEY_ARM_VERSION)
316 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
318 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
321 #if defined(JSON_HEDLEY_IBM_VERSION)
322 #undef JSON_HEDLEY_IBM_VERSION
324 #if defined(__ibmxl__)
325 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
326 #elif defined(__xlC__) && defined(__xlC_ver__)
327 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
328 #elif defined(__xlC__)
329 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
332 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
333 #undef JSON_HEDLEY_IBM_VERSION_CHECK
335 #if defined(JSON_HEDLEY_IBM_VERSION)
336 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
338 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
341 #if defined(JSON_HEDLEY_TI_VERSION)
342 #undef JSON_HEDLEY_TI_VERSION
345 defined(__TI_COMPILER_VERSION__) && \
347 defined(__TMS470__) || defined(__TI_ARM__) || \
348 defined(__MSP430__) || \
349 defined(__TMS320C2000__) \
351 #if (__TI_COMPILER_VERSION__ >= 16000000)
352 #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
356 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
357 #undef JSON_HEDLEY_TI_VERSION_CHECK
359 #if defined(JSON_HEDLEY_TI_VERSION)
360 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
362 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
365 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
366 #undef JSON_HEDLEY_TI_CL2000_VERSION
368 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
369 #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
372 #if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
373 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
375 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
376 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
378 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
381 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
382 #undef JSON_HEDLEY_TI_CL430_VERSION
384 #if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
385 #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
388 #if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
389 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
391 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
392 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
394 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
397 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
398 #undef JSON_HEDLEY_TI_ARMCL_VERSION
400 #if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
401 #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
404 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
405 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
407 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
408 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
410 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
413 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
414 #undef JSON_HEDLEY_TI_CL6X_VERSION
416 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
417 #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
420 #if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
421 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
423 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
424 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
426 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
429 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
430 #undef JSON_HEDLEY_TI_CL7X_VERSION
432 #if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
433 #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
436 #if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
437 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
439 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
440 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
442 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
445 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
446 #undef JSON_HEDLEY_TI_CLPRU_VERSION
448 #if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
449 #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
452 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
453 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
455 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
456 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
458 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
461 #if defined(JSON_HEDLEY_CRAY_VERSION)
462 #undef JSON_HEDLEY_CRAY_VERSION
465 #if defined(_RELEASE_PATCHLEVEL)
466 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
468 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
472 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
473 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
475 #if defined(JSON_HEDLEY_CRAY_VERSION)
476 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
478 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
481 #if defined(JSON_HEDLEY_IAR_VERSION)
482 #undef JSON_HEDLEY_IAR_VERSION
484 #if defined(__IAR_SYSTEMS_ICC__)
486 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
488 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(VER / 100, __VER__ % 100, 0)
492 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
493 #undef JSON_HEDLEY_IAR_VERSION_CHECK
495 #if defined(JSON_HEDLEY_IAR_VERSION)
496 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
498 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
501 #if defined(JSON_HEDLEY_TINYC_VERSION)
502 #undef JSON_HEDLEY_TINYC_VERSION
504 #if defined(__TINYC__)
505 #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
508 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
509 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
511 #if defined(JSON_HEDLEY_TINYC_VERSION)
512 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
514 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
517 #if defined(JSON_HEDLEY_DMC_VERSION)
518 #undef JSON_HEDLEY_DMC_VERSION
521 #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
524 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
525 #undef JSON_HEDLEY_DMC_VERSION_CHECK
527 #if defined(JSON_HEDLEY_DMC_VERSION)
528 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
530 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
533 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
534 #undef JSON_HEDLEY_COMPCERT_VERSION
536 #if defined(__COMPCERT_VERSION__)
537 #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
540 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
541 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
543 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
544 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
546 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
549 #if defined(JSON_HEDLEY_PELLES_VERSION)
550 #undef JSON_HEDLEY_PELLES_VERSION
552 #if defined(__POCC__)
553 #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
556 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
557 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
559 #if defined(JSON_HEDLEY_PELLES_VERSION)
560 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
562 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
565 #if defined(JSON_HEDLEY_GCC_VERSION)
566 #undef JSON_HEDLEY_GCC_VERSION
569 defined(JSON_HEDLEY_GNUC_VERSION) && \
570 !defined(__clang__) && \
571 !defined(JSON_HEDLEY_INTEL_VERSION) && \
572 !defined(JSON_HEDLEY_PGI_VERSION) && \
573 !defined(JSON_HEDLEY_ARM_VERSION) && \
574 !defined(JSON_HEDLEY_TI_VERSION) && \
575 !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
576 !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
577 !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
578 !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
579 !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
580 !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
581 !defined(__COMPCERT__)
582 #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
585 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
586 #undef JSON_HEDLEY_GCC_VERSION_CHECK
588 #if defined(JSON_HEDLEY_GCC_VERSION)
589 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
591 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
594 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
595 #undef JSON_HEDLEY_HAS_ATTRIBUTE
597 #if defined(__has_attribute)
598 #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
600 #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
603 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
604 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
606 #if defined(__has_attribute)
607 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
609 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
612 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
613 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
615 #if defined(__has_attribute)
616 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
618 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
621 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
622 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
625 defined(__has_cpp_attribute) && \
626 defined(__cplusplus) && \
627 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
628 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
630 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
633 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
634 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
636 #if !defined(__cplusplus) || !defined(__has_cpp_attribute)
637 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
639 !defined(JSON_HEDLEY_PGI_VERSION) && \
640 !defined(JSON_HEDLEY_IAR_VERSION) && \
641 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
642 (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
643 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
645 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
648 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
649 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
651 #if defined(__has_cpp_attribute) && defined(__cplusplus)
652 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
654 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
657 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
658 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
660 #if defined(__has_cpp_attribute) && defined(__cplusplus)
661 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
663 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
666 #if defined(JSON_HEDLEY_HAS_BUILTIN)
667 #undef JSON_HEDLEY_HAS_BUILTIN
669 #if defined(__has_builtin)
670 #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
672 #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
675 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
676 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
678 #if defined(__has_builtin)
679 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
681 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
684 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
685 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
687 #if defined(__has_builtin)
688 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
690 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
693 #if defined(JSON_HEDLEY_HAS_FEATURE)
694 #undef JSON_HEDLEY_HAS_FEATURE
696 #if defined(__has_feature)
697 #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
699 #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
702 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
703 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
705 #if defined(__has_feature)
706 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
708 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
711 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
712 #undef JSON_HEDLEY_GCC_HAS_FEATURE
714 #if defined(__has_feature)
715 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
717 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
720 #if defined(JSON_HEDLEY_HAS_EXTENSION)
721 #undef JSON_HEDLEY_HAS_EXTENSION
723 #if defined(__has_extension)
724 #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
726 #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
729 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
730 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
732 #if defined(__has_extension)
733 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
735 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
738 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
739 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
741 #if defined(__has_extension)
742 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
744 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
747 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
748 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
750 #if defined(__has_declspec_attribute)
751 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
753 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
756 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
757 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
759 #if defined(__has_declspec_attribute)
760 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
762 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
765 #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
766 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
768 #if defined(__has_declspec_attribute)
769 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
771 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
774 #if defined(JSON_HEDLEY_HAS_WARNING)
775 #undef JSON_HEDLEY_HAS_WARNING
777 #if defined(__has_warning)
778 #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
780 #define JSON_HEDLEY_HAS_WARNING(warning) (0)
783 #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
784 #undef JSON_HEDLEY_GNUC_HAS_WARNING
786 #if defined(__has_warning)
787 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
789 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
792 #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
793 #undef JSON_HEDLEY_GCC_HAS_WARNING
795 #if defined(__has_warning)
796 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
798 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
803 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
804 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
806 #if defined(__cplusplus)
807 # if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
808 # if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
809 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
810 JSON_HEDLEY_DIAGNOSTIC_PUSH \
811 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
812 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
814 JSON_HEDLEY_DIAGNOSTIC_POP
816 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
817 JSON_HEDLEY_DIAGNOSTIC_PUSH \
818 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
820 JSON_HEDLEY_DIAGNOSTIC_POP
824 #if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
825 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
828 #if defined(JSON_HEDLEY_CONST_CAST)
829 #undef JSON_HEDLEY_CONST_CAST
831 #if defined(__cplusplus)
832 # define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
834 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
835 JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
836 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
837 # define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
838 JSON_HEDLEY_DIAGNOSTIC_PUSH \
839 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
841 JSON_HEDLEY_DIAGNOSTIC_POP \
844 # define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
847 #if defined(JSON_HEDLEY_REINTERPRET_CAST)
848 #undef JSON_HEDLEY_REINTERPRET_CAST
850 #if defined(__cplusplus)
851 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
853 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
856 #if defined(JSON_HEDLEY_STATIC_CAST)
857 #undef JSON_HEDLEY_STATIC_CAST
859 #if defined(__cplusplus)
860 #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
862 #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
865 #if defined(JSON_HEDLEY_CPP_CAST)
866 #undef JSON_HEDLEY_CPP_CAST
868 #if defined(__cplusplus)
869 # if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
870 # define JSON_HEDLEY_CPP_CAST(T, expr) \
871 JSON_HEDLEY_DIAGNOSTIC_PUSH \
872 _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
874 JSON_HEDLEY_DIAGNOSTIC_POP
875 # elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
876 # define JSON_HEDLEY_CPP_CAST(T, expr) \
877 JSON_HEDLEY_DIAGNOSTIC_PUSH \
878 _Pragma("diag_suppress=Pe137") \
879 JSON_HEDLEY_DIAGNOSTIC_POP \
881 # define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
884 # define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
888 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
889 defined(__clang__) || \
890 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
891 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
892 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
893 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
894 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
895 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
896 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
897 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
898 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
899 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
900 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
901 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
902 JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
903 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
904 JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
905 (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
906 #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
907 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
908 #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
910 #define JSON_HEDLEY_PRAGMA(value)
913 #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
914 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
916 #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
917 #undef JSON_HEDLEY_DIAGNOSTIC_POP
919 #if defined(__clang__)
920 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
921 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
922 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
923 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
924 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
925 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
926 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
927 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
928 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
929 #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
930 #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
931 #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
932 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
933 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
935 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
936 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
937 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
938 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
939 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
940 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
941 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
942 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
943 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
944 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
945 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
947 #define JSON_HEDLEY_DIAGNOSTIC_PUSH
948 #define JSON_HEDLEY_DIAGNOSTIC_POP
951 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
952 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
954 #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
955 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
956 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
957 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
958 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
959 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
960 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
961 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
962 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
963 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
965 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
966 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
967 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
968 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
969 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
970 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
971 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
972 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
973 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
974 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
975 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
976 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
977 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
978 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
979 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
980 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
981 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
982 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
983 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
984 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
986 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
989 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
990 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
992 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
993 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
994 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
995 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
996 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
997 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
998 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
999 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1000 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1001 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1003 JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1004 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1005 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1006 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1007 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1008 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1009 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1010 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1011 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1013 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1016 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1017 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1019 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1020 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1021 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1022 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1023 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1024 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1025 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1026 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1027 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1028 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1029 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1030 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1032 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1033 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1034 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1035 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1036 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1037 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1039 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1042 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1043 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1045 #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1046 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1047 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1048 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1049 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1050 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1052 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1055 #if defined(JSON_HEDLEY_DEPRECATED)
1056 #undef JSON_HEDLEY_DEPRECATED
1058 #if defined(JSON_HEDLEY_DEPRECATED_FOR)
1059 #undef JSON_HEDLEY_DEPRECATED_FOR
1061 #if JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0)
1062 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1063 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1064 #elif defined(__cplusplus) && (__cplusplus >= 201402L)
1065 #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1066 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1068 JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) || \
1069 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1070 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1071 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1072 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1073 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1074 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1075 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1076 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1077 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1078 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1079 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1080 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1082 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1083 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1084 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1085 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1086 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1087 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1088 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1089 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1090 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1091 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1092 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1093 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1094 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1095 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1096 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1097 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1099 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1100 JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0)
1101 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1102 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1103 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1104 #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1105 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1107 #define JSON_HEDLEY_DEPRECATED(since)
1108 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1111 #if defined(JSON_HEDLEY_UNAVAILABLE)
1112 #undef JSON_HEDLEY_UNAVAILABLE
1115 JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1116 JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1117 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1118 #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1120 #define JSON_HEDLEY_UNAVAILABLE(available_since)
1129 #if (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1130 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1131 #define _MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1132 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1133 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1134 #define _MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1136 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1137 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1138 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1139 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1140 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1141 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1142 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1143 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1144 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1145 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1146 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1147 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1148 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1149 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1150 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1151 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1152 #define __attribute__((__warn_unused_result__))
1153 #define _MSG(msg) __attribute__((__warn_unused_result__))
1154 #elif defined(_Check_return_)
1155 #define _Check_return_
1156 #define _MSG(msg) _Check_return_
1162 #if defined(JSON_HEDLEY_SENTINEL)
1163 #undef JSON_HEDLEY_SENTINEL
1166 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1167 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1168 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1169 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0)
1170 #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1172 #define JSON_HEDLEY_SENTINEL(position)
1175 #if defined(JSON_HEDLEY_NO_RETURN)
1176 #undef JSON_HEDLEY_NO_RETURN
1178 #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1179 #define JSON_HEDLEY_NO_RETURN __noreturn
1180 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1181 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1182 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1183 #define JSON_HEDLEY_NO_RETURN _Noreturn
1184 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
1185 #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1187 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1188 JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1189 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1190 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1191 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1192 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1193 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1194 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1195 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1196 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1197 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1198 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1199 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1200 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1201 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1202 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1203 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1204 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1205 #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1206 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
1207 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1208 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1209 #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1210 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1211 #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1212 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1213 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1215 #define JSON_HEDLEY_NO_RETURN
1218 #if defined(JSON_HEDLEY_NO_ESCAPE)
1219 #undef JSON_HEDLEY_NO_ESCAPE
1221 #if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1222 #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1224 #define JSON_HEDLEY_NO_ESCAPE
1227 #if defined(JSON_HEDLEY_UNREACHABLE)
1228 #undef JSON_HEDLEY_UNREACHABLE
1230 #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1231 #undef JSON_HEDLEY_UNREACHABLE_RETURN
1233 #if defined(JSON_HEDLEY_ASSUME)
1234 #undef JSON_HEDLEY_ASSUME
1237 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1238 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1239 #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1240 #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1241 #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1243 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1244 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1245 #if defined(__cplusplus)
1246 #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1248 #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1252 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1253 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1254 JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1255 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1256 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5)
1257 #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1258 #elif defined(JSON_HEDLEY_ASSUME)
1259 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1261 #if !defined(JSON_HEDLEY_ASSUME)
1262 #if defined(JSON_HEDLEY_UNREACHABLE)
1263 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1265 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1268 #if defined(JSON_HEDLEY_UNREACHABLE)
1270 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1271 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1272 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1274 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1277 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1279 #if !defined(JSON_HEDLEY_UNREACHABLE)
1280 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1283 JSON_HEDLEY_DIAGNOSTIC_PUSH
1284 #if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1285 #pragma clang diagnostic ignored "-Wpedantic"
1287 #if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1288 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1290 #if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1291 #if defined(__clang__)
1292 #pragma clang diagnostic ignored "-Wvariadic-macros"
1293 #elif defined(JSON_HEDLEY_GCC_VERSION)
1294 #pragma GCC diagnostic ignored "-Wvariadic-macros"
1297 #if defined(JSON_HEDLEY_NON_NULL)
1298 #undef JSON_HEDLEY_NON_NULL
1301 JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1302 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1303 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1304 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1305 #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1307 #define JSON_HEDLEY_NON_NULL(...)
1309 JSON_HEDLEY_DIAGNOSTIC_POP
1311 #if defined(JSON_HEDLEY_PRINTF_FORMAT)
1312 #undef JSON_HEDLEY_PRINTF_FORMAT
1314 #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1315 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1316 #elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1317 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1319 JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1320 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1321 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1322 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1323 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1324 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1325 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1326 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1327 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1328 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1329 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1330 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1331 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1332 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1333 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1334 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1335 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1336 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1337 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1339 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1342 #if defined(JSON_HEDLEY_CONSTEXPR)
1343 #undef JSON_HEDLEY_CONSTEXPR
1345 #if defined(__cplusplus)
1346 #if __cplusplus >= 201103L
1347 #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1350 #if !defined(JSON_HEDLEY_CONSTEXPR)
1351 #define JSON_HEDLEY_CONSTEXPR
1354 #if defined(JSON_HEDLEY_PREDICT)
1355 #undef JSON_HEDLEY_PREDICT
1357 #if defined(JSON_HEDLEY_LIKELY)
1358 #undef JSON_HEDLEY_LIKELY
1360 #if defined(JSON_HEDLEY_UNLIKELY)
1361 #undef JSON_HEDLEY_UNLIKELY
1363 #if defined(JSON_HEDLEY_UNPREDICTABLE)
1364 #undef JSON_HEDLEY_UNPREDICTABLE
1366 #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1367 #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1370 JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) || \
1371 JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0)
1372 # define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1373 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1374 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1375 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1376 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1378 JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) || \
1379 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1380 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1381 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1382 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1383 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1384 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1385 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1386 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1387 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1388 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1389 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1390 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1391 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1392 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
1393 # define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1394 (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1395 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1397 double hedley_probability_ = (probability); \
1398 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1400 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1402 double hedley_probability_ = (probability); \
1403 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1405 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1406 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1408 # define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1409 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1410 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1411 # define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1412 # define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1414 #if !defined(JSON_HEDLEY_UNPREDICTABLE)
1415 #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1418 #if defined(JSON_HEDLEY_MALLOC)
1419 #undef JSON_HEDLEY_MALLOC
1422 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1423 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1424 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1425 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1426 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1427 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1428 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1429 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1430 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1431 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1432 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1433 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1434 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1435 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1436 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1437 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1438 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1439 #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1440 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1441 #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1442 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(14, 0, 0)
1443 #define JSON_HEDLEY_MALLOC __declspec(restrict)
1445 #define JSON_HEDLEY_MALLOC
1448 #if defined(JSON_HEDLEY_PURE)
1449 #undef JSON_HEDLEY_PURE
1452 JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1453 JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1454 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1455 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1456 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1457 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1458 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1459 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1460 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1461 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1462 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1463 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1464 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1465 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1466 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1467 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1468 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1469 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1470 # define JSON_HEDLEY_PURE __attribute__((__pure__))
1471 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1472 # define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1473 #elif defined(__cplusplus) && \
1475 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1476 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1477 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1479 # define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1481 # define JSON_HEDLEY_PURE
1484 #if defined(JSON_HEDLEY_CONST)
1485 #undef JSON_HEDLEY_CONST
1488 JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1489 JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1490 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1491 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1492 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1493 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1494 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1495 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1496 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1497 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1498 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1499 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1500 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1501 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1502 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1503 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1504 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1505 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1506 #define JSON_HEDLEY_CONST __attribute__((__const__))
1508 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1509 #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1511 #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1514 #if defined(JSON_HEDLEY_RESTRICT)
1515 #undef JSON_HEDLEY_RESTRICT
1517 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1518 #define JSON_HEDLEY_RESTRICT restrict
1520 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1521 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1522 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1523 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1524 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1525 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1526 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1527 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1528 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1529 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1530 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1531 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1533 #define JSON_HEDLEY_RESTRICT __restrict
1534 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1535 #define JSON_HEDLEY_RESTRICT _Restrict
1537 #define JSON_HEDLEY_RESTRICT
1540 #if defined(JSON_HEDLEY_INLINE)
1541 #undef JSON_HEDLEY_INLINE
1544 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1545 (defined(__cplusplus) && (__cplusplus >= 199711L))
1546 #define JSON_HEDLEY_INLINE inline
1548 defined(JSON_HEDLEY_GCC_VERSION) || \
1549 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1550 #define JSON_HEDLEY_INLINE __inline__
1552 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1553 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1554 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1555 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1556 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1557 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1558 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1559 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1560 #define JSON_HEDLEY_INLINE __inline
1562 #define JSON_HEDLEY_INLINE
1565 #if defined(JSON_HEDLEY_ALWAYS_INLINE)
1566 #undef JSON_HEDLEY_ALWAYS_INLINE
1569 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1570 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1571 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1572 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1573 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1574 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1575 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1576 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1577 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1578 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1579 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1580 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1581 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1582 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1583 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1584 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1585 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1586 # define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1587 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0)
1588 # define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1589 #elif defined(__cplusplus) && \
1591 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1592 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1593 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1594 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1595 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1596 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1598 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1599 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1600 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1602 # define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1605 #if defined(JSON_HEDLEY_NEVER_INLINE)
1606 #undef JSON_HEDLEY_NEVER_INLINE
1609 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1610 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1611 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1612 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1613 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1614 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1615 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1616 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1617 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1618 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1619 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1620 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1621 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1622 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1623 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1624 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1625 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1626 #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1627 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
1628 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1629 #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1630 #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1631 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1632 #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1633 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1634 #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1635 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1636 #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1637 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1638 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1640 #define JSON_HEDLEY_NEVER_INLINE
1643 #if defined(JSON_HEDLEY_PRIVATE)
1644 #undef JSON_HEDLEY_PRIVATE
1646 #if defined(JSON_HEDLEY_PUBLIC)
1647 #undef JSON_HEDLEY_PUBLIC
1649 #if defined(JSON_HEDLEY_IMPORT)
1650 #undef JSON_HEDLEY_IMPORT
1652 #if defined(_WIN32) || defined(__CYGWIN__)
1653 # define JSON_HEDLEY_PRIVATE
1654 # define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1655 # define JSON_HEDLEY_IMPORT __declspec(dllimport)
1658 JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1659 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1660 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1661 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1662 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1663 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1665 defined(__TI_EABI__) && \
1667 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1668 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1671 # define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1672 # define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1674 # define JSON_HEDLEY_PRIVATE
1675 # define JSON_HEDLEY_PUBLIC
1677 # define JSON_HEDLEY_IMPORT extern
1680 #if defined(JSON_HEDLEY_NO_THROW)
1681 #undef JSON_HEDLEY_NO_THROW
1684 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1685 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1686 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1687 #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1689 JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1690 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1691 #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1693 #define JSON_HEDLEY_NO_THROW
1696 #if defined(JSON_HEDLEY_FALL_THROUGH)
1697 #undef JSON_HEDLEY_FALL_THROUGH
1700 JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1701 JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0)
1702 #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1703 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1704 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1705 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1706 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1707 #elif defined(__fallthrough)
1708 #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1710 #define JSON_HEDLEY_FALL_THROUGH
1717 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1718 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
1719 #define __attribute__((__returns_nonnull__))
1720 #elif defined(_Ret_notnull_)
1721 #define _Ret_notnull_
1726 #if defined(JSON_HEDLEY_ARRAY_PARAM)
1727 #undef JSON_HEDLEY_ARRAY_PARAM
1730 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1731 !defined(__STDC_NO_VLA__) && \
1732 !defined(__cplusplus) && \
1733 !defined(JSON_HEDLEY_PGI_VERSION) && \
1734 !defined(JSON_HEDLEY_TINYC_VERSION)
1735 #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1737 #define JSON_HEDLEY_ARRAY_PARAM(name)
1740 #if defined(JSON_HEDLEY_IS_CONSTANT)
1741 #undef JSON_HEDLEY_IS_CONSTANT
1743 #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1744 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1748 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1749 #undef JSON_HEDLEY_IS_CONSTEXPR_
1752 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1753 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1754 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1755 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1756 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1757 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1758 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1759 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1760 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
1761 #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1763 #if !defined(__cplusplus)
1765 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1766 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1767 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1768 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1769 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1770 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1771 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1772 #if defined(__INTPTR_TYPE__)
1773 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1776 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1780 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1781 !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1782 !defined(JSON_HEDLEY_PGI_VERSION) && \
1783 !defined(JSON_HEDLEY_IAR_VERSION)) || \
1784 JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) || \
1785 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1786 JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1787 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1788 JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1789 #if defined(__INTPTR_TYPE__)
1790 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1793 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1796 defined(JSON_HEDLEY_GCC_VERSION) || \
1797 defined(JSON_HEDLEY_INTEL_VERSION) || \
1798 defined(JSON_HEDLEY_TINYC_VERSION) || \
1799 defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1800 JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1801 defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1802 defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1803 defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1804 defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1806 # define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1810 ((void*) ((expr) * 0L) ) : \
1811 ((struct { char v[sizeof(void) * 2]; } *) 1) \
1817 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1818 #if !defined(JSON_HEDLEY_IS_CONSTANT)
1819 #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1821 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
1823 #if !defined(JSON_HEDLEY_IS_CONSTANT)
1824 #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
1826 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
1829 #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
1830 #undef JSON_HEDLEY_BEGIN_C_DECLS
1832 #if defined(JSON_HEDLEY_END_C_DECLS)
1833 #undef JSON_HEDLEY_END_C_DECLS
1835 #if defined(JSON_HEDLEY_C_DECL)
1836 #undef JSON_HEDLEY_C_DECL
1838 #if defined(__cplusplus)
1839 #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
1840 #define JSON_HEDLEY_END_C_DECLS }
1841 #define JSON_HEDLEY_C_DECL extern "C"
1843 #define JSON_HEDLEY_BEGIN_C_DECLS
1844 #define JSON_HEDLEY_END_C_DECLS
1845 #define JSON_HEDLEY_C_DECL
1848 #if defined(JSON_HEDLEY_STATIC_ASSERT)
1849 #undef JSON_HEDLEY_STATIC_ASSERT
1852 !defined(__cplusplus) && ( \
1853 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
1854 JSON_HEDLEY_HAS_FEATURE(c_static_assert) || \
1855 JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
1856 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1857 defined(_Static_assert) \
1859 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
1861 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
1862 JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0)
1863 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
1865 # define JSON_HEDLEY_STATIC_ASSERT(expr, message)
1868 #if defined(JSON_HEDLEY_NULL)
1869 #undef JSON_HEDLEY_NULL
1871 #if defined(__cplusplus)
1872 #if __cplusplus >= 201103L
1873 #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
1875 #define JSON_HEDLEY_NULL NULL
1877 #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
1880 #define JSON_HEDLEY_NULL NULL
1882 #define JSON_HEDLEY_NULL ((void*) 0)
1885 #if defined(JSON_HEDLEY_MESSAGE)
1886 #undef JSON_HEDLEY_MESSAGE
1888 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1889 # define JSON_HEDLEY_MESSAGE(msg) \
1890 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1891 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1892 JSON_HEDLEY_PRAGMA(message msg) \
1893 JSON_HEDLEY_DIAGNOSTIC_POP
1895 JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
1896 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1897 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
1898 #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
1899 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
1900 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1901 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1902 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
1903 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1905 # define JSON_HEDLEY_MESSAGE(msg)
1908 #if defined(JSON_HEDLEY_WARNING)
1909 #undef JSON_HEDLEY_WARNING
1911 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1912 # define JSON_HEDLEY_WARNING(msg) \
1913 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1914 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1915 JSON_HEDLEY_PRAGMA(clang warning msg) \
1916 JSON_HEDLEY_DIAGNOSTIC_POP
1918 JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
1919 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
1920 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1921 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
1922 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1923 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
1925 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
1928 #if defined(JSON_HEDLEY_REQUIRE)
1929 #undef JSON_HEDLEY_REQUIRE
1931 #if defined(JSON_HEDLEY_REQUIRE_MSG)
1932 #undef JSON_HEDLEY_REQUIRE_MSG
1934 #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
1935 # if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
1936 # define JSON_HEDLEY_REQUIRE(expr) \
1937 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1938 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1939 __attribute__((diagnose_if(!(expr), #expr, "error"))) \
1940 JSON_HEDLEY_DIAGNOSTIC_POP
1941 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
1942 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1943 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1944 __attribute__((diagnose_if(!(expr), msg, "error"))) \
1945 JSON_HEDLEY_DIAGNOSTIC_POP
1947 # define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
1948 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
1951 # define JSON_HEDLEY_REQUIRE(expr)
1952 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
1955 #if defined(JSON_HEDLEY_FLAGS)
1956 #undef JSON_HEDLEY_FLAGS
1958 #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum)
1959 #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
1962 #if defined(JSON_HEDLEY_FLAGS_CAST)
1963 #undef JSON_HEDLEY_FLAGS_CAST
1965 #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
1966 # define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
1967 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1968 _Pragma("warning(disable:188)") \
1970 JSON_HEDLEY_DIAGNOSTIC_POP \
1973 # define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
1976 #if defined(JSON_HEDLEY_EMPTY_BASES)
1977 #undef JSON_HEDLEY_EMPTY_BASES
1979 #if JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)
1980 #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
1982 #define JSON_HEDLEY_EMPTY_BASES
1987 #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
1988 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
1990 #if defined(__clang__)
1991 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
1993 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1996 #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
1997 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
1999 #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2001 #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2002 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2004 #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2006 #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2007 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2009 #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2011 #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2012 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2014 #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2016 #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2017 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2019 #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2021 #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2022 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2024 #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2026 #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2027 #undef JSON_HEDLEY_CLANG_HAS_WARNING
2029 #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2038 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2039 #if defined(__clang__)
2040 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2041 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2043 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2044 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2045 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2051 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2052 #define JSON_HAS_CPP_17
2053 #define JSON_HAS_CPP_14
2054 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2055 #define JSON_HAS_CPP_14
2059 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
2060 #pragma GCC diagnostic push
2061 #pragma GCC diagnostic ignored "-Wfloat-equal"
2065 #if defined(__clang__)
2066 #pragma GCC diagnostic push
2067 #pragma GCC diagnostic ignored "-Wdocumentation"
2071 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2072 #define JSON_THROW(exception) throw exception
2073 #define JSON_TRY try
2074 #define JSON_CATCH(exception) catch(exception)
2075 #define JSON_INTERNAL_CATCH(exception) catch(exception)
2078 #define JSON_THROW(exception) std::abort()
2079 #define JSON_TRY if(true)
2080 #define JSON_CATCH(exception) if(false)
2081 #define JSON_INTERNAL_CATCH(exception) if(false)
2085 #if defined(JSON_THROW_USER)
2087 #define JSON_THROW JSON_THROW_USER
2089 #if defined(JSON_TRY_USER)
2091 #define JSON_TRY JSON_TRY_USER
2093 #if defined(JSON_CATCH_USER)
2095 #define JSON_CATCH JSON_CATCH_USER
2096 #undef JSON_INTERNAL_CATCH
2097 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2099 #if defined(JSON_INTERNAL_CATCH_USER)
2100 #undef JSON_INTERNAL_CATCH
2101 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2109 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2110 template<typename BasicJsonType> \
2111 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2113 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2114 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2115 auto it = std::find_if(std::begin(m), std::end(m), \
2116 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2118 return ej_pair.first == e; \
2120 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2122 template<typename BasicJsonType> \
2123 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2125 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2126 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2127 auto it = std::find_if(std::begin(m), std::end(m), \
2128 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2130 return ej_pair.second == j; \
2132 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2138 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2139 template<template<typename, typename, typename...> class ObjectType, \
2140 template<typename, typename...> class ArrayType, \
2141 class StringType, class BooleanType, class NumberIntegerType, \
2142 class NumberUnsignedType, class NumberFloatType, \
2143 template<typename> class AllocatorType, \
2144 template<typename, typename = void> class JSONSerializer, \
2147 #define NLOHMANN_BASIC_JSON_TPL \
2148 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2149 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2150 AllocatorType, JSONSerializer, BinaryType>
2189 class exception :
public std::exception
2194 const char* what() const noexcept
override
2203 JSON_HEDLEY_NON_NULL(3)
2204 exception(
int id_, const
char* what_arg) :
id(id_), m(what_arg) {}
2206 static std::string name(
const std::string& ename,
int id_)
2208 return "[json.exception." + ename +
"." + std::to_string(id_) +
"] ";
2213 std::runtime_error m;
2260 class parse_error :
public exception
2272 static parse_error create(
int id_,
const position_t& pos,
const std::string& what_arg)
2274 std::string w = exception::name(
"parse_error", id_) +
"parse error" +
2275 position_string(pos) +
": " + what_arg;
2276 return parse_error(id_, pos.chars_read_total, w.c_str());
2279 static parse_error create(
int id_, std::size_t byte_,
const std::string& what_arg)
2281 std::string w = exception::name(
"parse_error", id_) +
"parse error" +
2282 (byte_ != 0 ? (
" at byte " + std::to_string(byte_)) :
"") +
2284 return parse_error(id_, byte_, w.c_str());
2296 const std::size_t byte;
2299 parse_error(
int id_, std::size_t byte_,
const char* what_arg)
2300 : exception(id_, what_arg), byte(byte_) {}
2302 static std::string position_string(
const position_t& pos)
2304 return " at line " + std::to_string(pos.lines_read + 1) +
2305 ", column " + std::to_string(pos.chars_read_current_line);
2346 class invalid_iterator :
public exception
2349 static invalid_iterator create(
int id_,
const std::string& what_arg)
2351 std::string w = exception::name(
"invalid_iterator", id_) + what_arg;
2352 return invalid_iterator(id_, w.c_str());
2356 JSON_HEDLEY_NON_NULL(3)
2357 invalid_iterator(
int id_, const
char* what_arg)
2358 : exception(id_, what_arg) {}
2400 class type_error :
public exception
2403 static type_error create(
int id_,
const std::string& what_arg)
2405 std::string w = exception::name(
"type_error", id_) + what_arg;
2406 return type_error(id_, w.c_str());
2410 JSON_HEDLEY_NON_NULL(3)
2411 type_error(
int id_, const
char* what_arg) : exception(id_, what_arg) {}
2447 class out_of_range :
public exception
2450 static out_of_range create(
int id_,
const std::string& what_arg)
2452 std::string w = exception::name(
"out_of_range", id_) + what_arg;
2453 return out_of_range(id_, w.c_str());
2457 JSON_HEDLEY_NON_NULL(3)
2458 out_of_range(
int id_, const
char* what_arg) : exception(id_, what_arg) {}
2485 class other_error :
public exception
2488 static other_error create(
int id_,
const std::string& what_arg)
2490 std::string w = exception::name(
"other_error", id_) + what_arg;
2491 return other_error(id_, w.c_str());
2495 JSON_HEDLEY_NON_NULL(3)
2496 other_error(
int id_, const
char* what_arg) : exception(id_, what_arg) {}
2507 #include <type_traits>
2517 template<
bool B,
typename T =
void>
2518 using enable_if_t =
typename std::enable_if<B, T>::type;
2520 template<
typename T>
2521 using uncvref_t =
typename std::remove_cv<typename std::remove_reference<T>::type>::type;
2525 template<std::size_t... Ints>
2526 struct index_sequence
2528 using type = index_sequence;
2529 using value_type = std::size_t;
2530 static constexpr std::size_t size() noexcept
2532 return sizeof...(Ints);
2536 template<
class Sequence1,
class Sequence2>
2537 struct merge_and_renumber;
2539 template<std::size_t... I1, std::size_t... I2>
2540 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
2541 : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
2543 template<std::
size_t N>
2544 struct make_index_sequence
2545 : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
2546 typename make_index_sequence < N - N / 2 >::type > {};
2548 template<>
struct make_index_sequence<0> : index_sequence<> {};
2549 template<>
struct make_index_sequence<1> : index_sequence<0> {};
2551 template<
typename... Ts>
2552 using index_sequence_for = make_index_sequence<
sizeof...(Ts)>;
2555 template<
unsigned N>
struct priority_tag : priority_tag < N - 1 > {};
2556 template<>
struct priority_tag<0> {};
2559 template<
typename T>
2562 static constexpr T value{};
2565 template<
typename T>
2566 constexpr T static_const<T>::value;
2574 #include <type_traits>
2591 template <
typename ...Ts>
struct make_void
2595 template <
typename ...Ts>
using void_t =
typename make_void<Ts...>::type;
2606 template <
typename It,
typename =
void>
2607 struct iterator_types {};
2609 template <
typename It>
2610 struct iterator_types <
2612 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
2613 typename It::reference, typename It::iterator_category >>
2615 using difference_type =
typename It::difference_type;
2616 using value_type =
typename It::value_type;
2617 using pointer =
typename It::pointer;
2618 using reference =
typename It::reference;
2619 using iterator_category =
typename It::iterator_category;
2624 template <
typename T,
typename =
void>
2625 struct iterator_traits
2629 template <
typename T>
2630 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
2635 template <
typename T>
2636 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
2638 using iterator_category = std::random_access_iterator_tag;
2639 using value_type = T;
2640 using difference_type = ptrdiff_t;
2642 using reference = T&;
2654 #include <type_traits>
2666 nonesuch() =
delete;
2667 ~nonesuch() =
delete;
2668 nonesuch(nonesuch
const&) =
delete;
2669 nonesuch(nonesuch
const&&) =
delete;
2670 void operator=(nonesuch
const&) =
delete;
2671 void operator=(nonesuch&&) =
delete;
2674 template <
class Default,
2676 template <
class...>
class Op,
2680 using value_t = std::false_type;
2681 using type = Default;
2684 template <
class Default,
template <
class...>
class Op,
class... Args>
2685 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2687 using value_t = std::true_type;
2688 using type = Op<Args...>;
2691 template <
template <
class...>
class Op,
class... Args>
2692 using is_detected =
typename detector<nonesuch, void, Op, Args...>::value_t;
2694 template <
template <
class...>
class Op,
class... Args>
2695 using detected_t =
typename detector<nonesuch, void, Op, Args...>::type;
2697 template <
class Default,
template <
class...>
class Op,
class... Args>
2698 using detected_or = detector<Default, void, Op, Args...>;
2700 template <
class Default,
template <
class...>
class Op,
class... Args>
2701 using detected_or_t =
typename detected_or<Default, Op, Args...>::type;
2703 template <
class Expected,
template <
class...>
class Op,
class... Args>
2704 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2706 template <
class To,
template <
class...>
class Op,
class... Args>
2707 using is_detected_convertible =
2708 std::is_convertible<detected_t<Op, Args...>, To>;
2713 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
2714 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
2736 template<
typename T =
void,
typename SFINAE =
void>
2739 template<
template<
typename U,
typename V,
typename... Args>
class ObjectType =
2741 template<
typename U,
typename... Args>
class ArrayType = std::vector,
2742 class StringType = std::string,
class BooleanType = bool,
2743 class NumberIntegerType = std::int64_t,
2744 class NumberUnsignedType = std::uint64_t,
2745 class NumberFloatType = double,
2746 template<
typename U>
class AllocatorType = std::allocator,
2747 template<
typename T,
typename SFINAE =
void>
class JSONSerializer =
2749 class BinaryType = std::vector<std::uint8_t>>
2763 template<
typename BasicJsonType>
2777 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
2805 template<
typename>
struct is_basic_json : std::false_type {};
2807 NLOHMANN_BASIC_JSON_TPL_DECLARATION
2808 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
2818 struct is_json_ref : std::false_type {};
2820 template <
typename T>
2821 struct is_json_ref<json_ref<T>> : std::true_type {};
2827 template <
typename T>
2828 using mapped_type_t =
typename T::mapped_type;
2830 template <
typename T>
2831 using key_type_t =
typename T::key_type;
2833 template <
typename T>
2834 using value_type_t =
typename T::value_type;
2836 template <
typename T>
2837 using difference_type_t =
typename T::difference_type;
2839 template <
typename T>
2840 using pointer_t =
typename T::pointer;
2842 template <
typename T>
2843 using reference_t =
typename T::reference;
2845 template <
typename T>
2846 using iterator_category_t =
typename T::iterator_category;
2848 template <
typename T>
2849 using iterator_t =
typename T::iterator;
2851 template <
typename T,
typename... Args>
2852 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
2854 template <
typename T,
typename... Args>
2855 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
2857 template <
typename T,
typename U>
2858 using get_template_function = decltype(std::declval<T>().
template get<U>());
2861 template <
typename BasicJsonType,
typename T,
typename =
void>
2862 struct has_from_json : std::false_type {};
2864 template <
typename BasicJsonType,
typename T>
2865 struct has_from_json<BasicJsonType, T,
2866 enable_if_t<not is_basic_json<T>::value>>
2868 using serializer =
typename BasicJsonType::template json_serializer<T, void>;
2870 static constexpr
bool value =
2871 is_detected_exact<void, from_json_function, serializer,
2872 const BasicJsonType&, T&>::value;
2877 template <
typename BasicJsonType,
typename T,
typename =
void>
2878 struct has_non_default_from_json : std::false_type {};
2880 template<
typename BasicJsonType,
typename T>
2881 struct has_non_default_from_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
2883 using serializer =
typename BasicJsonType::template json_serializer<T, void>;
2885 static constexpr
bool value =
2886 is_detected_exact<T, from_json_function, serializer,
2887 const BasicJsonType&>::value;
2892 template <
typename BasicJsonType,
typename T,
typename =
void>
2893 struct has_to_json : std::false_type {};
2895 template <
typename BasicJsonType,
typename T>
2896 struct has_to_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
2898 using serializer =
typename BasicJsonType::template json_serializer<T, void>;
2900 static constexpr
bool value =
2901 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
2910 template <
typename T,
typename =
void>
2911 struct is_iterator_traits : std::false_type {};
2913 template <
typename T>
2914 struct is_iterator_traits<iterator_traits<T>>
2917 using traits = iterator_traits<T>;
2920 static constexpr
auto value =
2921 is_detected<value_type_t, traits>::value &&
2922 is_detected<difference_type_t, traits>::value &&
2923 is_detected<pointer_t, traits>::value &&
2924 is_detected<iterator_category_t, traits>::value &&
2925 is_detected<reference_t, traits>::value;
2930 template <
typename T,
typename =
void>
2931 struct is_complete_type : std::false_type {};
2933 template <
typename T>
2934 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
2936 template <
typename BasicJsonType,
typename CompatibleObjectType,
2938 struct is_compatible_object_type_impl : std::false_type {};
2940 template <
typename BasicJsonType,
typename CompatibleObjectType>
2941 struct is_compatible_object_type_impl <
2942 BasicJsonType, CompatibleObjectType,
2943 enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value and
2944 is_detected<key_type_t, CompatibleObjectType>::value >>
2947 using object_t =
typename BasicJsonType::object_t;
2950 static constexpr
bool value =
2951 std::is_constructible<
typename object_t::key_type,
2952 typename CompatibleObjectType::key_type>::value and
2953 std::is_constructible<
typename object_t::mapped_type,
2954 typename CompatibleObjectType::mapped_type>::value;
2957 template <
typename BasicJsonType,
typename CompatibleObjectType>
2958 struct is_compatible_object_type
2959 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
2961 template <
typename BasicJsonType,
typename ConstructibleObjectType,
2963 struct is_constructible_object_type_impl : std::false_type {};
2965 template <
typename BasicJsonType,
typename ConstructibleObjectType>
2966 struct is_constructible_object_type_impl <
2967 BasicJsonType, ConstructibleObjectType,
2968 enable_if_t<is_detected<mapped_type_t, ConstructibleObjectType>::value and
2969 is_detected<key_type_t, ConstructibleObjectType>::value >>
2971 using object_t =
typename BasicJsonType::object_t;
2973 static constexpr
bool value =
2974 (std::is_default_constructible<ConstructibleObjectType>::value and
2975 (std::is_move_assignable<ConstructibleObjectType>::value or
2976 std::is_copy_assignable<ConstructibleObjectType>::value) and
2977 (std::is_constructible<
typename ConstructibleObjectType::key_type,
2978 typename object_t::key_type>::value and
2980 typename object_t::mapped_type,
2981 typename ConstructibleObjectType::mapped_type >::value)) or
2982 (has_from_json<BasicJsonType,
2983 typename ConstructibleObjectType::mapped_type>::value or
2984 has_non_default_from_json <
2986 typename ConstructibleObjectType::mapped_type >::value);
2989 template <
typename BasicJsonType,
typename ConstructibleObjectType>
2990 struct is_constructible_object_type
2991 : is_constructible_object_type_impl<BasicJsonType,
2992 ConstructibleObjectType> {};
2994 template <
typename BasicJsonType,
typename CompatibleStringType,
2996 struct is_compatible_string_type_impl : std::false_type {};
2998 template <
typename BasicJsonType,
typename CompatibleStringType>
2999 struct is_compatible_string_type_impl <
3000 BasicJsonType, CompatibleStringType,
3001 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3002 value_type_t, CompatibleStringType>::value >>
3004 static constexpr
auto value =
3005 std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
3008 template <
typename BasicJsonType,
typename ConstructibleStringType>
3009 struct is_compatible_string_type
3010 : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3012 template <
typename BasicJsonType,
typename ConstructibleStringType,
3014 struct is_constructible_string_type_impl : std::false_type {};
3016 template <
typename BasicJsonType,
typename ConstructibleStringType>
3017 struct is_constructible_string_type_impl <
3018 BasicJsonType, ConstructibleStringType,
3019 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3020 value_type_t, ConstructibleStringType>::value >>
3022 static constexpr
auto value =
3023 std::is_constructible<ConstructibleStringType,
3024 typename BasicJsonType::string_t>::value;
3027 template <
typename BasicJsonType,
typename ConstructibleStringType>
3028 struct is_constructible_string_type
3029 : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3031 template <
typename BasicJsonType,
typename CompatibleArrayType,
typename =
void>
3032 struct is_compatible_array_type_impl : std::false_type {};
3034 template <
typename BasicJsonType,
typename CompatibleArrayType>
3035 struct is_compatible_array_type_impl <
3036 BasicJsonType, CompatibleArrayType,
3037 enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value and
3038 is_detected<iterator_t, CompatibleArrayType>::value and
3042 not is_iterator_traits<
3043 iterator_traits<CompatibleArrayType>>::value >>
3045 static constexpr
bool value =
3046 std::is_constructible<BasicJsonType,
3047 typename CompatibleArrayType::value_type>::value;
3050 template <
typename BasicJsonType,
typename CompatibleArrayType>
3051 struct is_compatible_array_type
3052 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3054 template <
typename BasicJsonType,
typename ConstructibleArrayType,
typename =
void>
3055 struct is_constructible_array_type_impl : std::false_type {};
3057 template <
typename BasicJsonType,
typename ConstructibleArrayType>
3058 struct is_constructible_array_type_impl <
3059 BasicJsonType, ConstructibleArrayType,
3060 enable_if_t<std::is_same<ConstructibleArrayType,
3061 typename BasicJsonType::value_type>::value >>
3062 : std::true_type {};
3064 template <
typename BasicJsonType,
typename ConstructibleArrayType>
3065 struct is_constructible_array_type_impl <
3066 BasicJsonType, ConstructibleArrayType,
3067 enable_if_t<not std::is_same<ConstructibleArrayType,
3068 typename BasicJsonType::value_type>::value and
3069 std::is_default_constructible<ConstructibleArrayType>::value and
3070 (std::is_move_assignable<ConstructibleArrayType>::value or
3071 std::is_copy_assignable<ConstructibleArrayType>::value) and
3072 is_detected<value_type_t, ConstructibleArrayType>::value and
3073 is_detected<iterator_t, ConstructibleArrayType>::value and
3075 detected_t<value_type_t, ConstructibleArrayType>>::value >>
3077 static constexpr
bool value =
3083 not is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value and
3085 (std::is_same<
typename ConstructibleArrayType::value_type,
3086 typename BasicJsonType::array_t::value_type>::value or
3087 has_from_json<BasicJsonType,
3088 typename ConstructibleArrayType::value_type>::value or
3089 has_non_default_from_json <
3090 BasicJsonType,
typename ConstructibleArrayType::value_type >::value);
3093 template <
typename BasicJsonType,
typename ConstructibleArrayType>
3094 struct is_constructible_array_type
3095 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3097 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType,
3099 struct is_compatible_integer_type_impl : std::false_type {};
3101 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType>
3102 struct is_compatible_integer_type_impl <
3103 RealIntegerType, CompatibleNumberIntegerType,
3104 enable_if_t<std::is_integral<RealIntegerType>::value and
3105 std::is_integral<CompatibleNumberIntegerType>::value and
3106 not std::is_same<bool, CompatibleNumberIntegerType>::value >>
3109 using RealLimits = std::numeric_limits<RealIntegerType>;
3110 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3112 static constexpr
auto value =
3113 std::is_constructible<RealIntegerType,
3114 CompatibleNumberIntegerType>::value and
3115 CompatibleLimits::is_integer and
3116 RealLimits::is_signed == CompatibleLimits::is_signed;
3119 template <
typename RealIntegerType,
typename CompatibleNumberIntegerType>
3120 struct is_compatible_integer_type
3121 : is_compatible_integer_type_impl<RealIntegerType,
3122 CompatibleNumberIntegerType> {};
3124 template <
typename BasicJsonType,
typename CompatibleType,
typename =
void>
3125 struct is_compatible_type_impl: std::false_type {};
3127 template <
typename BasicJsonType,
typename CompatibleType>
3128 struct is_compatible_type_impl <
3129 BasicJsonType, CompatibleType,
3130 enable_if_t<is_complete_type<CompatibleType>::value >>
3132 static constexpr
bool value =
3133 has_to_json<BasicJsonType, CompatibleType>::value;
3136 template <
typename BasicJsonType,
typename CompatibleType>
3137 struct is_compatible_type
3138 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3141 template<
class...>
struct conjunction : std::true_type { };
3142 template<
class B1>
struct conjunction<B1> : B1 { };
3143 template<
class B1,
class... Bn>
3144 struct conjunction<B1, Bn...>
3145 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3147 template <
typename T1,
typename T2>
3148 struct is_constructible_tuple : std::false_type {};
3150 template <
typename T1,
typename... Args>
3151 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<std::is_constructible<T1, Args>...> {};
3198 enum class value_t : std::uint8_t
3225 inline bool operator<(
const value_t lhs,
const value_t rhs) noexcept
3227 static constexpr std::array<std::uint8_t, 9> order = {{
3234 const auto l_index =
static_cast<std::size_t
>(lhs);
3235 const auto r_index =
static_cast<std::size_t
>(rhs);
3236 return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
3246 template<
typename BasicJsonType>
3247 void from_json(
const BasicJsonType& j,
typename std::nullptr_t& n)
3249 if (JSON_HEDLEY_UNLIKELY(not j.is_null()))
3251 JSON_THROW(type_error::create(302,
"type must be null, but is " + std::string(j.type_name())));
3257 template<
typename BasicJsonType,
typename ArithmeticType,
3258 enable_if_t<std::is_arithmetic<ArithmeticType>::value and
3259 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3261 void get_arithmetic_value(
const BasicJsonType& j, ArithmeticType& val)
3263 switch (
static_cast<value_t
>(j))
3265 case value_t::number_unsigned:
3267 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3270 case value_t::number_integer:
3272 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3275 case value_t::number_float:
3277 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3282 JSON_THROW(type_error::create(302,
"type must be number, but is " + std::string(j.type_name())));
3286 template<
typename BasicJsonType>
3287 void from_json(
const BasicJsonType& j,
typename BasicJsonType::boolean_t& b)
3289 if (JSON_HEDLEY_UNLIKELY(not j.is_boolean()))
3291 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(j.type_name())));
3293 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
3296 template<
typename BasicJsonType>
3297 void from_json(
const BasicJsonType& j,
typename BasicJsonType::string_t& s)
3299 if (JSON_HEDLEY_UNLIKELY(not j.is_string()))
3301 JSON_THROW(type_error::create(302,
"type must be string, but is " + std::string(j.type_name())));
3303 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3307 typename BasicJsonType,
typename ConstructibleStringType,
3309 is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value and
3310 not std::is_same<
typename BasicJsonType::string_t,
3311 ConstructibleStringType>::value,
3313 void from_json(
const BasicJsonType& j, ConstructibleStringType& s)
3315 if (JSON_HEDLEY_UNLIKELY(not j.is_string()))
3317 JSON_THROW(type_error::create(302,
"type must be string, but is " + std::string(j.type_name())));
3320 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3323 template<
typename BasicJsonType>
3324 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_float_t& val)
3326 get_arithmetic_value(j, val);
3329 template<
typename BasicJsonType>
3330 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_unsigned_t& val)
3332 get_arithmetic_value(j, val);
3335 template<
typename BasicJsonType>
3336 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_integer_t& val)
3338 get_arithmetic_value(j, val);
3341 template<
typename BasicJsonType,
typename EnumType,
3342 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
3343 void from_json(
const BasicJsonType& j, EnumType& e)
3345 typename std::underlying_type<EnumType>::type val;
3346 get_arithmetic_value(j, val);
3347 e =
static_cast<EnumType
>(val);
3351 template<
typename BasicJsonType,
typename T,
typename Allocator,
3352 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
3353 void from_json(
const BasicJsonType& j, std::forward_list<T, Allocator>& l)
3355 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3357 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
3360 std::transform(j.rbegin(), j.rend(),
3361 std::front_inserter(l), [](
const BasicJsonType & i)
3363 return i.template get<T>();
3368 template<
typename BasicJsonType,
typename T,
3369 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
3370 void from_json(
const BasicJsonType& j, std::valarray<T>& l)
3372 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3374 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
3377 std::copy(j.begin(), j.end(), std::begin(l));
3380 template <
typename BasicJsonType,
typename T, std::
size_t N>
3381 auto from_json(
const BasicJsonType& j, T (&arr)[N])
3382 -> decltype(j.template get<T>(),
void())
3384 for (std::size_t i = 0; i < N; ++i)
3386 arr[i] = j.at(i).template get<T>();
3390 template<
typename BasicJsonType>
3391 void from_json_array_impl(
const BasicJsonType& j,
typename BasicJsonType::array_t& arr, priority_tag<3> )
3393 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
3396 template <
typename BasicJsonType,
typename T, std::
size_t N>
3397 auto from_json_array_impl(
const BasicJsonType& j, std::array<T, N>& arr,
3399 -> decltype(j.template get<T>(),
void())
3401 for (std::size_t i = 0; i < N; ++i)
3403 arr[i] = j.at(i).template get<T>();
3407 template<
typename BasicJsonType,
typename ConstructibleArrayType>
3408 auto from_json_array_impl(
const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> )
3410 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
3411 j.template get<typename ConstructibleArrayType::value_type>(),
3416 ConstructibleArrayType ret;
3417 ret.reserve(j.size());
3418 std::transform(j.begin(), j.end(),
3419 std::inserter(ret, end(ret)), [](
const BasicJsonType & i)
3423 return i.template get<typename ConstructibleArrayType::value_type>();
3425 arr = std::move(ret);
3428 template <
typename BasicJsonType,
typename ConstructibleArrayType>
3429 void from_json_array_impl(
const BasicJsonType& j, ConstructibleArrayType& arr,
3434 ConstructibleArrayType ret;
3436 j.begin(), j.end(), std::inserter(ret, end(ret)),
3437 [](
const BasicJsonType & i)
3441 return i.template get<typename ConstructibleArrayType::value_type>();
3443 arr = std::move(ret);
3446 template <
typename BasicJsonType,
typename ConstructibleArrayType,
3448 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value and
3449 not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value and
3450 not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value and
3451 not std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value and
3452 not is_basic_json<ConstructibleArrayType>::value,
3454 auto from_json(
const BasicJsonType& j, ConstructibleArrayType& arr)
3455 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
3456 j.template get<typename ConstructibleArrayType::value_type>(),
3459 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3461 JSON_THROW(type_error::create(302,
"type must be array, but is " +
3462 std::string(j.type_name())));
3465 from_json_array_impl(j, arr, priority_tag<3> {});
3468 template <
typename BasicJsonType>
3469 void from_json(
const BasicJsonType& j,
typename BasicJsonType::binary_t& bin)
3471 if (JSON_HEDLEY_UNLIKELY(not j.is_binary()))
3473 JSON_THROW(type_error::create(302,
"type must be binary, but is " + std::string(j.type_name())));
3476 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
3479 template<
typename BasicJsonType,
typename ConstructibleObjectType,
3480 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value,
int> = 0>
3481 void from_json(
const BasicJsonType& j, ConstructibleObjectType& obj)
3483 if (JSON_HEDLEY_UNLIKELY(not j.is_object()))
3485 JSON_THROW(type_error::create(302,
"type must be object, but is " + std::string(j.type_name())));
3488 ConstructibleObjectType ret;
3489 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
3490 using value_type =
typename ConstructibleObjectType::value_type;
3492 inner_object->begin(), inner_object->end(),
3493 std::inserter(ret, ret.begin()),
3494 [](
typename BasicJsonType::object_t::value_type
const & p)
3496 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
3498 obj = std::move(ret);
3505 template<
typename BasicJsonType,
typename ArithmeticType,
3507 std::is_arithmetic<ArithmeticType>::value and
3508 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
3509 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
3510 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
3511 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3513 void from_json(
const BasicJsonType& j, ArithmeticType& val)
3515 switch (
static_cast<value_t
>(j))
3517 case value_t::number_unsigned:
3519 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3522 case value_t::number_integer:
3524 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3527 case value_t::number_float:
3529 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3532 case value_t::boolean:
3534 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
3539 JSON_THROW(type_error::create(302,
"type must be number, but is " + std::string(j.type_name())));
3543 template<
typename BasicJsonType,
typename A1,
typename A2>
3544 void from_json(
const BasicJsonType& j, std::pair<A1, A2>& p)
3546 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
3549 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
3550 void from_json_tuple_impl(
const BasicJsonType& j, Tuple& t, index_sequence<Idx...> )
3552 t = std::make_tuple(j.at(Idx).template get<
typename std::tuple_element<Idx, Tuple>::type>()...);
3555 template<
typename BasicJsonType,
typename... Args>
3556 void from_json(
const BasicJsonType& j, std::tuple<Args...>& t)
3558 from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
3561 template <
typename BasicJsonType,
typename Key,
typename Value,
typename Compare,
typename Allocator,
3562 typename = enable_if_t<not std::is_constructible<
3563 typename BasicJsonType::string_t, Key>::value>>
3564 void from_json(
const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
3566 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3568 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
3571 for (
const auto& p : j)
3573 if (JSON_HEDLEY_UNLIKELY(not p.is_array()))
3575 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(p.type_name())));
3577 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3581 template <
typename BasicJsonType,
typename Key,
typename Value,
typename Hash,
typename KeyEqual,
typename Allocator,
3582 typename = enable_if_t<not std::is_constructible<
3583 typename BasicJsonType::string_t, Key>::value>>
3584 void from_json(
const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
3586 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3588 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
3591 for (
const auto& p : j)
3593 if (JSON_HEDLEY_UNLIKELY(not p.is_array()))
3595 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(p.type_name())));
3597 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3603 template<
typename BasicJsonType,
typename T>
3604 auto operator()(
const BasicJsonType& j, T& val)
const
3618 constexpr
const auto&
from_json = detail::static_const<detail::from_json_fn>::value;
3625 #include <algorithm>
3629 #include <type_traits>
3653 template<
typename string_type>
3654 void int_to_string( string_type& target, std::size_t value )
3656 target = std::to_string(value);
3658 template <
typename IteratorType>
class iteration_proxy_value
3661 using difference_type = std::ptrdiff_t;
3662 using value_type = iteration_proxy_value;
3663 using pointer = value_type * ;
3664 using reference = value_type & ;
3665 using iterator_category = std::input_iterator_tag;
3666 using string_type =
typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
3670 IteratorType anchor;
3672 std::size_t array_index = 0;
3674 mutable std::size_t array_index_last = 0;
3676 mutable string_type array_index_str =
"0";
3678 const string_type empty_str =
"";
3681 explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
3684 iteration_proxy_value& operator*()
3690 iteration_proxy_value& operator++()
3699 bool operator==(
const iteration_proxy_value& o)
const
3701 return anchor == o.anchor;
3705 bool operator!=(
const iteration_proxy_value& o)
const
3707 return anchor != o.anchor;
3711 const string_type& key()
const
3713 assert(anchor.m_object !=
nullptr);
3715 switch (anchor.m_object->type())
3718 case value_t::array:
3720 if (array_index != array_index_last)
3722 int_to_string( array_index_str, array_index );
3723 array_index_last = array_index;
3725 return array_index_str;
3729 case value_t::object:
3730 return anchor.key();
3739 typename IteratorType::reference value()
const
3741 return anchor.value();
3746 template<
typename IteratorType>
class iteration_proxy
3750 typename IteratorType::reference container;
3754 explicit iteration_proxy(
typename IteratorType::reference cont) noexcept
3755 : container(cont) {}
3758 iteration_proxy_value<IteratorType> begin() noexcept
3760 return iteration_proxy_value<IteratorType>(container.begin());
3764 iteration_proxy_value<IteratorType> end() noexcept
3766 return iteration_proxy_value<IteratorType>(container.end());
3772 template <std::
size_t N,
typename IteratorType, enable_if_t<N == 0,
int> = 0>
3773 auto get(
const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
3780 template <std::
size_t N,
typename IteratorType, enable_if_t<N == 1,
int> = 0>
3781 auto get(
const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
3794 #if defined(__clang__)
3796 #pragma clang diagnostic push
3797 #pragma clang diagnostic ignored "-Wmismatched-tags"
3799 template <
typename IteratorType>
3800 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
3801 :
public std::integral_constant<std::size_t, 2> {};
3803 template <std::
size_t N,
typename IteratorType>
3804 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
3807 using type = decltype(
3808 get<N>(std::declval <
3809 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
3811 #if defined(__clang__)
3812 #pragma clang diagnostic pop
3831 template<value_t>
struct external_constructor;
3834 struct external_constructor<value_t::boolean>
3836 template<
typename BasicJsonType>
3837 static void construct(BasicJsonType& j,
typename BasicJsonType::boolean_t b) noexcept
3839 j.m_type = value_t::boolean;
3841 j.assert_invariant();
3846 struct external_constructor<value_t::string>
3848 template<
typename BasicJsonType>
3849 static void construct(BasicJsonType& j,
const typename BasicJsonType::string_t& s)
3851 j.m_type = value_t::string;
3853 j.assert_invariant();
3856 template<
typename BasicJsonType>
3857 static void construct(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
3859 j.m_type = value_t::string;
3860 j.m_value = std::move(s);
3861 j.assert_invariant();
3864 template<
typename BasicJsonType,
typename CompatibleStringType,
3865 enable_if_t<not std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
3867 static void construct(BasicJsonType& j,
const CompatibleStringType& str)
3869 j.m_type = value_t::string;
3870 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
3871 j.assert_invariant();
3876 struct external_constructor<value_t::binary>
3878 template<
typename BasicJsonType>
3879 static void construct(BasicJsonType& j,
const typename BasicJsonType::binary_t& b)
3881 j.m_type = value_t::binary;
3882 typename BasicJsonType::binary_t value{b};
3884 j.assert_invariant();
3887 template<
typename BasicJsonType>
3888 static void construct(BasicJsonType& j,
typename BasicJsonType::binary_t&& b)
3890 j.m_type = value_t::binary;
3891 typename BasicJsonType::binary_t value{std::move(b)};
3893 j.assert_invariant();
3898 struct external_constructor<value_t::number_float>
3900 template<
typename BasicJsonType>
3901 static void construct(BasicJsonType& j,
typename BasicJsonType::number_float_t val) noexcept
3903 j.m_type = value_t::number_float;
3905 j.assert_invariant();
3910 struct external_constructor<value_t::number_unsigned>
3912 template<
typename BasicJsonType>
3913 static void construct(BasicJsonType& j,
typename BasicJsonType::number_unsigned_t val) noexcept
3915 j.m_type = value_t::number_unsigned;
3917 j.assert_invariant();
3922 struct external_constructor<value_t::number_integer>
3924 template<
typename BasicJsonType>
3925 static void construct(BasicJsonType& j,
typename BasicJsonType::number_integer_t val) noexcept
3927 j.m_type = value_t::number_integer;
3929 j.assert_invariant();
3934 struct external_constructor<value_t::array>
3936 template<
typename BasicJsonType>
3937 static void construct(BasicJsonType& j,
const typename BasicJsonType::array_t& arr)
3939 j.m_type = value_t::array;
3941 j.assert_invariant();
3944 template<
typename BasicJsonType>
3945 static void construct(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
3947 j.m_type = value_t::array;
3948 j.m_value = std::move(arr);
3949 j.assert_invariant();
3952 template<
typename BasicJsonType,
typename CompatibleArrayType,
3953 enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
3955 static void construct(BasicJsonType& j,
const CompatibleArrayType& arr)
3959 j.m_type = value_t::array;
3960 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
3961 j.assert_invariant();
3964 template<
typename BasicJsonType>
3965 static void construct(BasicJsonType& j,
const std::vector<bool>& arr)
3967 j.m_type = value_t::array;
3968 j.m_value = value_t::array;
3969 j.m_value.array->reserve(arr.size());
3970 for (
const bool x : arr)
3972 j.m_value.array->push_back(x);
3974 j.assert_invariant();
3977 template<
typename BasicJsonType,
typename T,
3978 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
3979 static void construct(BasicJsonType& j,
const std::valarray<T>& arr)
3981 j.m_type = value_t::array;
3982 j.m_value = value_t::array;
3983 j.m_value.array->resize(arr.size());
3986 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
3988 j.assert_invariant();
3993 struct external_constructor<value_t::object>
3995 template<
typename BasicJsonType>
3996 static void construct(BasicJsonType& j,
const typename BasicJsonType::object_t& obj)
3998 j.m_type = value_t::object;
4000 j.assert_invariant();
4003 template<
typename BasicJsonType>
4004 static void construct(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
4006 j.m_type = value_t::object;
4007 j.m_value = std::move(obj);
4008 j.assert_invariant();
4011 template<
typename BasicJsonType,
typename CompatibleObjectType,
4012 enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value,
int> = 0>
4013 static void construct(BasicJsonType& j,
const CompatibleObjectType& obj)
4018 j.m_type = value_t::object;
4019 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4020 j.assert_invariant();
4028 template<
typename BasicJsonType,
typename T,
4029 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value,
int> = 0>
4030 void to_json(BasicJsonType& j, T b) noexcept
4032 external_constructor<value_t::boolean>::construct(j, b);
4035 template<
typename BasicJsonType,
typename CompatibleString,
4036 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value,
int> = 0>
4037 void to_json(BasicJsonType& j,
const CompatibleString& s)
4039 external_constructor<value_t::string>::construct(j, s);
4042 template<
typename BasicJsonType>
4043 void to_json(BasicJsonType& j,
typename BasicJsonType::string_t&& s)
4045 external_constructor<value_t::string>::construct(j, std::move(s));
4048 template<
typename BasicJsonType,
typename FloatType,
4049 enable_if_t<std::is_floating_point<FloatType>::value,
int> = 0>
4050 void to_json(BasicJsonType& j, FloatType val) noexcept
4052 external_constructor<value_t::number_float>::construct(j,
static_cast<typename BasicJsonType::number_float_t
>(val));
4055 template<
typename BasicJsonType,
typename CompatibleNumberUnsignedType,
4056 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value,
int> = 0>
4057 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4059 external_constructor<value_t::number_unsigned>::construct(j,
static_cast<typename BasicJsonType::number_unsigned_t
>(val));
4062 template<
typename BasicJsonType,
typename CompatibleNumberIntegerType,
4063 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value,
int> = 0>
4064 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4066 external_constructor<value_t::number_integer>::construct(j,
static_cast<typename BasicJsonType::number_integer_t
>(val));
4069 template<
typename BasicJsonType,
typename EnumType,
4070 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
4071 void to_json(BasicJsonType& j, EnumType e) noexcept
4073 using underlying_type =
typename std::underlying_type<EnumType>::type;
4074 external_constructor<value_t::number_integer>::construct(j,
static_cast<underlying_type
>(e));
4077 template<
typename BasicJsonType>
4078 void to_json(BasicJsonType& j,
const std::vector<bool>& e)
4080 external_constructor<value_t::array>::construct(j, e);
4083 template <
typename BasicJsonType,
typename CompatibleArrayType,
4084 enable_if_t<is_compatible_array_type<BasicJsonType,
4085 CompatibleArrayType>::value and
4086 not is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value and
4087 not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
4088 not std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value and
4089 not is_basic_json<CompatibleArrayType>::value,
4091 void to_json(BasicJsonType& j,
const CompatibleArrayType& arr)
4093 external_constructor<value_t::array>::construct(j, arr);
4096 template <
typename BasicJsonType>
4097 void to_json(BasicJsonType& j,
const typename BasicJsonType::binary_t& bin)
4099 external_constructor<value_t::binary>::construct(j, bin);
4102 template<
typename BasicJsonType,
typename T,
4103 enable_if_t<std::is_convertible<T, BasicJsonType>::value,
int> = 0>
4104 void to_json(BasicJsonType& j,
const std::valarray<T>& arr)
4106 external_constructor<value_t::array>::construct(j, std::move(arr));
4109 template<
typename BasicJsonType>
4110 void to_json(BasicJsonType& j,
typename BasicJsonType::array_t&& arr)
4112 external_constructor<value_t::array>::construct(j, std::move(arr));
4115 template<
typename BasicJsonType,
typename CompatibleObjectType,
4116 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value and not is_basic_json<CompatibleObjectType>::value,
int> = 0>
4117 void to_json(BasicJsonType& j,
const CompatibleObjectType& obj)
4119 external_constructor<value_t::object>::construct(j, obj);
4122 template<
typename BasicJsonType>
4123 void to_json(BasicJsonType& j,
typename BasicJsonType::object_t&& obj)
4125 external_constructor<value_t::object>::construct(j, std::move(obj));
4129 typename BasicJsonType,
typename T, std::size_t N,
4130 enable_if_t<not std::is_constructible<
typename BasicJsonType::string_t,
4131 const T(&)[N]>::value,
4133 void to_json(BasicJsonType& j,
const T(&arr)[N])
4135 external_constructor<value_t::array>::construct(j, arr);
4138 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value,
int > = 0 >
4139 void to_json(BasicJsonType& j,
const std::pair<T1, T2>& p)
4141 j = { p.first, p.second };
4145 template <
typename BasicJsonType,
typename T,
4146 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value,
int> = 0>
4147 void to_json(BasicJsonType& j,
const T& b)
4149 j = { {b.key(), b.value()} };
4152 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
4153 void to_json_tuple_impl(BasicJsonType& j,
const Tuple& t, index_sequence<Idx...> )
4155 j = { std::get<Idx>(t)... };
4158 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value,
int > = 0>
4159 void to_json(BasicJsonType& j,
const T& t)
4161 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
4166 template<
typename BasicJsonType,
typename T>
4167 auto operator()(BasicJsonType& j, T&& val)
const noexcept(noexcept(
to_json(j, std::forward<T>(val))))
4168 -> decltype(
to_json(j, std::forward<T>(val)),
void())
4170 return to_json(j, std::forward<T>(val));
4178 constexpr
const auto&
to_json = detail::static_const<detail::to_json_fn>::value;
4186 template<
typename,
typename>
4187 struct adl_serializer
4198 template<
typename BasicJsonType,
typename ValueType>
4199 static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
4200 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
4201 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val),
void())
4203 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
4215 template <
typename BasicJsonType,
typename ValueType>
4216 static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
4217 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
4218 -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)),
void())
4220 ::nlohmann::to_json(j, std::forward<ValueType>(val));
4249 template<
typename BinaryType>
4271 , m_has_subtype(true)
4277 , m_has_subtype(true)
4282 return std::tie(
static_cast<const BinaryType&
>(*
this), m_subtype, m_has_subtype) ==
4283 std::tie(
static_cast<const BinaryType&
>(rhs), rhs.m_subtype, rhs.m_has_subtype);
4288 return !(rhs == *
this);
4312 m_has_subtype =
true;
4359 return m_has_subtype;
4384 m_has_subtype =
false;
4388 std::uint8_t m_subtype = 0;
4389 bool m_has_subtype =
false;
4405 #include <algorithm>
4433 #include <type_traits>
4446 enum class input_format_t {
json, cbor, msgpack, ubjson, bson };
4456 class file_input_adapter
4459 using char_type = char;
4461 JSON_HEDLEY_NON_NULL(2)
4462 explicit file_input_adapter(std::FILE* f) noexcept
4467 file_input_adapter(
const file_input_adapter&) =
delete;
4468 file_input_adapter(file_input_adapter&&) =
default;
4469 file_input_adapter& operator=(
const file_input_adapter&) =
delete;
4470 file_input_adapter& operator=(file_input_adapter&&) =
delete;
4472 std::char_traits<char>::int_type get_character() noexcept
4474 return std::fgetc(m_file);
4492 class input_stream_adapter
4495 using char_type = char;
4497 ~input_stream_adapter()
4503 is->clear(is->rdstate() & std::ios::eofbit);
4507 explicit input_stream_adapter(std::istream& i)
4508 : is(&i), sb(i.rdbuf())
4512 input_stream_adapter(
const input_stream_adapter&) =
delete;
4513 input_stream_adapter& operator=(input_stream_adapter&) =
delete;
4514 input_stream_adapter& operator=(input_stream_adapter&& rhs) =
delete;
4516 input_stream_adapter(input_stream_adapter&& rhs) : is(rhs.is), sb(rhs.sb)
4525 std::char_traits<char>::int_type get_character()
4527 auto res = sb->sbumpc();
4529 if (JSON_HEDLEY_UNLIKELY(res == EOF))
4531 is->clear(is->rdstate() | std::ios::eofbit);
4538 std::istream* is =
nullptr;
4539 std::streambuf* sb =
nullptr;
4544 template<
typename IteratorType>
4545 class iterator_input_adapter
4548 using char_type =
typename std::iterator_traits<IteratorType>::value_type;
4550 iterator_input_adapter(IteratorType first, IteratorType last)
4551 : current(std::move(first)), end(std::move(last)) {}
4553 typename std::char_traits<char_type>::int_type get_character()
4555 if (JSON_HEDLEY_LIKELY(current != end))
4557 auto result = std::char_traits<char_type>::to_int_type(*current);
4558 std::advance(current, 1);
4563 return std::char_traits<char_type>::eof();
4568 IteratorType current;
4571 template<
typename BaseInputAdapter,
size_t T>
4572 friend struct wide_string_input_helper;
4576 return current == end;
4582 template<
typename BaseInputAdapter,
size_t T>
4583 struct wide_string_input_helper;
4585 template<
typename BaseInputAdapter>
4586 struct wide_string_input_helper<BaseInputAdapter, 4>
4589 static void fill_buffer(BaseInputAdapter& input,
4590 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4591 size_t& utf8_bytes_index,
4592 size_t& utf8_bytes_filled)
4594 utf8_bytes_index = 0;
4596 if (JSON_HEDLEY_UNLIKELY(input.empty()))
4598 utf8_bytes[0] = std::char_traits<char>::eof();
4599 utf8_bytes_filled = 1;
4604 const auto wc = input.get_character();
4609 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
4610 utf8_bytes_filled = 1;
4612 else if (wc <= 0x7FF)
4614 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xC0u | ((
static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
4615 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (
static_cast<unsigned int>(wc) & 0x3Fu));
4616 utf8_bytes_filled = 2;
4618 else if (wc <= 0xFFFF)
4620 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xE0u | ((
static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
4621 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((
static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4622 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (
static_cast<unsigned int>(wc) & 0x3Fu));
4623 utf8_bytes_filled = 3;
4625 else if (wc <= 0x10FFFF)
4627 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xF0u | ((
static_cast<unsigned int>(wc) >> 18u) & 0x07u));
4628 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((
static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
4629 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((
static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4630 utf8_bytes[3] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (
static_cast<unsigned int>(wc) & 0x3Fu));
4631 utf8_bytes_filled = 4;
4636 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
4637 utf8_bytes_filled = 1;
4643 template<
typename BaseInputAdapter>
4644 struct wide_string_input_helper<BaseInputAdapter, 2>
4647 static void fill_buffer(BaseInputAdapter& input,
4648 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4649 size_t& utf8_bytes_index,
4650 size_t& utf8_bytes_filled)
4652 utf8_bytes_index = 0;
4654 if (JSON_HEDLEY_UNLIKELY(input.empty()))
4656 utf8_bytes[0] = std::char_traits<char>::eof();
4657 utf8_bytes_filled = 1;
4662 const auto wc = input.get_character();
4667 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
4668 utf8_bytes_filled = 1;
4670 else if (wc <= 0x7FF)
4672 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xC0u | ((
static_cast<unsigned int>(wc) >> 6u)));
4673 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (
static_cast<unsigned int>(wc) & 0x3Fu));
4674 utf8_bytes_filled = 2;
4676 else if (0xD800 > wc or wc >= 0xE000)
4678 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xE0u | ((
static_cast<unsigned int>(wc) >> 12u)));
4679 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((
static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4680 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (
static_cast<unsigned int>(wc) & 0x3Fu));
4681 utf8_bytes_filled = 3;
4685 if (JSON_HEDLEY_UNLIKELY(not input.empty()))
4687 const auto wc2 =
static_cast<unsigned int>(input.get_character());
4688 const auto charcode = 0x10000u + (((
static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
4689 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xF0u | (charcode >> 18u));
4690 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((charcode >> 12u) & 0x3Fu));
4691 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((charcode >> 6u) & 0x3Fu));
4692 utf8_bytes[3] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (charcode & 0x3Fu));
4693 utf8_bytes_filled = 4;
4697 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
4698 utf8_bytes_filled = 1;
4706 template<
typename BaseInputAdapter,
typename W
ideCharType>
4707 class wide_string_input_adapter
4710 using char_type = char;
4712 wide_string_input_adapter(BaseInputAdapter base)
4713 : base_adapter(base) {}
4715 typename std::char_traits<char>::int_type get_character() noexcept
4718 if (utf8_bytes_index == utf8_bytes_filled)
4720 fill_buffer<sizeof(WideCharType)>();
4722 assert(utf8_bytes_filled > 0);
4723 assert(utf8_bytes_index == 0);
4727 assert(utf8_bytes_filled > 0);
4728 assert(utf8_bytes_index < utf8_bytes_filled);
4729 return utf8_bytes[utf8_bytes_index++];
4733 BaseInputAdapter base_adapter;
4738 wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
4742 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
4745 std::size_t utf8_bytes_index = 0;
4747 std::size_t utf8_bytes_filled = 0;
4751 template<
typename IteratorType,
typename Enable =
void>
4752 struct iterator_input_adapter_factory
4754 using iterator_type = IteratorType;
4755 using char_type =
typename std::iterator_traits<iterator_type>::value_type;
4756 using adapter_type = iterator_input_adapter<iterator_type>;
4758 static adapter_type create(IteratorType first, IteratorType last)
4760 return adapter_type(std::move(first), std::move(last));
4764 template<
typename T>
4765 struct is_iterator_of_multibyte
4767 using value_type =
typename std::iterator_traits<T>::value_type;
4770 value =
sizeof(value_type) > 1
4774 template<
typename IteratorType>
4775 struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
4777 using iterator_type = IteratorType;
4778 using char_type =
typename std::iterator_traits<iterator_type>::value_type;
4779 using base_adapter_type = iterator_input_adapter<iterator_type>;
4780 using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
4782 static adapter_type create(IteratorType first, IteratorType last)
4784 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
4789 template<
typename IteratorType>
4790 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
4792 using factory_type = iterator_input_adapter_factory<IteratorType>;
4793 return factory_type::create(first, last);
4797 template<
typename ContainerType>
4798 auto input_adapter(
const ContainerType& container) -> decltype(input_adapter(begin(container), end(container)))
4804 return input_adapter(begin(container), end(container));
4808 inline file_input_adapter input_adapter(std::FILE* file)
4810 return file_input_adapter(file);
4813 inline input_stream_adapter input_adapter(std::istream& stream)
4815 return input_stream_adapter(stream);
4818 inline input_stream_adapter input_adapter(std::istream&& stream)
4820 return input_stream_adapter(stream);
4823 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
4826 template <
typename CharT,
4827 typename std::enable_if <
4828 std::is_pointer<CharT>::value and
4829 not std::is_array<CharT>::value and
4830 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
4831 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
4833 contiguous_bytes_input_adapter input_adapter(CharT b)
4835 auto length = std::strlen(
reinterpret_cast<const char*
>(b));
4836 auto ptr =
reinterpret_cast<const char*
>(b);
4837 return input_adapter(ptr, ptr + length);
4840 template<
typename T, std::
size_t N>
4841 auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N))
4843 return input_adapter(array, array + N);
4849 class span_input_adapter
4852 template<
typename CharT,
4853 typename std::enable_if<
4854 std::is_pointer<CharT>::value and
4855 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
4856 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
4858 span_input_adapter(CharT b, std::size_t l)
4859 : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
4861 template<
class IteratorType,
4862 typename std::enable_if<
4863 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
4865 span_input_adapter(IteratorType first, IteratorType last)
4866 : ia(input_adapter(first, last)) {}
4868 contiguous_bytes_input_adapter&& get()
4870 return std::move(ia);
4874 contiguous_bytes_input_adapter ia;
4904 template<
typename BasicJsonType>
4917 virtual bool null() = 0;
5008 const std::string& last_token,
5009 const detail::exception& ex) = 0;
5030 template<
typename BasicJsonType>
5031 class json_sax_dom_parser
5034 using number_integer_t =
typename BasicJsonType::number_integer_t;
5035 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
5036 using number_float_t =
typename BasicJsonType::number_float_t;
5037 using string_t =
typename BasicJsonType::string_t;
5038 using binary_t =
typename BasicJsonType::binary_t;
5045 explicit json_sax_dom_parser(BasicJsonType& r,
const bool allow_exceptions_ =
true)
5046 : root(r), allow_exceptions(allow_exceptions_)
5050 json_sax_dom_parser(
const json_sax_dom_parser&) =
delete;
5051 json_sax_dom_parser(json_sax_dom_parser&&) =
default;
5052 json_sax_dom_parser& operator=(
const json_sax_dom_parser&) =
delete;
5053 json_sax_dom_parser& operator=(json_sax_dom_parser&&) =
default;
5054 ~json_sax_dom_parser() =
default;
5058 handle_value(
nullptr);
5062 bool boolean(
bool val)
5068 bool number_integer(number_integer_t val)
5074 bool number_unsigned(number_unsigned_t val)
5080 bool number_float(number_float_t val,
const string_t& )
5086 bool string(string_t& val)
5092 bool binary(binary_t& val)
5094 handle_value(std::move(val));
5098 bool start_object(std::size_t len)
5100 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
5102 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
5104 JSON_THROW(out_of_range::create(408,
5105 "excessive object size: " + std::to_string(len)));
5111 bool key(string_t& val)
5114 object_element = &(ref_stack.back()->m_value.object->operator[](val));
5120 ref_stack.pop_back();
5124 bool start_array(std::size_t len)
5126 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
5128 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
5130 JSON_THROW(out_of_range::create(408,
5131 "excessive array size: " + std::to_string(len)));
5139 ref_stack.pop_back();
5143 bool parse_error(std::size_t ,
const std::string& ,
5144 const detail::exception& ex)
5147 if (allow_exceptions)
5150 switch ((ex.id / 100) % 100)
5153 JSON_THROW(*
static_cast<const detail::parse_error*
>(&ex));
5155 JSON_THROW(*
static_cast<const detail::out_of_range*
>(&ex));
5158 JSON_THROW(*
static_cast<const detail::invalid_iterator*
>(&ex));
5160 JSON_THROW(*
static_cast<const detail::type_error*
>(&ex));
5162 JSON_THROW(*
static_cast<const detail::other_error*
>(&ex));
5171 constexpr
bool is_errored()
const
5183 template<
typename Value>
5185 BasicJsonType* handle_value(Value&& v)
5187 if (ref_stack.empty())
5189 root = BasicJsonType(std::forward<Value>(v));
5193 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
5195 if (ref_stack.back()->is_array())
5197 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
5198 return &(ref_stack.back()->m_value.array->back());
5201 assert(ref_stack.back()->is_object());
5202 assert(object_element);
5203 *object_element = BasicJsonType(std::forward<Value>(v));
5204 return object_element;
5208 BasicJsonType& root;
5210 std::vector<BasicJsonType*> ref_stack {};
5212 BasicJsonType* object_element =
nullptr;
5214 bool errored =
false;
5216 const bool allow_exceptions =
true;
5219 template<
typename BasicJsonType>
5220 class json_sax_dom_callback_parser
5223 using number_integer_t =
typename BasicJsonType::number_integer_t;
5224 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
5225 using number_float_t =
typename BasicJsonType::number_float_t;
5226 using string_t =
typename BasicJsonType::string_t;
5227 using binary_t =
typename BasicJsonType::binary_t;
5228 using parser_callback_t =
typename BasicJsonType::parser_callback_t;
5229 using parse_event_t =
typename BasicJsonType::parse_event_t;
5231 json_sax_dom_callback_parser(BasicJsonType& r,
5232 const parser_callback_t cb,
5233 const bool allow_exceptions_ =
true)
5234 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
5236 keep_stack.push_back(
true);
5240 json_sax_dom_callback_parser(
const json_sax_dom_callback_parser&) =
delete;
5241 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) =
default;
5242 json_sax_dom_callback_parser& operator=(
const json_sax_dom_callback_parser&) =
delete;
5243 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) =
default;
5244 ~json_sax_dom_callback_parser() =
default;
5248 handle_value(
nullptr);
5252 bool boolean(
bool val)
5258 bool number_integer(number_integer_t val)
5264 bool number_unsigned(number_unsigned_t val)
5270 bool number_float(number_float_t val,
const string_t& )
5276 bool string(string_t& val)
5282 bool binary(binary_t& val)
5284 handle_value(std::move(val));
5288 bool start_object(std::size_t len)
5291 const bool keep = callback(
static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
5292 keep_stack.push_back(keep);
5294 auto val = handle_value(BasicJsonType::value_t::object,
true);
5295 ref_stack.push_back(val.second);
5298 if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
5300 JSON_THROW(out_of_range::create(408,
"excessive object size: " + std::to_string(len)));
5306 bool key(string_t& val)
5308 BasicJsonType k = BasicJsonType(val);
5311 const bool keep = callback(
static_cast<int>(ref_stack.size()), parse_event_t::key, k);
5312 key_keep_stack.push_back(keep);
5315 if (keep and ref_stack.back())
5317 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
5325 if (ref_stack.back() and not callback(
static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
5328 *ref_stack.back() = discarded;
5331 assert(not ref_stack.empty());
5332 assert(not keep_stack.empty());
5333 ref_stack.pop_back();
5334 keep_stack.pop_back();
5336 if (not ref_stack.empty() and ref_stack.back() and ref_stack.back()->is_structured())
5339 for (
auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
5341 if (it->is_discarded())
5343 ref_stack.back()->erase(it);
5352 bool start_array(std::size_t len)
5354 const bool keep = callback(
static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
5355 keep_stack.push_back(keep);
5357 auto val = handle_value(BasicJsonType::value_t::array,
true);
5358 ref_stack.push_back(val.second);
5361 if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
5363 JSON_THROW(out_of_range::create(408,
"excessive array size: " + std::to_string(len)));
5373 if (ref_stack.back())
5375 keep = callback(
static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
5379 *ref_stack.back() = discarded;
5383 assert(not ref_stack.empty());
5384 assert(not keep_stack.empty());
5385 ref_stack.pop_back();
5386 keep_stack.pop_back();
5389 if (not keep and not ref_stack.empty() and ref_stack.back()->is_array())
5391 ref_stack.back()->m_value.array->pop_back();
5397 bool parse_error(std::size_t ,
const std::string& ,
5398 const detail::exception& ex)
5401 if (allow_exceptions)
5404 switch ((ex.id / 100) % 100)
5407 JSON_THROW(*
static_cast<const detail::parse_error*
>(&ex));
5409 JSON_THROW(*
static_cast<const detail::out_of_range*
>(&ex));
5412 JSON_THROW(*
static_cast<const detail::invalid_iterator*
>(&ex));
5414 JSON_THROW(*
static_cast<const detail::type_error*
>(&ex));
5416 JSON_THROW(*
static_cast<const detail::other_error*
>(&ex));
5425 constexpr
bool is_errored()
const
5446 template<
typename Value>
5447 std::pair<bool, BasicJsonType*> handle_value(Value&& v,
const bool skip_callback =
false)
5449 assert(not keep_stack.empty());
5453 if (not keep_stack.back())
5455 return {
false,
nullptr};
5459 auto value = BasicJsonType(std::forward<Value>(v));
5462 const bool keep = skip_callback or callback(
static_cast<int>(ref_stack.size()), parse_event_t::value, value);
5467 return {
false,
nullptr};
5470 if (ref_stack.empty())
5472 root = std::move(value);
5473 return {
true, &root};
5478 if (not ref_stack.back())
5480 return {
false,
nullptr};
5484 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
5487 if (ref_stack.back()->is_array())
5489 ref_stack.back()->m_value.array->push_back(std::move(value));
5490 return {
true, &(ref_stack.back()->m_value.array->back())};
5494 assert(ref_stack.back()->is_object());
5496 assert(not key_keep_stack.empty());
5497 const bool store_element = key_keep_stack.back();
5498 key_keep_stack.pop_back();
5500 if (not store_element)
5502 return {
false,
nullptr};
5505 assert(object_element);
5506 *object_element = std::move(value);
5507 return {
true, object_element};
5511 BasicJsonType& root;
5513 std::vector<BasicJsonType*> ref_stack {};
5515 std::vector<bool> keep_stack {};
5517 std::vector<bool> key_keep_stack {};
5519 BasicJsonType* object_element =
nullptr;
5521 bool errored =
false;
5523 const parser_callback_t callback =
nullptr;
5525 const bool allow_exceptions =
true;
5527 BasicJsonType discarded = BasicJsonType::value_t::discarded;
5530 template<
typename BasicJsonType>
5531 class json_sax_acceptor
5534 using number_integer_t =
typename BasicJsonType::number_integer_t;
5535 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
5536 using number_float_t =
typename BasicJsonType::number_float_t;
5537 using string_t =
typename BasicJsonType::string_t;
5538 using binary_t =
typename BasicJsonType::binary_t;
5550 bool number_integer(number_integer_t )
5555 bool number_unsigned(number_unsigned_t )
5560 bool number_float(number_float_t ,
const string_t& )
5565 bool string(string_t& )
5570 bool binary(binary_t& )
5575 bool start_object(std::size_t = std::size_t(-1))
5580 bool key(string_t& )
5590 bool start_array(std::size_t = std::size_t(-1))
5600 bool parse_error(std::size_t ,
const std::string& ,
const detail::exception& )
5627 template <
typename T>
5628 using null_function_t = decltype(std::declval<T&>().
null());
5630 template <
typename T>
5631 using boolean_function_t =
5632 decltype(std::declval<T&>().
boolean(std::declval<bool>()));
5634 template <
typename T,
typename Integer>
5635 using number_integer_function_t =
5636 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
5638 template <
typename T,
typename Un
signed>
5639 using number_unsigned_function_t =
5640 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
5642 template <
typename T,
typename Float,
typename String>
5643 using number_float_function_t = decltype(std::declval<T&>().number_float(
5644 std::declval<Float>(), std::declval<const String&>()));
5646 template <
typename T,
typename String>
5647 using string_function_t =
5648 decltype(std::declval<T&>().
string(std::declval<String&>()));
5650 template <
typename T>
5651 using start_object_function_t =
5652 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
5654 template <
typename T,
typename String>
5655 using key_function_t =
5656 decltype(std::declval<T&>().key(std::declval<String&>()));
5658 template <
typename T>
5659 using end_object_function_t = decltype(std::declval<T&>().end_object());
5661 template <
typename T>
5662 using start_array_function_t =
5663 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
5665 template <
typename T>
5666 using end_array_function_t = decltype(std::declval<T&>().end_array());
5668 template <
typename T,
typename Exception>
5669 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
5670 std::declval<std::size_t>(), std::declval<const std::string&>(),
5671 std::declval<const Exception&>()));
5673 template <
typename SAX,
typename BasicJsonType>
5677 static_assert(is_basic_json<BasicJsonType>::value,
5678 "BasicJsonType must be of type basic_json<...>");
5680 using number_integer_t =
typename BasicJsonType::number_integer_t;
5681 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
5682 using number_float_t =
typename BasicJsonType::number_float_t;
5683 using string_t =
typename BasicJsonType::string_t;
5684 using exception_t =
typename BasicJsonType::exception;
5687 static constexpr
bool value =
5688 is_detected_exact<bool, null_function_t, SAX>::value &&
5689 is_detected_exact<bool, boolean_function_t, SAX>::value &&
5690 is_detected_exact<bool, number_integer_function_t, SAX,
5691 number_integer_t>::value &&
5692 is_detected_exact<bool, number_unsigned_function_t, SAX,
5693 number_unsigned_t>::value &&
5694 is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
5696 is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
5697 is_detected_exact<bool, start_object_function_t, SAX>::value &&
5698 is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
5699 is_detected_exact<bool, end_object_function_t, SAX>::value &&
5700 is_detected_exact<bool, start_array_function_t, SAX>::value &&
5701 is_detected_exact<bool, end_array_function_t, SAX>::value &&
5702 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
5705 template <
typename SAX,
typename BasicJsonType>
5706 struct is_sax_static_asserts
5709 static_assert(is_basic_json<BasicJsonType>::value,
5710 "BasicJsonType must be of type basic_json<...>");
5712 using number_integer_t =
typename BasicJsonType::number_integer_t;
5713 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
5714 using number_float_t =
typename BasicJsonType::number_float_t;
5715 using string_t =
typename BasicJsonType::string_t;
5716 using exception_t =
typename BasicJsonType::exception;
5719 static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
5720 "Missing/invalid function: bool null()");
5721 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
5722 "Missing/invalid function: bool boolean(bool)");
5723 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
5724 "Missing/invalid function: bool boolean(bool)");
5726 is_detected_exact<
bool, number_integer_function_t, SAX,
5727 number_integer_t>::value,
5728 "Missing/invalid function: bool number_integer(number_integer_t)");
5730 is_detected_exact<
bool, number_unsigned_function_t, SAX,
5731 number_unsigned_t>::value,
5732 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
5733 static_assert(is_detected_exact<
bool, number_float_function_t, SAX,
5734 number_float_t, string_t>::value,
5735 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
5737 is_detected_exact<bool, string_function_t, SAX, string_t>::value,
5738 "Missing/invalid function: bool string(string_t&)");
5739 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
5740 "Missing/invalid function: bool start_object(std::size_t)");
5741 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
5742 "Missing/invalid function: bool key(string_t&)");
5743 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
5744 "Missing/invalid function: bool end_object()");
5745 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
5746 "Missing/invalid function: bool start_array(std::size_t)");
5747 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
5748 "Missing/invalid function: bool end_array()");
5750 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
5751 "Missing/invalid function: bool parse_error(std::size_t, const "
5752 "std::string&, const exception&)");
5772 static inline bool little_endianess(
int num = 1) noexcept
5774 return *
reinterpret_cast<char*
>(&num) == 1;
5785 template<
typename BasicJsonType,
typename InputAdapterType,
typename SAX = json_sax_dom_parser<BasicJsonType>>
5788 using number_integer_t =
typename BasicJsonType::number_integer_t;
5789 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
5790 using number_float_t =
typename BasicJsonType::number_float_t;
5791 using string_t =
typename BasicJsonType::string_t;
5792 using binary_t =
typename BasicJsonType::binary_t;
5793 using json_sax_t = SAX;
5794 using char_type =
typename InputAdapterType::char_type;
5795 using char_int_type =
typename std::char_traits<char_type>::int_type;
5803 explicit binary_reader(InputAdapterType&& adapter) : ia(std::move(adapter))
5805 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
5809 binary_reader(
const binary_reader&) =
delete;
5810 binary_reader(binary_reader&&) =
default;
5811 binary_reader& operator=(
const binary_reader&) =
delete;
5812 binary_reader& operator=(binary_reader&&) =
default;
5813 ~binary_reader() =
default;
5822 JSON_HEDLEY_NON_NULL(3)
5823 bool sax_parse(const input_format_t format,
5825 const
bool strict = true)
5828 bool result =
false;
5832 case input_format_t::bson:
5833 result = parse_bson_internal();
5836 case input_format_t::cbor:
5837 result = parse_cbor_internal();
5840 case input_format_t::msgpack:
5841 result = parse_msgpack_internal();
5844 case input_format_t::ubjson:
5845 result = parse_ubjson_internal();
5853 if (result and strict)
5855 if (format == input_format_t::ubjson)
5864 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
5866 return sax->parse_error(chars_read, get_token_string(),
5867 parse_error::create(110, chars_read, exception_message(format,
"expected end of input; last byte: 0x" + get_token_string(),
"value")));
5883 bool parse_bson_internal()
5885 std::int32_t document_size;
5886 get_number<std::int32_t, true>(input_format_t::bson, document_size);
5888 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
5893 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(
false)))
5898 return sax->end_object();
5908 bool get_bson_cstr(string_t& result)
5910 auto out = std::back_inserter(result);
5914 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson,
"cstring")))
5918 if (current == 0x00)
5922 *out++ =
static_cast<typename string_t::value_type
>(current);
5939 template<
typename NumberType>
5940 bool get_bson_string(
const NumberType len, string_t& result)
5942 if (JSON_HEDLEY_UNLIKELY(len < 1))
5944 auto last_token = get_token_string();
5945 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")));
5948 return get_string(input_format_t::bson, len -
static_cast<NumberType
>(1), result) and get() != std::char_traits<char_type>::eof();
5960 template<
typename NumberType>
5961 bool get_bson_binary(
const NumberType len, binary_t& result)
5963 if (JSON_HEDLEY_UNLIKELY(len < 0))
5965 auto last_token = get_token_string();
5966 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson,
"byte array length cannot be negative, is " + std::to_string(len),
"binary")));
5970 std::uint8_t subtype;
5971 get_number<std::uint8_t>(input_format_t::bson, subtype);
5972 result.set_subtype(subtype);
5974 return get_binary(input_format_t::bson, len, result);
5987 bool parse_bson_element_internal(
const char_int_type element_type,
5988 const std::size_t element_type_parse_position)
5990 switch (element_type)
5995 return get_number<double, true>(input_format_t::bson, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
6002 return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_string(len, value) and sax->string(value);
6007 return parse_bson_internal();
6012 return parse_bson_array();
6019 return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_binary(len, value) and sax->binary(value);
6024 return sax->boolean(get() != 0);
6035 return get_number<std::int32_t, true>(input_format_t::bson, value) and sax->number_integer(value);
6041 return get_number<std::int64_t, true>(input_format_t::bson, value) and sax->number_integer(value);
6046 std::array<char, 3> cr{{}};
6047 (std::snprintf)(cr.data(), cr.size(),
"%.2hhX",
static_cast<unsigned char>(element_type));
6048 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())));
6065 bool parse_bson_element_list(
const bool is_array)
6069 while (
auto element_type = get())
6071 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson,
"element list")))
6076 const std::size_t element_type_parse_position = chars_read;
6077 if (JSON_HEDLEY_UNLIKELY(not get_bson_cstr(key)))
6082 if (not is_array and not sax->key(key))
6087 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
6103 bool parse_bson_array()
6105 std::int32_t document_size;
6106 get_number<std::int32_t, true>(input_format_t::bson, document_size);
6108 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
6113 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(
true)))
6118 return sax->end_array();
6132 bool parse_cbor_internal(
const bool get_char =
true)
6134 switch (get_char ? get() : current)
6137 case std::char_traits<char_type>::eof():
6138 return unexpect_eof(input_format_t::cbor,
"value");
6165 return sax->number_unsigned(
static_cast<number_unsigned_t
>(current));
6169 std::uint8_t number;
6170 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6175 std::uint16_t number;
6176 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6181 std::uint32_t number;
6182 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6187 std::uint64_t number;
6188 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6216 return sax->number_integer(
static_cast<std::int8_t
>(0x20 - 1 - current));
6220 std::uint8_t number;
6221 return get_number(input_format_t::cbor, number) and sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
6226 std::uint16_t number;
6227 return get_number(input_format_t::cbor, number) and sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
6232 std::uint32_t number;
6233 return get_number(input_format_t::cbor, number) and sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
6238 std::uint64_t number;
6239 return get_number(input_format_t::cbor, number) and sax->number_integer(
static_cast<number_integer_t
>(-1)
6240 -
static_cast<number_integer_t
>(number));
6275 return get_cbor_binary(b) and sax->binary(b);
6310 return get_cbor_string(s) and sax->string(s);
6338 return get_cbor_array(
static_cast<std::size_t
>(
static_cast<unsigned int>(current) & 0x1Fu));
6343 return get_number(input_format_t::cbor, len) and get_cbor_array(
static_cast<std::size_t
>(len));
6349 return get_number(input_format_t::cbor, len) and get_cbor_array(
static_cast<std::size_t
>(len));
6355 return get_number(input_format_t::cbor, len) and get_cbor_array(
static_cast<std::size_t
>(len));
6361 return get_number(input_format_t::cbor, len) and get_cbor_array(
static_cast<std::size_t
>(len));
6365 return get_cbor_array(std::size_t(-1));
6392 return get_cbor_object(
static_cast<std::size_t
>(
static_cast<unsigned int>(current) & 0x1Fu));
6397 return get_number(input_format_t::cbor, len) and get_cbor_object(
static_cast<std::size_t
>(len));
6403 return get_number(input_format_t::cbor, len) and get_cbor_object(
static_cast<std::size_t
>(len));
6409 return get_number(input_format_t::cbor, len) and get_cbor_object(
static_cast<std::size_t
>(len));
6415 return get_number(input_format_t::cbor, len) and get_cbor_object(
static_cast<std::size_t
>(len));
6419 return get_cbor_object(std::size_t(-1));
6422 return sax->boolean(
false);
6425 return sax->boolean(
true);
6432 const auto byte1_raw = get();
6433 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor,
"number")))
6437 const auto byte2_raw = get();
6438 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor,
"number")))
6443 const auto byte1 =
static_cast<unsigned char>(byte1_raw);
6444 const auto byte2 =
static_cast<unsigned char>(byte2_raw);
6454 const auto half =
static_cast<unsigned int>((byte1 << 8u) + byte2);
6455 const double val = [&half]
6457 const int exp = (half >> 10u) & 0x1Fu;
6458 const unsigned int mant = half & 0x3FFu;
6459 assert(0 <= exp and exp <= 32);
6460 assert(mant <= 1024);
6464 return std::ldexp(mant, -24);
6467 ? std::numeric_limits<double>::infinity()
6468 : std::numeric_limits<double>::quiet_NaN();
6470 return std::ldexp(mant + 1024, exp - 25);
6473 return sax->number_float((half & 0x8000u) != 0
6474 ?
static_cast<number_float_t
>(-val)
6475 :
static_cast<number_float_t
>(val),
"");
6481 return get_number(input_format_t::cbor, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
6487 return get_number(input_format_t::cbor, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
6492 auto last_token = get_token_string();
6493 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")));
6509 bool get_cbor_string(string_t& result)
6511 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor,
"string")))
6544 return get_string(input_format_t::cbor,
static_cast<unsigned int>(current) & 0x1Fu, result);
6550 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
6556 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
6562 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
6568 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
6573 while (get() != 0xFF)
6576 if (not get_cbor_string(chunk))
6580 result.append(chunk);
6587 auto last_token = get_token_string();
6588 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")));
6604 bool get_cbor_binary(binary_t& result)
6606 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor,
"binary")))
6639 return get_binary(input_format_t::cbor,
static_cast<unsigned int>(current) & 0x1Fu, result);
6645 return get_number(input_format_t::cbor, len) and
6646 get_binary(input_format_t::cbor, len, result);
6652 return get_number(input_format_t::cbor, len) and
6653 get_binary(input_format_t::cbor, len, result);
6659 return get_number(input_format_t::cbor, len) and
6660 get_binary(input_format_t::cbor, len, result);
6666 return get_number(input_format_t::cbor, len) and
6667 get_binary(input_format_t::cbor, len, result);
6672 while (get() != 0xFF)
6675 if (not get_cbor_binary(chunk))
6679 result.insert(result.end(), chunk.begin(), chunk.end());
6686 auto last_token = get_token_string();
6687 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor,
"expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token,
"binary")));
6697 bool get_cbor_array(
const std::size_t len)
6699 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len)))
6704 if (len != std::size_t(-1))
6706 for (std::size_t i = 0; i < len; ++i)
6708 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
6716 while (get() != 0xFF)
6718 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal(
false)))
6725 return sax->end_array();
6733 bool get_cbor_object(
const std::size_t len)
6735 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len)))
6741 if (len != std::size_t(-1))
6743 for (std::size_t i = 0; i < len; ++i)
6746 if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
6751 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
6760 while (get() != 0xFF)
6762 if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
6767 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
6775 return sax->end_object();
6785 bool parse_msgpack_internal()
6790 case std::char_traits<char_type>::eof():
6791 return unexpect_eof(input_format_t::msgpack,
"value");
6922 return sax->number_unsigned(
static_cast<number_unsigned_t
>(current));
6941 return get_msgpack_object(
static_cast<std::size_t
>(
static_cast<unsigned int>(current) & 0x0Fu));
6960 return get_msgpack_array(
static_cast<std::size_t
>(
static_cast<unsigned int>(current) & 0x0Fu));
7000 return get_msgpack_string(s) and sax->string(s);
7007 return sax->boolean(
false);
7010 return sax->boolean(
true);
7025 return get_msgpack_binary(b) and sax->binary(b);
7031 return get_number(input_format_t::msgpack, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
7037 return get_number(input_format_t::msgpack, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
7042 std::uint8_t number;
7043 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7048 std::uint16_t number;
7049 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7054 std::uint32_t number;
7055 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7060 std::uint64_t number;
7061 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7067 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7072 std::int16_t number;
7073 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7078 std::int32_t number;
7079 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7084 std::int64_t number;
7085 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7091 return get_number(input_format_t::msgpack, len) and get_msgpack_array(
static_cast<std::size_t
>(len));
7097 return get_number(input_format_t::msgpack, len) and get_msgpack_array(
static_cast<std::size_t
>(len));
7103 return get_number(input_format_t::msgpack, len) and get_msgpack_object(
static_cast<std::size_t
>(len));
7109 return get_number(input_format_t::msgpack, len) and get_msgpack_object(
static_cast<std::size_t
>(len));
7145 return sax->number_integer(
static_cast<std::int8_t
>(current));
7149 auto last_token = get_token_string();
7150 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")));
7165 bool get_msgpack_string(string_t& result)
7167 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::msgpack,
"string")))
7208 return get_string(input_format_t::msgpack,
static_cast<unsigned int>(current) & 0x1Fu, result);
7214 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7220 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7226 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7231 auto last_token = get_token_string();
7232 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")));
7247 bool get_msgpack_binary(binary_t& result)
7250 auto assign_and_return_true = [&result](std::int8_t subtype)
7252 result.set_subtype(
static_cast<std::uint8_t
>(subtype));
7261 return get_number(input_format_t::msgpack, len) and
7262 get_binary(input_format_t::msgpack, len, result);
7268 return get_number(input_format_t::msgpack, len) and
7269 get_binary(input_format_t::msgpack, len, result);
7275 return get_number(input_format_t::msgpack, len) and
7276 get_binary(input_format_t::msgpack, len, result);
7282 std::int8_t subtype;
7283 return get_number(input_format_t::msgpack, len) and
7284 get_number(input_format_t::msgpack, subtype) and
7285 get_binary(input_format_t::msgpack, len, result) and
7286 assign_and_return_true(subtype);
7292 std::int8_t subtype;
7293 return get_number(input_format_t::msgpack, len) and
7294 get_number(input_format_t::msgpack, subtype) and
7295 get_binary(input_format_t::msgpack, len, result) and
7296 assign_and_return_true(subtype);
7302 std::int8_t subtype;
7303 return get_number(input_format_t::msgpack, len) and
7304 get_number(input_format_t::msgpack, subtype) and
7305 get_binary(input_format_t::msgpack, len, result) and
7306 assign_and_return_true(subtype);
7311 std::int8_t subtype;
7312 return get_number(input_format_t::msgpack, subtype) and
7313 get_binary(input_format_t::msgpack, 1, result) and
7314 assign_and_return_true(subtype);
7319 std::int8_t subtype;
7320 return get_number(input_format_t::msgpack, subtype) and
7321 get_binary(input_format_t::msgpack, 2, result) and
7322 assign_and_return_true(subtype);
7327 std::int8_t subtype;
7328 return get_number(input_format_t::msgpack, subtype) and
7329 get_binary(input_format_t::msgpack, 4, result) and
7330 assign_and_return_true(subtype);
7335 std::int8_t subtype;
7336 return get_number(input_format_t::msgpack, subtype) and
7337 get_binary(input_format_t::msgpack, 8, result) and
7338 assign_and_return_true(subtype);
7343 std::int8_t subtype;
7344 return get_number(input_format_t::msgpack, subtype) and
7345 get_binary(input_format_t::msgpack, 16, result) and
7346 assign_and_return_true(subtype);
7358 bool get_msgpack_array(
const std::size_t len)
7360 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len)))
7365 for (std::size_t i = 0; i < len; ++i)
7367 if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal()))
7373 return sax->end_array();
7380 bool get_msgpack_object(
const std::size_t len)
7382 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len)))
7388 for (std::size_t i = 0; i < len; ++i)
7391 if (JSON_HEDLEY_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
7396 if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal()))
7403 return sax->end_object();
7417 bool parse_ubjson_internal(
const bool get_char =
true)
7419 return get_ubjson_value(get_char ? get_ignore_noop() : current);
7436 bool get_ubjson_string(string_t& result,
const bool get_char =
true)
7443 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson,
"value")))
7453 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7459 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7465 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7471 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7477 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7481 auto last_token = get_token_string();
7482 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")));
7490 bool get_ubjson_size_value(std::size_t& result)
7492 switch (get_ignore_noop())
7496 std::uint8_t number;
7497 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7501 result =
static_cast<std::size_t
>(number);
7508 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7512 result =
static_cast<std::size_t
>(number);
7518 std::int16_t number;
7519 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7523 result =
static_cast<std::size_t
>(number);
7529 std::int32_t number;
7530 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7534 result =
static_cast<std::size_t
>(number);
7540 std::int64_t number;
7541 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7545 result =
static_cast<std::size_t
>(number);
7551 auto last_token = get_token_string();
7552 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")));
7567 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
7569 result.first = string_t::npos;
7576 result.second = get();
7577 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson,
"type")))
7583 if (JSON_HEDLEY_UNLIKELY(current !=
'#'))
7585 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson,
"value")))
7589 auto last_token = get_token_string();
7590 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")));
7593 return get_ubjson_size_value(result.first);
7598 return get_ubjson_size_value(result.first);
7608 bool get_ubjson_value(
const char_int_type prefix)
7612 case std::char_traits<char_type>::eof():
7613 return unexpect_eof(input_format_t::ubjson,
"value");
7616 return sax->boolean(
true);
7618 return sax->boolean(
false);
7625 std::uint8_t number;
7626 return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number);
7632 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7637 std::int16_t number;
7638 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7643 std::int32_t number;
7644 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7649 std::int64_t number;
7650 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7656 return get_number(input_format_t::ubjson, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
7662 return get_number(input_format_t::ubjson, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
7668 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson,
"char")))
7672 if (JSON_HEDLEY_UNLIKELY(current > 127))
7674 auto last_token = get_token_string();
7675 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")));
7677 string_t s(1,
static_cast<typename string_t::value_type
>(current));
7678 return sax->string(s);
7684 return get_ubjson_string(s) and sax->string(s);
7688 return get_ubjson_array();
7691 return get_ubjson_object();
7695 auto last_token = get_token_string();
7696 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")));
7704 bool get_ubjson_array()
7706 std::pair<std::size_t, char_int_type> size_and_type;
7707 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
7712 if (size_and_type.first != string_t::npos)
7714 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(size_and_type.first)))
7719 if (size_and_type.second != 0)
7721 if (size_and_type.second !=
'N')
7723 for (std::size_t i = 0; i < size_and_type.first; ++i)
7725 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second)))
7734 for (std::size_t i = 0; i < size_and_type.first; ++i)
7736 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
7745 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
7750 while (current !=
']')
7752 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal(
false)))
7760 return sax->end_array();
7766 bool get_ubjson_object()
7768 std::pair<std::size_t, char_int_type> size_and_type;
7769 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
7775 if (size_and_type.first != string_t::npos)
7777 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(size_and_type.first)))
7782 if (size_and_type.second != 0)
7784 for (std::size_t i = 0; i < size_and_type.first; ++i)
7786 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
7790 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second)))
7799 for (std::size_t i = 0; i < size_and_type.first; ++i)
7801 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
7805 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
7815 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
7820 while (current !=
'}')
7822 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key,
false) or not sax->key(key)))
7826 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
7835 return sax->end_object();
7857 return current = ia.get_character();
7863 char_int_type get_ignore_noop()
7869 while (current ==
'N');
7887 template<
typename NumberType,
bool InputIsLittleEndian = false>
7888 bool get_number(
const input_format_t format, NumberType& result)
7891 std::array<std::uint8_t,
sizeof(NumberType)> vec;
7892 for (std::size_t i = 0; i <
sizeof(NumberType); ++i)
7895 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format,
"number")))
7901 if (is_little_endian != InputIsLittleEndian)
7903 vec[
sizeof(NumberType) - i - 1] =
static_cast<std::uint8_t
>(current);
7907 vec[i] =
static_cast<std::uint8_t
>(current);
7912 std::memcpy(&result, vec.data(),
sizeof(NumberType));
7930 template<
typename NumberType>
7931 bool get_string(
const input_format_t format,
7932 const NumberType len,
7935 bool success =
true;
7936 std::generate_n(std::back_inserter(result), len, [
this, &success, &format]()
7939 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format,
"string")))
7943 return std::char_traits<char_type>::to_char_type(current);
7962 template<
typename NumberType>
7963 bool get_binary(
const input_format_t format,
7964 const NumberType len,
7967 bool success =
true;
7968 std::generate_n(std::back_inserter(result), len, [
this, &success, &format]()
7971 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format,
"binary")))
7975 return static_cast<std::uint8_t
>(current);
7985 JSON_HEDLEY_NON_NULL(3)
7986 bool unexpect_eof(const input_format_t format, const
char* context)
const
7988 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
7990 return sax->parse_error(chars_read,
"<end of file>",
7991 parse_error::create(110, chars_read, exception_message(format,
"unexpected end of input", context)));
7999 std::string get_token_string()
const
8001 std::array<char, 3> cr{{}};
8002 (std::snprintf)(cr.data(), cr.size(),
"%.2hhX",
static_cast<unsigned char>(current));
8003 return std::string{cr.data()};
8012 std::string exception_message(
const input_format_t format,
8013 const std::string& detail,
8014 const std::string& context)
const
8016 std::string error_msg =
"syntax error while parsing ";
8020 case input_format_t::cbor:
8021 error_msg +=
"CBOR";
8024 case input_format_t::msgpack:
8025 error_msg +=
"MessagePack";
8028 case input_format_t::ubjson:
8029 error_msg +=
"UBJSON";
8032 case input_format_t::bson:
8033 error_msg +=
"BSON";
8040 return error_msg +
" " + context +
": " + detail;
8045 InputAdapterType ia;
8048 char_int_type current = std::char_traits<char_type>::eof();
8051 std::size_t chars_read = 0;
8054 const bool is_little_endian = little_endianess();
8057 json_sax_t* sax =
nullptr;
8072 #include <initializer_list>
8092 template<
typename BasicJsonType>
8097 enum class token_type
8121 static const char* token_type_name(
const token_type t) noexcept
8125 case token_type::uninitialized:
8126 return "<uninitialized>";
8127 case token_type::literal_true:
8128 return "true literal";
8129 case token_type::literal_false:
8130 return "false literal";
8131 case token_type::literal_null:
8132 return "null literal";
8133 case token_type::value_string:
8134 return "string literal";
8135 case token_type::value_unsigned:
8136 case token_type::value_integer:
8137 case token_type::value_float:
8138 return "number literal";
8139 case token_type::begin_array:
8141 case token_type::begin_object:
8143 case token_type::end_array:
8145 case token_type::end_object:
8147 case token_type::name_separator:
8149 case token_type::value_separator:
8151 case token_type::parse_error:
8152 return "<parse error>";
8153 case token_type::end_of_input:
8154 return "end of input";
8155 case token_type::literal_or_value:
8156 return "'[', '{', or a literal";
8159 return "unknown token";
8169 template<
typename BasicJsonType,
typename InputAdapterType>
8170 class lexer :
public lexer_base<BasicJsonType>
8172 using number_integer_t =
typename BasicJsonType::number_integer_t;
8173 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
8174 using number_float_t =
typename BasicJsonType::number_float_t;
8175 using string_t =
typename BasicJsonType::string_t;
8176 using char_type =
typename InputAdapterType::char_type;
8177 using char_int_type =
typename std::char_traits<char_type>::int_type;
8180 using token_type =
typename lexer_base<BasicJsonType>::token_type;
8182 explicit lexer(InputAdapterType&& adapter)
8183 : ia(std::move(adapter)), decimal_point_char(static_cast<char_int_type>(get_decimal_point())) {}
8186 lexer(
const lexer&) =
delete;
8187 lexer(lexer&&) =
default;
8188 lexer& operator=(lexer&) =
delete;
8189 lexer& operator=(lexer&&) =
default;
8199 static char get_decimal_point() noexcept
8201 const auto loc = localeconv();
8202 assert(loc !=
nullptr);
8203 return (loc->decimal_point ==
nullptr) ?
'.' : *(loc->decimal_point);
8228 assert(current ==
'u');
8231 const auto factors = { 12u, 8u, 4u, 0u };
8232 for (
const auto factor : factors)
8236 if (current >=
'0' and current <=
'9')
8238 codepoint +=
static_cast<int>((
static_cast<unsigned int>(current) - 0x30u) << factor);
8240 else if (current >=
'A' and current <=
'F')
8242 codepoint +=
static_cast<int>((
static_cast<unsigned int>(current) - 0x37u) << factor);
8244 else if (current >=
'a' and current <=
'f')
8246 codepoint +=
static_cast<int>((
static_cast<unsigned int>(current) - 0x57u) << factor);
8254 assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
8273 bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
8275 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
8278 for (
auto range = ranges.begin(); range != ranges.end(); ++range)
8281 if (JSON_HEDLEY_LIKELY(*range <= current and current <= *(++range)))
8287 error_message =
"invalid string: ill-formed UTF-8 byte";
8310 token_type scan_string()
8316 assert(current ==
'\"');
8324 case std::char_traits<char_type>::eof():
8326 error_message =
"invalid string: missing closing quote";
8327 return token_type::parse_error;
8333 return token_type::value_string;
8377 const int codepoint1 = get_codepoint();
8378 int codepoint = codepoint1;
8380 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
8382 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
8383 return token_type::parse_error;
8387 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
8390 if (JSON_HEDLEY_LIKELY(get() ==
'\\' and get() ==
'u'))
8392 const int codepoint2 = get_codepoint();
8394 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
8396 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
8397 return token_type::parse_error;
8401 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
8404 codepoint =
static_cast<int>(
8406 (
static_cast<unsigned int>(codepoint1) << 10u)
8408 +
static_cast<unsigned int>(codepoint2)
8416 error_message =
"invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
8417 return token_type::parse_error;
8422 error_message =
"invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
8423 return token_type::parse_error;
8428 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
8430 error_message =
"invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
8431 return token_type::parse_error;
8436 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
8439 if (codepoint < 0x80)
8442 add(
static_cast<char_int_type
>(codepoint));
8444 else if (codepoint <= 0x7FF)
8447 add(
static_cast<char_int_type
>(0xC0u | (
static_cast<unsigned int>(codepoint) >> 6u)));
8448 add(
static_cast<char_int_type
>(0x80u | (
static_cast<unsigned int>(codepoint) & 0x3Fu)));
8450 else if (codepoint <= 0xFFFF)
8453 add(
static_cast<char_int_type
>(0xE0u | (
static_cast<unsigned int>(codepoint) >> 12u)));
8454 add(
static_cast<char_int_type
>(0x80u | ((
static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
8455 add(
static_cast<char_int_type
>(0x80u | (
static_cast<unsigned int>(codepoint) & 0x3Fu)));
8460 add(
static_cast<char_int_type
>(0xF0u | (
static_cast<unsigned int>(codepoint) >> 18u)));
8461 add(
static_cast<char_int_type
>(0x80u | ((
static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
8462 add(
static_cast<char_int_type
>(0x80u | ((
static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
8463 add(
static_cast<char_int_type
>(0x80u | (
static_cast<unsigned int>(codepoint) & 0x3Fu)));
8471 error_message =
"invalid string: forbidden character after backslash";
8472 return token_type::parse_error;
8481 error_message =
"invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
8482 return token_type::parse_error;
8487 error_message =
"invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
8488 return token_type::parse_error;
8493 error_message =
"invalid string: control character U+0002 (STX) must be escaped to \\u0002";
8494 return token_type::parse_error;
8499 error_message =
"invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
8500 return token_type::parse_error;
8505 error_message =
"invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
8506 return token_type::parse_error;
8511 error_message =
"invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
8512 return token_type::parse_error;
8517 error_message =
"invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
8518 return token_type::parse_error;
8523 error_message =
"invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
8524 return token_type::parse_error;
8529 error_message =
"invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
8530 return token_type::parse_error;
8535 error_message =
"invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
8536 return token_type::parse_error;
8541 error_message =
"invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
8542 return token_type::parse_error;
8547 error_message =
"invalid string: control character U+000B (VT) must be escaped to \\u000B";
8548 return token_type::parse_error;
8553 error_message =
"invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
8554 return token_type::parse_error;
8559 error_message =
"invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
8560 return token_type::parse_error;
8565 error_message =
"invalid string: control character U+000E (SO) must be escaped to \\u000E";
8566 return token_type::parse_error;
8571 error_message =
"invalid string: control character U+000F (SI) must be escaped to \\u000F";
8572 return token_type::parse_error;
8577 error_message =
"invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
8578 return token_type::parse_error;
8583 error_message =
"invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
8584 return token_type::parse_error;
8589 error_message =
"invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
8590 return token_type::parse_error;
8595 error_message =
"invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
8596 return token_type::parse_error;
8601 error_message =
"invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
8602 return token_type::parse_error;
8607 error_message =
"invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
8608 return token_type::parse_error;
8613 error_message =
"invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
8614 return token_type::parse_error;
8619 error_message =
"invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
8620 return token_type::parse_error;
8625 error_message =
"invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
8626 return token_type::parse_error;
8631 error_message =
"invalid string: control character U+0019 (EM) must be escaped to \\u0019";
8632 return token_type::parse_error;
8637 error_message =
"invalid string: control character U+001A (SUB) must be escaped to \\u001A";
8638 return token_type::parse_error;
8643 error_message =
"invalid string: control character U+001B (ESC) must be escaped to \\u001B";
8644 return token_type::parse_error;
8649 error_message =
"invalid string: control character U+001C (FS) must be escaped to \\u001C";
8650 return token_type::parse_error;
8655 error_message =
"invalid string: control character U+001D (GS) must be escaped to \\u001D";
8656 return token_type::parse_error;
8661 error_message =
"invalid string: control character U+001E (RS) must be escaped to \\u001E";
8662 return token_type::parse_error;
8667 error_message =
"invalid string: control character U+001F (US) must be escaped to \\u001F";
8668 return token_type::parse_error;
8803 if (JSON_HEDLEY_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
8805 return token_type::parse_error;
8813 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
8815 return token_type::parse_error;
8837 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
8839 return token_type::parse_error;
8847 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
8849 return token_type::parse_error;
8857 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
8859 return token_type::parse_error;
8869 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
8871 return token_type::parse_error;
8879 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
8881 return token_type::parse_error;
8889 error_message =
"invalid string: ill-formed UTF-8 byte";
8890 return token_type::parse_error;
8896 JSON_HEDLEY_NON_NULL(2)
8897 static
void strtof(
float& f, const
char* str,
char** endptr) noexcept
8899 f = std::strtof(str, endptr);
8902 JSON_HEDLEY_NON_NULL(2)
8903 static
void strtof(
double& f, const
char* str,
char** endptr) noexcept
8905 f = std::strtod(str, endptr);
8908 JSON_HEDLEY_NON_NULL(2)
8909 static
void strtof(
long double& f, const
char* str,
char** endptr) noexcept
8911 f = std::strtold(str, endptr);
8954 token_type scan_number()
8961 token_type number_type = token_type::value_unsigned;
8969 goto scan_number_minus;
8975 goto scan_number_zero;
8989 goto scan_number_any1;
8999 number_type = token_type::value_integer;
9005 goto scan_number_zero;
9019 goto scan_number_any1;
9024 error_message =
"invalid number; expected digit after '-'";
9025 return token_type::parse_error;
9035 add(decimal_point_char);
9036 goto scan_number_decimal1;
9043 goto scan_number_exponent;
9047 goto scan_number_done;
9066 goto scan_number_any1;
9071 add(decimal_point_char);
9072 goto scan_number_decimal1;
9079 goto scan_number_exponent;
9083 goto scan_number_done;
9086 scan_number_decimal1:
9088 number_type = token_type::value_float;
9103 goto scan_number_decimal2;
9108 error_message =
"invalid number; expected digit after '.'";
9109 return token_type::parse_error;
9113 scan_number_decimal2:
9129 goto scan_number_decimal2;
9136 goto scan_number_exponent;
9140 goto scan_number_done;
9143 scan_number_exponent:
9145 number_type = token_type::value_float;
9152 goto scan_number_sign;
9167 goto scan_number_any2;
9173 "invalid number; expected '+', '-', or digit after exponent";
9174 return token_type::parse_error;
9194 goto scan_number_any2;
9199 error_message =
"invalid number; expected digit after exponent sign";
9200 return token_type::parse_error;
9220 goto scan_number_any2;
9224 goto scan_number_done;
9232 char* endptr =
nullptr;
9236 if (number_type == token_type::value_unsigned)
9238 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
9241 assert(endptr == token_buffer.data() + token_buffer.size());
9245 value_unsigned =
static_cast<number_unsigned_t
>(x);
9246 if (value_unsigned == x)
9248 return token_type::value_unsigned;
9252 else if (number_type == token_type::value_integer)
9254 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
9257 assert(endptr == token_buffer.data() + token_buffer.size());
9261 value_integer =
static_cast<number_integer_t
>(x);
9262 if (value_integer == x)
9264 return token_type::value_integer;
9271 strtof(value_float, token_buffer.data(), &endptr);
9274 assert(endptr == token_buffer.data() + token_buffer.size());
9276 return token_type::value_float;
9284 JSON_HEDLEY_NON_NULL(2)
9285 token_type scan_literal(const char_type* literal_text, const std::
size_t length,
9286 token_type return_type)
9288 assert(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
9289 for (std::size_t i = 1; i < length; ++i)
9291 if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
9293 error_message =
"invalid literal";
9294 return token_type::parse_error;
9305 void reset() noexcept
9307 token_buffer.clear();
9308 token_string.clear();
9309 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
9324 ++position.chars_read_total;
9325 ++position.chars_read_current_line;
9334 current = ia.get_character();
9337 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
9339 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
9342 if (current ==
'\n')
9344 ++position.lines_read;
9345 position.chars_read_current_line = 0;
9363 --position.chars_read_total;
9366 if (position.chars_read_current_line == 0)
9368 if (position.lines_read > 0)
9370 --position.lines_read;
9375 --position.chars_read_current_line;
9378 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
9380 assert(not token_string.empty());
9381 token_string.pop_back();
9386 void add(char_int_type c)
9388 token_buffer.push_back(
static_cast<typename string_t::value_type
>(c));
9397 constexpr number_integer_t get_number_integer() const noexcept
9399 return value_integer;
9403 constexpr number_unsigned_t get_number_unsigned() const noexcept
9405 return value_unsigned;
9409 constexpr number_float_t get_number_float() const noexcept
9415 string_t& get_string()
9417 return token_buffer;
9425 constexpr position_t get_position() const noexcept
9433 std::string get_token_string()
const
9437 for (
const auto c : token_string)
9439 if (
static_cast<unsigned char>(c) <=
'\x1F')
9442 std::array<char, 9> cs{{}};
9443 (std::snprintf)(cs.data(), cs.size(),
"<U+%.4X>",
static_cast<unsigned char>(c));
9444 result += cs.data();
9449 result.push_back(
static_cast<std::string::value_type
>(c));
9458 constexpr
const char* get_error_message() const noexcept
9460 return error_message;
9476 return get() == 0xBB and get() == 0xBF;
9488 if (position.chars_read_total == 0 and not skip_bom())
9490 error_message =
"invalid BOM; must be 0xEF 0xBB 0xBF if given";
9491 return token_type::parse_error;
9499 while (current ==
' ' or current ==
'\t' or current ==
'\n' or current ==
'\r');
9505 return token_type::begin_array;
9507 return token_type::end_array;
9509 return token_type::begin_object;
9511 return token_type::end_object;
9513 return token_type::name_separator;
9515 return token_type::value_separator;
9520 std::array<char_type, 4> true_literal = {{
't',
'r',
'u',
'e'}};
9521 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
9525 std::array<char_type, 5> false_literal = {{
'f',
'a',
'l',
's',
'e'}};
9526 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
9530 std::array<char_type, 4> null_literal = {{
'n',
'u',
'l',
'l'}};
9531 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
9536 return scan_string();
9550 return scan_number();
9555 case std::char_traits<char_type>::eof():
9556 return token_type::end_of_input;
9560 error_message =
"invalid literal";
9561 return token_type::parse_error;
9567 InputAdapterType ia;
9570 char_int_type current = std::char_traits<char_type>::eof();
9573 bool next_unget =
false;
9576 position_t position {};
9579 std::vector<char_type> token_string {};
9582 string_t token_buffer {};
9585 const char* error_message =
"";
9588 number_integer_t value_integer = 0;
9589 number_unsigned_t value_unsigned = 0;
9590 number_float_t value_float = 0;
9593 const char_int_type decimal_point_char =
'.';
9604 #include <functional>
9632 enum class parse_event_t : uint8_t
9648 template<
typename BasicJsonType>
9649 using parser_callback_t =
9650 std::function<bool(
int depth, parse_event_t event, BasicJsonType& parsed)>;
9657 template<
typename BasicJsonType,
typename InputAdapterType>
9660 using number_integer_t =
typename BasicJsonType::number_integer_t;
9661 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
9662 using number_float_t =
typename BasicJsonType::number_float_t;
9663 using string_t =
typename BasicJsonType::string_t;
9664 using lexer_t = lexer<BasicJsonType, InputAdapterType>;
9665 using token_type =
typename lexer_t::token_type;
9669 explicit parser(InputAdapterType&& adapter,
9670 const parser_callback_t<BasicJsonType> cb =
nullptr,
9671 const bool allow_exceptions_ =
true)
9672 : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
9688 void parse(
const bool strict, BasicJsonType& result)
9692 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
9693 sax_parse_internal(&sdp);
9694 result.assert_invariant();
9697 if (strict and (get_token() != token_type::end_of_input))
9699 sdp.parse_error(m_lexer.get_position(),
9700 m_lexer.get_token_string(),
9701 parse_error::create(101, m_lexer.get_position(),
9702 exception_message(token_type::end_of_input,
"value")));
9706 if (sdp.is_errored())
9708 result = value_t::discarded;
9714 if (result.is_discarded())
9721 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
9722 sax_parse_internal(&sdp);
9723 result.assert_invariant();
9726 if (strict and (get_token() != token_type::end_of_input))
9728 sdp.parse_error(m_lexer.get_position(),
9729 m_lexer.get_token_string(),
9730 parse_error::create(101, m_lexer.get_position(),
9731 exception_message(token_type::end_of_input,
"value")));
9735 if (sdp.is_errored())
9737 result = value_t::discarded;
9749 bool accept(
const bool strict =
true)
9751 json_sax_acceptor<BasicJsonType> sax_acceptor;
9752 return sax_parse(&sax_acceptor, strict);
9755 template <
typename SAX>
9756 JSON_HEDLEY_NON_NULL(2)
9757 bool sax_parse(SAX* sax, const
bool strict = true)
9759 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
9760 const bool result = sax_parse_internal(sax);
9763 if (result and strict and (get_token() != token_type::end_of_input))
9765 return sax->parse_error(m_lexer.get_position(),
9766 m_lexer.get_token_string(),
9767 parse_error::create(101, m_lexer.get_position(),
9768 exception_message(token_type::end_of_input,
"value")));
9775 template <
typename SAX>
9776 JSON_HEDLEY_NON_NULL(2)
9777 bool sax_parse_internal(SAX* sax)
9781 std::vector<bool> states;
9783 bool skip_to_state_evaluation =
false;
9787 if (not skip_to_state_evaluation)
9792 case token_type::begin_object:
9794 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
9800 if (get_token() == token_type::end_object)
9802 if (JSON_HEDLEY_UNLIKELY(not sax->end_object()))
9810 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
9812 return sax->parse_error(m_lexer.get_position(),
9813 m_lexer.get_token_string(),
9814 parse_error::create(101, m_lexer.get_position(),
9815 exception_message(token_type::value_string,
"object key")));
9817 if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
9823 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
9825 return sax->parse_error(m_lexer.get_position(),
9826 m_lexer.get_token_string(),
9827 parse_error::create(101, m_lexer.get_position(),
9828 exception_message(token_type::name_separator,
"object separator")));
9832 states.push_back(
false);
9839 case token_type::begin_array:
9841 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
9847 if (get_token() == token_type::end_array)
9849 if (JSON_HEDLEY_UNLIKELY(not sax->end_array()))
9857 states.push_back(
true);
9863 case token_type::value_float:
9865 const auto res = m_lexer.get_number_float();
9867 if (JSON_HEDLEY_UNLIKELY(not std::isfinite(res)))
9869 return sax->parse_error(m_lexer.get_position(),
9870 m_lexer.get_token_string(),
9871 out_of_range::create(406,
"number overflow parsing '" + m_lexer.get_token_string() +
"'"));
9874 if (JSON_HEDLEY_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
9882 case token_type::literal_false:
9884 if (JSON_HEDLEY_UNLIKELY(not sax->boolean(
false)))
9891 case token_type::literal_null:
9893 if (JSON_HEDLEY_UNLIKELY(not sax->null()))
9900 case token_type::literal_true:
9902 if (JSON_HEDLEY_UNLIKELY(not sax->boolean(
true)))
9909 case token_type::value_integer:
9911 if (JSON_HEDLEY_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
9918 case token_type::value_string:
9920 if (JSON_HEDLEY_UNLIKELY(not sax->string(m_lexer.get_string())))
9927 case token_type::value_unsigned:
9929 if (JSON_HEDLEY_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
9936 case token_type::parse_error:
9939 return sax->parse_error(m_lexer.get_position(),
9940 m_lexer.get_token_string(),
9941 parse_error::create(101, m_lexer.get_position(),
9942 exception_message(token_type::uninitialized,
"value")));
9947 return sax->parse_error(m_lexer.get_position(),
9948 m_lexer.get_token_string(),
9949 parse_error::create(101, m_lexer.get_position(),
9950 exception_message(token_type::literal_or_value,
"value")));
9956 skip_to_state_evaluation =
false;
9969 if (get_token() == token_type::value_separator)
9977 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
9979 if (JSON_HEDLEY_UNLIKELY(not sax->end_array()))
9988 assert(not states.empty());
9990 skip_to_state_evaluation =
true;
9994 return sax->parse_error(m_lexer.get_position(),
9995 m_lexer.get_token_string(),
9996 parse_error::create(101, m_lexer.get_position(),
9997 exception_message(token_type::end_array,
"array")));
10002 if (get_token() == token_type::value_separator)
10005 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
10007 return sax->parse_error(m_lexer.get_position(),
10008 m_lexer.get_token_string(),
10009 parse_error::create(101, m_lexer.get_position(),
10010 exception_message(token_type::value_string,
"object key")));
10013 if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
10019 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10021 return sax->parse_error(m_lexer.get_position(),
10022 m_lexer.get_token_string(),
10023 parse_error::create(101, m_lexer.get_position(),
10024 exception_message(token_type::name_separator,
"object separator")));
10033 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
10035 if (JSON_HEDLEY_UNLIKELY(not sax->end_object()))
10044 assert(not states.empty());
10046 skip_to_state_evaluation =
true;
10050 return sax->parse_error(m_lexer.get_position(),
10051 m_lexer.get_token_string(),
10052 parse_error::create(101, m_lexer.get_position(),
10053 exception_message(token_type::end_object,
"object")));
10059 token_type get_token()
10061 return last_token = m_lexer.scan();
10064 std::string exception_message(
const token_type expected,
const std::string& context)
10066 std::string error_msg =
"syntax error ";
10068 if (not context.empty())
10070 error_msg +=
"while parsing " + context +
" ";
10075 if (last_token == token_type::parse_error)
10077 error_msg += std::string(m_lexer.get_error_message()) +
"; last read: '" +
10078 m_lexer.get_token_string() +
"'";
10082 error_msg +=
"unexpected " + std::string(lexer_t::token_type_name(last_token));
10085 if (expected != token_type::uninitialized)
10087 error_msg +=
"; expected " + std::string(lexer_t::token_type_name(expected));
10095 const parser_callback_t<BasicJsonType> callback =
nullptr;
10097 token_type last_token = token_type::uninitialized;
10101 const bool allow_exceptions =
true;
10128 class primitive_iterator_t
10131 using difference_type = std::ptrdiff_t;
10132 static constexpr difference_type begin_value = 0;
10133 static constexpr difference_type end_value = begin_value + 1;
10136 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
10139 constexpr difference_type get_value() const noexcept
10145 void set_begin() noexcept
10147 m_it = begin_value;
10151 void set_end() noexcept
10157 constexpr
bool is_begin() const noexcept
10159 return m_it == begin_value;
10163 constexpr
bool is_end() const noexcept
10165 return m_it == end_value;
10168 friend constexpr
bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10170 return lhs.m_it == rhs.m_it;
10173 friend constexpr
bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10175 return lhs.m_it < rhs.m_it;
10178 primitive_iterator_t operator+(difference_type n) noexcept
10180 auto result = *
this;
10185 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10187 return lhs.m_it - rhs.m_it;
10190 primitive_iterator_t& operator++() noexcept
10196 primitive_iterator_t
const operator++(
int) noexcept
10198 auto result = *
this;
10203 primitive_iterator_t& operator--() noexcept
10209 primitive_iterator_t
const operator--(
int) noexcept
10211 auto result = *
this;
10216 primitive_iterator_t& operator+=(difference_type n) noexcept
10222 primitive_iterator_t& operator-=(difference_type n) noexcept
10242 template<
typename BasicJsonType>
struct internal_iterator
10245 typename BasicJsonType::object_t::iterator object_iterator {};
10247 typename BasicJsonType::array_t::iterator array_iterator {};
10249 typename BasicJsonType::binary_t::container_type::iterator binary_iterator {};
10251 primitive_iterator_t primitive_iterator {};
10259 #include <iterator>
10260 #include <type_traits>
10284 template<
typename IteratorType>
class iteration_proxy;
10285 template<
typename IteratorType>
class iteration_proxy_value;
10303 template<
typename BasicJsonType>
10307 friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value,
typename std::remove_const<BasicJsonType>::type,
const BasicJsonType>::type>;
10308 friend BasicJsonType;
10309 friend iteration_proxy<iter_impl>;
10310 friend iteration_proxy_value<iter_impl>;
10312 using object_t =
typename BasicJsonType::object_t;
10313 using array_t =
typename BasicJsonType::array_t;
10315 static_assert(is_basic_json<
typename std::remove_const<BasicJsonType>::type>::value,
10316 "iter_impl only accepts (const) basic_json");
10325 using iterator_category = std::bidirectional_iterator_tag;
10328 using value_type =
typename BasicJsonType::value_type;
10330 using difference_type =
typename BasicJsonType::difference_type;
10332 using pointer =
typename std::conditional<std::is_const<BasicJsonType>::value,
10333 typename BasicJsonType::const_pointer,
10334 typename BasicJsonType::pointer>::type;
10337 typename std::conditional<std::is_const<BasicJsonType>::value,
10338 typename BasicJsonType::const_reference,
10339 typename BasicJsonType::reference>::type;
10342 iter_impl() =
default;
10350 explicit iter_impl(pointer
object) noexcept : m_object(
object)
10352 assert(m_object !=
nullptr);
10354 switch (m_object->m_type)
10356 case value_t::object:
10358 m_it.object_iterator =
typename object_t::iterator();
10362 case value_t::array:
10364 m_it.array_iterator =
typename array_t::iterator();
10370 m_it.primitive_iterator = primitive_iterator_t();
10392 iter_impl(
const iter_impl<const BasicJsonType>& other) noexcept
10393 : m_object(other.m_object), m_it(other.m_it)
10402 iter_impl& operator=(
const iter_impl<const BasicJsonType>& other) noexcept
10404 m_object = other.m_object;
10414 iter_impl(
const iter_impl<
typename std::remove_const<BasicJsonType>::type>& other) noexcept
10415 : m_object(other.m_object), m_it(other.m_it)
10424 iter_impl& operator=(
const iter_impl<
typename std::remove_const<BasicJsonType>::type>& other) noexcept
10426 m_object = other.m_object;
10436 void set_begin() noexcept
10438 assert(m_object !=
nullptr);
10440 switch (m_object->m_type)
10442 case value_t::object:
10444 m_it.object_iterator = m_object->m_value.object->begin();
10448 case value_t::array:
10450 m_it.array_iterator = m_object->m_value.array->begin();
10454 case value_t::null:
10457 m_it.primitive_iterator.set_end();
10463 m_it.primitive_iterator.set_begin();
10473 void set_end() noexcept
10475 assert(m_object !=
nullptr);
10477 switch (m_object->m_type)
10479 case value_t::object:
10481 m_it.object_iterator = m_object->m_value.object->end();
10485 case value_t::array:
10487 m_it.array_iterator = m_object->m_value.array->end();
10493 m_it.primitive_iterator.set_end();
10504 reference operator*()
const
10506 assert(m_object !=
nullptr);
10508 switch (m_object->m_type)
10510 case value_t::object:
10512 assert(m_it.object_iterator != m_object->m_value.object->end());
10513 return m_it.object_iterator->second;
10516 case value_t::array:
10518 assert(m_it.array_iterator != m_object->m_value.array->end());
10519 return *m_it.array_iterator;
10522 case value_t::null:
10523 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
10527 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
10532 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
10541 pointer operator->()
const
10543 assert(m_object !=
nullptr);
10545 switch (m_object->m_type)
10547 case value_t::object:
10549 assert(m_it.object_iterator != m_object->m_value.object->end());
10550 return &(m_it.object_iterator->second);
10553 case value_t::array:
10555 assert(m_it.array_iterator != m_object->m_value.array->end());
10556 return &*m_it.array_iterator;
10561 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
10566 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
10575 iter_impl
const operator++(
int)
10577 auto result = *
this;
10586 iter_impl& operator++()
10588 assert(m_object !=
nullptr);
10590 switch (m_object->m_type)
10592 case value_t::object:
10594 std::advance(m_it.object_iterator, 1);
10598 case value_t::array:
10600 std::advance(m_it.array_iterator, 1);
10606 ++m_it.primitive_iterator;
10618 iter_impl
const operator--(
int)
10620 auto result = *
this;
10629 iter_impl& operator--()
10631 assert(m_object !=
nullptr);
10633 switch (m_object->m_type)
10635 case value_t::object:
10637 std::advance(m_it.object_iterator, -1);
10641 case value_t::array:
10643 std::advance(m_it.array_iterator, -1);
10649 --m_it.primitive_iterator;
10661 bool operator==(
const iter_impl& other)
const
10664 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
10666 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
10669 assert(m_object !=
nullptr);
10671 switch (m_object->m_type)
10673 case value_t::object:
10674 return (m_it.object_iterator == other.m_it.object_iterator);
10676 case value_t::array:
10677 return (m_it.array_iterator == other.m_it.array_iterator);
10680 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
10688 bool operator!=(
const iter_impl& other)
const
10690 return not operator==(other);
10697 bool operator<(
const iter_impl& other)
const
10700 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
10702 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
10705 assert(m_object !=
nullptr);
10707 switch (m_object->m_type)
10709 case value_t::object:
10710 JSON_THROW(invalid_iterator::create(213,
"cannot compare order of object iterators"));
10712 case value_t::array:
10713 return (m_it.array_iterator < other.m_it.array_iterator);
10716 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
10724 bool operator<=(
const iter_impl& other)
const
10726 return not other.operator < (*this);
10733 bool operator>(
const iter_impl& other)
const
10735 return not operator<=(other);
10742 bool operator>=(
const iter_impl& other)
const
10744 return not operator<(other);
10751 iter_impl& operator+=(difference_type i)
10753 assert(m_object !=
nullptr);
10755 switch (m_object->m_type)
10757 case value_t::object:
10758 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
10760 case value_t::array:
10762 std::advance(m_it.array_iterator, i);
10768 m_it.primitive_iterator += i;
10780 iter_impl& operator-=(difference_type i)
10782 return operator+=(-i);
10789 iter_impl operator+(difference_type i)
const
10791 auto result = *
this;
10800 friend iter_impl operator+(difference_type i,
const iter_impl& it)
10811 iter_impl operator-(difference_type i)
const
10813 auto result = *
this;
10822 difference_type operator-(
const iter_impl& other)
const
10824 assert(m_object !=
nullptr);
10826 switch (m_object->m_type)
10828 case value_t::object:
10829 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
10831 case value_t::array:
10832 return m_it.array_iterator - other.m_it.array_iterator;
10835 return m_it.primitive_iterator - other.m_it.primitive_iterator;
10843 reference operator[](difference_type n)
const
10845 assert(m_object !=
nullptr);
10847 switch (m_object->m_type)
10849 case value_t::object:
10850 JSON_THROW(invalid_iterator::create(208,
"cannot use operator[] for object iterators"));
10852 case value_t::array:
10853 return *std::next(m_it.array_iterator, n);
10855 case value_t::null:
10856 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
10860 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
10865 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
10874 const typename object_t::key_type& key()
const
10876 assert(m_object !=
nullptr);
10878 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
10880 return m_it.object_iterator->first;
10883 JSON_THROW(invalid_iterator::create(207,
"cannot use key() for non-object iterators"));
10890 reference value()
const
10892 return operator*();
10897 pointer m_object =
nullptr;
10899 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
10910 #include <iterator>
10939 template<
typename Base>
10940 class json_reverse_iterator :
public std::reverse_iterator<Base>
10943 using difference_type = std::ptrdiff_t;
10945 using base_iterator = std::reverse_iterator<Base>;
10947 using reference =
typename Base::reference;
10950 explicit json_reverse_iterator(
const typename base_iterator::iterator_type& it) noexcept
10951 : base_iterator(it) {}
10954 explicit json_reverse_iterator(
const base_iterator& it) noexcept : base_iterator(it) {}
10957 json_reverse_iterator
const operator++(
int)
10959 return static_cast<json_reverse_iterator
>(base_iterator::operator++(1));
10963 json_reverse_iterator& operator++()
10965 return static_cast<json_reverse_iterator&
>(base_iterator::operator++());
10969 json_reverse_iterator
const operator--(
int)
10971 return static_cast<json_reverse_iterator
>(base_iterator::operator--(1));
10975 json_reverse_iterator& operator--()
10977 return static_cast<json_reverse_iterator&
>(base_iterator::operator--());
10981 json_reverse_iterator& operator+=(difference_type i)
10983 return static_cast<json_reverse_iterator&
>(base_iterator::operator+=(i));
10987 json_reverse_iterator operator+(difference_type i)
const
10989 return static_cast<json_reverse_iterator
>(base_iterator::operator+(i));
10993 json_reverse_iterator operator-(difference_type i)
const
10995 return static_cast<json_reverse_iterator
>(base_iterator::operator-(i));
10999 difference_type operator-(
const json_reverse_iterator& other)
const
11001 return base_iterator(*
this) - base_iterator(other);
11005 reference operator[](difference_type n)
const
11007 return *(this->operator+(n));
11011 auto key() const -> decltype(std::declval<Base>().key())
11013 auto it = --this->base();
11018 reference value()
const
11020 auto it = --this->base();
11021 return it.operator * ();
11032 #include <algorithm>
11049 template<
typename BasicJsonType>
11053 NLOHMANN_BASIC_JSON_TPL_DECLARATION
11079 : reference_tokens(split(s))
11098 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
11100 [](
const std::string & a,
const std::string & b)
11102 return a +
"/" + escape(b);
11107 operator std::string()
const
11130 reference_tokens.insert(reference_tokens.end(),
11131 ptr.reference_tokens.begin(),
11132 ptr.reference_tokens.end());
11176 return *
this /= std::to_string(array_idx);
11280 if (JSON_HEDLEY_UNLIKELY(
empty()))
11282 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
11285 reference_tokens.pop_back();
11304 if (JSON_HEDLEY_UNLIKELY(
empty()))
11306 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
11309 return reference_tokens.back();
11326 reference_tokens.push_back(token);
11332 reference_tokens.push_back(std::move(token));
11351 return reference_tokens.empty();
11362 static int array_index(
const std::string& s)
11365 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 and s[0] ==
'0'))
11367 JSON_THROW(detail::parse_error::create(106, 0,
11368 "array index '" + s +
11369 "' must not begin with '0'"));
11373 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 and not (s[0] >=
'1' and s[0] <=
'9')))
11375 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + s +
"' is not a number"));
11378 std::size_t processed_chars = 0;
11382 res = std::stoi(s, &processed_chars);
11384 JSON_CATCH(std::out_of_range&)
11386 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + s +
"'"));
11390 if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
11392 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + s +
"'"));
11400 if (JSON_HEDLEY_UNLIKELY(
empty()))
11402 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
11406 result.reference_tokens = {reference_tokens[0]};
11418 BasicJsonType& get_and_create(BasicJsonType& j)
const
11420 using size_type =
typename BasicJsonType::size_type;
11425 for (
const auto& reference_token : reference_tokens)
11427 switch (result->type())
11429 case detail::value_t::null:
11431 if (reference_token ==
"0")
11434 result = &result->operator[](0);
11439 result = &result->operator[](reference_token);
11444 case detail::value_t::object:
11447 result = &result->operator[](reference_token);
11451 case detail::value_t::array:
11454 result = &result->operator[](
static_cast<size_type
>(array_index(reference_token)));
11465 JSON_THROW(detail::type_error::create(313,
"invalid value to unflatten"));
11491 BasicJsonType& get_unchecked(BasicJsonType* ptr)
const
11493 using size_type =
typename BasicJsonType::size_type;
11494 for (
const auto& reference_token : reference_tokens)
11497 if (ptr->is_null())
11501 std::all_of(reference_token.begin(), reference_token.end(),
11502 [](
const unsigned char x)
11504 return std::isdigit(x);
11508 *ptr = (nums or reference_token ==
"-")
11509 ? detail::value_t::array
11510 : detail::value_t::object;
11513 switch (ptr->type())
11515 case detail::value_t::object:
11518 ptr = &ptr->operator[](reference_token);
11522 case detail::value_t::array:
11524 if (reference_token ==
"-")
11527 ptr = &ptr->operator[](ptr->m_value.array->size());
11532 ptr = &ptr->operator[](
11533 static_cast<size_type
>(array_index(reference_token)));
11539 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
11552 BasicJsonType& get_checked(BasicJsonType* ptr)
const
11554 using size_type =
typename BasicJsonType::size_type;
11555 for (
const auto& reference_token : reference_tokens)
11557 switch (ptr->type())
11559 case detail::value_t::object:
11562 ptr = &ptr->at(reference_token);
11566 case detail::value_t::array:
11568 if (JSON_HEDLEY_UNLIKELY(reference_token ==
"-"))
11571 JSON_THROW(detail::out_of_range::create(402,
11572 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
11573 ") is out of range"));
11577 ptr = &ptr->at(
static_cast<size_type
>(array_index(reference_token)));
11582 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
11602 const BasicJsonType& get_unchecked(
const BasicJsonType* ptr)
const
11604 using size_type =
typename BasicJsonType::size_type;
11605 for (
const auto& reference_token : reference_tokens)
11607 switch (ptr->type())
11609 case detail::value_t::object:
11612 ptr = &ptr->operator[](reference_token);
11616 case detail::value_t::array:
11618 if (JSON_HEDLEY_UNLIKELY(reference_token ==
"-"))
11621 JSON_THROW(detail::out_of_range::create(402,
11622 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
11623 ") is out of range"));
11627 ptr = &ptr->operator[](
11628 static_cast<size_type
>(array_index(reference_token)));
11633 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
11646 const BasicJsonType& get_checked(
const BasicJsonType* ptr)
const
11648 using size_type =
typename BasicJsonType::size_type;
11649 for (
const auto& reference_token : reference_tokens)
11651 switch (ptr->type())
11653 case detail::value_t::object:
11656 ptr = &ptr->at(reference_token);
11660 case detail::value_t::array:
11662 if (JSON_HEDLEY_UNLIKELY(reference_token ==
"-"))
11665 JSON_THROW(detail::out_of_range::create(402,
11666 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
11667 ") is out of range"));
11671 ptr = &ptr->at(
static_cast<size_type
>(array_index(reference_token)));
11676 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
11687 bool contains(
const BasicJsonType* ptr)
const
11689 using size_type =
typename BasicJsonType::size_type;
11690 for (
const auto& reference_token : reference_tokens)
11692 switch (ptr->type())
11694 case detail::value_t::object:
11696 if (not ptr->contains(reference_token))
11702 ptr = &ptr->operator[](reference_token);
11706 case detail::value_t::array:
11708 if (JSON_HEDLEY_UNLIKELY(reference_token ==
"-"))
11713 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 and not (
"0" <= reference_token and reference_token <=
"9")))
11718 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
11720 if (JSON_HEDLEY_UNLIKELY(not (
'1' <= reference_token[0] and reference_token[0] <=
'9')))
11725 for (std::size_t i = 1; i < reference_token.size(); i++)
11727 if (JSON_HEDLEY_UNLIKELY(not (
'0' <= reference_token[i] and reference_token[i] <=
'9')))
11735 const auto idx =
static_cast<size_type
>(array_index(reference_token));
11736 if (idx >= ptr->size())
11742 ptr = &ptr->operator[](idx);
11768 static std::vector<std::string> split(
const std::string& reference_string)
11770 std::vector<std::string> result;
11773 if (reference_string.empty())
11779 if (JSON_HEDLEY_UNLIKELY(reference_string[0] !=
'/'))
11781 JSON_THROW(detail::parse_error::create(107, 1,
11782 "JSON pointer must be empty or begin with '/' - was: '" +
11783 reference_string +
"'"));
11791 std::size_t slash = reference_string.find_first_of(
'/', 1),
11798 start = (slash == std::string::npos) ? 0 : slash + 1,
11800 slash = reference_string.find_first_of(
'/', start))
11804 auto reference_token = reference_string.substr(start, slash - start);
11807 for (std::size_t pos = reference_token.find_first_of(
'~');
11808 pos != std::string::npos;
11809 pos = reference_token.find_first_of(
'~', pos + 1))
11811 assert(reference_token[pos] ==
'~');
11814 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 or
11815 (reference_token[pos + 1] !=
'0' and
11816 reference_token[pos + 1] !=
'1')))
11818 JSON_THROW(detail::parse_error::create(108, 0,
"escape character '~' must be followed with '0' or '1'"));
11823 unescape(reference_token);
11824 result.push_back(reference_token);
11843 static void replace_substring(std::string& s,
const std::string& f,
11844 const std::string& t)
11846 assert(not f.empty());
11847 for (
auto pos = s.find(f);
11848 pos != std::string::npos;
11849 s.replace(pos, f.size(), t),
11850 pos = s.find(f, pos + t.size()))
11855 static std::string escape(std::string s)
11857 replace_substring(s,
"~",
"~0");
11858 replace_substring(s,
"/",
"~1");
11863 static void unescape(std::string& s)
11865 replace_substring(s,
"~1",
"/");
11866 replace_substring(s,
"~0",
"~");
11876 static void flatten(
const std::string& reference_string,
11877 const BasicJsonType& value,
11878 BasicJsonType& result)
11880 switch (value.type())
11882 case detail::value_t::array:
11884 if (value.m_value.array->empty())
11887 result[reference_string] =
nullptr;
11892 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
11894 flatten(reference_string +
"/" + std::to_string(i),
11895 value.m_value.array->operator[](i), result);
11901 case detail::value_t::object:
11903 if (value.m_value.object->empty())
11906 result[reference_string] =
nullptr;
11911 for (
const auto& element : *value.m_value.object)
11913 flatten(reference_string +
"/" + escape(element.first), element.second, result);
11922 result[reference_string] = value;
11938 static BasicJsonType
11939 unflatten(
const BasicJsonType& value)
11941 if (JSON_HEDLEY_UNLIKELY(not value.is_object()))
11943 JSON_THROW(detail::type_error::create(314,
"only objects can be unflattened"));
11946 BasicJsonType result;
11949 for (
const auto& element : *value.m_value.object)
11951 if (JSON_HEDLEY_UNLIKELY(not element.second.is_primitive()))
11953 JSON_THROW(detail::type_error::create(315,
"values in object must be primitive"));
11960 json_pointer(element.first).get_and_create(result) = element.second;
11980 return lhs.reference_tokens == rhs.reference_tokens;
11997 return not (lhs == rhs);
12001 std::vector<std::string> reference_tokens;
12008 #include <initializer_list>
12018 template<
typename BasicJsonType>
12022 using value_type = BasicJsonType;
12024 json_ref(value_type&& value)
12025 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
12028 json_ref(
const value_type& value)
12029 : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
12032 json_ref(std::initializer_list<json_ref> init)
12033 : owned_value(init), value_ref(&owned_value), is_rvalue(true)
12038 enable_if_t<std::is_constructible<value_type, Args...>::value,
int> = 0 >
12039 json_ref(Args && ... args)
12040 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value),
12044 json_ref(json_ref&&) =
default;
12045 json_ref(
const json_ref&) =
delete;
12046 json_ref& operator=(
const json_ref&) =
delete;
12047 json_ref& operator=(json_ref&&) =
delete;
12048 ~json_ref() =
default;
12050 value_type moved_or_copied()
const
12054 return std::move(*value_ref);
12059 value_type
const& operator*()
const
12061 return *
static_cast<value_type const*
>(value_ref);
12064 value_type
const* operator->()
const
12066 return static_cast<value_type const*
>(value_ref);
12070 mutable value_type owned_value =
nullptr;
12071 value_type* value_ref =
nullptr;
12072 const bool is_rvalue;
12086 #include <algorithm>
12101 #include <algorithm>
12104 #include <iterator>
12117 template<
typename CharType>
struct output_adapter_protocol
12119 virtual void write_character(CharType c) = 0;
12120 virtual void write_characters(
const CharType* s, std::size_t length) = 0;
12121 virtual ~output_adapter_protocol() =
default;
12125 template<
typename CharType>
12126 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
12129 template<
typename CharType>
12130 class output_vector_adapter :
public output_adapter_protocol<CharType>
12133 explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
12137 void write_character(CharType c)
override
12142 JSON_HEDLEY_NON_NULL(2)
12143 void write_characters(const CharType* s, std::
size_t length)
override
12145 std::copy(s, s + length, std::back_inserter(v));
12149 std::vector<CharType>& v;
12153 template<
typename CharType>
12154 class output_stream_adapter :
public output_adapter_protocol<CharType>
12157 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
12161 void write_character(CharType c)
override
12166 JSON_HEDLEY_NON_NULL(2)
12167 void write_characters(const CharType* s, std::
size_t length)
override
12169 stream.write(s,
static_cast<std::streamsize
>(length));
12173 std::basic_ostream<CharType>& stream;
12177 template<
typename CharType,
typename StringType = std::basic_
string<CharType>>
12178 class output_string_adapter :
public output_adapter_protocol<CharType>
12181 explicit output_string_adapter(StringType& s) noexcept
12185 void write_character(CharType c)
override
12190 JSON_HEDLEY_NON_NULL(2)
12191 void write_characters(const CharType* s, std::
size_t length)
override
12193 str.append(s, length);
12200 template<
typename CharType,
typename StringType = std::basic_
string<CharType>>
12201 class output_adapter
12204 output_adapter(std::vector<CharType>& vec)
12205 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
12207 output_adapter(std::basic_ostream<CharType>& s)
12208 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
12210 output_adapter(StringType& s)
12211 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
12213 operator output_adapter_t<CharType>()
12219 output_adapter_t<CharType> oa =
nullptr;
12236 template<
typename BasicJsonType,
typename CharType>
12237 class binary_writer
12239 using string_t =
typename BasicJsonType::string_t;
12240 using binary_t =
typename BasicJsonType::binary_t;
12248 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
12257 void write_bson(
const BasicJsonType& j)
12261 case value_t::object:
12263 write_bson_object(*j.m_value.object);
12269 JSON_THROW(type_error::create(317,
"to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
12277 void write_cbor(
const BasicJsonType& j)
12281 case value_t::null:
12283 oa->write_character(to_char_type(0xF6));
12287 case value_t::boolean:
12289 oa->write_character(j.m_value.boolean
12290 ? to_char_type(0xF5)
12291 : to_char_type(0xF4));
12295 case value_t::number_integer:
12297 if (j.m_value.number_integer >= 0)
12302 if (j.m_value.number_integer <= 0x17)
12304 write_number(
static_cast<std::uint8_t
>(j.m_value.number_integer));
12306 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
12308 oa->write_character(to_char_type(0x18));
12309 write_number(
static_cast<std::uint8_t
>(j.m_value.number_integer));
12311 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
12313 oa->write_character(to_char_type(0x19));
12314 write_number(
static_cast<std::uint16_t
>(j.m_value.number_integer));
12316 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
12318 oa->write_character(to_char_type(0x1A));
12319 write_number(
static_cast<std::uint32_t
>(j.m_value.number_integer));
12323 oa->write_character(to_char_type(0x1B));
12324 write_number(
static_cast<std::uint64_t
>(j.m_value.number_integer));
12331 const auto positive_number = -1 - j.m_value.number_integer;
12332 if (j.m_value.number_integer >= -24)
12334 write_number(
static_cast<std::uint8_t
>(0x20 + positive_number));
12336 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
12338 oa->write_character(to_char_type(0x38));
12339 write_number(
static_cast<std::uint8_t
>(positive_number));
12341 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
12343 oa->write_character(to_char_type(0x39));
12344 write_number(
static_cast<std::uint16_t
>(positive_number));
12346 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
12348 oa->write_character(to_char_type(0x3A));
12349 write_number(
static_cast<std::uint32_t
>(positive_number));
12353 oa->write_character(to_char_type(0x3B));
12354 write_number(
static_cast<std::uint64_t
>(positive_number));
12360 case value_t::number_unsigned:
12362 if (j.m_value.number_unsigned <= 0x17)
12364 write_number(
static_cast<std::uint8_t
>(j.m_value.number_unsigned));
12366 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12368 oa->write_character(to_char_type(0x18));
12369 write_number(
static_cast<std::uint8_t
>(j.m_value.number_unsigned));
12371 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12373 oa->write_character(to_char_type(0x19));
12374 write_number(
static_cast<std::uint16_t
>(j.m_value.number_unsigned));
12376 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12378 oa->write_character(to_char_type(0x1A));
12379 write_number(
static_cast<std::uint32_t
>(j.m_value.number_unsigned));
12383 oa->write_character(to_char_type(0x1B));
12384 write_number(
static_cast<std::uint64_t
>(j.m_value.number_unsigned));
12389 case value_t::number_float:
12391 if (std::isnan(j.m_value.number_float))
12394 oa->write_character(to_char_type(0xF9));
12395 oa->write_character(to_char_type(0x7E));
12396 oa->write_character(to_char_type(0x00));
12398 else if (std::isinf(j.m_value.number_float))
12401 oa->write_character(to_char_type(0xf9));
12402 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
12403 oa->write_character(to_char_type(0x00));
12407 if (
static_cast<double>(j.m_value.number_float) >=
static_cast<double>(std::numeric_limits<float>::lowest()) and
12408 static_cast<double>(j.m_value.number_float) <=
static_cast<double>((std::numeric_limits<float>::max)()) and
12409 static_cast<double>(
static_cast<float>(j.m_value.number_float)) ==
static_cast<double>(j.m_value.number_float))
12411 oa->write_character(get_cbor_float_prefix(
static_cast<float>(j.m_value.number_float)));
12412 write_number(
static_cast<float>(j.m_value.number_float));
12416 oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
12417 write_number(j.m_value.number_float);
12423 case value_t::string:
12426 const auto N = j.m_value.string->size();
12429 write_number(
static_cast<std::uint8_t
>(0x60 + N));
12431 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12433 oa->write_character(to_char_type(0x78));
12434 write_number(
static_cast<std::uint8_t
>(N));
12436 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12438 oa->write_character(to_char_type(0x79));
12439 write_number(
static_cast<std::uint16_t
>(N));
12441 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12443 oa->write_character(to_char_type(0x7A));
12444 write_number(
static_cast<std::uint32_t
>(N));
12447 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12449 oa->write_character(to_char_type(0x7B));
12450 write_number(
static_cast<std::uint64_t
>(N));
12455 oa->write_characters(
12456 reinterpret_cast<const CharType*
>(j.m_value.string->c_str()),
12457 j.m_value.string->size());
12461 case value_t::array:
12464 const auto N = j.m_value.array->size();
12467 write_number(
static_cast<std::uint8_t
>(0x80 + N));
12469 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12471 oa->write_character(to_char_type(0x98));
12472 write_number(
static_cast<std::uint8_t
>(N));
12474 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12476 oa->write_character(to_char_type(0x99));
12477 write_number(
static_cast<std::uint16_t
>(N));
12479 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12481 oa->write_character(to_char_type(0x9A));
12482 write_number(
static_cast<std::uint32_t
>(N));
12485 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12487 oa->write_character(to_char_type(0x9B));
12488 write_number(
static_cast<std::uint64_t
>(N));
12493 for (
const auto& el : *j.m_value.array)
12500 case value_t::binary:
12503 const auto N = j.m_value.binary->size();
12506 write_number(
static_cast<std::uint8_t
>(0x40 + N));
12508 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12510 oa->write_character(to_char_type(0x58));
12511 write_number(
static_cast<std::uint8_t
>(N));
12513 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12515 oa->write_character(to_char_type(0x59));
12516 write_number(
static_cast<std::uint16_t
>(N));
12518 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12520 oa->write_character(to_char_type(0x5A));
12521 write_number(
static_cast<std::uint32_t
>(N));
12524 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12526 oa->write_character(to_char_type(0x5B));
12527 write_number(
static_cast<std::uint64_t
>(N));
12532 oa->write_characters(
12533 reinterpret_cast<const CharType*
>(j.m_value.binary->data()),
12539 case value_t::object:
12542 const auto N = j.m_value.object->size();
12545 write_number(
static_cast<std::uint8_t
>(0xA0 + N));
12547 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12549 oa->write_character(to_char_type(0xB8));
12550 write_number(
static_cast<std::uint8_t
>(N));
12552 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12554 oa->write_character(to_char_type(0xB9));
12555 write_number(
static_cast<std::uint16_t
>(N));
12557 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12559 oa->write_character(to_char_type(0xBA));
12560 write_number(
static_cast<std::uint32_t
>(N));
12563 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12565 oa->write_character(to_char_type(0xBB));
12566 write_number(
static_cast<std::uint64_t
>(N));
12571 for (
const auto& el : *j.m_value.object)
12573 write_cbor(el.first);
12574 write_cbor(el.second);
12587 void write_msgpack(
const BasicJsonType& j)
12591 case value_t::null:
12593 oa->write_character(to_char_type(0xC0));
12597 case value_t::boolean:
12599 oa->write_character(j.m_value.boolean
12600 ? to_char_type(0xC3)
12601 : to_char_type(0xC2));
12605 case value_t::number_integer:
12607 if (j.m_value.number_integer >= 0)
12612 if (j.m_value.number_unsigned < 128)
12615 write_number(
static_cast<std::uint8_t
>(j.m_value.number_integer));
12617 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12620 oa->write_character(to_char_type(0xCC));
12621 write_number(
static_cast<std::uint8_t
>(j.m_value.number_integer));
12623 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12626 oa->write_character(to_char_type(0xCD));
12627 write_number(
static_cast<std::uint16_t
>(j.m_value.number_integer));
12629 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12632 oa->write_character(to_char_type(0xCE));
12633 write_number(
static_cast<std::uint32_t
>(j.m_value.number_integer));
12635 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
12638 oa->write_character(to_char_type(0xCF));
12639 write_number(
static_cast<std::uint64_t
>(j.m_value.number_integer));
12644 if (j.m_value.number_integer >= -32)
12647 write_number(
static_cast<std::int8_t
>(j.m_value.number_integer));
12649 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() and
12650 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
12653 oa->write_character(to_char_type(0xD0));
12654 write_number(
static_cast<std::int8_t
>(j.m_value.number_integer));
12656 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() and
12657 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
12660 oa->write_character(to_char_type(0xD1));
12661 write_number(
static_cast<std::int16_t
>(j.m_value.number_integer));
12663 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() and
12664 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
12667 oa->write_character(to_char_type(0xD2));
12668 write_number(
static_cast<std::int32_t
>(j.m_value.number_integer));
12670 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() and
12671 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
12674 oa->write_character(to_char_type(0xD3));
12675 write_number(
static_cast<std::int64_t
>(j.m_value.number_integer));
12681 case value_t::number_unsigned:
12683 if (j.m_value.number_unsigned < 128)
12686 write_number(
static_cast<std::uint8_t
>(j.m_value.number_integer));
12688 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12691 oa->write_character(to_char_type(0xCC));
12692 write_number(
static_cast<std::uint8_t
>(j.m_value.number_integer));
12694 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12697 oa->write_character(to_char_type(0xCD));
12698 write_number(
static_cast<std::uint16_t
>(j.m_value.number_integer));
12700 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12703 oa->write_character(to_char_type(0xCE));
12704 write_number(
static_cast<std::uint32_t
>(j.m_value.number_integer));
12706 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
12709 oa->write_character(to_char_type(0xCF));
12710 write_number(
static_cast<std::uint64_t
>(j.m_value.number_integer));
12715 case value_t::number_float:
12717 oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
12718 write_number(j.m_value.number_float);
12722 case value_t::string:
12725 const auto N = j.m_value.string->size();
12729 write_number(
static_cast<std::uint8_t
>(0xA0 | N));
12731 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12734 oa->write_character(to_char_type(0xD9));
12735 write_number(
static_cast<std::uint8_t
>(N));
12737 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12740 oa->write_character(to_char_type(0xDA));
12741 write_number(
static_cast<std::uint16_t
>(N));
12743 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12746 oa->write_character(to_char_type(0xDB));
12747 write_number(
static_cast<std::uint32_t
>(N));
12751 oa->write_characters(
12752 reinterpret_cast<const CharType*
>(j.m_value.string->c_str()),
12753 j.m_value.string->size());
12757 case value_t::array:
12760 const auto N = j.m_value.array->size();
12764 write_number(
static_cast<std::uint8_t
>(0x90 | N));
12766 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12769 oa->write_character(to_char_type(0xDC));
12770 write_number(
static_cast<std::uint16_t
>(N));
12772 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12775 oa->write_character(to_char_type(0xDD));
12776 write_number(
static_cast<std::uint32_t
>(N));
12780 for (
const auto& el : *j.m_value.array)
12787 case value_t::binary:
12791 const bool use_ext = j.m_value.binary->has_subtype();
12794 const auto N = j.m_value.binary->size();
12795 if (N <= (std::numeric_limits<std::uint8_t>::max)())
12797 std::uint8_t output_type;
12804 output_type = 0xD4;
12807 output_type = 0xD5;
12810 output_type = 0xD6;
12813 output_type = 0xD7;
12816 output_type = 0xD8;
12819 output_type = 0xC7;
12827 output_type = 0xC4;
12831 oa->write_character(to_char_type(output_type));
12834 write_number(
static_cast<std::uint8_t
>(N));
12837 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12839 std::uint8_t output_type;
12842 output_type = 0xC8;
12846 output_type = 0xC5;
12849 oa->write_character(to_char_type(output_type));
12850 write_number(
static_cast<std::uint16_t
>(N));
12852 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12854 std::uint8_t output_type;
12857 output_type = 0xC9;
12861 output_type = 0xC6;
12864 oa->write_character(to_char_type(output_type));
12865 write_number(
static_cast<std::uint32_t
>(N));
12871 write_number(
static_cast<std::int8_t
>(j.m_value.binary->subtype()));
12875 oa->write_characters(
12876 reinterpret_cast<const CharType*
>(j.m_value.binary->data()),
12882 case value_t::object:
12885 const auto N = j.m_value.object->size();
12889 write_number(
static_cast<std::uint8_t
>(0x80 | (N & 0xF)));
12891 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12894 oa->write_character(to_char_type(0xDE));
12895 write_number(
static_cast<std::uint16_t
>(N));
12897 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12900 oa->write_character(to_char_type(0xDF));
12901 write_number(
static_cast<std::uint32_t
>(N));
12905 for (
const auto& el : *j.m_value.object)
12907 write_msgpack(el.first);
12908 write_msgpack(el.second);
12924 void write_ubjson(
const BasicJsonType& j,
const bool use_count,
12925 const bool use_type,
const bool add_prefix =
true)
12929 case value_t::null:
12933 oa->write_character(to_char_type(
'Z'));
12938 case value_t::boolean:
12942 oa->write_character(j.m_value.boolean
12943 ? to_char_type(
'T')
12944 : to_char_type(
'F'));
12949 case value_t::number_integer:
12951 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
12955 case value_t::number_unsigned:
12957 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
12961 case value_t::number_float:
12963 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
12967 case value_t::string:
12971 oa->write_character(to_char_type(
'S'));
12973 write_number_with_ubjson_prefix(j.m_value.string->size(),
true);
12974 oa->write_characters(
12975 reinterpret_cast<const CharType*
>(j.m_value.string->c_str()),
12976 j.m_value.string->size());
12980 case value_t::array:
12984 oa->write_character(to_char_type(
'['));
12987 bool prefix_required =
true;
12988 if (use_type and not j.m_value.array->empty())
12991 const CharType first_prefix = ubjson_prefix(j.front());
12992 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
12993 [
this, first_prefix](
const BasicJsonType & v)
12995 return ubjson_prefix(v) == first_prefix;
13000 prefix_required =
false;
13001 oa->write_character(to_char_type(
'$'));
13002 oa->write_character(first_prefix);
13008 oa->write_character(to_char_type(
'#'));
13009 write_number_with_ubjson_prefix(j.m_value.array->size(),
true);
13012 for (
const auto& el : *j.m_value.array)
13014 write_ubjson(el, use_count, use_type, prefix_required);
13019 oa->write_character(to_char_type(
']'));
13025 case value_t::binary:
13029 oa->write_character(to_char_type(
'['));
13032 if (use_type and not j.m_value.binary->empty())
13035 oa->write_character(to_char_type(
'$'));
13036 oa->write_character(
'U');
13041 oa->write_character(to_char_type(
'#'));
13042 write_number_with_ubjson_prefix(j.m_value.binary->size(),
true);
13047 oa->write_characters(
13048 reinterpret_cast<const CharType*
>(j.m_value.binary->data()),
13049 j.m_value.binary->size());
13053 for (
size_t i = 0; i < j.m_value.binary->size(); ++i)
13055 oa->write_character(to_char_type(
'U'));
13056 oa->write_character(j.m_value.binary->data()[i]);
13062 oa->write_character(to_char_type(
']'));
13068 case value_t::object:
13072 oa->write_character(to_char_type(
'{'));
13075 bool prefix_required =
true;
13076 if (use_type and not j.m_value.object->empty())
13079 const CharType first_prefix = ubjson_prefix(j.front());
13080 const bool same_prefix = std::all_of(j.begin(), j.end(),
13081 [
this, first_prefix](
const BasicJsonType & v)
13083 return ubjson_prefix(v) == first_prefix;
13088 prefix_required =
false;
13089 oa->write_character(to_char_type(
'$'));
13090 oa->write_character(first_prefix);
13096 oa->write_character(to_char_type(
'#'));
13097 write_number_with_ubjson_prefix(j.m_value.object->size(),
true);
13100 for (
const auto& el : *j.m_value.object)
13102 write_number_with_ubjson_prefix(el.first.size(),
true);
13103 oa->write_characters(
13104 reinterpret_cast<const CharType*
>(el.first.c_str()),
13106 write_ubjson(el.second, use_count, use_type, prefix_required);
13111 oa->write_character(to_char_type(
'}'));
13131 static std::size_t calc_bson_entry_header_size(
const string_t& name)
13133 const auto it = name.find(
static_cast<typename string_t::value_type
>(0));
13134 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
13136 JSON_THROW(out_of_range::create(409,
13137 "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) +
")"));
13140 return 1ul + name.size() + 1u;
13146 void write_bson_entry_header(
const string_t& name,
13147 const std::uint8_t element_type)
13149 oa->write_character(to_char_type(element_type));
13150 oa->write_characters(
13151 reinterpret_cast<const CharType*
>(name.c_str()),
13158 void write_bson_boolean(
const string_t& name,
13161 write_bson_entry_header(name, 0x08);
13162 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
13168 void write_bson_double(
const string_t& name,
13169 const double value)
13171 write_bson_entry_header(name, 0x01);
13172 write_number<double, true>(value);
13178 static std::size_t calc_bson_string_size(
const string_t& value)
13180 return sizeof(std::int32_t) + value.size() + 1ul;
13186 void write_bson_string(
const string_t& name,
13187 const string_t& value)
13189 write_bson_entry_header(name, 0x02);
13191 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(value.size() + 1ul));
13192 oa->write_characters(
13193 reinterpret_cast<const CharType*
>(value.c_str()),
13200 void write_bson_null(
const string_t& name)
13202 write_bson_entry_header(name, 0x0A);
13208 static std::size_t calc_bson_integer_size(
const std::int64_t value)
13210 return (std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)()
13211 ?
sizeof(std::int32_t)
13212 :
sizeof(std::int64_t);
13218 void write_bson_integer(
const string_t& name,
13219 const std::int64_t value)
13221 if ((std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)())
13223 write_bson_entry_header(name, 0x10);
13224 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(value));
13228 write_bson_entry_header(name, 0x12);
13229 write_number<std::int64_t, true>(
static_cast<std::int64_t
>(value));
13236 static constexpr std::size_t calc_bson_unsigned_size(
const std::uint64_t value) noexcept
13238 return (value <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int32_t>::max)()))
13239 ?
sizeof(std::int32_t)
13240 :
sizeof(std::int64_t);
13246 void write_bson_unsigned(
const string_t& name,
13247 const std::uint64_t value)
13249 if (value <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int32_t>::max)()))
13251 write_bson_entry_header(name, 0x10 );
13252 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(value));
13254 else if (value <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int64_t>::max)()))
13256 write_bson_entry_header(name, 0x12 );
13257 write_number<std::int64_t, true>(
static_cast<std::int64_t
>(value));
13261 JSON_THROW(out_of_range::create(407,
"integer number " + std::to_string(value) +
" cannot be represented by BSON as it does not fit int64"));
13268 void write_bson_object_entry(
const string_t& name,
13269 const typename BasicJsonType::object_t& value)
13271 write_bson_entry_header(name, 0x03);
13272 write_bson_object(value);
13278 static std::size_t calc_bson_array_size(
const typename BasicJsonType::array_t& value)
13280 std::size_t array_index = 0ul;
13282 const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result,
const typename BasicJsonType::array_t::value_type & el)
13284 return result + calc_bson_element_size(std::to_string(array_index++), el);
13287 return sizeof(std::int32_t) + embedded_document_size + 1ul;
13293 static std::size_t calc_bson_binary_size(
const typename BasicJsonType::binary_t& value)
13295 return sizeof(std::int32_t) + value.size() + 1ul;
13301 void write_bson_array(
const string_t& name,
13302 const typename BasicJsonType::array_t& value)
13304 write_bson_entry_header(name, 0x04);
13305 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(calc_bson_array_size(value)));
13307 std::size_t array_index = 0ul;
13309 for (
const auto& el : value)
13311 write_bson_element(std::to_string(array_index++), el);
13314 oa->write_character(to_char_type(0x00));
13320 void write_bson_binary(
const string_t& name,
13321 const binary_t& value)
13323 write_bson_entry_header(name, 0x05);
13325 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(value.size()));
13326 write_number(value.has_subtype() ? value.subtype() : std::uint8_t(0x00));
13328 oa->write_characters(
reinterpret_cast<const CharType*
>(value.data()), value.size());
13335 static std::size_t calc_bson_element_size(
const string_t& name,
13336 const BasicJsonType& j)
13338 const auto header_size = calc_bson_entry_header_size(name);
13341 case value_t::object:
13342 return header_size + calc_bson_object_size(*j.m_value.object);
13344 case value_t::array:
13345 return header_size + calc_bson_array_size(*j.m_value.array);
13347 case value_t::binary:
13348 return header_size + calc_bson_binary_size(*j.m_value.binary);
13350 case value_t::boolean:
13351 return header_size + 1ul;
13353 case value_t::number_float:
13354 return header_size + 8ul;
13356 case value_t::number_integer:
13357 return header_size + calc_bson_integer_size(j.m_value.number_integer);
13359 case value_t::number_unsigned:
13360 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
13362 case value_t::string:
13363 return header_size + calc_bson_string_size(*j.m_value.string);
13365 case value_t::null:
13366 return header_size + 0ul;
13383 void write_bson_element(
const string_t& name,
13384 const BasicJsonType& j)
13388 case value_t::object:
13389 return write_bson_object_entry(name, *j.m_value.object);
13391 case value_t::array:
13392 return write_bson_array(name, *j.m_value.array);
13394 case value_t::binary:
13395 return write_bson_binary(name, *j.m_value.binary);
13397 case value_t::boolean:
13398 return write_bson_boolean(name, j.m_value.boolean);
13400 case value_t::number_float:
13401 return write_bson_double(name, j.m_value.number_float);
13403 case value_t::number_integer:
13404 return write_bson_integer(name, j.m_value.number_integer);
13406 case value_t::number_unsigned:
13407 return write_bson_unsigned(name, j.m_value.number_unsigned);
13409 case value_t::string:
13410 return write_bson_string(name, *j.m_value.string);
13412 case value_t::null:
13413 return write_bson_null(name);
13429 static std::size_t calc_bson_object_size(
const typename BasicJsonType::object_t& value)
13431 std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
13432 [](
size_t result,
const typename BasicJsonType::object_t::value_type & el)
13434 return result += calc_bson_element_size(el.first, el.second);
13437 return sizeof(std::int32_t) + document_size + 1ul;
13444 void write_bson_object(
const typename BasicJsonType::object_t& value)
13446 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(calc_bson_object_size(value)));
13448 for (
const auto& el : value)
13450 write_bson_element(el.first, el.second);
13453 oa->write_character(to_char_type(0x00));
13460 static constexpr CharType get_cbor_float_prefix(
float )
13462 return to_char_type(0xFA);
13465 static constexpr CharType get_cbor_float_prefix(
double )
13467 return to_char_type(0xFB);
13474 static constexpr CharType get_msgpack_float_prefix(
float )
13476 return to_char_type(0xCA);
13479 static constexpr CharType get_msgpack_float_prefix(
double )
13481 return to_char_type(0xCB);
13489 template<
typename NumberType,
typename std::enable_if<
13490 std::is_floating_point<NumberType>::value,
int>::type = 0>
13491 void write_number_with_ubjson_prefix(
const NumberType n,
13492 const bool add_prefix)
13496 oa->write_character(get_ubjson_float_prefix(n));
13502 template<
typename NumberType,
typename std::enable_if<
13503 std::is_unsigned<NumberType>::value,
int>::type = 0>
13504 void write_number_with_ubjson_prefix(
const NumberType n,
13505 const bool add_prefix)
13507 if (n <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int8_t>::max)()))
13511 oa->write_character(to_char_type(
'i'));
13513 write_number(
static_cast<std::uint8_t
>(n));
13515 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
13519 oa->write_character(to_char_type(
'U'));
13521 write_number(
static_cast<std::uint8_t
>(n));
13523 else if (n <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int16_t>::max)()))
13527 oa->write_character(to_char_type(
'I'));
13529 write_number(
static_cast<std::int16_t
>(n));
13531 else if (n <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int32_t>::max)()))
13535 oa->write_character(to_char_type(
'l'));
13537 write_number(
static_cast<std::int32_t
>(n));
13539 else if (n <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int64_t>::max)()))
13543 oa->write_character(to_char_type(
'L'));
13545 write_number(
static_cast<std::int64_t
>(n));
13549 JSON_THROW(out_of_range::create(407,
"integer number " + std::to_string(n) +
" cannot be represented by UBJSON as it does not fit int64"));
13554 template<
typename NumberType,
typename std::enable_if<
13555 std::is_signed<NumberType>::value and
13556 not std::is_floating_point<NumberType>::value,
int>::type = 0>
13557 void write_number_with_ubjson_prefix(
const NumberType n,
13558 const bool add_prefix)
13560 if ((std::numeric_limits<std::int8_t>::min)() <= n and n <= (std::numeric_limits<std::int8_t>::max)())
13564 oa->write_character(to_char_type(
'i'));
13566 write_number(
static_cast<std::int8_t
>(n));
13568 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)()))
13572 oa->write_character(to_char_type(
'U'));
13574 write_number(
static_cast<std::uint8_t
>(n));
13576 else if ((std::numeric_limits<std::int16_t>::min)() <= n and n <= (std::numeric_limits<std::int16_t>::max)())
13580 oa->write_character(to_char_type(
'I'));
13582 write_number(
static_cast<std::int16_t
>(n));
13584 else if ((std::numeric_limits<std::int32_t>::min)() <= n and n <= (std::numeric_limits<std::int32_t>::max)())
13588 oa->write_character(to_char_type(
'l'));
13590 write_number(
static_cast<std::int32_t
>(n));
13592 else if ((std::numeric_limits<std::int64_t>::min)() <= n and n <= (std::numeric_limits<std::int64_t>::max)())
13596 oa->write_character(to_char_type(
'L'));
13598 write_number(
static_cast<std::int64_t
>(n));
13603 JSON_THROW(out_of_range::create(407,
"integer number " + std::to_string(n) +
" cannot be represented by UBJSON as it does not fit int64"));
13617 CharType ubjson_prefix(
const BasicJsonType& j)
const noexcept
13621 case value_t::null:
13624 case value_t::boolean:
13625 return j.m_value.boolean ?
'T' :
'F';
13627 case value_t::number_integer:
13629 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)())
13633 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)())
13637 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)())
13641 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)())
13649 case value_t::number_unsigned:
13651 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int8_t>::max)()))
13655 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t
>((std::numeric_limits<std::uint8_t>::max)()))
13659 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int16_t>::max)()))
13663 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int32_t>::max)()))
13671 case value_t::number_float:
13672 return get_ubjson_float_prefix(j.m_value.number_float);
13674 case value_t::string:
13677 case value_t::array:
13678 case value_t::binary:
13681 case value_t::object:
13689 static constexpr CharType get_ubjson_float_prefix(
float )
13694 static constexpr CharType get_ubjson_float_prefix(
double )
13714 template<
typename NumberType,
bool OutputIsLittleEndian = false>
13715 void write_number(
const NumberType n)
13718 std::array<CharType,
sizeof(NumberType)> vec;
13719 std::memcpy(vec.data(), &n,
sizeof(NumberType));
13722 if (is_little_endian != OutputIsLittleEndian)
13725 std::reverse(vec.begin(), vec.end());
13728 oa->write_characters(vec.data(),
sizeof(NumberType));
13736 template <
typename C = CharType,
13737 enable_if_t < std::is_signed<C>::value and std::is_signed<char>::value > * =
nullptr >
13738 static constexpr CharType to_char_type(std::uint8_t x) noexcept
13740 return *
reinterpret_cast<char*
>(&x);
13743 template <
typename C = CharType,
13744 enable_if_t < std::is_signed<C>::value and std::is_unsigned<char>::value > * =
nullptr >
13745 static CharType to_char_type(std::uint8_t x) noexcept
13747 static_assert(
sizeof(std::uint8_t) ==
sizeof(CharType),
"size of CharType must be equal to std::uint8_t");
13748 static_assert(std::is_trivial<CharType>::value,
"CharType must be trivial");
13750 std::memcpy(&result, &x,
sizeof(x));
13754 template<
typename C = CharType,
13755 enable_if_t<std::is_unsigned<C>::value>* =
nullptr>
13756 static constexpr CharType to_char_type(std::uint8_t x) noexcept
13761 template <
typename InputCharType,
typename C = CharType,
13763 std::is_signed<C>::value and
13764 std::is_signed<char>::value and
13765 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
13767 static constexpr CharType to_char_type(InputCharType x) noexcept
13774 const bool is_little_endian = little_endianess();
13777 output_adapter_t<CharType> oa =
nullptr;
13787 #include <algorithm>
13797 #include <type_traits>
13811 #include <type_traits>
13842 namespace dtoa_impl
13845 template <
typename Target,
typename Source>
13846 Target reinterpret_bits(
const Source source)
13848 static_assert(
sizeof(Target) ==
sizeof(Source),
"size mismatch");
13851 std::memcpy(&target, &source,
sizeof(Source));
13857 static constexpr
int kPrecision = 64;
13859 std::uint64_t f = 0;
13862 constexpr diyfp(std::uint64_t f_,
int e_) noexcept : f(f_), e(e_) {}
13868 static diyfp sub(
const diyfp& x,
const diyfp& y) noexcept
13870 assert(x.e == y.e);
13871 assert(x.f >= y.f);
13873 return {x.f - y.f, x.e};
13880 static diyfp mul(
const diyfp& x,
const diyfp& y) noexcept
13882 static_assert(kPrecision == 64,
"internal error");
13907 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
13908 const std::uint64_t u_hi = x.f >> 32u;
13909 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
13910 const std::uint64_t v_hi = y.f >> 32u;
13912 const std::uint64_t p0 = u_lo * v_lo;
13913 const std::uint64_t p1 = u_lo * v_hi;
13914 const std::uint64_t p2 = u_hi * v_lo;
13915 const std::uint64_t p3 = u_hi * v_hi;
13917 const std::uint64_t p0_hi = p0 >> 32u;
13918 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
13919 const std::uint64_t p1_hi = p1 >> 32u;
13920 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
13921 const std::uint64_t p2_hi = p2 >> 32u;
13923 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
13934 Q += std::uint64_t{1} << (64u - 32u - 1u);
13936 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
13938 return {h, x.e + y.e + 64};
13945 static diyfp normalize(diyfp x) noexcept
13949 while ((x.f >> 63u) == 0)
13962 static diyfp normalize_to(
const diyfp& x,
const int target_exponent) noexcept
13964 const int delta = x.e - target_exponent;
13966 assert(delta >= 0);
13967 assert(((x.f << delta) >> delta) == x.f);
13969 return {x.f << delta, target_exponent};
13986 template <
typename FloatType>
13987 boundaries compute_boundaries(FloatType value)
13989 assert(std::isfinite(value));
13999 static_assert(std::numeric_limits<FloatType>::is_iec559,
14000 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
14002 constexpr
int kPrecision = std::numeric_limits<FloatType>::digits;
14003 constexpr
int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
14004 constexpr
int kMinExp = 1 - kBias;
14005 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1);
14007 using bits_type =
typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
14009 const std::uint64_t bits = reinterpret_bits<bits_type>(value);
14010 const std::uint64_t E = bits >> (kPrecision - 1);
14011 const std::uint64_t F = bits & (kHiddenBit - 1);
14013 const bool is_denormal = E == 0;
14014 const diyfp v = is_denormal
14015 ? diyfp(F, kMinExp)
14016 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
14039 const bool lower_boundary_is_closer = F == 0 and E > 1;
14040 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
14041 const diyfp m_minus = lower_boundary_is_closer
14042 ? diyfp(4 * v.f - 1, v.e - 2)
14043 : diyfp(2 * v.f - 1, v.e - 1);
14046 const diyfp w_plus = diyfp::normalize(m_plus);
14049 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
14051 return {diyfp::normalize(v), w_minus, w_plus};
14109 constexpr
int kAlpha = -60;
14110 constexpr
int kGamma = -32;
14112 struct cached_power
14126 inline cached_power get_cached_power_for_binary_exponent(
int e)
14178 constexpr
int kCachedPowersMinDecExp = -300;
14179 constexpr
int kCachedPowersDecStep = 8;
14181 static constexpr std::array<cached_power, 79> kCachedPowers =
14184 { 0xAB70FE17C79AC6CA, -1060, -300 },
14185 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
14186 { 0xBE5691EF416BD60C, -1007, -284 },
14187 { 0x8DD01FAD907FFC3C, -980, -276 },
14188 { 0xD3515C2831559A83, -954, -268 },
14189 { 0x9D71AC8FADA6C9B5, -927, -260 },
14190 { 0xEA9C227723EE8BCB, -901, -252 },
14191 { 0xAECC49914078536D, -874, -244 },
14192 { 0x823C12795DB6CE57, -847, -236 },
14193 { 0xC21094364DFB5637, -821, -228 },
14194 { 0x9096EA6F3848984F, -794, -220 },
14195 { 0xD77485CB25823AC7, -768, -212 },
14196 { 0xA086CFCD97BF97F4, -741, -204 },
14197 { 0xEF340A98172AACE5, -715, -196 },
14198 { 0xB23867FB2A35B28E, -688, -188 },
14199 { 0x84C8D4DFD2C63F3B, -661, -180 },
14200 { 0xC5DD44271AD3CDBA, -635, -172 },
14201 { 0x936B9FCEBB25C996, -608, -164 },
14202 { 0xDBAC6C247D62A584, -582, -156 },
14203 { 0xA3AB66580D5FDAF6, -555, -148 },
14204 { 0xF3E2F893DEC3F126, -529, -140 },
14205 { 0xB5B5ADA8AAFF80B8, -502, -132 },
14206 { 0x87625F056C7C4A8B, -475, -124 },
14207 { 0xC9BCFF6034C13053, -449, -116 },
14208 { 0x964E858C91BA2655, -422, -108 },
14209 { 0xDFF9772470297EBD, -396, -100 },
14210 { 0xA6DFBD9FB8E5B88F, -369, -92 },
14211 { 0xF8A95FCF88747D94, -343, -84 },
14212 { 0xB94470938FA89BCF, -316, -76 },
14213 { 0x8A08F0F8BF0F156B, -289, -68 },
14214 { 0xCDB02555653131B6, -263, -60 },
14215 { 0x993FE2C6D07B7FAC, -236, -52 },
14216 { 0xE45C10C42A2B3B06, -210, -44 },
14217 { 0xAA242499697392D3, -183, -36 },
14218 { 0xFD87B5F28300CA0E, -157, -28 },
14219 { 0xBCE5086492111AEB, -130, -20 },
14220 { 0x8CBCCC096F5088CC, -103, -12 },
14221 { 0xD1B71758E219652C, -77, -4 },
14222 { 0x9C40000000000000, -50, 4 },
14223 { 0xE8D4A51000000000, -24, 12 },
14224 { 0xAD78EBC5AC620000, 3, 20 },
14225 { 0x813F3978F8940984, 30, 28 },
14226 { 0xC097CE7BC90715B3, 56, 36 },
14227 { 0x8F7E32CE7BEA5C70, 83, 44 },
14228 { 0xD5D238A4ABE98068, 109, 52 },
14229 { 0x9F4F2726179A2245, 136, 60 },
14230 { 0xED63A231D4C4FB27, 162, 68 },
14231 { 0xB0DE65388CC8ADA8, 189, 76 },
14232 { 0x83C7088E1AAB65DB, 216, 84 },
14233 { 0xC45D1DF942711D9A, 242, 92 },
14234 { 0x924D692CA61BE758, 269, 100 },
14235 { 0xDA01EE641A708DEA, 295, 108 },
14236 { 0xA26DA3999AEF774A, 322, 116 },
14237 { 0xF209787BB47D6B85, 348, 124 },
14238 { 0xB454E4A179DD1877, 375, 132 },
14239 { 0x865B86925B9BC5C2, 402, 140 },
14240 { 0xC83553C5C8965D3D, 428, 148 },
14241 { 0x952AB45CFA97A0B3, 455, 156 },
14242 { 0xDE469FBD99A05FE3, 481, 164 },
14243 { 0xA59BC234DB398C25, 508, 172 },
14244 { 0xF6C69A72A3989F5C, 534, 180 },
14245 { 0xB7DCBF5354E9BECE, 561, 188 },
14246 { 0x88FCF317F22241E2, 588, 196 },
14247 { 0xCC20CE9BD35C78A5, 614, 204 },
14248 { 0x98165AF37B2153DF, 641, 212 },
14249 { 0xE2A0B5DC971F303A, 667, 220 },
14250 { 0xA8D9D1535CE3B396, 694, 228 },
14251 { 0xFB9B7CD9A4A7443C, 720, 236 },
14252 { 0xBB764C4CA7A44410, 747, 244 },
14253 { 0x8BAB8EEFB6409C1A, 774, 252 },
14254 { 0xD01FEF10A657842C, 800, 260 },
14255 { 0x9B10A4E5E9913129, 827, 268 },
14256 { 0xE7109BFBA19C0C9D, 853, 276 },
14257 { 0xAC2820D9623BF429, 880, 284 },
14258 { 0x80444B5E7AA7CF85, 907, 292 },
14259 { 0xBF21E44003ACDD2D, 933, 300 },
14260 { 0x8E679C2F5E44FF8F, 960, 308 },
14261 { 0xD433179D9C8CB841, 986, 316 },
14262 { 0x9E19DB92B4E31BA9, 1013, 324 },
14270 assert(e >= -1500);
14272 const int f = kAlpha - e - 1;
14273 const int k = (f * 78913) / (1 << 18) +
static_cast<int>(f > 0);
14275 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
14276 assert(index >= 0);
14277 assert(
static_cast<std::size_t
>(index) < kCachedPowers.size());
14279 const cached_power cached = kCachedPowers[
static_cast<std::size_t
>(index)];
14280 assert(kAlpha <= cached.e + e + 64);
14281 assert(kGamma >= cached.e + e + 64);
14290 inline int find_largest_pow10(
const std::uint32_t n, std::uint32_t& pow10)
14293 if (n >= 1000000000)
14295 pow10 = 1000000000;
14299 else if (n >= 100000000)
14304 else if (n >= 10000000)
14309 else if (n >= 1000000)
14314 else if (n >= 100000)
14319 else if (n >= 10000)
14324 else if (n >= 1000)
14346 inline void grisu2_round(
char* buf,
int len, std::uint64_t dist, std::uint64_t delta,
14347 std::uint64_t rest, std::uint64_t ten_k)
14350 assert(dist <= delta);
14351 assert(rest <= delta);
14374 and delta - rest >= ten_k
14375 and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
14377 assert(buf[len - 1] !=
'0');
14387 inline void grisu2_digit_gen(
char* buffer,
int& length,
int& decimal_exponent,
14388 diyfp M_minus, diyfp w, diyfp M_plus)
14390 static_assert(kAlpha >= -60,
"internal error");
14391 static_assert(kGamma <= -32,
"internal error");
14405 assert(M_plus.e >= kAlpha);
14406 assert(M_plus.e <= kGamma);
14408 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f;
14409 std::uint64_t dist = diyfp::sub(M_plus, w ).f;
14418 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
14420 auto p1 =
static_cast<std::uint32_t
>(M_plus.f >> -one.e);
14421 std::uint64_t p2 = M_plus.f & (one.f - 1);
14429 std::uint32_t pow10;
14430 const int k = find_largest_pow10(p1, pow10);
14457 const std::uint32_t d = p1 / pow10;
14458 const std::uint32_t r = p1 % pow10;
14464 buffer[length++] =
static_cast<char>(
'0' + d);
14483 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
14488 decimal_exponent += n;
14499 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
14500 grisu2_round(buffer, length, dist, delta, rest, ten_n);
14550 assert(p2 > delta);
14561 assert(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
14563 const std::uint64_t d = p2 >> -one.e;
14564 const std::uint64_t r = p2 & (one.f - 1);
14571 buffer[length++] =
static_cast<char>(
'0' + d);
14596 decimal_exponent -= m;
14604 const std::uint64_t ten_m = one.f;
14605 grisu2_round(buffer, length, dist, delta, p2, ten_m);
14627 JSON_HEDLEY_NON_NULL(1)
14628 inline
void grisu2(
char* buf,
int& len,
int& decimal_exponent,
14629 diyfp m_minus, diyfp v, diyfp m_plus)
14631 assert(m_plus.e == m_minus.e);
14632 assert(m_plus.e == v.e);
14643 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
14645 const diyfp c_minus_k(cached.f, cached.e);
14648 const diyfp w = diyfp::mul(v, c_minus_k);
14649 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
14650 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
14673 const diyfp M_minus(w_minus.f + 1, w_minus.e);
14674 const diyfp M_plus (w_plus.f - 1, w_plus.e );
14676 decimal_exponent = -cached.k;
14678 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
14686 template <
typename FloatType>
14687 JSON_HEDLEY_NON_NULL(1)
14688 void grisu2(
char* buf,
int& len,
int& decimal_exponent, FloatType value)
14690 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
14691 "internal error: not enough precision");
14693 assert(std::isfinite(value));
14713 const boundaries w = compute_boundaries(
static_cast<double>(value));
14715 const boundaries w = compute_boundaries(value);
14718 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
14726 JSON_HEDLEY_NON_NULL(1)
14728 inline
char* append_exponent(
char* buf,
int e)
14743 auto k =
static_cast<std::uint32_t
>(e);
14749 *buf++ =
static_cast<char>(
'0' + k);
14753 *buf++ =
static_cast<char>(
'0' + k / 10);
14755 *buf++ =
static_cast<char>(
'0' + k);
14759 *buf++ =
static_cast<char>(
'0' + k / 100);
14761 *buf++ =
static_cast<char>(
'0' + k / 10);
14763 *buf++ =
static_cast<char>(
'0' + k);
14778 JSON_HEDLEY_NON_NULL(1)
14780 inline
char* format_buffer(
char* buf,
int len,
int decimal_exponent,
14781 int min_exp,
int max_exp)
14783 assert(min_exp < 0);
14784 assert(max_exp > 0);
14787 const int n = len + decimal_exponent;
14793 if (k <= n and n <= max_exp)
14798 std::memset(buf + k,
'0',
static_cast<size_t>(n) -
static_cast<size_t>(k));
14802 return buf + (
static_cast<size_t>(n) + 2);
14805 if (0 < n and n <= max_exp)
14812 std::memmove(buf + (
static_cast<size_t>(n) + 1), buf + n,
static_cast<size_t>(k) -
static_cast<size_t>(n));
14814 return buf + (
static_cast<size_t>(k) + 1U);
14817 if (min_exp < n and n <= 0)
14822 std::memmove(buf + (2 +
static_cast<size_t>(-n)), buf,
static_cast<size_t>(k));
14825 std::memset(buf + 2,
'0',
static_cast<size_t>(-n));
14826 return buf + (2U +
static_cast<size_t>(-n) +
static_cast<size_t>(k));
14841 std::memmove(buf + 2, buf + 1,
static_cast<size_t>(k) - 1);
14843 buf += 1 +
static_cast<size_t>(k);
14847 return append_exponent(buf, n - 1);
14862 template <
typename FloatType>
14863 JSON_HEDLEY_NON_NULL(1, 2)
14865 char* to_chars(
char* first, const
char* last, FloatType value)
14867 static_cast<void>(last);
14868 assert(std::isfinite(value));
14871 if (std::signbit(value))
14886 assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
14893 int decimal_exponent = 0;
14894 dtoa_impl::grisu2(first, len, decimal_exponent, value);
14896 assert(len <= std::numeric_limits<FloatType>::max_digits10);
14899 constexpr
int kMinExp = -4;
14901 constexpr
int kMaxExp = std::numeric_limits<FloatType>::digits10;
14903 assert(last - first >= kMaxExp + 2);
14904 assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
14905 assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
14907 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
14935 enum class error_handler_t
14942 template<
typename BasicJsonType>
14945 using string_t =
typename BasicJsonType::string_t;
14946 using number_float_t =
typename BasicJsonType::number_float_t;
14947 using number_integer_t =
typename BasicJsonType::number_integer_t;
14948 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
14949 using binary_char_t =
typename BasicJsonType::binary_t::value_type;
14950 static constexpr std::uint8_t UTF8_ACCEPT = 0;
14951 static constexpr std::uint8_t UTF8_REJECT = 1;
14959 serializer(output_adapter_t<char> s,
const char ichar,
14960 error_handler_t error_handler_ = error_handler_t::strict)
14962 , loc(std::localeconv())
14963 , thousands_sep(loc->thousands_sep == nullptr ?
'\0' : * (loc->thousands_sep))
14964 , decimal_point(loc->decimal_point == nullptr ?
'\0' : * (loc->decimal_point))
14965 , indent_char(ichar)
14966 , indent_string(512, indent_char)
14967 , error_handler(error_handler_)
14971 serializer(
const serializer&) =
delete;
14972 serializer& operator=(
const serializer&) =
delete;
14973 serializer(serializer&&) =
delete;
14974 serializer& operator=(serializer&&) =
delete;
14975 ~serializer() =
default;
14999 void dump(
const BasicJsonType& val,
15000 const bool pretty_print,
15001 const bool ensure_ascii,
15002 const unsigned int indent_step,
15003 const unsigned int current_indent = 0)
15005 switch (val.m_type)
15007 case value_t::object:
15009 if (val.m_value.object->empty())
15011 o->write_characters(
"{}", 2);
15017 o->write_characters(
"{\n", 2);
15020 const auto new_indent = current_indent + indent_step;
15021 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15023 indent_string.resize(indent_string.size() * 2,
' ');
15027 auto i = val.m_value.object->cbegin();
15028 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15030 o->write_characters(indent_string.c_str(), new_indent);
15031 o->write_character(
'\"');
15032 dump_escaped(i->first, ensure_ascii);
15033 o->write_characters(
"\": ", 3);
15034 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
15035 o->write_characters(
",\n", 2);
15039 assert(i != val.m_value.object->cend());
15040 assert(std::next(i) == val.m_value.object->cend());
15041 o->write_characters(indent_string.c_str(), new_indent);
15042 o->write_character(
'\"');
15043 dump_escaped(i->first, ensure_ascii);
15044 o->write_characters(
"\": ", 3);
15045 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
15047 o->write_character(
'\n');
15048 o->write_characters(indent_string.c_str(), current_indent);
15049 o->write_character(
'}');
15053 o->write_character(
'{');
15056 auto i = val.m_value.object->cbegin();
15057 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15059 o->write_character(
'\"');
15060 dump_escaped(i->first, ensure_ascii);
15061 o->write_characters(
"\":", 2);
15062 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
15063 o->write_character(
',');
15067 assert(i != val.m_value.object->cend());
15068 assert(std::next(i) == val.m_value.object->cend());
15069 o->write_character(
'\"');
15070 dump_escaped(i->first, ensure_ascii);
15071 o->write_characters(
"\":", 2);
15072 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
15074 o->write_character(
'}');
15080 case value_t::array:
15082 if (val.m_value.array->empty())
15084 o->write_characters(
"[]", 2);
15090 o->write_characters(
"[\n", 2);
15093 const auto new_indent = current_indent + indent_step;
15094 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15096 indent_string.resize(indent_string.size() * 2,
' ');
15100 for (
auto i = val.m_value.array->cbegin();
15101 i != val.m_value.array->cend() - 1; ++i)
15103 o->write_characters(indent_string.c_str(), new_indent);
15104 dump(*i,
true, ensure_ascii, indent_step, new_indent);
15105 o->write_characters(
",\n", 2);
15109 assert(not val.m_value.array->empty());
15110 o->write_characters(indent_string.c_str(), new_indent);
15111 dump(val.m_value.array->back(),
true, ensure_ascii, indent_step, new_indent);
15113 o->write_character(
'\n');
15114 o->write_characters(indent_string.c_str(), current_indent);
15115 o->write_character(
']');
15119 o->write_character(
'[');
15122 for (
auto i = val.m_value.array->cbegin();
15123 i != val.m_value.array->cend() - 1; ++i)
15125 dump(*i,
false, ensure_ascii, indent_step, current_indent);
15126 o->write_character(
',');
15130 assert(not val.m_value.array->empty());
15131 dump(val.m_value.array->back(),
false, ensure_ascii, indent_step, current_indent);
15133 o->write_character(
']');
15139 case value_t::string:
15141 o->write_character(
'\"');
15142 dump_escaped(*val.m_value.string, ensure_ascii);
15143 o->write_character(
'\"');
15147 case value_t::binary:
15151 o->write_characters(
"{\n", 2);
15154 const auto new_indent = current_indent + indent_step;
15155 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15157 indent_string.resize(indent_string.size() * 2,
' ');
15160 o->write_characters(indent_string.c_str(), new_indent);
15162 o->write_characters(
"\"bytes\": [", 10);
15164 if (not val.m_value.binary->empty())
15166 for (
auto i = val.m_value.binary->cbegin();
15167 i != val.m_value.binary->cend() - 1; ++i)
15170 o->write_characters(
", ", 2);
15172 dump_integer(val.m_value.binary->back());
15175 o->write_characters(
"],\n", 3);
15176 o->write_characters(indent_string.c_str(), new_indent);
15178 o->write_characters(
"\"subtype\": ", 11);
15179 if (val.m_value.binary->has_subtype())
15181 dump_integer(val.m_value.binary->subtype());
15185 o->write_characters(
"null", 4);
15187 o->write_character(
'\n');
15188 o->write_characters(indent_string.c_str(), current_indent);
15189 o->write_character(
'}');
15193 o->write_characters(
"{\"bytes\":[", 10);
15195 if (not val.m_value.binary->empty())
15197 for (
auto i = val.m_value.binary->cbegin();
15198 i != val.m_value.binary->cend() - 1; ++i)
15201 o->write_character(
',');
15203 dump_integer(val.m_value.binary->back());
15206 o->write_characters(
"],\"subtype\":", 12);
15207 if (val.m_value.binary->has_subtype())
15209 dump_integer(val.m_value.binary->subtype());
15210 o->write_character(
'}');
15214 o->write_characters(
"null}", 5);
15220 case value_t::boolean:
15222 if (val.m_value.boolean)
15224 o->write_characters(
"true", 4);
15228 o->write_characters(
"false", 5);
15233 case value_t::number_integer:
15235 dump_integer(val.m_value.number_integer);
15239 case value_t::number_unsigned:
15241 dump_integer(val.m_value.number_unsigned);
15245 case value_t::number_float:
15247 dump_float(val.m_value.number_float);
15251 case value_t::discarded:
15253 o->write_characters(
"<discarded>", 11);
15257 case value_t::null:
15259 o->write_characters(
"null", 4);
15283 void dump_escaped(
const string_t& s,
const bool ensure_ascii)
15285 std::uint32_t codepoint;
15286 std::uint8_t state = UTF8_ACCEPT;
15287 std::size_t bytes = 0;
15290 std::size_t bytes_after_last_accept = 0;
15291 std::size_t undumped_chars = 0;
15293 for (std::size_t i = 0; i < s.size(); ++i)
15295 const auto byte =
static_cast<uint8_t
>(s[i]);
15297 switch (decode(state, codepoint,
byte))
15305 string_buffer[bytes++] =
'\\';
15306 string_buffer[bytes++] =
'b';
15312 string_buffer[bytes++] =
'\\';
15313 string_buffer[bytes++] =
't';
15319 string_buffer[bytes++] =
'\\';
15320 string_buffer[bytes++] =
'n';
15326 string_buffer[bytes++] =
'\\';
15327 string_buffer[bytes++] =
'f';
15333 string_buffer[bytes++] =
'\\';
15334 string_buffer[bytes++] =
'r';
15340 string_buffer[bytes++] =
'\\';
15341 string_buffer[bytes++] =
'\"';
15347 string_buffer[bytes++] =
'\\';
15348 string_buffer[bytes++] =
'\\';
15356 if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
15358 if (codepoint <= 0xFFFF)
15360 (std::snprintf)(string_buffer.data() + bytes, 7,
"\\u%04x",
15361 static_cast<std::uint16_t
>(codepoint));
15366 (std::snprintf)(string_buffer.data() + bytes, 13,
"\\u%04x\\u%04x",
15367 static_cast<std::uint16_t
>(0xD7C0u + (codepoint >> 10u)),
15368 static_cast<std::uint16_t
>(0xDC00u + (codepoint & 0x3FFu)));
15376 string_buffer[bytes++] = s[i];
15385 if (string_buffer.size() - bytes < 13)
15387 o->write_characters(string_buffer.data(), bytes);
15392 bytes_after_last_accept = bytes;
15393 undumped_chars = 0;
15399 switch (error_handler)
15401 case error_handler_t::strict:
15403 std::string sn(3,
'\0');
15404 (std::snprintf)(&sn[0], sn.size(),
"%.2X", byte);
15405 JSON_THROW(type_error::create(316,
"invalid UTF-8 byte at index " + std::to_string(i) +
": 0x" + sn));
15408 case error_handler_t::ignore:
15409 case error_handler_t::replace:
15415 if (undumped_chars > 0)
15422 bytes = bytes_after_last_accept;
15424 if (error_handler == error_handler_t::replace)
15429 string_buffer[bytes++] =
'\\';
15430 string_buffer[bytes++] =
'u';
15431 string_buffer[bytes++] =
'f';
15432 string_buffer[bytes++] =
'f';
15433 string_buffer[bytes++] =
'f';
15434 string_buffer[bytes++] =
'd';
15438 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type(
'\xEF');
15439 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type(
'\xBF');
15440 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type(
'\xBD');
15446 if (string_buffer.size() - bytes < 13)
15448 o->write_characters(string_buffer.data(), bytes);
15452 bytes_after_last_accept = bytes;
15455 undumped_chars = 0;
15458 state = UTF8_ACCEPT;
15470 if (not ensure_ascii)
15473 string_buffer[bytes++] = s[i];
15482 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
15487 o->write_characters(string_buffer.data(), bytes);
15493 switch (error_handler)
15495 case error_handler_t::strict:
15497 std::string sn(3,
'\0');
15498 (std::snprintf)(&sn[0], sn.size(),
"%.2X",
static_cast<std::uint8_t
>(s.back()));
15499 JSON_THROW(type_error::create(316,
"incomplete UTF-8 string; last byte: 0x" + sn));
15502 case error_handler_t::ignore:
15505 o->write_characters(string_buffer.data(), bytes_after_last_accept);
15509 case error_handler_t::replace:
15512 o->write_characters(string_buffer.data(), bytes_after_last_accept);
15516 o->write_characters(
"\\ufffd", 6);
15520 o->write_characters(
"\xEF\xBF\xBD", 3);
15539 inline unsigned int count_digits(number_unsigned_t x) noexcept
15541 unsigned int n_digits = 1;
15550 return n_digits + 1;
15554 return n_digits + 2;
15558 return n_digits + 3;
15574 template<
typename NumberType, detail::enable_if_t<
15575 std::is_same<NumberType, number_unsigned_t>::value or
15576 std::is_same<NumberType, number_integer_t>::value or
15577 std::is_same<NumberType, binary_char_t>::value,
15579 void dump_integer(NumberType x)
15581 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
15584 {{
'0',
'0'}}, {{
'0',
'1'}}, {{
'0',
'2'}}, {{
'0',
'3'}}, {{
'0',
'4'}}, {{
'0',
'5'}}, {{
'0',
'6'}}, {{
'0',
'7'}}, {{
'0',
'8'}}, {{
'0',
'9'}},
15585 {{
'1',
'0'}}, {{
'1',
'1'}}, {{
'1',
'2'}}, {{
'1',
'3'}}, {{
'1',
'4'}}, {{
'1',
'5'}}, {{
'1',
'6'}}, {{
'1',
'7'}}, {{
'1',
'8'}}, {{
'1',
'9'}},
15586 {{
'2',
'0'}}, {{
'2',
'1'}}, {{
'2',
'2'}}, {{
'2',
'3'}}, {{
'2',
'4'}}, {{
'2',
'5'}}, {{
'2',
'6'}}, {{
'2',
'7'}}, {{
'2',
'8'}}, {{
'2',
'9'}},
15587 {{
'3',
'0'}}, {{
'3',
'1'}}, {{
'3',
'2'}}, {{
'3',
'3'}}, {{
'3',
'4'}}, {{
'3',
'5'}}, {{
'3',
'6'}}, {{
'3',
'7'}}, {{
'3',
'8'}}, {{
'3',
'9'}},
15588 {{
'4',
'0'}}, {{
'4',
'1'}}, {{
'4',
'2'}}, {{
'4',
'3'}}, {{
'4',
'4'}}, {{
'4',
'5'}}, {{
'4',
'6'}}, {{
'4',
'7'}}, {{
'4',
'8'}}, {{
'4',
'9'}},
15589 {{
'5',
'0'}}, {{
'5',
'1'}}, {{
'5',
'2'}}, {{
'5',
'3'}}, {{
'5',
'4'}}, {{
'5',
'5'}}, {{
'5',
'6'}}, {{
'5',
'7'}}, {{
'5',
'8'}}, {{
'5',
'9'}},
15590 {{
'6',
'0'}}, {{
'6',
'1'}}, {{
'6',
'2'}}, {{
'6',
'3'}}, {{
'6',
'4'}}, {{
'6',
'5'}}, {{
'6',
'6'}}, {{
'6',
'7'}}, {{
'6',
'8'}}, {{
'6',
'9'}},
15591 {{
'7',
'0'}}, {{
'7',
'1'}}, {{
'7',
'2'}}, {{
'7',
'3'}}, {{
'7',
'4'}}, {{
'7',
'5'}}, {{
'7',
'6'}}, {{
'7',
'7'}}, {{
'7',
'8'}}, {{
'7',
'9'}},
15592 {{
'8',
'0'}}, {{
'8',
'1'}}, {{
'8',
'2'}}, {{
'8',
'3'}}, {{
'8',
'4'}}, {{
'8',
'5'}}, {{
'8',
'6'}}, {{
'8',
'7'}}, {{
'8',
'8'}}, {{
'8',
'9'}},
15593 {{
'9',
'0'}}, {{
'9',
'1'}}, {{
'9',
'2'}}, {{
'9',
'3'}}, {{
'9',
'4'}}, {{
'9',
'5'}}, {{
'9',
'6'}}, {{
'9',
'7'}}, {{
'9',
'8'}}, {{
'9',
'9'}},
15600 o->write_character(
'0');
15605 auto buffer_ptr = number_buffer.begin();
15607 const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not(x >= 0);
15608 number_unsigned_t abs_value;
15610 unsigned int n_chars;
15615 abs_value = remove_sign(
static_cast<number_integer_t
>(x));
15618 n_chars = 1 + count_digits(abs_value);
15622 abs_value =
static_cast<number_unsigned_t
>(x);
15623 n_chars = count_digits(abs_value);
15627 assert(n_chars < number_buffer.size() - 1);
15631 buffer_ptr += n_chars;
15635 while (abs_value >= 100)
15637 const auto digits_index =
static_cast<unsigned>((abs_value % 100));
15639 *(--buffer_ptr) = digits_to_99[digits_index][1];
15640 *(--buffer_ptr) = digits_to_99[digits_index][0];
15643 if (abs_value >= 10)
15645 const auto digits_index =
static_cast<unsigned>(abs_value);
15646 *(--buffer_ptr) = digits_to_99[digits_index][1];
15647 *(--buffer_ptr) = digits_to_99[digits_index][0];
15651 *(--buffer_ptr) =
static_cast<char>(
'0' + abs_value);
15654 o->write_characters(number_buffer.data(), n_chars);
15665 void dump_float(number_float_t x)
15668 if (not std::isfinite(x))
15670 o->write_characters(
"null", 4);
15679 static constexpr
bool is_ieee_single_or_double
15680 = (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
15681 (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);
15683 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
15686 void dump_float(number_float_t x, std::true_type )
15688 char* begin = number_buffer.data();
15689 char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
15691 o->write_characters(begin,
static_cast<size_t>(end - begin));
15694 void dump_float(number_float_t x, std::false_type )
15697 static constexpr
auto d = std::numeric_limits<number_float_t>::max_digits10;
15700 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(),
"%.*g", d, x);
15705 assert(
static_cast<std::size_t
>(len) < number_buffer.size());
15708 if (thousands_sep !=
'\0')
15710 const auto end = std::remove(number_buffer.begin(),
15711 number_buffer.begin() + len, thousands_sep);
15712 std::fill(end, number_buffer.end(),
'\0');
15713 assert((end - number_buffer.begin()) <= len);
15714 len = (end - number_buffer.begin());
15718 if (decimal_point !=
'\0' and decimal_point !=
'.')
15720 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
15721 if (dec_pos != number_buffer.end())
15727 o->write_characters(number_buffer.data(),
static_cast<std::size_t
>(len));
15730 const bool value_is_int_like =
15731 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
15734 return c ==
'.' or c ==
'e';
15737 if (value_is_int_like)
15739 o->write_characters(
".0", 2);
15764 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep,
const std::uint8_t
byte) noexcept
15766 static const std::array<std::uint8_t, 400> utf8d =
15769 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,
15770 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,
15771 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,
15772 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,
15773 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,
15774 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,
15775 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,
15776 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3,
15777 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
15778 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1,
15779 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,
15780 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,
15781 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,
15782 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
15786 const std::uint8_t type = utf8d[byte];
15788 codep = (state != UTF8_ACCEPT)
15789 ? (
byte & 0x3fu) | (codep << 6u)
15790 : (0xFFu >> type) & (byte);
15792 std::size_t index = 256u +
static_cast<size_t>(state) * 16u +
static_cast<size_t>(type);
15793 assert(index < 400);
15794 state = utf8d[index];
15803 number_unsigned_t remove_sign(number_unsigned_t x)
15818 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
15820 assert(x < 0 and x < (std::numeric_limits<number_integer_t>::max)());
15821 return static_cast<number_unsigned_t
>(-(x + 1)) + 1;
15826 output_adapter_t<char> o =
nullptr;
15829 std::array<char, 64> number_buffer{{}};
15832 const std::lconv* loc =
nullptr;
15834 const char thousands_sep =
'\0';
15836 const char decimal_point =
'\0';
15839 std::array<char, 512> string_buffer{{}};
15842 const char indent_char;
15844 string_t indent_string;
15847 const error_handler_t error_handler;
15949 NLOHMANN_BASIC_JSON_TPL_DECLARATION
15954 friend ::nlohmann::json_pointer<basic_json>;
15956 template<
typename BasicJsonType,
typename InputType>
15957 friend class ::nlohmann::detail::parser;
15958 friend ::nlohmann::detail::serializer<basic_json>;
15959 template<
typename BasicJsonType>
15960 friend class ::nlohmann::detail::iter_impl;
15961 template<
typename BasicJsonType,
typename CharType>
15962 friend class ::nlohmann::detail::binary_writer;
15963 template<
typename BasicJsonType,
typename InputType,
typename SAX>
15964 friend class ::nlohmann::detail::binary_reader;
15965 template<
typename BasicJsonType>
15966 friend class ::nlohmann::detail::json_sax_dom_parser;
15967 template<
typename BasicJsonType>
15968 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
15971 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
15974 using lexer = ::nlohmann::detail::lexer_base<basic_json>;
15976 template<
typename InputAdapterType>
15977 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
15978 InputAdapterType adapter,
15979 detail::parser_callback_t<basic_json>cb =
nullptr,
15980 bool allow_exceptions =
true
15983 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter), std::move(cb), allow_exceptions);
15986 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
15987 template<
typename BasicJsonType>
15988 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
15989 template<
typename BasicJsonType>
15990 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
15991 template<
typename Iterator>
15992 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
15993 template<
typename Base>
using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
15995 template<
typename CharType>
15996 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
15998 template<
typename InputType>
15999 using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
16000 template<
typename CharType>
using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
16002 using serializer = ::nlohmann::detail::serializer<basic_json>;
16005 using value_t = detail::value_t;
16008 template<
typename T,
typename SFINAE>
16011 using error_handler_t = detail::error_handler_t;
16015 using input_format_t = detail::input_format_t;
16069 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
16071 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
16124 result[
"copyright"] =
"(C) 2013-2017 Niels Lohmann";
16125 result[
"name"] =
"JSON for Modern C++";
16126 result[
"url"] =
"https://github.com/nlohmann/json";
16127 result[
"version"][
"string"] =
16128 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) +
"." +
16129 std::to_string(NLOHMANN_JSON_VERSION_MINOR) +
"." +
16130 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
16131 result[
"version"][
"major"] = NLOHMANN_JSON_VERSION_MAJOR;
16132 result[
"version"][
"minor"] = NLOHMANN_JSON_VERSION_MINOR;
16133 result[
"version"][
"patch"] = NLOHMANN_JSON_VERSION_PATCH;
16136 result[
"platform"] =
"win32";
16137 #elif defined __linux__
16138 result[
"platform"] =
"linux";
16139 #elif defined __APPLE__
16140 result[
"platform"] =
"apple";
16141 #elif defined __unix__
16142 result[
"platform"] =
"unix";
16144 result[
"platform"] =
"unknown";
16147 #if defined(__ICC) || defined(__INTEL_COMPILER)
16148 result[
"compiler"] = {{
"family",
"icc"}, {
"version", __INTEL_COMPILER}};
16149 #elif defined(__clang__)
16150 result[
"compiler"] = {{
"family",
"clang"}, {
"version", __clang_version__}};
16151 #elif defined(__GNUC__) || defined(__GNUG__)
16152 result[
"compiler"] = {{
"family",
"gcc"}, {
"version", std::to_string(__GNUC__) +
"." + std::to_string(__GNUC_MINOR__) +
"." + std::to_string(__GNUC_PATCHLEVEL__)}};
16153 #elif defined(__HP_cc) || defined(__HP_aCC)
16154 result[
"compiler"] =
"hp"
16155 #elif defined(__IBMCPP__)
16156 result[
"compiler"] = {{
"family",
"ilecpp"}, {
"version", __IBMCPP__}};
16157 #elif defined(_MSC_VER)
16158 result[
"compiler"] = {{
"family",
"msvc"}, {
"version", _MSC_VER}};
16159 #elif defined(__PGI)
16160 result[
"compiler"] = {{
"family",
"pgcpp"}, {
"version", __PGI}};
16161 #elif defined(__SUNPRO_CC)
16162 result[
"compiler"] = {{
"family",
"sunpro"}, {
"version", __SUNPRO_CC}};
16164 result[
"compiler"] = {{
"family",
"unknown"}, {
"version",
"unknown"}};
16168 result[
"compiler"][
"c++"] = std::to_string(__cplusplus);
16170 result[
"compiler"][
"c++"] =
"unknown";
16185 #if defined(JSON_HAS_CPP_14)
16279 AllocatorType<std::pair<
const StringType,
16326 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
16693 template<
typename T,
typename... Args>
16695 static T* create(Args&& ... args)
16697 AllocatorType<T> alloc;
16698 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
16700 auto deleter = [&](T *
object)
16702 AllocatorTraits::deallocate(alloc,
object, 1);
16704 std::unique_ptr<T, decltype(deleter)>
object(AllocatorTraits::allocate(alloc, 1), deleter);
16705 AllocatorTraits::construct(alloc,
object.
get(), std::forward<Args>(args)...);
16706 assert(
object !=
nullptr);
16707 return object.release();
16759 json_value() =
default;
16761 json_value(
boolean_t v) noexcept : boolean(v) {}
16773 case value_t::object:
16775 object = create<object_t>();
16779 case value_t::array:
16781 array = create<array_t>();
16785 case value_t::string:
16787 string = create<string_t>(
"");
16791 case value_t::binary:
16793 binary = create<binary_t>();
16797 case value_t::boolean:
16803 case value_t::number_integer:
16809 case value_t::number_unsigned:
16815 case value_t::number_float:
16821 case value_t::null:
16830 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
16832 JSON_THROW(other_error::create(500,
"961c151d2e87f2686a955a9be24d316f1362bf21 3.8.0"));
16842 string = create<string_t>(
value);
16848 string = create<string_t>(std::move(
value));
16854 object = create<object_t>(
value);
16860 object = create<object_t>(std::move(
value));
16899 void destroy(
value_t t) noexcept
16902 std::vector<basic_json> stack;
16905 if (t == value_t::array)
16910 else if (t == value_t::object)
16913 for (
auto&& it : *
object)
16915 stack.push_back(std::move(it.second));
16919 while (not stack.empty())
16922 basic_json current_item(std::move(stack.back()));
16927 if (current_item.is_array())
16929 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
16930 std::back_inserter(stack));
16932 current_item.m_value.array->clear();
16934 else if (current_item.is_object())
16936 for (
auto&& it : *current_item.m_value.object)
16938 stack.push_back(std::move(it.second));
16941 current_item.m_value.object->clear();
16950 case value_t::object:
16952 AllocatorType<object_t> alloc;
16953 std::allocator_traits<decltype(alloc)>::destroy(alloc,
object);
16954 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
object, 1);
16958 case value_t::array:
16960 AllocatorType<array_t> alloc;
16961 std::allocator_traits<decltype(alloc)>::destroy(alloc,
array);
16962 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
array, 1);
16966 case value_t::string:
16968 AllocatorType<string_t> alloc;
16969 std::allocator_traits<decltype(alloc)>::destroy(alloc,
string);
16970 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
string, 1);
16974 case value_t::binary:
16976 AllocatorType<binary_t> alloc;
16977 std::allocator_traits<decltype(alloc)>::destroy(alloc,
binary);
16978 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
binary, 1);
16999 void assert_invariant() const noexcept
17001 assert(m_type != value_t::object or m_value.object !=
nullptr);
17002 assert(m_type != value_t::array or m_value.array !=
nullptr);
17003 assert(m_type != value_t::string or m_value.string !=
nullptr);
17004 assert(m_type != value_t::binary or m_value.binary !=
nullptr);
17027 using parse_event_t = detail::parse_event_t;
17120 : m_type(v), m_value(v)
17122 assert_invariant();
17146 assert_invariant();
17212 template <
typename CompatibleType,
17213 typename U = detail::uncvref_t<CompatibleType>,
17214 detail::enable_if_t<
17215 not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value,
int> = 0>
17217 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
17218 std::forward<CompatibleType>(val))))
17220 JSONSerializer<U>::to_json(*
this, std::forward<CompatibleType>(val));
17221 assert_invariant();
17250 template <
typename BasicJsonType,
17251 detail::enable_if_t<
17252 detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value,
int> = 0>
17255 using other_boolean_t =
typename BasicJsonType::boolean_t;
17256 using other_number_float_t =
typename BasicJsonType::number_float_t;
17257 using other_number_integer_t =
typename BasicJsonType::number_integer_t;
17258 using other_number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
17259 using other_string_t =
typename BasicJsonType::string_t;
17260 using other_object_t =
typename BasicJsonType::object_t;
17261 using other_array_t =
typename BasicJsonType::array_t;
17262 using other_binary_t =
typename BasicJsonType::binary_t;
17264 switch (val.type())
17266 case value_t::boolean:
17267 JSONSerializer<other_boolean_t>::to_json(*
this, val.template get<other_boolean_t>());
17269 case value_t::number_float:
17270 JSONSerializer<other_number_float_t>::to_json(*
this, val.template get<other_number_float_t>());
17272 case value_t::number_integer:
17273 JSONSerializer<other_number_integer_t>::to_json(*
this, val.template get<other_number_integer_t>());
17275 case value_t::number_unsigned:
17276 JSONSerializer<other_number_unsigned_t>::to_json(*
this, val.template get<other_number_unsigned_t>());
17278 case value_t::string:
17279 JSONSerializer<other_string_t>::to_json(*
this, val.template get_ref<const other_string_t&>());
17281 case value_t::object:
17282 JSONSerializer<other_object_t>::to_json(*
this, val.template get_ref<const other_object_t&>());
17284 case value_t::array:
17285 JSONSerializer<other_array_t>::to_json(*
this, val.template get_ref<const other_array_t&>());
17287 case value_t::binary:
17288 JSONSerializer<other_binary_t>::to_json(*
this, val.template get_ref<const other_binary_t&>());
17290 case value_t::null:
17293 case value_t::discarded:
17294 m_type = value_t::discarded;
17299 assert_invariant();
17377 bool type_deduction =
true,
17378 value_t manual_type = value_t::array)
17382 bool is_an_object = std::all_of(init.begin(), init.end(),
17383 [](
const detail::json_ref<basic_json>& element_ref)
17385 return element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string();
17389 if (not type_deduction)
17392 if (manual_type == value_t::array)
17394 is_an_object =
false;
17398 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object and not is_an_object))
17400 JSON_THROW(type_error::create(301,
"cannot create object from initializer list"));
17407 m_type = value_t::object;
17408 m_value = value_t::object;
17410 std::for_each(init.begin(), init.end(), [
this](
const detail::json_ref<basic_json>& element_ref)
17412 auto element = element_ref.moved_or_copied();
17413 m_value.object->emplace(
17414 std::move(*((*element.m_value.array)[0].m_value.string)),
17415 std::move((*element.m_value.array)[1]));
17421 m_type = value_t::array;
17422 m_value.array = create<array_t>(init.begin(), init.end());
17425 assert_invariant();
17459 res.m_type = value_t::binary;
17460 res.m_value = init;
17496 res.m_type = value_t::binary;
17497 res.m_value =
binary_t(init, subtype);
17506 res.m_type = value_t::binary;
17507 res.m_value = std::move(init);
17516 res.m_type = value_t::binary;
17517 res.m_value =
binary_t(std::move(init), subtype);
17561 return basic_json(init,
false, value_t::array);
17605 return basic_json(init,
false, value_t::object);
17631 : m_type(value_t::
array)
17633 m_value.array = create<array_t>(cnt, val);
17634 assert_invariant();
17692 template<
class InputIT,
typename std::enable_if<
17693 std::is_same<InputIT, typename basic_json_t::iterator>::value or
17694 std::is_same<InputIT, typename basic_json_t::const_iterator>::value,
int>
::type = 0>
17697 assert(first.m_object !=
nullptr);
17698 assert(last.m_object !=
nullptr);
17701 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
17703 JSON_THROW(invalid_iterator::create(201,
"iterators are not compatible"));
17707 m_type = first.m_object->m_type;
17712 case value_t::boolean:
17713 case value_t::number_float:
17714 case value_t::number_integer:
17715 case value_t::number_unsigned:
17716 case value_t::string:
17718 if (JSON_HEDLEY_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
17719 or not last.m_it.primitive_iterator.is_end()))
17721 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
17732 case value_t::number_integer:
17734 m_value.number_integer = first.m_object->m_value.number_integer;
17738 case value_t::number_unsigned:
17740 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
17744 case value_t::number_float:
17746 m_value.number_float = first.m_object->m_value.number_float;
17750 case value_t::boolean:
17752 m_value.boolean = first.m_object->m_value.boolean;
17756 case value_t::string:
17758 m_value = *first.m_object->m_value.string;
17762 case value_t::object:
17764 m_value.object = create<object_t>(first.m_it.object_iterator,
17765 last.m_it.object_iterator);
17769 case value_t::array:
17771 m_value.array = create<array_t>(first.m_it.array_iterator,
17772 last.m_it.array_iterator);
17776 case value_t::binary:
17778 m_value = *first.m_object->m_value.binary;
17783 JSON_THROW(invalid_iterator::create(206,
"cannot construct with iterators from " +
17784 std::string(first.m_object->type_name())));
17787 assert_invariant();
17795 template <
typename JsonRef,
17796 detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
17797 std::is_same<typename JsonRef::value_type, basic_json>>
::value,
int> = 0 >
17826 : m_type(other.m_type)
17829 other.assert_invariant();
17833 case value_t::object:
17835 m_value = *other.m_value.object;
17839 case value_t::array:
17841 m_value = *other.m_value.array;
17845 case value_t::string:
17847 m_value = *other.m_value.string;
17851 case value_t::boolean:
17853 m_value = other.m_value.boolean;
17857 case value_t::number_integer:
17859 m_value = other.m_value.number_integer;
17863 case value_t::number_unsigned:
17865 m_value = other.m_value.number_unsigned;
17869 case value_t::number_float:
17871 m_value = other.m_value.number_float;
17875 case value_t::binary:
17877 m_value = *other.m_value.binary;
17885 assert_invariant();
17915 : m_type(std::move(other.m_type)),
17916 m_value(std::move(other.m_value))
17919 other.assert_invariant();
17922 other.m_type = value_t::null;
17923 other.m_value = {};
17925 assert_invariant();
17952 std::is_nothrow_move_constructible<value_t>::value and
17953 std::is_nothrow_move_assignable<value_t>::value and
17954 std::is_nothrow_move_constructible<json_value>::value and
17955 std::is_nothrow_move_assignable<json_value>::value
17959 other.assert_invariant();
17962 swap(m_type, other.m_type);
17963 swap(m_value, other.m_value);
17965 assert_invariant();
17986 assert_invariant();
17987 m_value.destroy(m_type);
18048 const char indent_char =
' ',
18049 const bool ensure_ascii =
false,
18050 const error_handler_t error_handler = error_handler_t::strict)
const
18053 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
18057 s.dump(*
this,
true, ensure_ascii,
static_cast<unsigned int>(indent));
18061 s.dump(*
this,
false, ensure_ascii, 0);
18100 constexpr value_t
type() const noexcept
18182 return m_type == value_t::null;
18204 return m_type == value_t::boolean;
18263 return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
18291 return m_type == value_t::number_unsigned;
18319 return m_type == value_t::number_float;
18341 return m_type == value_t::object;
18363 return m_type == value_t::array;
18385 return m_type == value_t::string;
18407 return m_type == value_t::binary;
18434 return m_type == value_t::discarded;
18475 return m_value.boolean;
18478 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(
type_name())));
18484 return is_object() ? m_value.object :
nullptr;
18490 return is_object() ? m_value.object :
nullptr;
18496 return is_array() ? m_value.array :
nullptr;
18500 constexpr
const array_t* get_impl_ptr(
const array_t* )
const noexcept
18502 return is_array() ? m_value.array :
nullptr;
18508 return is_string() ? m_value.string :
nullptr;
18514 return is_string() ? m_value.string :
nullptr;
18520 return is_boolean() ? &m_value.boolean :
nullptr;
18526 return is_boolean() ? &m_value.boolean :
nullptr;
18568 return is_binary() ? m_value.binary :
nullptr;
18574 return is_binary() ? m_value.binary :
nullptr;
18588 template<
typename ReferenceType,
typename ThisType>
18589 static ReferenceType get_ref_impl(ThisType& obj)
18592 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
18594 if (JSON_HEDLEY_LIKELY(ptr !=
nullptr))
18599 JSON_THROW(type_error::create(303,
"incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
18621 template<
typename BasicJsonType, detail::enable_if_t<
18622 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>
::value,
18644 template<
typename BasicJsonType, detail::enable_if_t<
18645 not std::is_same<BasicJsonType, basic_json>::value and
18646 detail::is_basic_json<BasicJsonType>::value,
int> = 0>
18691 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
18692 detail::enable_if_t <
18693 not detail::is_basic_json<ValueType>::value and
18694 detail::has_from_json<basic_json_t, ValueType>::value and
18695 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
18697 ValueType
get() const noexcept(noexcept(
18698 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
18703 static_assert(not std::is_reference<ValueTypeCV>::value,
18704 "get() cannot be used with reference types, you might want to use get_ref()");
18705 static_assert(std::is_default_constructible<ValueType>::value,
18706 "types must be DefaultConstructible when used with get()");
18709 JSONSerializer<ValueType>::from_json(*
this, ret);
18744 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
18745 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
18746 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
18748 ValueType
get() const noexcept(noexcept(
18749 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
18751 static_assert(not std::is_reference<ValueTypeCV>::value,
18752 "get() cannot be used with reference types, you might want to use get_ref()");
18753 return JSONSerializer<ValueType>::from_json(*
this);
18789 template<
typename ValueType,
18790 detail::enable_if_t <
18791 not detail::is_basic_json<ValueType>::value and
18792 detail::has_from_json<basic_json_t, ValueType>::value,
18794 ValueType &
get_to(ValueType& v)
const noexcept(noexcept(
18795 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
18797 JSONSerializer<ValueType>::from_json(*
this, v);
18802 typename T, std::size_t N,
18803 typename Array = T (&)[N],
18804 detail::enable_if_t <
18805 detail::has_from_json<basic_json_t, Array>::value,
int > = 0 >
18807 noexcept(noexcept(JSONSerializer<Array>::from_json(
18808 std::declval<const basic_json_t&>(), v)))
18810 JSONSerializer<Array>::from_json(*
this, v);
18841 template<
typename PointerType,
typename std::enable_if<
18842 std::is_pointer<PointerType>::value,
int>
::type = 0>
18843 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
18846 return get_impl_ptr(
static_cast<PointerType
>(
nullptr));
18853 template<
typename PointerType,
typename std::enable_if<
18854 std::is_pointer<PointerType>::value and
18855 std::is_const<typename std::remove_pointer<PointerType>::type>
::value,
int>
::type = 0>
18856 constexpr
auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
18859 return get_impl_ptr(
static_cast<PointerType
>(
nullptr));
18889 template<
typename PointerType,
typename std::enable_if<
18890 std::is_pointer<PointerType>::value,
int>
::type = 0>
18891 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template
get_ptr<PointerType>())
18894 return get_ptr<PointerType>();
18901 template<
typename PointerType,
typename std::enable_if<
18902 std::is_pointer<PointerType>::value,
int>
::type = 0>
18903 constexpr
auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template
get_ptr<PointerType>())
18906 return get_ptr<PointerType>();
18935 template<
typename ReferenceType,
typename std::enable_if<
18936 std::is_reference<ReferenceType>::value,
int>
::type = 0>
18940 return get_ref_impl<ReferenceType>(*
this);
18947 template<
typename ReferenceType,
typename std::enable_if<
18948 std::is_reference<ReferenceType>::value and
18949 std::is_const<typename std::remove_reference<ReferenceType>::type>
::value,
int>
::type = 0>
18953 return get_ref_impl<ReferenceType>(*
this);
18985 template <
typename ValueType,
typename std::enable_if <
18986 not std::is_pointer<ValueType>::value and
18987 not std::is_same<ValueType, detail::json_ref<basic_json>>
::value and
18988 not std::is_same<ValueType, typename string_t::value_type>::value and
18989 not detail::is_basic_json<ValueType>::value
18990 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>
::value
18991 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) and _MSC_VER >= 1910 and _MSC_VER <= 1914))
18992 and not std::is_same<ValueType, typename std::string_view>::value
18994 and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
18996 operator ValueType()
const
18999 return get<ValueType>();
19015 JSON_THROW(type_error::create(302,
"type must be binary, but is " + std::string(
type_name())));
19018 return *get_ptr<binary_t*>();
19026 JSON_THROW(type_error::create(302,
"type must be binary, but is " + std::string(
type_name())));
19029 return *get_ptr<const binary_t*>();
19072 if (JSON_HEDLEY_LIKELY(
is_array()))
19076 return m_value.array->at(idx);
19078 JSON_CATCH (std::out_of_range&)
19081 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
19086 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(
type_name())));
19119 if (JSON_HEDLEY_LIKELY(
is_array()))
19123 return m_value.array->at(idx);
19125 JSON_CATCH (std::out_of_range&)
19128 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
19133 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(
type_name())));
19167 reference at(
const typename object_t::key_type& key)
19174 return m_value.object->at(key);
19176 JSON_CATCH (std::out_of_range&)
19179 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
19184 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(
type_name())));
19225 return m_value.object->at(key);
19227 JSON_CATCH (std::out_of_range&)
19230 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
19235 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(
type_name())));
19269 m_type = value_t::array;
19270 m_value.array = create<array_t>();
19271 assert_invariant();
19275 if (JSON_HEDLEY_LIKELY(
is_array()))
19278 if (idx >= m_value.array->size())
19280 m_value.array->insert(m_value.array->end(),
19281 idx - m_value.array->size() + 1,
19285 return m_value.array->operator[](idx);
19288 JSON_THROW(type_error::create(305,
"cannot use operator[] with a numeric argument with " + std::string(
type_name())));
19313 if (JSON_HEDLEY_LIKELY(
is_array()))
19315 return m_value.array->operator[](idx);
19318 JSON_THROW(type_error::create(305,
"cannot use operator[] with a numeric argument with " + std::string(
type_name())));
19353 m_type = value_t::object;
19354 m_value.object = create<object_t>();
19355 assert_invariant();
19361 return m_value.object->operator[](key);
19364 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(
type_name())));
19402 assert(m_value.object->find(key) != m_value.object->end());
19403 return m_value.object->find(key)->second;
19406 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(
type_name())));
19436 template<
typename T>
19437 JSON_HEDLEY_NON_NULL(2)
19443 m_type = value_t::object;
19444 m_value = value_t::object;
19445 assert_invariant();
19451 return m_value.object->operator[](key);
19454 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(
type_name())));
19487 template<
typename T>
19488 JSON_HEDLEY_NON_NULL(2)
19494 assert(m_value.object->find(key) != m_value.object->end());
19495 return m_value.object->find(key)->second;
19498 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(
type_name())));
19551 template<
class ValueType,
typename std::enable_if<
19552 std::is_convertible<basic_json_t, ValueType>::value
19553 and not std::is_same<value_t, ValueType>::value,
int>
::type = 0>
19554 ValueType
value(
const typename object_t::key_type& key,
const ValueType& default_value)
const
19560 const auto it =
find(key);
19566 return default_value;
19569 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(
type_name())));
19576 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const
19624 template<
class ValueType,
typename std::enable_if<
19625 std::is_convertible<basic_json_t, ValueType>::value,
int>
::type = 0>
19634 return ptr.get_checked(
this);
19638 return default_value;
19642 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(
type_name())));
19649 JSON_HEDLEY_NON_NULL(3)
19787 template<
class IteratorType,
typename std::enable_if<
19788 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
19789 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>
::type
19791 IteratorType
erase(IteratorType pos)
19794 if (JSON_HEDLEY_UNLIKELY(
this != pos.m_object))
19796 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
19799 IteratorType result =
end();
19803 case value_t::boolean:
19804 case value_t::number_float:
19805 case value_t::number_integer:
19806 case value_t::number_unsigned:
19807 case value_t::string:
19808 case value_t::binary:
19810 if (JSON_HEDLEY_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
19812 JSON_THROW(invalid_iterator::create(205,
"iterator out of range"));
19817 AllocatorType<string_t> alloc;
19818 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
19819 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
19820 m_value.string =
nullptr;
19824 AllocatorType<binary_t> alloc;
19825 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
19826 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
19827 m_value.binary =
nullptr;
19830 m_type = value_t::null;
19831 assert_invariant();
19835 case value_t::object:
19837 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
19841 case value_t::array:
19843 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
19848 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(
type_name())));
19900 template<
class IteratorType,
typename std::enable_if<
19901 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
19902 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>
::type
19904 IteratorType
erase(IteratorType first, IteratorType last)
19907 if (JSON_HEDLEY_UNLIKELY(
this != first.m_object or
this != last.m_object))
19909 JSON_THROW(invalid_iterator::create(203,
"iterators do not fit current value"));
19912 IteratorType result =
end();
19916 case value_t::boolean:
19917 case value_t::number_float:
19918 case value_t::number_integer:
19919 case value_t::number_unsigned:
19920 case value_t::string:
19921 case value_t::binary:
19923 if (JSON_HEDLEY_LIKELY(not first.m_it.primitive_iterator.is_begin()
19924 or not last.m_it.primitive_iterator.is_end()))
19926 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
19931 AllocatorType<string_t> alloc;
19932 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
19933 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
19934 m_value.string =
nullptr;
19938 AllocatorType<binary_t> alloc;
19939 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
19940 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
19941 m_value.binary =
nullptr;
19944 m_type = value_t::null;
19945 assert_invariant();
19949 case value_t::object:
19951 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
19952 last.m_it.object_iterator);
19956 case value_t::array:
19958 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
19959 last.m_it.array_iterator);
19964 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(
type_name())));
20004 return m_value.object->erase(key);
20007 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(
type_name())));
20037 if (JSON_HEDLEY_LIKELY(
is_array()))
20039 if (JSON_HEDLEY_UNLIKELY(idx >=
size()))
20041 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
20048 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(
type_name())));
20086 template<
typename KeyT>
20089 auto result =
end();
20093 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20103 template<
typename KeyT>
20106 auto result =
cend();
20110 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20137 template<
typename KeyT>
20141 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
20169 template<
typename KeyT,
typename std::enable_if<
20173 return is_object() and m_value.
object->
find(std::forward<KeyT>(key)) != m_value.
object->
end();
20204 return ptr.contains(
this);
20244 result.set_begin();
20284 result.set_begin();
20548 JSON_HEDLEY_DEPRECATED_FOR(3.1.0,
items())
20551 return ref.items();
20557 JSON_HEDLEY_DEPRECATED_FOR(3.1.0,
items())
20560 return ref.items();
20631 iteration_proxy<iterator>
items() noexcept
20633 return iteration_proxy<iterator>(*
this);
20639 iteration_proxy<const_iterator>
items() const noexcept
20641 return iteration_proxy<const_iterator>(*
this);
20696 bool empty() const noexcept
20700 case value_t::null:
20706 case value_t::array:
20709 return m_value.array->empty();
20712 case value_t::object:
20715 return m_value.object->empty();
20773 case value_t::null:
20779 case value_t::array:
20782 return m_value.array->size();
20785 case value_t::object:
20788 return m_value.object->size();
20844 case value_t::array:
20847 return m_value.array->max_size();
20850 case value_t::object:
20853 return m_value.object->max_size();
20911 void clear() noexcept
20915 case value_t::number_integer:
20917 m_value.number_integer = 0;
20921 case value_t::number_unsigned:
20923 m_value.number_unsigned = 0;
20927 case value_t::number_float:
20929 m_value.number_float = 0.0;
20933 case value_t::boolean:
20935 m_value.boolean =
false;
20939 case value_t::string:
20941 m_value.string->clear();
20945 case value_t::binary:
20947 m_value.binary->clear();
20951 case value_t::array:
20953 m_value.array->clear();
20957 case value_t::object:
20959 m_value.object->clear();
20993 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(
type_name())));
20999 m_type = value_t::array;
21000 m_value = value_t::array;
21001 assert_invariant();
21005 m_value.array->push_back(std::move(val));
21028 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(
type_name())));
21034 m_type = value_t::array;
21035 m_value = value_t::array;
21036 assert_invariant();
21040 m_value.array->push_back(val);
21073 void push_back(
const typename object_t::value_type& val)
21078 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(
type_name())));
21084 m_type = value_t::object;
21085 m_value = value_t::object;
21086 assert_invariant();
21090 m_value.object->insert(val);
21130 if (
is_object() and init.size() == 2 and (*init.begin())->is_string())
21132 basic_json&& key = init.begin()->moved_or_copied();
21133 push_back(
typename object_t::value_type(
21134 std::move(key.get_ref<
string_t&>()), (init.begin() + 1)->moved_or_copied()));
21175 template<
class... Args>
21181 JSON_THROW(type_error::create(311,
"cannot use emplace_back() with " + std::string(
type_name())));
21187 m_type = value_t::array;
21188 m_value = value_t::array;
21189 assert_invariant();
21193 #ifdef JSON_HAS_CPP_17
21194 return m_value.array->emplace_back(std::forward<Args>(args)...);
21196 m_value.array->emplace_back(std::forward<Args>(args)...);
21197 return m_value.array->back();
21228 template<
class... Args>
21229 std::pair<iterator, bool>
emplace(Args&& ... args)
21234 JSON_THROW(type_error::create(311,
"cannot use emplace() with " + std::string(
type_name())));
21240 m_type = value_t::object;
21241 m_value = value_t::object;
21242 assert_invariant();
21246 auto res = m_value.object->emplace(std::forward<Args>(args)...);
21249 it.m_it.object_iterator = res.first;
21252 return {it, res.second};
21258 template<
typename... Args>
21262 assert(m_value.array !=
nullptr);
21264 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
21265 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
21266 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
21300 if (JSON_HEDLEY_LIKELY(
is_array()))
21303 if (JSON_HEDLEY_UNLIKELY(pos.m_object !=
this))
21305 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
21312 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(
type_name())));
21321 return insert(pos, val);
21351 if (JSON_HEDLEY_LIKELY(
is_array()))
21354 if (JSON_HEDLEY_UNLIKELY(pos.m_object !=
this))
21356 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
21363 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(
type_name())));
21399 if (JSON_HEDLEY_UNLIKELY(not
is_array()))
21401 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(
type_name())));
21405 if (JSON_HEDLEY_UNLIKELY(pos.m_object !=
this))
21407 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
21411 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21413 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
21416 if (JSON_HEDLEY_UNLIKELY(first.m_object ==
this))
21418 JSON_THROW(invalid_iterator::create(211,
"passed iterators may not belong to container"));
21422 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
21452 if (JSON_HEDLEY_UNLIKELY(not
is_array()))
21454 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(
type_name())));
21458 if (JSON_HEDLEY_UNLIKELY(pos.m_object !=
this))
21460 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
21493 if (JSON_HEDLEY_UNLIKELY(not
is_object()))
21495 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(
type_name())));
21499 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21501 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
21505 if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object()))
21507 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
21510 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
21537 m_type = value_t::object;
21538 m_value.object = create<object_t>();
21539 assert_invariant();
21544 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(
type_name())));
21546 if (JSON_HEDLEY_UNLIKELY(not j.is_object()))
21548 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(j.type_name())));
21551 for (
auto it = j.cbegin(); it != j.cend(); ++it)
21553 m_value.object->operator[](it.key()) = it.value();
21588 m_type = value_t::object;
21589 m_value.object = create<object_t>();
21590 assert_invariant();
21595 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(
type_name())));
21599 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21601 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
21605 if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object()
21606 or not last.m_object->is_object()))
21608 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
21611 for (
auto it = first; it != last; ++it)
21613 m_value.object->operator[](it.key()) = it.value();
21635 std::is_nothrow_move_constructible<value_t>::value and
21636 std::is_nothrow_move_assignable<value_t>::value and
21637 std::is_nothrow_move_constructible<json_value>::value and
21638 std::is_nothrow_move_assignable<json_value>::value
21641 std::swap(m_type, other.m_type);
21642 std::swap(m_value, other.m_value);
21643 assert_invariant();
21669 if (JSON_HEDLEY_LIKELY(
is_array()))
21671 std::swap(*(m_value.array), other);
21675 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(
type_name())));
21704 std::swap(*(m_value.object), other);
21708 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(
type_name())));
21737 std::swap(*(m_value.string), other);
21741 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(
type_name())));
21770 std::swap(*(m_value.binary), other);
21774 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(
type_name())));
21784 std::swap(*(m_value.binary), other);
21788 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(
type_name())));
21859 const auto lhs_type = lhs.type();
21860 const auto rhs_type = rhs.type();
21862 if (lhs_type == rhs_type)
21866 case value_t::array:
21867 return *lhs.m_value.array == *rhs.m_value.array;
21869 case value_t::object:
21870 return *lhs.m_value.object == *rhs.m_value.object;
21872 case value_t::null:
21875 case value_t::string:
21876 return *lhs.m_value.string == *rhs.m_value.string;
21878 case value_t::boolean:
21879 return lhs.m_value.boolean == rhs.m_value.boolean;
21881 case value_t::number_integer:
21882 return lhs.m_value.number_integer == rhs.m_value.number_integer;
21884 case value_t::number_unsigned:
21885 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
21887 case value_t::number_float:
21888 return lhs.m_value.number_float == rhs.m_value.number_float;
21890 case value_t::binary:
21891 return *lhs.m_value.binary == *rhs.m_value.binary;
21897 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
21899 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
21901 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
21903 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer);
21905 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
21907 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
21909 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
21911 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned);
21913 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
21915 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
21917 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
21919 return lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
21929 template<
typename ScalarType,
typename std::enable_if<
21930 std::is_scalar<ScalarType>::value,
int>
::type = 0>
21940 template<
typename ScalarType,
typename std::enable_if<
21941 std::is_scalar<ScalarType>::value,
int>
::type = 0>
21967 return not (lhs == rhs);
21974 template<
typename ScalarType,
typename std::enable_if<
21975 std::is_scalar<ScalarType>::value,
int>
::type = 0>
21985 template<
typename ScalarType,
typename std::enable_if<
21986 std::is_scalar<ScalarType>::value,
int>
::type = 0>
22020 const auto lhs_type = lhs.type();
22021 const auto rhs_type = rhs.type();
22023 if (lhs_type == rhs_type)
22027 case value_t::array:
22030 return (*lhs.m_value.array) < (*rhs.m_value.array);
22032 case value_t::object:
22033 return (*lhs.m_value.object) < (*rhs.m_value.object);
22035 case value_t::null:
22038 case value_t::string:
22039 return (*lhs.m_value.string) < (*rhs.m_value.string);
22041 case value_t::boolean:
22042 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
22044 case value_t::number_integer:
22045 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
22047 case value_t::number_unsigned:
22048 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
22050 case value_t::number_float:
22051 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
22053 case value_t::binary:
22054 return (*lhs.m_value.binary) < (*rhs.m_value.binary);
22060 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
22062 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
22064 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
22066 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
22068 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
22070 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
22072 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
22074 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
22076 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
22078 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22080 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
22082 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
22095 template<
typename ScalarType,
typename std::enable_if<
22096 std::is_scalar<ScalarType>::value,
int>
::type = 0>
22106 template<
typename ScalarType,
typename std::enable_if<
22107 std::is_scalar<ScalarType>::value,
int>
::type = 0>
22134 return not (rhs < lhs);
22141 template<
typename ScalarType,
typename std::enable_if<
22142 std::is_scalar<ScalarType>::value,
int>
::type = 0>
22152 template<
typename ScalarType,
typename std::enable_if<
22153 std::is_scalar<ScalarType>::value,
int>
::type = 0>
22180 return not (lhs <= rhs);
22187 template<
typename ScalarType,
typename std::enable_if<
22188 std::is_scalar<ScalarType>::value,
int>
::type = 0>
22198 template<
typename ScalarType,
typename std::enable_if<
22199 std::is_scalar<ScalarType>::value,
int>
::type = 0>
22226 return not (lhs < rhs);
22233 template<
typename ScalarType,
typename std::enable_if<
22234 std::is_scalar<ScalarType>::value,
int>
::type = 0>
22244 template<
typename ScalarType,
typename std::enable_if<
22245 std::is_scalar<ScalarType>::value,
int>
::type = 0>
22294 const bool pretty_print = o.width() > 0;
22295 const auto indentation = pretty_print ? o.width() : 0;
22301 serializer s(detail::output_adapter<char>(o), o.fill());
22302 s.dump(j, pretty_print,
false,
static_cast<unsigned int>(indentation));
22314 JSON_HEDLEY_DEPRECATED_FOR(3.0.0,
operator<<(std::ostream&,
const basic_json&))
22377 template<
typename InputType>
22381 const bool allow_exceptions =
true)
22384 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions).parse(
true, result);
22411 template<
typename IteratorType>
22416 const bool allow_exceptions =
true)
22419 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions).parse(
true, result);
22424 JSON_HEDLEY_DEPRECATED_FOR(3.8.0,
parse(ptr, ptr + len))
22427 const bool allow_exceptions =
true)
22430 parser(i.get(), cb, allow_exceptions).parse(
true, result);
22461 template<
typename InputType>
22462 static bool accept(InputType&& i)
22464 return parser(detail::input_adapter(std::forward<InputType>(i))).accept(
true);
22467 template<
typename IteratorType>
22468 static bool accept(IteratorType first, IteratorType last)
22470 return parser(detail::input_adapter(std::move(first), std::move(last))).accept(
true);
22474 JSON_HEDLEY_DEPRECATED_FOR(3.8.0,
accept(ptr, ptr + len))
22475 static bool accept(detail::span_input_adapter&& i)
22477 return parser(i.get()).accept(
true);
22517 template <
typename InputType,
typename SAX>
22518 JSON_HEDLEY_NON_NULL(2)
22519 static
bool sax_parse(InputType&& i, SAX* sax,
22521 const
bool strict = true)
22523 auto ia = detail::input_adapter(std::forward<InputType>(i));
22524 return format == input_format_t::json
22525 ? parser(std::move(ia)).sax_parse(sax, strict)
22526 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
22529 template<
class IteratorType,
class SAX>
22530 JSON_HEDLEY_NON_NULL(3)
22531 static
bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
22532 input_format_t format = input_format_t::
json,
22533 const
bool strict = true)
22535 auto ia = detail::input_adapter(std::move(first), std::move(last));
22536 return format == input_format_t::json
22537 ? parser(std::move(ia)).sax_parse(sax, strict)
22538 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
22541 template <
typename SAX>
22542 JSON_HEDLEY_DEPRECATED_FOR(3.8.0,
sax_parse(ptr, ptr + len, ...))
22543 JSON_HEDLEY_NON_NULL(2)
22544 static
bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
22545 input_format_t format = input_format_t::
json,
22546 const
bool strict = true)
22549 return format == input_format_t::json
22550 ? parser(std::move(ia)).sax_parse(sax, strict)
22551 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
22562 JSON_HEDLEY_DEPRECATED_FOR(3.0.0,
operator>>(std::istream&,
basic_json&))
22595 parser(detail::input_adapter(i)).parse(
false, j);
22642 case value_t::null:
22644 case value_t::object:
22646 case value_t::array:
22648 case value_t::string:
22650 case value_t::boolean:
22652 case value_t::binary:
22654 case value_t::discarded:
22655 return "discarded";
22669 value_t m_type = value_t::null;
22672 json_value m_value = {};
22779 std::vector<uint8_t> result;
22786 binary_writer<uint8_t>(o).write_cbor(j);
22791 binary_writer<char>(o).write_cbor(j);
22876 std::vector<uint8_t> result;
22883 binary_writer<uint8_t>(o).write_msgpack(j);
22888 binary_writer<char>(o).write_msgpack(j);
22978 const bool use_size =
false,
22979 const bool use_type =
false)
22981 std::vector<uint8_t> result;
22982 to_ubjson(j, result, use_size, use_type);
22987 const bool use_size =
false,
const bool use_type =
false)
22989 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
22993 const bool use_size =
false,
const bool use_type =
false)
22995 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23057 std::vector<uint8_t> result;
23072 binary_writer<uint8_t>(o).write_bson(j);
23080 binary_writer<char>(o).write_bson(j);
23186 template<
typename InputType>
23189 const bool strict =
true,
23190 const bool allow_exceptions =
true)
23193 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23194 auto ia = detail::input_adapter(std::forward<InputType>(i));
23195 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict);
23196 return res ? result :
basic_json(value_t::discarded);
23202 template<
typename IteratorType>
23205 const bool strict =
true,
23206 const bool allow_exceptions =
true)
23209 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23210 auto ia = detail::input_adapter(std::move(first), std::move(last));
23211 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict);
23212 return res ? result :
basic_json(value_t::discarded);
23215 template<
typename T>
23217 JSON_HEDLEY_DEPRECATED_FOR(3.8.0,
from_cbor(ptr, ptr + len))
23219 const bool strict =
true,
23220 const bool allow_exceptions =
true)
23222 return from_cbor(ptr, ptr + len, strict, allow_exceptions);
23227 JSON_HEDLEY_DEPRECATED_FOR(3.8.0,
from_cbor(ptr, ptr + len))
23229 const
bool strict = true,
23230 const
bool allow_exceptions = true)
23233 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23235 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict);
23236 return res ? result :
basic_json(value_t::discarded);
23325 template<
typename InputType>
23328 const bool strict =
true,
23329 const bool allow_exceptions =
true)
23332 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23333 auto ia = detail::input_adapter(std::forward<InputType>(i));
23334 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
23335 return res ? result :
basic_json(value_t::discarded);
23341 template<
typename IteratorType>
23344 const bool strict =
true,
23345 const bool allow_exceptions =
true)
23348 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23349 auto ia = detail::input_adapter(std::move(first), std::move(last));
23350 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
23351 return res ? result :
basic_json(value_t::discarded);
23355 template<
typename T>
23357 JSON_HEDLEY_DEPRECATED_FOR(3.8.0,
from_msgpack(ptr, ptr + len))
23359 const bool strict =
true,
23360 const bool allow_exceptions =
true)
23362 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
23366 JSON_HEDLEY_DEPRECATED_FOR(3.8.0,
from_msgpack(ptr, ptr + len))
23368 const bool strict =
true,
23369 const bool allow_exceptions =
true)
23372 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23374 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
23375 return res ? result :
basic_json(value_t::discarded);
23440 template<
typename InputType>
23443 const bool strict =
true,
23444 const bool allow_exceptions =
true)
23447 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23448 auto ia = detail::input_adapter(std::forward<InputType>(i));
23449 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
23450 return res ? result :
basic_json(value_t::discarded);
23456 template<
typename IteratorType>
23459 const bool strict =
true,
23460 const bool allow_exceptions =
true)
23463 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23464 auto ia = detail::input_adapter(std::move(first), std::move(last));
23465 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
23466 return res ? result :
basic_json(value_t::discarded);
23469 template<
typename T>
23471 JSON_HEDLEY_DEPRECATED_FOR(3.8.0,
from_ubjson(ptr, ptr + len))
23473 const bool strict =
true,
23474 const bool allow_exceptions =
true)
23476 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
23480 JSON_HEDLEY_DEPRECATED_FOR(3.8.0,
from_ubjson(ptr, ptr + len))
23482 const bool strict =
true,
23483 const bool allow_exceptions =
true)
23486 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23488 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
23489 return res ? result :
basic_json(value_t::discarded);
23553 template<
typename InputType>
23556 const bool strict =
true,
23557 const bool allow_exceptions =
true)
23560 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23561 auto ia = detail::input_adapter(std::forward<InputType>(i));
23562 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
23563 return res ? result :
basic_json(value_t::discarded);
23569 template<
typename IteratorType>
23572 const bool strict =
true,
23573 const bool allow_exceptions =
true)
23576 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23577 auto ia = detail::input_adapter(std::move(first), std::move(last));
23578 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
23579 return res ? result :
basic_json(value_t::discarded);
23582 template<
typename T>
23584 JSON_HEDLEY_DEPRECATED_FOR(3.8.0,
from_bson(ptr, ptr + len))
23586 const bool strict =
true,
23587 const bool allow_exceptions =
true)
23589 return from_bson(ptr, ptr + len, strict, allow_exceptions);
23593 JSON_HEDLEY_DEPRECATED_FOR(3.8.0,
from_bson(ptr, ptr + len))
23595 const bool strict =
true,
23596 const bool allow_exceptions =
true)
23599 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23601 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
23602 return res ? result :
basic_json(value_t::discarded);
23648 return ptr.get_unchecked(
this);
23676 return ptr.get_unchecked(
this);
23719 return ptr.get_checked(
this);
23762 return ptr.get_checked(
this);
23790 json_pointer::flatten(
"", *
this, result);
23826 return json_pointer::unflatten(*
this);
23891 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
23893 const auto get_op = [](
const std::string & op)
23897 return patch_operations::add;
23899 if (op ==
"remove")
23901 return patch_operations::remove;
23903 if (op ==
"replace")
23905 return patch_operations::replace;
23909 return patch_operations::move;
23913 return patch_operations::copy;
23917 return patch_operations::test;
23920 return patch_operations::invalid;
23935 if (top_pointer != ptr)
23937 result.at(top_pointer);
23941 const auto last_path = ptr.back();
23945 switch (parent.m_type)
23947 case value_t::null:
23948 case value_t::object:
23951 parent[last_path] = val;
23955 case value_t::array:
23957 if (last_path ==
"-")
23960 parent.push_back(val);
23964 const auto idx = json_pointer::array_index(last_path);
23965 if (JSON_HEDLEY_UNLIKELY(
static_cast<size_type>(idx) > parent.size()))
23968 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
23972 parent.insert(parent.begin() +
static_cast<difference_type>(idx), val);
23984 const auto operation_remove = [&result](
json_pointer & ptr)
23987 const auto last_path = ptr.back();
23992 if (parent.is_object())
23995 auto it = parent.find(last_path);
23996 if (JSON_HEDLEY_LIKELY(it != parent.end()))
24002 JSON_THROW(out_of_range::create(403,
"key '" + last_path +
"' not found"));
24005 else if (parent.is_array())
24008 parent.erase(
static_cast<size_type>(json_pointer::array_index(last_path)));
24013 if (JSON_HEDLEY_UNLIKELY(not json_patch.is_array()))
24015 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
24019 for (
const auto& val : json_patch)
24022 const auto get_value = [&val](
const std::string & op,
24023 const std::string & member,
24027 auto it = val.m_value.object->find(member);
24030 const auto error_msg = (op ==
"op") ?
"operation" :
"operation '" + op +
"'";
24033 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
24035 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have member '" + member +
"'"));
24039 if (JSON_HEDLEY_UNLIKELY(string_type and not it->second.is_string()))
24041 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have string member '" + member +
"'"));
24049 if (JSON_HEDLEY_UNLIKELY(not val.is_object()))
24051 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
24055 const std::string op = get_value(
"op",
"op",
true);
24056 const std::string path = get_value(op,
"path",
true);
24059 switch (get_op(op))
24061 case patch_operations::add:
24063 operation_add(ptr, get_value(
"add",
"value",
false));
24067 case patch_operations::remove:
24069 operation_remove(ptr);
24073 case patch_operations::replace:
24076 result.at(ptr) = get_value(
"replace",
"value",
false);
24080 case patch_operations::move:
24082 const std::string from_path = get_value(
"move",
"from",
true);
24092 operation_remove(from_ptr);
24093 operation_add(ptr, v);
24097 case patch_operations::copy:
24099 const std::string from_path = get_value(
"copy",
"from",
true);
24108 operation_add(ptr, v);
24112 case patch_operations::test:
24114 bool success =
false;
24119 success = (result.at(ptr) == get_value(
"test",
"value",
false));
24127 if (JSON_HEDLEY_UNLIKELY(not success))
24129 JSON_THROW(other_error::create(501,
"unsuccessful: " + val.dump()));
24139 JSON_THROW(parse_error::create(105, 0,
"operation value '" + op +
"' is invalid"));
24182 const std::string& path =
"")
24188 if (source == target)
24193 if (source.type() != target.type())
24198 {
"op",
"replace"}, {
"path", path}, {
"value", target}
24203 switch (source.type())
24205 case value_t::array:
24209 while (i < source.size() and i < target.size())
24212 auto temp_diff =
diff(source[i], target[i], path +
"/" + std::to_string(i));
24213 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24222 while (i < source.size())
24226 result.insert(result.begin() + end_index,
object(
24229 {
"path", path +
"/" + std::to_string(i)}
24235 while (i < target.size())
24240 {
"path", path +
"/-"},
24241 {
"value", target[i]}
24249 case value_t::object:
24252 for (
auto it = source.cbegin(); it != source.cend(); ++it)
24255 const auto key = json_pointer::escape(it.key());
24257 if (target.find(it.key()) != target.end())
24260 auto temp_diff =
diff(it.value(), target[it.key()], path +
"/" + key);
24261 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24266 result.push_back(
object(
24268 {
"op",
"remove"}, {
"path", path +
"/" + key}
24274 for (
auto it = target.cbegin(); it != target.cend(); ++it)
24276 if (source.find(it.key()) == source.end())
24279 const auto key = json_pointer::escape(it.key());
24282 {
"op",
"add"}, {
"path", path +
"/" + key},
24283 {
"value", it.value()}
24296 {
"op",
"replace"}, {
"path", path}, {
"value", target}
24358 if (apply_patch.is_object())
24364 for (
auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
24366 if (it.value().is_null())
24378 *
this = apply_patch;
24394 NLOHMANN_BASIC_JSON_TPL_DECLARATION
24395 std::string
to_string(
const NLOHMANN_BASIC_JSON_TPL& j)
24421 const auto& h = hash<nlohmann::json::string_t>();
24422 return h(j.
dump());
24430 struct less<::nlohmann::detail::value_t>
24436 bool operator()(nlohmann::detail::value_t lhs,
24437 nlohmann::detail::value_t rhs)
const noexcept
24439 return nlohmann::detail::operator<(lhs, rhs);
24450 is_nothrow_move_constructible<nlohmann::json>::value and
24451 is_nothrow_move_assignable<nlohmann::json>::value
24472 JSON_HEDLEY_NON_NULL(1)
24473 inline
nlohmann::
json operator "" _json(const
char* s, std::
size_t n)
24491 JSON_HEDLEY_NON_NULL(1)
24492 inline
nlohmann::
json::json_pointer operator "" _json_pointer(const
char* s, std::
size_t n)
24501 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
24502 #pragma GCC diagnostic pop
24504 #if defined(__clang__)
24505 #pragma GCC diagnostic pop
24509 #undef JSON_INTERNAL_CATCH
24513 #undef JSON_HAS_CPP_14
24514 #undef JSON_HAS_CPP_17
24515 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
24516 #undef NLOHMANN_BASIC_JSON_TPL
24519 #undef JSON_HEDLEY_ALWAYS_INLINE
24520 #undef JSON_HEDLEY_ARM_VERSION
24521 #undef JSON_HEDLEY_ARM_VERSION_CHECK
24522 #undef JSON_HEDLEY_ARRAY_PARAM
24523 #undef JSON_HEDLEY_ASSUME
24524 #undef JSON_HEDLEY_BEGIN_C_DECLS
24525 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
24526 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
24527 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
24528 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
24529 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
24530 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
24531 #undef JSON_HEDLEY_CLANG_HAS_WARNING
24532 #undef JSON_HEDLEY_COMPCERT_VERSION
24533 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
24534 #undef JSON_HEDLEY_CONCAT
24535 #undef JSON_HEDLEY_CONCAT3
24536 #undef JSON_HEDLEY_CONCAT3_EX
24537 #undef JSON_HEDLEY_CONCAT_EX
24538 #undef JSON_HEDLEY_CONST
24539 #undef JSON_HEDLEY_CONSTEXPR
24540 #undef JSON_HEDLEY_CONST_CAST
24541 #undef JSON_HEDLEY_CPP_CAST
24542 #undef JSON_HEDLEY_CRAY_VERSION
24543 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
24544 #undef JSON_HEDLEY_C_DECL
24545 #undef JSON_HEDLEY_DEPRECATED
24546 #undef JSON_HEDLEY_DEPRECATED_FOR
24547 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
24548 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
24549 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
24550 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
24551 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
24552 #undef JSON_HEDLEY_DIAGNOSTIC_POP
24553 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
24554 #undef JSON_HEDLEY_DMC_VERSION
24555 #undef JSON_HEDLEY_DMC_VERSION_CHECK
24556 #undef JSON_HEDLEY_EMPTY_BASES
24557 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
24558 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
24559 #undef JSON_HEDLEY_END_C_DECLS
24560 #undef JSON_HEDLEY_FLAGS
24561 #undef JSON_HEDLEY_FLAGS_CAST
24562 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
24563 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
24564 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
24565 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
24566 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
24567 #undef JSON_HEDLEY_GCC_HAS_FEATURE
24568 #undef JSON_HEDLEY_GCC_HAS_WARNING
24569 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
24570 #undef JSON_HEDLEY_GCC_VERSION
24571 #undef JSON_HEDLEY_GCC_VERSION_CHECK
24572 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
24573 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
24574 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
24575 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
24576 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
24577 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
24578 #undef JSON_HEDLEY_GNUC_HAS_WARNING
24579 #undef JSON_HEDLEY_GNUC_VERSION
24580 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
24581 #undef JSON_HEDLEY_HAS_ATTRIBUTE
24582 #undef JSON_HEDLEY_HAS_BUILTIN
24583 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
24584 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
24585 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
24586 #undef JSON_HEDLEY_HAS_EXTENSION
24587 #undef JSON_HEDLEY_HAS_FEATURE
24588 #undef JSON_HEDLEY_HAS_WARNING
24589 #undef JSON_HEDLEY_IAR_VERSION
24590 #undef JSON_HEDLEY_IAR_VERSION_CHECK
24591 #undef JSON_HEDLEY_IBM_VERSION
24592 #undef JSON_HEDLEY_IBM_VERSION_CHECK
24593 #undef JSON_HEDLEY_IMPORT
24594 #undef JSON_HEDLEY_INLINE
24595 #undef JSON_HEDLEY_INTEL_VERSION
24596 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
24597 #undef JSON_HEDLEY_IS_CONSTANT
24598 #undef JSON_HEDLEY_IS_CONSTEXPR_
24599 #undef JSON_HEDLEY_LIKELY
24600 #undef JSON_HEDLEY_MALLOC
24601 #undef JSON_HEDLEY_MESSAGE
24602 #undef JSON_HEDLEY_MSVC_VERSION
24603 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
24604 #undef JSON_HEDLEY_NEVER_INLINE
24605 #undef JSON_HEDLEY_NON_NULL
24606 #undef JSON_HEDLEY_NO_ESCAPE
24607 #undef JSON_HEDLEY_NO_RETURN
24608 #undef JSON_HEDLEY_NO_THROW
24609 #undef JSON_HEDLEY_NULL
24610 #undef JSON_HEDLEY_PELLES_VERSION
24611 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
24612 #undef JSON_HEDLEY_PGI_VERSION
24613 #undef JSON_HEDLEY_PGI_VERSION_CHECK
24614 #undef JSON_HEDLEY_PREDICT
24615 #undef JSON_HEDLEY_PRINTF_FORMAT
24616 #undef JSON_HEDLEY_PRIVATE
24617 #undef JSON_HEDLEY_PUBLIC
24618 #undef JSON_HEDLEY_PURE
24619 #undef JSON_HEDLEY_REINTERPRET_CAST
24620 #undef JSON_HEDLEY_REQUIRE
24621 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
24622 #undef JSON_HEDLEY_REQUIRE_MSG
24623 #undef JSON_HEDLEY_RESTRICT
24625 #undef JSON_HEDLEY_SENTINEL
24626 #undef JSON_HEDLEY_STATIC_ASSERT
24627 #undef JSON_HEDLEY_STATIC_CAST
24628 #undef JSON_HEDLEY_STRINGIFY
24629 #undef JSON_HEDLEY_STRINGIFY_EX
24630 #undef JSON_HEDLEY_SUNPRO_VERSION
24631 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
24632 #undef JSON_HEDLEY_TINYC_VERSION
24633 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
24634 #undef JSON_HEDLEY_TI_ARMCL_VERSION
24635 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
24636 #undef JSON_HEDLEY_TI_CL2000_VERSION
24637 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
24638 #undef JSON_HEDLEY_TI_CL430_VERSION
24639 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
24640 #undef JSON_HEDLEY_TI_CL6X_VERSION
24641 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
24642 #undef JSON_HEDLEY_TI_CL7X_VERSION
24643 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
24644 #undef JSON_HEDLEY_TI_CLPRU_VERSION
24645 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
24646 #undef JSON_HEDLEY_TI_VERSION
24647 #undef JSON_HEDLEY_TI_VERSION_CHECK
24648 #undef JSON_HEDLEY_UNAVAILABLE
24649 #undef JSON_HEDLEY_UNLIKELY
24650 #undef JSON_HEDLEY_UNPREDICTABLE
24651 #undef JSON_HEDLEY_UNREACHABLE
24652 #undef JSON_HEDLEY_UNREACHABLE_RETURN
24653 #undef JSON_HEDLEY_VERSION
24654 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
24655 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
24656 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
24657 #undef JSON_HEDLEY_VERSION_ENCODE
24658 #undef JSON_HEDLEY_WARNING
24661 #undef JSON_HEDLEY_FALL_THROUGH
24665 #endif // INCLUDE_NLOHMANN_JSON_HPP_