30 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
31 #define INCLUDE_NLOHMANN_JSON_HPP_
33 #define NLOHMANN_JSON_VERSION_MAJOR 3
34 #define NLOHMANN_JSON_VERSION_MINOR 7
35 #define NLOHMANN_JSON_VERSION_PATCH 3
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>
2737 struct adl_serializer;
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>
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 JSON_HEDLEY_NON_NULL(2)
4460 explicit file_input_adapter(std::FILE* f) noexcept
4465 file_input_adapter(
const file_input_adapter&) =
delete;
4466 file_input_adapter(file_input_adapter&&) =
default;
4467 file_input_adapter& operator=(
const file_input_adapter&) =
delete;
4468 file_input_adapter& operator=(file_input_adapter&&) =
delete;
4470 std::char_traits<char>::int_type get_character() noexcept
4472 return std::fgetc(m_file);
4490 class input_stream_adapter
4493 ~input_stream_adapter()
4499 is->clear(is->rdstate() & std::ios::eofbit);
4503 explicit input_stream_adapter(std::istream& i)
4504 : is(&i), sb(i.rdbuf())
4508 input_stream_adapter(
const input_stream_adapter&) =
delete;
4509 input_stream_adapter& operator=(input_stream_adapter&) =
delete;
4510 input_stream_adapter& operator=(input_stream_adapter&& rhs) =
delete;
4512 input_stream_adapter(input_stream_adapter&& rhs) : is(rhs.is), sb(rhs.sb)
4521 std::char_traits<char>::int_type get_character()
4523 auto res = sb->sbumpc();
4527 is->clear(is->rdstate() | std::ios::eofbit);
4534 std::istream* is =
nullptr;
4535 std::streambuf* sb =
nullptr;
4539 class input_buffer_adapter
4542 input_buffer_adapter(
const char* b,
const std::size_t l) noexcept
4543 : cursor(b), limit(b ==
nullptr ?
nullptr : (b + l))
4547 input_buffer_adapter(
const input_buffer_adapter&) =
delete;
4548 input_buffer_adapter& operator=(input_buffer_adapter&) =
delete;
4549 input_buffer_adapter(input_buffer_adapter&&) =
default;
4550 input_buffer_adapter& operator=(input_buffer_adapter&&) =
delete;
4552 std::char_traits<char>::int_type get_character() noexcept
4554 if (JSON_HEDLEY_LIKELY(cursor < limit))
4556 assert(cursor !=
nullptr and limit !=
nullptr);
4557 return std::char_traits<char>::to_int_type(*(cursor++));
4560 return std::char_traits<char>::eof();
4567 const char*
const limit;
4570 template<
typename W
ideStringType,
size_t T>
4571 struct wide_string_input_helper
4574 static void fill_buffer(
const WideStringType& str,
4575 size_t& current_wchar,
4576 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4577 size_t& utf8_bytes_index,
4578 size_t& utf8_bytes_filled)
4580 utf8_bytes_index = 0;
4582 if (current_wchar == str.size())
4584 utf8_bytes[0] = std::char_traits<char>::eof();
4585 utf8_bytes_filled = 1;
4590 const auto wc =
static_cast<unsigned int>(str[current_wchar++]);
4595 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
4596 utf8_bytes_filled = 1;
4598 else if (wc <= 0x7FF)
4600 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xC0u | ((wc >> 6u) & 0x1Fu));
4601 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (wc & 0x3Fu));
4602 utf8_bytes_filled = 2;
4604 else if (wc <= 0xFFFF)
4606 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xE0u | ((wc >> 12u) & 0x0Fu));
4607 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((wc >> 6u) & 0x3Fu));
4608 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (wc & 0x3Fu));
4609 utf8_bytes_filled = 3;
4611 else if (wc <= 0x10FFFF)
4613 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xF0u | ((wc >> 18u) & 0x07u));
4614 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((wc >> 12u) & 0x3Fu));
4615 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((wc >> 6u) & 0x3Fu));
4616 utf8_bytes[3] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (wc & 0x3Fu));
4617 utf8_bytes_filled = 4;
4622 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
4623 utf8_bytes_filled = 1;
4629 template<
typename W
ideStringType>
4630 struct wide_string_input_helper<WideStringType, 2>
4633 static void fill_buffer(
const WideStringType& str,
4634 size_t& current_wchar,
4635 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4636 size_t& utf8_bytes_index,
4637 size_t& utf8_bytes_filled)
4639 utf8_bytes_index = 0;
4641 if (current_wchar == str.size())
4643 utf8_bytes[0] = std::char_traits<char>::eof();
4644 utf8_bytes_filled = 1;
4649 const auto wc =
static_cast<unsigned int>(str[current_wchar++]);
4654 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
4655 utf8_bytes_filled = 1;
4657 else if (wc <= 0x7FF)
4659 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xC0u | ((wc >> 6u)));
4660 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (wc & 0x3Fu));
4661 utf8_bytes_filled = 2;
4663 else if (0xD800 > wc or wc >= 0xE000)
4665 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xE0u | ((wc >> 12u)));
4666 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((wc >> 6u) & 0x3Fu));
4667 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (wc & 0x3Fu));
4668 utf8_bytes_filled = 3;
4672 if (current_wchar < str.size())
4674 const auto wc2 =
static_cast<unsigned int>(str[current_wchar++]);
4675 const auto charcode = 0x10000u + (((wc & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
4676 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xF0u | (charcode >> 18u));
4677 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((charcode >> 12u) & 0x3Fu));
4678 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((charcode >> 6u) & 0x3Fu));
4679 utf8_bytes[3] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (charcode & 0x3Fu));
4680 utf8_bytes_filled = 4;
4686 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
4687 utf8_bytes_filled = 1;
4694 template<
typename W
ideStringType>
4695 class wide_string_input_adapter
4698 explicit wide_string_input_adapter(
const WideStringType& w) noexcept
4702 std::char_traits<char>::int_type get_character() noexcept
4705 if (utf8_bytes_index == utf8_bytes_filled)
4707 fill_buffer<sizeof(typename WideStringType::value_type)>();
4709 assert(utf8_bytes_filled > 0);
4710 assert(utf8_bytes_index == 0);
4714 assert(utf8_bytes_filled > 0);
4715 assert(utf8_bytes_index < utf8_bytes_filled);
4716 return utf8_bytes[utf8_bytes_index++];
4723 wide_string_input_helper<WideStringType, T>::fill_buffer(str, current_wchar, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
4727 const WideStringType& str;
4730 std::size_t current_wchar = 0;
4733 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
4736 std::size_t utf8_bytes_index = 0;
4738 std::size_t utf8_bytes_filled = 0;
4741 inline file_input_adapter input_adapter(std::FILE* file)
4743 return file_input_adapter(file);
4746 inline input_stream_adapter input_adapter(std::istream& stream)
4748 return input_stream_adapter(stream);
4751 inline input_stream_adapter input_adapter(std::istream&& stream)
4753 return input_stream_adapter(stream);
4756 template<
typename CharT,
4757 typename std::enable_if<
4758 std::is_pointer<CharT>::value and
4759 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
4760 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
4762 input_buffer_adapter input_adapter(CharT b, std::size_t l)
4764 return input_buffer_adapter(
reinterpret_cast<const char*
>(b), l);
4767 template<
typename CharT,
4768 typename std::enable_if<
4769 std::is_pointer<CharT>::value and
4770 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
4771 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
4773 input_buffer_adapter input_adapter(CharT b)
4775 return input_adapter(
reinterpret_cast<const char*
>(b),
4776 std::strlen(
reinterpret_cast<const char*
>(b)));
4779 template<
class IteratorType,
4780 typename std::enable_if<
4781 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
4783 input_buffer_adapter input_adapter(IteratorType first, IteratorType last)
4788 const auto is_contiguous = std::accumulate(
4789 first, last, std::pair<bool, int>(
true, 0),
4790 [&first](std::pair<bool, int> res, decltype(*first) val)
4792 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
4795 assert(is_contiguous);
4800 sizeof(
typename iterator_traits<IteratorType>::value_type) == 1,
4801 "each element in the iterator range must have the size of 1 byte");
4803 const auto len =
static_cast<size_t>(std::distance(first, last));
4804 if (JSON_HEDLEY_LIKELY(len > 0))
4807 return input_buffer_adapter(
reinterpret_cast<const char*
>(&(*first)), len);
4812 return input_buffer_adapter(
nullptr, len);
4816 inline wide_string_input_adapter<std::wstring> input_adapter(
const std::wstring& ws)
4818 return wide_string_input_adapter<std::wstring>(ws);
4822 inline wide_string_input_adapter<std::u16string> input_adapter(
const std::u16string& ws)
4824 return wide_string_input_adapter<std::u16string>(ws);
4827 inline wide_string_input_adapter<std::u32string> input_adapter(
const std::u32string& ws)
4829 return wide_string_input_adapter<std::u32string>(ws);
4832 template<
class ContiguousContainer,
typename
4833 std::enable_if<not std::is_pointer<ContiguousContainer>::value and
4834 std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
4836 input_buffer_adapter input_adapter(
const ContiguousContainer& c)
4838 return input_adapter(std::begin(c), std::end(c));
4842 template<
class T, std::
size_t N>
4843 input_buffer_adapter input_adapter(T (&array)[N])
4845 return input_adapter(std::begin(array), std::end(array));
4851 class span_input_adapter
4854 template<
typename CharT,
4855 typename std::enable_if<
4856 std::is_pointer<CharT>::value and
4857 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
4858 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
4860 span_input_adapter(CharT b, std::size_t l)
4861 : ia(reinterpret_cast<const char*>(b), l) {}
4863 template<
typename CharT,
4864 typename std::enable_if<
4865 std::is_pointer<CharT>::value and
4866 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
4867 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
4869 span_input_adapter(CharT b)
4870 : span_input_adapter(reinterpret_cast<const char*>(b),
4871 std::strlen(reinterpret_cast<const char*>(b))) {}
4873 template<
class IteratorType,
4874 typename std::enable_if<
4875 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
4877 span_input_adapter(IteratorType first, IteratorType last)
4878 : ia(input_adapter(first, last)) {}
4880 template<
class T, std::
size_t N>
4881 span_input_adapter(T (&array)[N])
4882 : span_input_adapter(std::begin(array), std::end(array)) {}
4885 template<
class ContiguousContainer,
typename
4886 std::enable_if<not std::is_pointer<ContiguousContainer>::value and
4887 std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
4889 span_input_adapter(
const ContiguousContainer& c)
4890 : span_input_adapter(std::begin(c), std::end(c)) {}
4892 input_buffer_adapter&& get()
4894 return std::move(ia);
4898 input_buffer_adapter ia;
4928 template<
typename BasicJsonType>
4941 virtual bool null() = 0;
5032 const std::string& last_token,
5033 const detail::exception& ex) = 0;
5054 template<
typename BasicJsonType>
5055 class json_sax_dom_parser
5058 using number_integer_t =
typename BasicJsonType::number_integer_t;
5059 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
5060 using number_float_t =
typename BasicJsonType::number_float_t;
5061 using string_t =
typename BasicJsonType::string_t;
5062 using binary_t =
typename BasicJsonType::binary_t;
5069 explicit json_sax_dom_parser(BasicJsonType& r,
const bool allow_exceptions_ =
true)
5070 : root(r), allow_exceptions(allow_exceptions_)
5074 json_sax_dom_parser(
const json_sax_dom_parser&) =
delete;
5075 json_sax_dom_parser(json_sax_dom_parser&&) =
default;
5076 json_sax_dom_parser& operator=(
const json_sax_dom_parser&) =
delete;
5077 json_sax_dom_parser& operator=(json_sax_dom_parser&&) =
default;
5078 ~json_sax_dom_parser() =
default;
5082 handle_value(
nullptr);
5086 bool boolean(
bool val)
5092 bool number_integer(number_integer_t val)
5098 bool number_unsigned(number_unsigned_t val)
5104 bool number_float(number_float_t val,
const string_t& )
5110 bool string(string_t& val)
5116 bool binary(binary_t& val)
5118 handle_value(std::move(val));
5122 bool start_object(std::size_t len)
5124 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
5126 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
5128 JSON_THROW(out_of_range::create(408,
5129 "excessive object size: " + std::to_string(len)));
5135 bool key(string_t& val)
5138 object_element = &(ref_stack.back()->m_value.object->operator[](val));
5144 ref_stack.pop_back();
5148 bool start_array(std::size_t len)
5150 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
5152 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
5154 JSON_THROW(out_of_range::create(408,
5155 "excessive array size: " + std::to_string(len)));
5163 ref_stack.pop_back();
5167 bool parse_error(std::size_t ,
const std::string& ,
5168 const detail::exception& ex)
5171 if (allow_exceptions)
5174 switch ((ex.id / 100) % 100)
5177 JSON_THROW(*
static_cast<const detail::parse_error*
>(&ex));
5179 JSON_THROW(*
static_cast<const detail::out_of_range*
>(&ex));
5182 JSON_THROW(*
static_cast<const detail::invalid_iterator*
>(&ex));
5184 JSON_THROW(*
static_cast<const detail::type_error*
>(&ex));
5186 JSON_THROW(*
static_cast<const detail::other_error*
>(&ex));
5195 constexpr
bool is_errored()
const
5207 template<
typename Value>
5209 BasicJsonType* handle_value(Value&& v)
5211 if (ref_stack.empty())
5213 root = BasicJsonType(std::forward<Value>(v));
5217 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
5219 if (ref_stack.back()->is_array())
5221 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
5222 return &(ref_stack.back()->m_value.array->back());
5225 assert(ref_stack.back()->is_object());
5226 assert(object_element);
5227 *object_element = BasicJsonType(std::forward<Value>(v));
5228 return object_element;
5232 BasicJsonType& root;
5234 std::vector<BasicJsonType*> ref_stack {};
5236 BasicJsonType* object_element =
nullptr;
5238 bool errored =
false;
5240 const bool allow_exceptions =
true;
5243 template<
typename BasicJsonType>
5244 class json_sax_dom_callback_parser
5247 using number_integer_t =
typename BasicJsonType::number_integer_t;
5248 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
5249 using number_float_t =
typename BasicJsonType::number_float_t;
5250 using string_t =
typename BasicJsonType::string_t;
5251 using binary_t =
typename BasicJsonType::binary_t;
5252 using parser_callback_t =
typename BasicJsonType::parser_callback_t;
5253 using parse_event_t =
typename BasicJsonType::parse_event_t;
5255 json_sax_dom_callback_parser(BasicJsonType& r,
5256 const parser_callback_t cb,
5257 const bool allow_exceptions_ =
true)
5258 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
5260 keep_stack.push_back(
true);
5264 json_sax_dom_callback_parser(
const json_sax_dom_callback_parser&) =
delete;
5265 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) =
default;
5266 json_sax_dom_callback_parser& operator=(
const json_sax_dom_callback_parser&) =
delete;
5267 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) =
default;
5268 ~json_sax_dom_callback_parser() =
default;
5272 handle_value(
nullptr);
5276 bool boolean(
bool val)
5282 bool number_integer(number_integer_t val)
5288 bool number_unsigned(number_unsigned_t val)
5294 bool number_float(number_float_t val,
const string_t& )
5300 bool string(string_t& val)
5306 bool binary(binary_t& val)
5308 handle_value(std::move(val));
5312 bool start_object(std::size_t len)
5315 const bool keep = callback(
static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
5316 keep_stack.push_back(keep);
5318 auto val = handle_value(BasicJsonType::value_t::object,
true);
5319 ref_stack.push_back(val.second);
5322 if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
5324 JSON_THROW(out_of_range::create(408,
"excessive object size: " + std::to_string(len)));
5330 bool key(string_t& val)
5332 BasicJsonType k = BasicJsonType(val);
5335 const bool keep = callback(
static_cast<int>(ref_stack.size()), parse_event_t::key, k);
5336 key_keep_stack.push_back(keep);
5339 if (keep and ref_stack.back())
5341 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
5349 if (ref_stack.back() and not callback(
static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
5352 *ref_stack.back() = discarded;
5355 assert(not ref_stack.empty());
5356 assert(not keep_stack.empty());
5357 ref_stack.pop_back();
5358 keep_stack.pop_back();
5360 if (not ref_stack.empty() and ref_stack.back() and ref_stack.back()->is_object())
5363 for (
auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
5365 if (it->is_discarded())
5367 ref_stack.back()->erase(it);
5376 bool start_array(std::size_t len)
5378 const bool keep = callback(
static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
5379 keep_stack.push_back(keep);
5381 auto val = handle_value(BasicJsonType::value_t::array,
true);
5382 ref_stack.push_back(val.second);
5385 if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
5387 JSON_THROW(out_of_range::create(408,
"excessive array size: " + std::to_string(len)));
5397 if (ref_stack.back())
5399 keep = callback(
static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
5403 *ref_stack.back() = discarded;
5407 assert(not ref_stack.empty());
5408 assert(not keep_stack.empty());
5409 ref_stack.pop_back();
5410 keep_stack.pop_back();
5413 if (not keep and not ref_stack.empty() and ref_stack.back()->is_array())
5415 ref_stack.back()->m_value.array->pop_back();
5421 bool parse_error(std::size_t ,
const std::string& ,
5422 const detail::exception& ex)
5425 if (allow_exceptions)
5428 switch ((ex.id / 100) % 100)
5431 JSON_THROW(*
static_cast<const detail::parse_error*
>(&ex));
5433 JSON_THROW(*
static_cast<const detail::out_of_range*
>(&ex));
5436 JSON_THROW(*
static_cast<const detail::invalid_iterator*
>(&ex));
5438 JSON_THROW(*
static_cast<const detail::type_error*
>(&ex));
5440 JSON_THROW(*
static_cast<const detail::other_error*
>(&ex));
5449 constexpr
bool is_errored()
const
5470 template<
typename Value>
5471 std::pair<bool, BasicJsonType*> handle_value(Value&& v,
const bool skip_callback =
false)
5473 assert(not keep_stack.empty());
5477 if (not keep_stack.back())
5479 return {
false,
nullptr};
5483 auto value = BasicJsonType(std::forward<Value>(v));
5486 const bool keep = skip_callback or callback(
static_cast<int>(ref_stack.size()), parse_event_t::value, value);
5491 return {
false,
nullptr};
5494 if (ref_stack.empty())
5496 root = std::move(value);
5497 return {
true, &root};
5502 if (not ref_stack.back())
5504 return {
false,
nullptr};
5508 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
5511 if (ref_stack.back()->is_array())
5513 ref_stack.back()->m_value.array->push_back(std::move(value));
5514 return {
true, &(ref_stack.back()->m_value.array->back())};
5518 assert(ref_stack.back()->is_object());
5520 assert(not key_keep_stack.empty());
5521 const bool store_element = key_keep_stack.back();
5522 key_keep_stack.pop_back();
5524 if (not store_element)
5526 return {
false,
nullptr};
5529 assert(object_element);
5530 *object_element = std::move(value);
5531 return {
true, object_element};
5535 BasicJsonType& root;
5537 std::vector<BasicJsonType*> ref_stack {};
5539 std::vector<bool> keep_stack {};
5541 std::vector<bool> key_keep_stack {};
5543 BasicJsonType* object_element =
nullptr;
5545 bool errored =
false;
5547 const parser_callback_t callback =
nullptr;
5549 const bool allow_exceptions =
true;
5551 BasicJsonType discarded = BasicJsonType::value_t::discarded;
5554 template<
typename BasicJsonType>
5555 class json_sax_acceptor
5558 using number_integer_t =
typename BasicJsonType::number_integer_t;
5559 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
5560 using number_float_t =
typename BasicJsonType::number_float_t;
5561 using string_t =
typename BasicJsonType::string_t;
5562 using binary_t =
typename BasicJsonType::binary_t;
5574 bool number_integer(number_integer_t )
5579 bool number_unsigned(number_unsigned_t )
5584 bool number_float(number_float_t ,
const string_t& )
5589 bool string(string_t& )
5594 bool binary(binary_t& )
5599 bool start_object(std::size_t = std::size_t(-1))
5604 bool key(string_t& )
5614 bool start_array(std::size_t = std::size_t(-1))
5624 bool parse_error(std::size_t ,
const std::string& ,
const detail::exception& )
5651 template <
typename T>
5652 using null_function_t = decltype(std::declval<T&>().
null());
5654 template <
typename T>
5655 using boolean_function_t =
5656 decltype(std::declval<T&>().
boolean(std::declval<bool>()));
5658 template <
typename T,
typename Integer>
5659 using number_integer_function_t =
5660 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
5662 template <
typename T,
typename Un
signed>
5663 using number_unsigned_function_t =
5664 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
5666 template <
typename T,
typename Float,
typename String>
5667 using number_float_function_t = decltype(std::declval<T&>().number_float(
5668 std::declval<Float>(), std::declval<const String&>()));
5670 template <
typename T,
typename String>
5671 using string_function_t =
5672 decltype(std::declval<T&>().
string(std::declval<String&>()));
5674 template <
typename T>
5675 using start_object_function_t =
5676 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
5678 template <
typename T,
typename String>
5679 using key_function_t =
5680 decltype(std::declval<T&>().key(std::declval<String&>()));
5682 template <
typename T>
5683 using end_object_function_t = decltype(std::declval<T&>().end_object());
5685 template <
typename T>
5686 using start_array_function_t =
5687 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
5689 template <
typename T>
5690 using end_array_function_t = decltype(std::declval<T&>().end_array());
5692 template <
typename T,
typename Exception>
5693 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
5694 std::declval<std::size_t>(), std::declval<const std::string&>(),
5695 std::declval<const Exception&>()));
5697 template <
typename SAX,
typename BasicJsonType>
5701 static_assert(is_basic_json<BasicJsonType>::value,
5702 "BasicJsonType must be of type basic_json<...>");
5704 using number_integer_t =
typename BasicJsonType::number_integer_t;
5705 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
5706 using number_float_t =
typename BasicJsonType::number_float_t;
5707 using string_t =
typename BasicJsonType::string_t;
5708 using exception_t =
typename BasicJsonType::exception;
5711 static constexpr
bool value =
5712 is_detected_exact<bool, null_function_t, SAX>::value &&
5713 is_detected_exact<bool, boolean_function_t, SAX>::value &&
5714 is_detected_exact<bool, number_integer_function_t, SAX,
5715 number_integer_t>::value &&
5716 is_detected_exact<bool, number_unsigned_function_t, SAX,
5717 number_unsigned_t>::value &&
5718 is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
5720 is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
5721 is_detected_exact<bool, start_object_function_t, SAX>::value &&
5722 is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
5723 is_detected_exact<bool, end_object_function_t, SAX>::value &&
5724 is_detected_exact<bool, start_array_function_t, SAX>::value &&
5725 is_detected_exact<bool, end_array_function_t, SAX>::value &&
5726 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
5729 template <
typename SAX,
typename BasicJsonType>
5730 struct is_sax_static_asserts
5733 static_assert(is_basic_json<BasicJsonType>::value,
5734 "BasicJsonType must be of type basic_json<...>");
5736 using number_integer_t =
typename BasicJsonType::number_integer_t;
5737 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
5738 using number_float_t =
typename BasicJsonType::number_float_t;
5739 using string_t =
typename BasicJsonType::string_t;
5740 using exception_t =
typename BasicJsonType::exception;
5743 static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
5744 "Missing/invalid function: bool null()");
5745 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
5746 "Missing/invalid function: bool boolean(bool)");
5747 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
5748 "Missing/invalid function: bool boolean(bool)");
5750 is_detected_exact<
bool, number_integer_function_t, SAX,
5751 number_integer_t>::value,
5752 "Missing/invalid function: bool number_integer(number_integer_t)");
5754 is_detected_exact<
bool, number_unsigned_function_t, SAX,
5755 number_unsigned_t>::value,
5756 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
5757 static_assert(is_detected_exact<
bool, number_float_function_t, SAX,
5758 number_float_t, string_t>::value,
5759 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
5761 is_detected_exact<bool, string_function_t, SAX, string_t>::value,
5762 "Missing/invalid function: bool string(string_t&)");
5763 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
5764 "Missing/invalid function: bool start_object(std::size_t)");
5765 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
5766 "Missing/invalid function: bool key(string_t&)");
5767 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
5768 "Missing/invalid function: bool end_object()");
5769 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
5770 "Missing/invalid function: bool start_array(std::size_t)");
5771 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
5772 "Missing/invalid function: bool end_array()");
5774 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
5775 "Missing/invalid function: bool parse_error(std::size_t, const "
5776 "std::string&, const exception&)");
5796 static inline bool little_endianess(
int num = 1) noexcept
5798 return *
reinterpret_cast<char*
>(&num) == 1;
5809 template<
typename BasicJsonType,
typename InputAdapterType,
typename SAX = json_sax_dom_parser<BasicJsonType>>
5812 using number_integer_t =
typename BasicJsonType::number_integer_t;
5813 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
5814 using number_float_t =
typename BasicJsonType::number_float_t;
5815 using string_t =
typename BasicJsonType::string_t;
5816 using binary_t =
typename BasicJsonType::binary_t;
5817 using json_sax_t = SAX;
5825 explicit binary_reader(InputAdapterType&& adapter) : ia(std::move(adapter))
5827 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
5831 binary_reader(
const binary_reader&) =
delete;
5832 binary_reader(binary_reader&&) =
default;
5833 binary_reader& operator=(
const binary_reader&) =
delete;
5834 binary_reader& operator=(binary_reader&&) =
default;
5835 ~binary_reader() =
default;
5844 JSON_HEDLEY_NON_NULL(3)
5845 bool sax_parse(const input_format_t format,
5847 const
bool strict = true)
5850 bool result =
false;
5854 case input_format_t::bson:
5855 result = parse_bson_internal();
5858 case input_format_t::cbor:
5859 result = parse_cbor_internal();
5862 case input_format_t::msgpack:
5863 result = parse_msgpack_internal();
5866 case input_format_t::ubjson:
5867 result = parse_ubjson_internal();
5875 if (result and strict)
5877 if (format == input_format_t::ubjson)
5886 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char>::eof()))
5888 return sax->parse_error(chars_read, get_token_string(),
5889 parse_error::create(110, chars_read, exception_message(format,
"expected end of input; last byte: 0x" + get_token_string(),
"value")));
5905 bool parse_bson_internal()
5907 std::int32_t document_size;
5908 get_number<std::int32_t, true>(input_format_t::bson, document_size);
5910 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
5915 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(
false)))
5920 return sax->end_object();
5930 bool get_bson_cstr(string_t& result)
5932 auto out = std::back_inserter(result);
5936 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson,
"cstring")))
5940 if (current == 0x00)
5944 *out++ =
static_cast<char>(current);
5961 template<
typename NumberType>
5962 bool get_bson_string(
const NumberType len, string_t& result)
5964 if (JSON_HEDLEY_UNLIKELY(len < 1))
5966 auto last_token = get_token_string();
5967 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")));
5970 return get_string(input_format_t::bson, len -
static_cast<NumberType
>(1), result) and get() != std::char_traits<char>::eof();
5982 template<
typename NumberType>
5983 bool get_bson_binary(
const NumberType len, binary_t& result)
5985 if (JSON_HEDLEY_UNLIKELY(len < 0))
5987 auto last_token = get_token_string();
5988 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")));
5992 std::uint8_t subtype;
5993 get_number<std::uint8_t>(input_format_t::bson, subtype);
5994 result.set_subtype(subtype);
5996 return get_binary(input_format_t::bson, len, result);
6009 bool parse_bson_element_internal(
const int element_type,
6010 const std::size_t element_type_parse_position)
6012 switch (element_type)
6017 return get_number<double, true>(input_format_t::bson, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
6024 return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_string(len, value) and sax->string(value);
6029 return parse_bson_internal();
6034 return parse_bson_array();
6041 return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_binary(len, value) and sax->binary(value);
6046 return sax->boolean(get() != 0);
6057 return get_number<std::int32_t, true>(input_format_t::bson, value) and sax->number_integer(value);
6063 return get_number<std::int64_t, true>(input_format_t::bson, value) and sax->number_integer(value);
6068 std::array<char, 3> cr{{}};
6069 (std::snprintf)(cr.data(), cr.size(),
"%.2hhX",
static_cast<unsigned char>(element_type));
6070 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())));
6087 bool parse_bson_element_list(
const bool is_array)
6091 while (
int element_type = get())
6093 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson,
"element list")))
6098 const std::size_t element_type_parse_position = chars_read;
6099 if (JSON_HEDLEY_UNLIKELY(not get_bson_cstr(key)))
6104 if (not is_array and not sax->key(key))
6109 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
6125 bool parse_bson_array()
6127 std::int32_t document_size;
6128 get_number<std::int32_t, true>(input_format_t::bson, document_size);
6130 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
6135 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(
true)))
6140 return sax->end_array();
6154 bool parse_cbor_internal(
const bool get_char =
true)
6156 switch (get_char ? get() : current)
6159 case std::char_traits<char>::eof():
6160 return unexpect_eof(input_format_t::cbor,
"value");
6187 return sax->number_unsigned(
static_cast<number_unsigned_t
>(current));
6191 std::uint8_t number;
6192 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6197 std::uint16_t number;
6198 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6203 std::uint32_t number;
6204 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6209 std::uint64_t number;
6210 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6238 return sax->number_integer(
static_cast<std::int8_t
>(0x20 - 1 - current));
6242 std::uint8_t number;
6243 return get_number(input_format_t::cbor, number) and sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
6248 std::uint16_t number;
6249 return get_number(input_format_t::cbor, number) and sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
6254 std::uint32_t number;
6255 return get_number(input_format_t::cbor, number) and sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
6260 std::uint64_t number;
6261 return get_number(input_format_t::cbor, number) and sax->number_integer(
static_cast<number_integer_t
>(-1)
6262 -
static_cast<number_integer_t
>(number));
6297 return get_cbor_binary(b) and sax->binary(b);
6332 return get_cbor_string(s) and sax->string(s);
6360 return get_cbor_array(
static_cast<std::size_t
>(
static_cast<unsigned int>(current) & 0x1Fu));
6365 return get_number(input_format_t::cbor, len) and get_cbor_array(
static_cast<std::size_t
>(len));
6371 return get_number(input_format_t::cbor, len) and get_cbor_array(
static_cast<std::size_t
>(len));
6377 return get_number(input_format_t::cbor, len) and get_cbor_array(
static_cast<std::size_t
>(len));
6383 return get_number(input_format_t::cbor, len) and get_cbor_array(
static_cast<std::size_t
>(len));
6387 return get_cbor_array(std::size_t(-1));
6414 return get_cbor_object(
static_cast<std::size_t
>(
static_cast<unsigned int>(current) & 0x1Fu));
6419 return get_number(input_format_t::cbor, len) and get_cbor_object(
static_cast<std::size_t
>(len));
6425 return get_number(input_format_t::cbor, len) and get_cbor_object(
static_cast<std::size_t
>(len));
6431 return get_number(input_format_t::cbor, len) and get_cbor_object(
static_cast<std::size_t
>(len));
6437 return get_number(input_format_t::cbor, len) and get_cbor_object(
static_cast<std::size_t
>(len));
6441 return get_cbor_object(std::size_t(-1));
6444 return sax->boolean(
false);
6447 return sax->boolean(
true);
6454 const int byte1_raw = get();
6455 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor,
"number")))
6459 const int byte2_raw = get();
6460 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor,
"number")))
6465 const auto byte1 =
static_cast<unsigned char>(byte1_raw);
6466 const auto byte2 =
static_cast<unsigned char>(byte2_raw);
6476 const auto half =
static_cast<unsigned int>((byte1 << 8u) + byte2);
6477 const double val = [&half]
6479 const int exp = (half >> 10u) & 0x1Fu;
6480 const unsigned int mant = half & 0x3FFu;
6481 assert(0 <= exp and exp <= 32);
6482 assert(mant <= 1024);
6486 return std::ldexp(mant, -24);
6489 ? std::numeric_limits<double>::infinity()
6490 : std::numeric_limits<double>::quiet_NaN();
6492 return std::ldexp(mant + 1024, exp - 25);
6495 return sax->number_float((half & 0x8000u) != 0
6496 ?
static_cast<number_float_t
>(-val)
6497 :
static_cast<number_float_t
>(val),
"");
6503 return get_number(input_format_t::cbor, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
6509 return get_number(input_format_t::cbor, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
6514 auto last_token = get_token_string();
6515 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")));
6531 bool get_cbor_string(string_t& result)
6533 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor,
"string")))
6566 return get_string(input_format_t::cbor,
static_cast<unsigned int>(current) & 0x1Fu, result);
6572 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
6578 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
6584 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
6590 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
6595 while (get() != 0xFF)
6598 if (not get_cbor_string(chunk))
6602 result.append(chunk);
6609 auto last_token = get_token_string();
6610 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")));
6626 bool get_cbor_binary(binary_t& result)
6628 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor,
"binary")))
6661 return get_binary(input_format_t::cbor,
static_cast<unsigned int>(current) & 0x1Fu, result);
6667 return get_number(input_format_t::cbor, len) and
6668 get_binary(input_format_t::cbor, len, result);
6674 return get_number(input_format_t::cbor, len) and
6675 get_binary(input_format_t::cbor, len, result);
6681 return get_number(input_format_t::cbor, len) and
6682 get_binary(input_format_t::cbor, len, result);
6688 return get_number(input_format_t::cbor, len) and
6689 get_binary(input_format_t::cbor, len, result);
6694 while (get() != 0xFF)
6697 if (not get_cbor_binary(chunk))
6701 result.insert(result.end(), chunk.begin(), chunk.end());
6708 auto last_token = get_token_string();
6709 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")));
6719 bool get_cbor_array(
const std::size_t len)
6721 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len)))
6726 if (len != std::size_t(-1))
6728 for (std::size_t i = 0; i < len; ++i)
6730 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
6738 while (get() != 0xFF)
6740 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal(
false)))
6747 return sax->end_array();
6755 bool get_cbor_object(
const std::size_t len)
6757 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len)))
6763 if (len != std::size_t(-1))
6765 for (std::size_t i = 0; i < len; ++i)
6768 if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
6773 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
6782 while (get() != 0xFF)
6784 if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
6789 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
6797 return sax->end_object();
6807 bool parse_msgpack_internal()
6812 case std::char_traits<char>::eof():
6813 return unexpect_eof(input_format_t::msgpack,
"value");
6944 return sax->number_unsigned(
static_cast<number_unsigned_t
>(current));
6963 return get_msgpack_object(
static_cast<std::size_t
>(
static_cast<unsigned int>(current) & 0x0Fu));
6982 return get_msgpack_array(
static_cast<std::size_t
>(
static_cast<unsigned int>(current) & 0x0Fu));
7022 return get_msgpack_string(s) and sax->string(s);
7029 return sax->boolean(
false);
7032 return sax->boolean(
true);
7047 return get_msgpack_binary(b) and sax->binary(b);
7053 return get_number(input_format_t::msgpack, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
7059 return get_number(input_format_t::msgpack, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
7064 std::uint8_t number;
7065 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7070 std::uint16_t number;
7071 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7076 std::uint32_t number;
7077 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7082 std::uint64_t number;
7083 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7089 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7094 std::int16_t number;
7095 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7100 std::int32_t number;
7101 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7106 std::int64_t number;
7107 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7113 return get_number(input_format_t::msgpack, len) and get_msgpack_array(
static_cast<std::size_t
>(len));
7119 return get_number(input_format_t::msgpack, len) and get_msgpack_array(
static_cast<std::size_t
>(len));
7125 return get_number(input_format_t::msgpack, len) and get_msgpack_object(
static_cast<std::size_t
>(len));
7131 return get_number(input_format_t::msgpack, len) and get_msgpack_object(
static_cast<std::size_t
>(len));
7167 return sax->number_integer(
static_cast<std::int8_t
>(current));
7171 auto last_token = get_token_string();
7172 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")));
7187 bool get_msgpack_string(string_t& result)
7189 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::msgpack,
"string")))
7230 return get_string(input_format_t::msgpack,
static_cast<unsigned int>(current) & 0x1Fu, result);
7236 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7242 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7248 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7253 auto last_token = get_token_string();
7254 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")));
7269 bool get_msgpack_binary(binary_t& result)
7272 auto assign_and_return_true = [&result](std::int8_t subtype)
7274 result.set_subtype(
static_cast<std::uint8_t
>(subtype));
7283 return get_number(input_format_t::msgpack, len) and
7284 get_binary(input_format_t::msgpack, len, result);
7290 return get_number(input_format_t::msgpack, len) and
7291 get_binary(input_format_t::msgpack, len, result);
7297 return get_number(input_format_t::msgpack, len) and
7298 get_binary(input_format_t::msgpack, len, result);
7304 std::int8_t subtype;
7305 return get_number(input_format_t::msgpack, len) and
7306 get_number(input_format_t::msgpack, subtype) and
7307 get_binary(input_format_t::msgpack, len, result) and
7308 assign_and_return_true(subtype);
7314 std::int8_t subtype;
7315 return get_number(input_format_t::msgpack, len) and
7316 get_number(input_format_t::msgpack, subtype) and
7317 get_binary(input_format_t::msgpack, len, result) and
7318 assign_and_return_true(subtype);
7324 std::int8_t subtype;
7325 return get_number(input_format_t::msgpack, len) and
7326 get_number(input_format_t::msgpack, subtype) and
7327 get_binary(input_format_t::msgpack, len, result) and
7328 assign_and_return_true(subtype);
7333 std::int8_t subtype;
7334 return get_number(input_format_t::msgpack, subtype) and
7335 get_binary(input_format_t::msgpack, 1, result) and
7336 assign_and_return_true(subtype);
7341 std::int8_t subtype;
7342 return get_number(input_format_t::msgpack, subtype) and
7343 get_binary(input_format_t::msgpack, 2, result) and
7344 assign_and_return_true(subtype);
7349 std::int8_t subtype;
7350 return get_number(input_format_t::msgpack, subtype) and
7351 get_binary(input_format_t::msgpack, 4, result) and
7352 assign_and_return_true(subtype);
7357 std::int8_t subtype;
7358 return get_number(input_format_t::msgpack, subtype) and
7359 get_binary(input_format_t::msgpack, 8, result) and
7360 assign_and_return_true(subtype);
7365 std::int8_t subtype;
7366 return get_number(input_format_t::msgpack, subtype) and
7367 get_binary(input_format_t::msgpack, 16, result) and
7368 assign_and_return_true(subtype);
7380 bool get_msgpack_array(
const std::size_t len)
7382 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len)))
7387 for (std::size_t i = 0; i < len; ++i)
7389 if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal()))
7395 return sax->end_array();
7402 bool get_msgpack_object(
const std::size_t len)
7404 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len)))
7410 for (std::size_t i = 0; i < len; ++i)
7413 if (JSON_HEDLEY_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
7418 if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal()))
7425 return sax->end_object();
7439 bool parse_ubjson_internal(
const bool get_char =
true)
7441 return get_ubjson_value(get_char ? get_ignore_noop() : current);
7458 bool get_ubjson_string(string_t& result,
const bool get_char =
true)
7465 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson,
"value")))
7475 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7481 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7487 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7493 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7499 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7503 auto last_token = get_token_string();
7504 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")));
7512 bool get_ubjson_size_value(std::size_t& result)
7514 switch (get_ignore_noop())
7518 std::uint8_t number;
7519 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7523 result =
static_cast<std::size_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::int16_t number;
7541 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7545 result =
static_cast<std::size_t
>(number);
7551 std::int32_t number;
7552 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7556 result =
static_cast<std::size_t
>(number);
7562 std::int64_t number;
7563 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7567 result =
static_cast<std::size_t
>(number);
7573 auto last_token = get_token_string();
7574 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")));
7589 bool get_ubjson_size_type(std::pair<std::size_t, int>& result)
7591 result.first = string_t::npos;
7598 result.second = get();
7599 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson,
"type")))
7605 if (JSON_HEDLEY_UNLIKELY(current !=
'#'))
7607 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson,
"value")))
7611 auto last_token = get_token_string();
7612 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")));
7615 return get_ubjson_size_value(result.first);
7620 return get_ubjson_size_value(result.first);
7630 bool get_ubjson_value(
const int prefix)
7634 case std::char_traits<char>::eof():
7635 return unexpect_eof(input_format_t::ubjson,
"value");
7638 return sax->boolean(
true);
7640 return sax->boolean(
false);
7647 std::uint8_t number;
7648 return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number);
7654 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7659 std::int16_t number;
7660 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7665 std::int32_t number;
7666 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7671 std::int64_t number;
7672 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7678 return get_number(input_format_t::ubjson, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
7684 return get_number(input_format_t::ubjson, number) and sax->number_float(
static_cast<number_float_t
>(number),
"");
7690 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson,
"char")))
7694 if (JSON_HEDLEY_UNLIKELY(current > 127))
7696 auto last_token = get_token_string();
7697 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")));
7699 string_t s(1,
static_cast<char>(current));
7700 return sax->string(s);
7706 return get_ubjson_string(s) and sax->string(s);
7710 return get_ubjson_array();
7713 return get_ubjson_object();
7717 auto last_token = get_token_string();
7718 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")));
7726 bool get_ubjson_array()
7728 std::pair<std::size_t, int> size_and_type;
7729 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
7734 if (size_and_type.first != string_t::npos)
7736 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(size_and_type.first)))
7741 if (size_and_type.second != 0)
7743 if (size_and_type.second !=
'N')
7745 for (std::size_t i = 0; i < size_and_type.first; ++i)
7747 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second)))
7756 for (std::size_t i = 0; i < size_and_type.first; ++i)
7758 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
7767 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
7772 while (current !=
']')
7774 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal(
false)))
7782 return sax->end_array();
7788 bool get_ubjson_object()
7790 std::pair<std::size_t, int> size_and_type;
7791 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
7797 if (size_and_type.first != string_t::npos)
7799 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(size_and_type.first)))
7804 if (size_and_type.second != 0)
7806 for (std::size_t i = 0; i < size_and_type.first; ++i)
7808 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
7812 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second)))
7821 for (std::size_t i = 0; i < size_and_type.first; ++i)
7823 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
7827 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
7837 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
7842 while (current !=
'}')
7844 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key,
false) or not sax->key(key)))
7848 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
7857 return sax->end_object();
7879 return current = ia.get_character();
7885 int get_ignore_noop()
7891 while (current ==
'N');
7909 template<
typename NumberType,
bool InputIsLittleEndian = false>
7910 bool get_number(
const input_format_t format, NumberType& result)
7913 std::array<std::uint8_t,
sizeof(NumberType)> vec;
7914 for (std::size_t i = 0; i <
sizeof(NumberType); ++i)
7917 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format,
"number")))
7923 if (is_little_endian != InputIsLittleEndian)
7925 vec[
sizeof(NumberType) - i - 1] =
static_cast<std::uint8_t
>(current);
7929 vec[i] =
static_cast<std::uint8_t
>(current);
7934 std::memcpy(&result, vec.data(),
sizeof(NumberType));
7952 template<
typename NumberType>
7953 bool get_string(
const input_format_t format,
7954 const NumberType len,
7957 bool success =
true;
7958 std::generate_n(std::back_inserter(result), len, [
this, &success, &format]()
7961 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format,
"string")))
7965 return static_cast<char>(current);
7984 template<
typename NumberType>
7985 bool get_binary(
const input_format_t format,
7986 const NumberType len,
7989 bool success =
true;
7990 std::generate_n(std::back_inserter(result), len, [
this, &success, &format]()
7993 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format,
"binary")))
7997 return static_cast<std::uint8_t
>(current);
8007 JSON_HEDLEY_NON_NULL(3)
8008 bool unexpect_eof(const input_format_t format, const
char* context)
const
8010 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char>::eof()))
8012 return sax->parse_error(chars_read,
"<end of file>",
8013 parse_error::create(110, chars_read, exception_message(format,
"unexpected end of input", context)));
8021 std::string get_token_string()
const
8023 std::array<char, 3> cr{{}};
8024 (std::snprintf)(cr.data(), cr.size(),
"%.2hhX",
static_cast<unsigned char>(current));
8025 return std::string{cr.data()};
8034 std::string exception_message(
const input_format_t format,
8035 const std::string& detail,
8036 const std::string& context)
const
8038 std::string error_msg =
"syntax error while parsing ";
8042 case input_format_t::cbor:
8043 error_msg +=
"CBOR";
8046 case input_format_t::msgpack:
8047 error_msg +=
"MessagePack";
8050 case input_format_t::ubjson:
8051 error_msg +=
"UBJSON";
8054 case input_format_t::bson:
8055 error_msg +=
"BSON";
8062 return error_msg +
" " + context +
": " + detail;
8067 InputAdapterType ia;
8070 int current = std::char_traits<char>::eof();
8073 std::size_t chars_read = 0;
8076 const bool is_little_endian = little_endianess();
8079 json_sax_t* sax =
nullptr;
8094 #include <initializer_list>
8114 template<
typename BasicJsonType>
8119 enum class token_type
8143 static const char* token_type_name(
const token_type t) noexcept
8147 case token_type::uninitialized:
8148 return "<uninitialized>";
8149 case token_type::literal_true:
8150 return "true literal";
8151 case token_type::literal_false:
8152 return "false literal";
8153 case token_type::literal_null:
8154 return "null literal";
8155 case token_type::value_string:
8156 return "string literal";
8157 case token_type::value_unsigned:
8158 case token_type::value_integer:
8159 case token_type::value_float:
8160 return "number literal";
8161 case token_type::begin_array:
8163 case token_type::begin_object:
8165 case token_type::end_array:
8167 case token_type::end_object:
8169 case token_type::name_separator:
8171 case token_type::value_separator:
8173 case token_type::parse_error:
8174 return "<parse error>";
8175 case token_type::end_of_input:
8176 return "end of input";
8177 case token_type::literal_or_value:
8178 return "'[', '{', or a literal";
8181 return "unknown token";
8191 template<
typename BasicJsonType,
typename InputAdapterType>
8192 class lexer :
public lexer_base<BasicJsonType>
8194 using number_integer_t =
typename BasicJsonType::number_integer_t;
8195 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
8196 using number_float_t =
typename BasicJsonType::number_float_t;
8197 using string_t =
typename BasicJsonType::string_t;
8200 using token_type =
typename lexer_base<BasicJsonType>::token_type;
8202 explicit lexer(InputAdapterType&& adapter)
8203 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
8206 lexer(
const lexer&) =
delete;
8207 lexer(lexer&&) =
default;
8208 lexer& operator=(lexer&) =
delete;
8209 lexer& operator=(lexer&&) =
default;
8219 static char get_decimal_point() noexcept
8221 const auto loc = localeconv();
8222 assert(loc !=
nullptr);
8223 return (loc->decimal_point ==
nullptr) ?
'.' : *(loc->decimal_point);
8248 assert(current ==
'u');
8251 const auto factors = { 12u, 8u, 4u, 0u };
8252 for (
const auto factor : factors)
8256 if (current >=
'0' and current <=
'9')
8258 codepoint +=
static_cast<int>((
static_cast<unsigned int>(current) - 0x30u) << factor);
8260 else if (current >=
'A' and current <=
'F')
8262 codepoint +=
static_cast<int>((
static_cast<unsigned int>(current) - 0x37u) << factor);
8264 else if (current >=
'a' and current <=
'f')
8266 codepoint +=
static_cast<int>((
static_cast<unsigned int>(current) - 0x57u) << factor);
8274 assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
8293 bool next_byte_in_range(std::initializer_list<int> ranges)
8295 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
8298 for (
auto range = ranges.begin(); range != ranges.end(); ++range)
8301 if (JSON_HEDLEY_LIKELY(*range <= current and current <= *(++range)))
8307 error_message =
"invalid string: ill-formed UTF-8 byte";
8330 token_type scan_string()
8336 assert(current ==
'\"');
8344 case std::char_traits<char>::eof():
8346 error_message =
"invalid string: missing closing quote";
8347 return token_type::parse_error;
8353 return token_type::value_string;
8397 const int codepoint1 = get_codepoint();
8398 int codepoint = codepoint1;
8400 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
8402 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
8403 return token_type::parse_error;
8407 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
8410 if (JSON_HEDLEY_LIKELY(get() ==
'\\' and get() ==
'u'))
8412 const int codepoint2 = get_codepoint();
8414 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
8416 error_message =
"invalid string: '\\u' must be followed by 4 hex digits";
8417 return token_type::parse_error;
8421 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
8424 codepoint =
static_cast<int>(
8426 (
static_cast<unsigned int>(codepoint1) << 10u)
8428 +
static_cast<unsigned int>(codepoint2)
8436 error_message =
"invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
8437 return token_type::parse_error;
8442 error_message =
"invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
8443 return token_type::parse_error;
8448 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
8450 error_message =
"invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
8451 return token_type::parse_error;
8456 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
8459 if (codepoint < 0x80)
8464 else if (codepoint <= 0x7FF)
8467 add(
static_cast<int>(0xC0u | (
static_cast<unsigned int>(codepoint) >> 6u)));
8468 add(
static_cast<int>(0x80u | (
static_cast<unsigned int>(codepoint) & 0x3Fu)));
8470 else if (codepoint <= 0xFFFF)
8473 add(
static_cast<int>(0xE0u | (
static_cast<unsigned int>(codepoint) >> 12u)));
8474 add(
static_cast<int>(0x80u | ((
static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
8475 add(
static_cast<int>(0x80u | (
static_cast<unsigned int>(codepoint) & 0x3Fu)));
8480 add(
static_cast<int>(0xF0u | (
static_cast<unsigned int>(codepoint) >> 18u)));
8481 add(
static_cast<int>(0x80u | ((
static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
8482 add(
static_cast<int>(0x80u | ((
static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
8483 add(
static_cast<int>(0x80u | (
static_cast<unsigned int>(codepoint) & 0x3Fu)));
8491 error_message =
"invalid string: forbidden character after backslash";
8492 return token_type::parse_error;
8501 error_message =
"invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
8502 return token_type::parse_error;
8507 error_message =
"invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
8508 return token_type::parse_error;
8513 error_message =
"invalid string: control character U+0002 (STX) must be escaped to \\u0002";
8514 return token_type::parse_error;
8519 error_message =
"invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
8520 return token_type::parse_error;
8525 error_message =
"invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
8526 return token_type::parse_error;
8531 error_message =
"invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
8532 return token_type::parse_error;
8537 error_message =
"invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
8538 return token_type::parse_error;
8543 error_message =
"invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
8544 return token_type::parse_error;
8549 error_message =
"invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
8550 return token_type::parse_error;
8555 error_message =
"invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
8556 return token_type::parse_error;
8561 error_message =
"invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
8562 return token_type::parse_error;
8567 error_message =
"invalid string: control character U+000B (VT) must be escaped to \\u000B";
8568 return token_type::parse_error;
8573 error_message =
"invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
8574 return token_type::parse_error;
8579 error_message =
"invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
8580 return token_type::parse_error;
8585 error_message =
"invalid string: control character U+000E (SO) must be escaped to \\u000E";
8586 return token_type::parse_error;
8591 error_message =
"invalid string: control character U+000F (SI) must be escaped to \\u000F";
8592 return token_type::parse_error;
8597 error_message =
"invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
8598 return token_type::parse_error;
8603 error_message =
"invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
8604 return token_type::parse_error;
8609 error_message =
"invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
8610 return token_type::parse_error;
8615 error_message =
"invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
8616 return token_type::parse_error;
8621 error_message =
"invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
8622 return token_type::parse_error;
8627 error_message =
"invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
8628 return token_type::parse_error;
8633 error_message =
"invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
8634 return token_type::parse_error;
8639 error_message =
"invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
8640 return token_type::parse_error;
8645 error_message =
"invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
8646 return token_type::parse_error;
8651 error_message =
"invalid string: control character U+0019 (EM) must be escaped to \\u0019";
8652 return token_type::parse_error;
8657 error_message =
"invalid string: control character U+001A (SUB) must be escaped to \\u001A";
8658 return token_type::parse_error;
8663 error_message =
"invalid string: control character U+001B (ESC) must be escaped to \\u001B";
8664 return token_type::parse_error;
8669 error_message =
"invalid string: control character U+001C (FS) must be escaped to \\u001C";
8670 return token_type::parse_error;
8675 error_message =
"invalid string: control character U+001D (GS) must be escaped to \\u001D";
8676 return token_type::parse_error;
8681 error_message =
"invalid string: control character U+001E (RS) must be escaped to \\u001E";
8682 return token_type::parse_error;
8687 error_message =
"invalid string: control character U+001F (US) must be escaped to \\u001F";
8688 return token_type::parse_error;
8823 if (JSON_HEDLEY_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
8825 return token_type::parse_error;
8833 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
8835 return token_type::parse_error;
8857 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
8859 return token_type::parse_error;
8867 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
8869 return token_type::parse_error;
8877 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
8879 return token_type::parse_error;
8889 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
8891 return token_type::parse_error;
8899 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
8901 return token_type::parse_error;
8909 error_message =
"invalid string: ill-formed UTF-8 byte";
8910 return token_type::parse_error;
8916 JSON_HEDLEY_NON_NULL(2)
8917 static
void strtof(
float& f, const
char* str,
char** endptr) noexcept
8919 f = std::strtof(str, endptr);
8922 JSON_HEDLEY_NON_NULL(2)
8923 static
void strtof(
double& f, const
char* str,
char** endptr) noexcept
8925 f = std::strtod(str, endptr);
8928 JSON_HEDLEY_NON_NULL(2)
8929 static
void strtof(
long double& f, const
char* str,
char** endptr) noexcept
8931 f = std::strtold(str, endptr);
8974 token_type scan_number()
8981 token_type number_type = token_type::value_unsigned;
8989 goto scan_number_minus;
8995 goto scan_number_zero;
9009 goto scan_number_any1;
9019 number_type = token_type::value_integer;
9025 goto scan_number_zero;
9039 goto scan_number_any1;
9044 error_message =
"invalid number; expected digit after '-'";
9045 return token_type::parse_error;
9055 add(decimal_point_char);
9056 goto scan_number_decimal1;
9063 goto scan_number_exponent;
9067 goto scan_number_done;
9086 goto scan_number_any1;
9091 add(decimal_point_char);
9092 goto scan_number_decimal1;
9099 goto scan_number_exponent;
9103 goto scan_number_done;
9106 scan_number_decimal1:
9108 number_type = token_type::value_float;
9123 goto scan_number_decimal2;
9128 error_message =
"invalid number; expected digit after '.'";
9129 return token_type::parse_error;
9133 scan_number_decimal2:
9149 goto scan_number_decimal2;
9156 goto scan_number_exponent;
9160 goto scan_number_done;
9163 scan_number_exponent:
9165 number_type = token_type::value_float;
9172 goto scan_number_sign;
9187 goto scan_number_any2;
9193 "invalid number; expected '+', '-', or digit after exponent";
9194 return token_type::parse_error;
9214 goto scan_number_any2;
9219 error_message =
"invalid number; expected digit after exponent sign";
9220 return token_type::parse_error;
9240 goto scan_number_any2;
9244 goto scan_number_done;
9252 char* endptr =
nullptr;
9256 if (number_type == token_type::value_unsigned)
9258 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
9261 assert(endptr == token_buffer.data() + token_buffer.size());
9265 value_unsigned =
static_cast<number_unsigned_t
>(x);
9266 if (value_unsigned == x)
9268 return token_type::value_unsigned;
9272 else if (number_type == token_type::value_integer)
9274 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
9277 assert(endptr == token_buffer.data() + token_buffer.size());
9281 value_integer =
static_cast<number_integer_t
>(x);
9282 if (value_integer == x)
9284 return token_type::value_integer;
9291 strtof(value_float, token_buffer.data(), &endptr);
9294 assert(endptr == token_buffer.data() + token_buffer.size());
9296 return token_type::value_float;
9304 JSON_HEDLEY_NON_NULL(2)
9305 token_type scan_literal(const
char* literal_text, const std::
size_t length,
9306 token_type return_type)
9308 assert(current == literal_text[0]);
9309 for (std::size_t i = 1; i < length; ++i)
9311 if (JSON_HEDLEY_UNLIKELY(get() != literal_text[i]))
9313 error_message =
"invalid literal";
9314 return token_type::parse_error;
9325 void reset() noexcept
9327 token_buffer.clear();
9328 token_string.clear();
9329 token_string.push_back(std::char_traits<char>::to_char_type(current));
9342 std::char_traits<char>::int_type get()
9344 ++position.chars_read_total;
9345 ++position.chars_read_current_line;
9354 current = ia.get_character();
9357 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char>::eof()))
9359 token_string.push_back(std::char_traits<char>::to_char_type(current));
9362 if (current ==
'\n')
9364 ++position.lines_read;
9365 position.chars_read_current_line = 0;
9383 --position.chars_read_total;
9386 if (position.chars_read_current_line == 0)
9388 if (position.lines_read > 0)
9390 --position.lines_read;
9395 --position.chars_read_current_line;
9398 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char>::eof()))
9400 assert(not token_string.empty());
9401 token_string.pop_back();
9408 token_buffer.push_back(std::char_traits<char>::to_char_type(c));
9417 constexpr number_integer_t get_number_integer() const noexcept
9419 return value_integer;
9423 constexpr number_unsigned_t get_number_unsigned() const noexcept
9425 return value_unsigned;
9429 constexpr number_float_t get_number_float() const noexcept
9435 string_t& get_string()
9437 return token_buffer;
9445 constexpr position_t get_position() const noexcept
9453 std::string get_token_string()
const
9457 for (
const auto c : token_string)
9459 if (
'\x00' <= c and c <=
'\x1F')
9462 std::array<char, 9> cs{{}};
9463 (std::snprintf)(cs.data(), cs.size(),
"<U+%.4X>",
static_cast<unsigned char>(c));
9464 result += cs.data();
9469 result.push_back(c);
9478 constexpr
const char* get_error_message() const noexcept
9480 return error_message;
9496 return get() == 0xBB and get() == 0xBF;
9508 if (position.chars_read_total == 0 and not skip_bom())
9510 error_message =
"invalid BOM; must be 0xEF 0xBB 0xBF if given";
9511 return token_type::parse_error;
9519 while (current ==
' ' or current ==
'\t' or current ==
'\n' or current ==
'\r');
9525 return token_type::begin_array;
9527 return token_type::end_array;
9529 return token_type::begin_object;
9531 return token_type::end_object;
9533 return token_type::name_separator;
9535 return token_type::value_separator;
9539 return scan_literal(
"true", 4, token_type::literal_true);
9541 return scan_literal(
"false", 5, token_type::literal_false);
9543 return scan_literal(
"null", 4, token_type::literal_null);
9547 return scan_string();
9561 return scan_number();
9566 case std::char_traits<char>::eof():
9567 return token_type::end_of_input;
9571 error_message =
"invalid literal";
9572 return token_type::parse_error;
9578 InputAdapterType ia;
9581 std::char_traits<char>::int_type current = std::char_traits<char>::eof();
9584 bool next_unget =
false;
9587 position_t position {};
9590 std::vector<char> token_string {};
9593 string_t token_buffer {};
9596 const char* error_message =
"";
9599 number_integer_t value_integer = 0;
9600 number_unsigned_t value_unsigned = 0;
9601 number_float_t value_float = 0;
9604 const char decimal_point_char =
'.';
9615 #include <functional>
9643 enum class parse_event_t : uint8_t
9659 template<
typename BasicJsonType>
9660 using parser_callback_t =
9661 std::function<bool(
int depth, parse_event_t event, BasicJsonType& parsed)>;
9668 template<
typename BasicJsonType,
typename InputAdapterType>
9671 using number_integer_t =
typename BasicJsonType::number_integer_t;
9672 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
9673 using number_float_t =
typename BasicJsonType::number_float_t;
9674 using string_t =
typename BasicJsonType::string_t;
9675 using lexer_t = lexer<BasicJsonType, InputAdapterType>;
9676 using token_type =
typename lexer_t::token_type;
9680 explicit parser(InputAdapterType&& adapter,
9681 const parser_callback_t<BasicJsonType> cb =
nullptr,
9682 const bool allow_exceptions_ =
true)
9683 : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
9699 void parse(
const bool strict, BasicJsonType& result)
9703 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
9704 sax_parse_internal(&sdp);
9705 result.assert_invariant();
9708 if (strict and (get_token() != token_type::end_of_input))
9710 sdp.parse_error(m_lexer.get_position(),
9711 m_lexer.get_token_string(),
9712 parse_error::create(101, m_lexer.get_position(),
9713 exception_message(token_type::end_of_input,
"value")));
9717 if (sdp.is_errored())
9719 result = value_t::discarded;
9725 if (result.is_discarded())
9732 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
9733 sax_parse_internal(&sdp);
9734 result.assert_invariant();
9737 if (strict and (get_token() != token_type::end_of_input))
9739 sdp.parse_error(m_lexer.get_position(),
9740 m_lexer.get_token_string(),
9741 parse_error::create(101, m_lexer.get_position(),
9742 exception_message(token_type::end_of_input,
"value")));
9746 if (sdp.is_errored())
9748 result = value_t::discarded;
9760 bool accept(
const bool strict =
true)
9762 json_sax_acceptor<BasicJsonType> sax_acceptor;
9763 return sax_parse(&sax_acceptor, strict);
9766 template <
typename SAX>
9767 JSON_HEDLEY_NON_NULL(2)
9768 bool sax_parse(SAX* sax, const
bool strict = true)
9770 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
9771 const bool result = sax_parse_internal(sax);
9774 if (result and strict and (get_token() != token_type::end_of_input))
9776 return sax->parse_error(m_lexer.get_position(),
9777 m_lexer.get_token_string(),
9778 parse_error::create(101, m_lexer.get_position(),
9779 exception_message(token_type::end_of_input,
"value")));
9786 template <
typename SAX>
9787 JSON_HEDLEY_NON_NULL(2)
9788 bool sax_parse_internal(SAX* sax)
9792 std::vector<bool> states;
9794 bool skip_to_state_evaluation =
false;
9798 if (not skip_to_state_evaluation)
9803 case token_type::begin_object:
9805 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
9811 if (get_token() == token_type::end_object)
9813 if (JSON_HEDLEY_UNLIKELY(not sax->end_object()))
9821 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
9823 return sax->parse_error(m_lexer.get_position(),
9824 m_lexer.get_token_string(),
9825 parse_error::create(101, m_lexer.get_position(),
9826 exception_message(token_type::value_string,
"object key")));
9828 if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
9834 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
9836 return sax->parse_error(m_lexer.get_position(),
9837 m_lexer.get_token_string(),
9838 parse_error::create(101, m_lexer.get_position(),
9839 exception_message(token_type::name_separator,
"object separator")));
9843 states.push_back(
false);
9850 case token_type::begin_array:
9852 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
9858 if (get_token() == token_type::end_array)
9860 if (JSON_HEDLEY_UNLIKELY(not sax->end_array()))
9868 states.push_back(
true);
9874 case token_type::value_float:
9876 const auto res = m_lexer.get_number_float();
9878 if (JSON_HEDLEY_UNLIKELY(not std::isfinite(res)))
9880 return sax->parse_error(m_lexer.get_position(),
9881 m_lexer.get_token_string(),
9882 out_of_range::create(406,
"number overflow parsing '" + m_lexer.get_token_string() +
"'"));
9885 if (JSON_HEDLEY_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
9893 case token_type::literal_false:
9895 if (JSON_HEDLEY_UNLIKELY(not sax->boolean(
false)))
9902 case token_type::literal_null:
9904 if (JSON_HEDLEY_UNLIKELY(not sax->null()))
9911 case token_type::literal_true:
9913 if (JSON_HEDLEY_UNLIKELY(not sax->boolean(
true)))
9920 case token_type::value_integer:
9922 if (JSON_HEDLEY_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
9929 case token_type::value_string:
9931 if (JSON_HEDLEY_UNLIKELY(not sax->string(m_lexer.get_string())))
9938 case token_type::value_unsigned:
9940 if (JSON_HEDLEY_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
9947 case token_type::parse_error:
9950 return sax->parse_error(m_lexer.get_position(),
9951 m_lexer.get_token_string(),
9952 parse_error::create(101, m_lexer.get_position(),
9953 exception_message(token_type::uninitialized,
"value")));
9958 return sax->parse_error(m_lexer.get_position(),
9959 m_lexer.get_token_string(),
9960 parse_error::create(101, m_lexer.get_position(),
9961 exception_message(token_type::literal_or_value,
"value")));
9967 skip_to_state_evaluation =
false;
9980 if (get_token() == token_type::value_separator)
9988 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
9990 if (JSON_HEDLEY_UNLIKELY(not sax->end_array()))
9999 assert(not states.empty());
10001 skip_to_state_evaluation =
true;
10005 return sax->parse_error(m_lexer.get_position(),
10006 m_lexer.get_token_string(),
10007 parse_error::create(101, m_lexer.get_position(),
10008 exception_message(token_type::end_array,
"array")));
10013 if (get_token() == token_type::value_separator)
10016 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
10018 return sax->parse_error(m_lexer.get_position(),
10019 m_lexer.get_token_string(),
10020 parse_error::create(101, m_lexer.get_position(),
10021 exception_message(token_type::value_string,
"object key")));
10024 if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
10030 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10032 return sax->parse_error(m_lexer.get_position(),
10033 m_lexer.get_token_string(),
10034 parse_error::create(101, m_lexer.get_position(),
10035 exception_message(token_type::name_separator,
"object separator")));
10044 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
10046 if (JSON_HEDLEY_UNLIKELY(not sax->end_object()))
10055 assert(not states.empty());
10057 skip_to_state_evaluation =
true;
10061 return sax->parse_error(m_lexer.get_position(),
10062 m_lexer.get_token_string(),
10063 parse_error::create(101, m_lexer.get_position(),
10064 exception_message(token_type::end_object,
"object")));
10070 token_type get_token()
10072 return last_token = m_lexer.scan();
10075 std::string exception_message(
const token_type expected,
const std::string& context)
10077 std::string error_msg =
"syntax error ";
10079 if (not context.empty())
10081 error_msg +=
"while parsing " + context +
" ";
10086 if (last_token == token_type::parse_error)
10088 error_msg += std::string(m_lexer.get_error_message()) +
"; last read: '" +
10089 m_lexer.get_token_string() +
"'";
10093 error_msg +=
"unexpected " + std::string(lexer_t::token_type_name(last_token));
10096 if (expected != token_type::uninitialized)
10098 error_msg +=
"; expected " + std::string(lexer_t::token_type_name(expected));
10106 const parser_callback_t<BasicJsonType> callback =
nullptr;
10108 token_type last_token = token_type::uninitialized;
10112 const bool allow_exceptions =
true;
10139 class primitive_iterator_t
10142 using difference_type = std::ptrdiff_t;
10143 static constexpr difference_type begin_value = 0;
10144 static constexpr difference_type end_value = begin_value + 1;
10147 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
10150 constexpr difference_type get_value() const noexcept
10156 void set_begin() noexcept
10158 m_it = begin_value;
10162 void set_end() noexcept
10168 constexpr
bool is_begin() const noexcept
10170 return m_it == begin_value;
10174 constexpr
bool is_end() const noexcept
10176 return m_it == end_value;
10179 friend constexpr
bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10181 return lhs.m_it == rhs.m_it;
10184 friend constexpr
bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10186 return lhs.m_it < rhs.m_it;
10189 primitive_iterator_t operator+(difference_type n) noexcept
10191 auto result = *
this;
10196 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10198 return lhs.m_it - rhs.m_it;
10201 primitive_iterator_t& operator++() noexcept
10207 primitive_iterator_t
const operator++(
int) noexcept
10209 auto result = *
this;
10214 primitive_iterator_t& operator--() noexcept
10220 primitive_iterator_t
const operator--(
int) noexcept
10222 auto result = *
this;
10227 primitive_iterator_t& operator+=(difference_type n) noexcept
10233 primitive_iterator_t& operator-=(difference_type n) noexcept
10253 template<
typename BasicJsonType>
struct internal_iterator
10256 typename BasicJsonType::object_t::iterator object_iterator {};
10258 typename BasicJsonType::array_t::iterator array_iterator {};
10260 typename BasicJsonType::binary_t::container_type::iterator binary_iterator {};
10262 primitive_iterator_t primitive_iterator {};
10270 #include <iterator>
10271 #include <type_traits>
10295 template<
typename IteratorType>
class iteration_proxy;
10296 template<
typename IteratorType>
class iteration_proxy_value;
10314 template<
typename BasicJsonType>
10318 friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value,
typename std::remove_const<BasicJsonType>::type,
const BasicJsonType>::type>;
10319 friend BasicJsonType;
10320 friend iteration_proxy<iter_impl>;
10321 friend iteration_proxy_value<iter_impl>;
10323 using object_t =
typename BasicJsonType::object_t;
10324 using array_t =
typename BasicJsonType::array_t;
10326 static_assert(is_basic_json<
typename std::remove_const<BasicJsonType>::type>::value,
10327 "iter_impl only accepts (const) basic_json");
10336 using iterator_category = std::bidirectional_iterator_tag;
10339 using value_type =
typename BasicJsonType::value_type;
10341 using difference_type =
typename BasicJsonType::difference_type;
10343 using pointer =
typename std::conditional<std::is_const<BasicJsonType>::value,
10344 typename BasicJsonType::const_pointer,
10345 typename BasicJsonType::pointer>::type;
10348 typename std::conditional<std::is_const<BasicJsonType>::value,
10349 typename BasicJsonType::const_reference,
10350 typename BasicJsonType::reference>::type;
10353 iter_impl() =
default;
10361 explicit iter_impl(pointer
object) noexcept : m_object(
object)
10363 assert(m_object !=
nullptr);
10365 switch (m_object->m_type)
10367 case value_t::object:
10369 m_it.object_iterator =
typename object_t::iterator();
10373 case value_t::array:
10375 m_it.array_iterator =
typename array_t::iterator();
10381 m_it.primitive_iterator = primitive_iterator_t();
10403 iter_impl(
const iter_impl<const BasicJsonType>& other) noexcept
10404 : m_object(other.m_object), m_it(other.m_it)
10413 iter_impl& operator=(
const iter_impl<const BasicJsonType>& other) noexcept
10415 m_object = other.m_object;
10425 iter_impl(
const iter_impl<
typename std::remove_const<BasicJsonType>::type>& other) noexcept
10426 : m_object(other.m_object), m_it(other.m_it)
10435 iter_impl& operator=(
const iter_impl<
typename std::remove_const<BasicJsonType>::type>& other) noexcept
10437 m_object = other.m_object;
10447 void set_begin() noexcept
10449 assert(m_object !=
nullptr);
10451 switch (m_object->m_type)
10453 case value_t::object:
10455 m_it.object_iterator = m_object->m_value.object->begin();
10459 case value_t::array:
10461 m_it.array_iterator = m_object->m_value.array->begin();
10465 case value_t::null:
10468 m_it.primitive_iterator.set_end();
10474 m_it.primitive_iterator.set_begin();
10484 void set_end() noexcept
10486 assert(m_object !=
nullptr);
10488 switch (m_object->m_type)
10490 case value_t::object:
10492 m_it.object_iterator = m_object->m_value.object->end();
10496 case value_t::array:
10498 m_it.array_iterator = m_object->m_value.array->end();
10504 m_it.primitive_iterator.set_end();
10515 reference operator*()
const
10517 assert(m_object !=
nullptr);
10519 switch (m_object->m_type)
10521 case value_t::object:
10523 assert(m_it.object_iterator != m_object->m_value.object->end());
10524 return m_it.object_iterator->second;
10527 case value_t::array:
10529 assert(m_it.array_iterator != m_object->m_value.array->end());
10530 return *m_it.array_iterator;
10533 case value_t::null:
10534 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
10538 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
10543 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
10552 pointer operator->()
const
10554 assert(m_object !=
nullptr);
10556 switch (m_object->m_type)
10558 case value_t::object:
10560 assert(m_it.object_iterator != m_object->m_value.object->end());
10561 return &(m_it.object_iterator->second);
10564 case value_t::array:
10566 assert(m_it.array_iterator != m_object->m_value.array->end());
10567 return &*m_it.array_iterator;
10572 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
10577 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
10586 iter_impl
const operator++(
int)
10588 auto result = *
this;
10597 iter_impl& operator++()
10599 assert(m_object !=
nullptr);
10601 switch (m_object->m_type)
10603 case value_t::object:
10605 std::advance(m_it.object_iterator, 1);
10609 case value_t::array:
10611 std::advance(m_it.array_iterator, 1);
10617 ++m_it.primitive_iterator;
10629 iter_impl
const operator--(
int)
10631 auto result = *
this;
10640 iter_impl& operator--()
10642 assert(m_object !=
nullptr);
10644 switch (m_object->m_type)
10646 case value_t::object:
10648 std::advance(m_it.object_iterator, -1);
10652 case value_t::array:
10654 std::advance(m_it.array_iterator, -1);
10660 --m_it.primitive_iterator;
10672 bool operator==(
const iter_impl& other)
const
10675 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
10677 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
10680 assert(m_object !=
nullptr);
10682 switch (m_object->m_type)
10684 case value_t::object:
10685 return (m_it.object_iterator == other.m_it.object_iterator);
10687 case value_t::array:
10688 return (m_it.array_iterator == other.m_it.array_iterator);
10691 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
10699 bool operator!=(
const iter_impl& other)
const
10701 return not operator==(other);
10708 bool operator<(
const iter_impl& other)
const
10711 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
10713 JSON_THROW(invalid_iterator::create(212,
"cannot compare iterators of different containers"));
10716 assert(m_object !=
nullptr);
10718 switch (m_object->m_type)
10720 case value_t::object:
10721 JSON_THROW(invalid_iterator::create(213,
"cannot compare order of object iterators"));
10723 case value_t::array:
10724 return (m_it.array_iterator < other.m_it.array_iterator);
10727 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
10735 bool operator<=(
const iter_impl& other)
const
10737 return not other.operator < (*this);
10744 bool operator>(
const iter_impl& other)
const
10746 return not operator<=(other);
10753 bool operator>=(
const iter_impl& other)
const
10755 return not operator<(other);
10762 iter_impl& operator+=(difference_type i)
10764 assert(m_object !=
nullptr);
10766 switch (m_object->m_type)
10768 case value_t::object:
10769 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
10771 case value_t::array:
10773 std::advance(m_it.array_iterator, i);
10779 m_it.primitive_iterator += i;
10791 iter_impl& operator-=(difference_type i)
10793 return operator+=(-i);
10800 iter_impl operator+(difference_type i)
const
10802 auto result = *
this;
10811 friend iter_impl operator+(difference_type i,
const iter_impl& it)
10822 iter_impl operator-(difference_type i)
const
10824 auto result = *
this;
10833 difference_type operator-(
const iter_impl& other)
const
10835 assert(m_object !=
nullptr);
10837 switch (m_object->m_type)
10839 case value_t::object:
10840 JSON_THROW(invalid_iterator::create(209,
"cannot use offsets with object iterators"));
10842 case value_t::array:
10843 return m_it.array_iterator - other.m_it.array_iterator;
10846 return m_it.primitive_iterator - other.m_it.primitive_iterator;
10854 reference operator[](difference_type n)
const
10856 assert(m_object !=
nullptr);
10858 switch (m_object->m_type)
10860 case value_t::object:
10861 JSON_THROW(invalid_iterator::create(208,
"cannot use operator[] for object iterators"));
10863 case value_t::array:
10864 return *std::next(m_it.array_iterator, n);
10866 case value_t::null:
10867 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
10871 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
10876 JSON_THROW(invalid_iterator::create(214,
"cannot get value"));
10885 const typename object_t::key_type& key()
const
10887 assert(m_object !=
nullptr);
10889 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
10891 return m_it.object_iterator->first;
10894 JSON_THROW(invalid_iterator::create(207,
"cannot use key() for non-object iterators"));
10901 reference value()
const
10903 return operator*();
10908 pointer m_object =
nullptr;
10910 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
10921 #include <iterator>
10950 template<
typename Base>
10951 class json_reverse_iterator :
public std::reverse_iterator<Base>
10954 using difference_type = std::ptrdiff_t;
10956 using base_iterator = std::reverse_iterator<Base>;
10958 using reference =
typename Base::reference;
10961 explicit json_reverse_iterator(
const typename base_iterator::iterator_type& it) noexcept
10962 : base_iterator(it) {}
10965 explicit json_reverse_iterator(
const base_iterator& it) noexcept : base_iterator(it) {}
10968 json_reverse_iterator
const operator++(
int)
10970 return static_cast<json_reverse_iterator
>(base_iterator::operator++(1));
10974 json_reverse_iterator& operator++()
10976 return static_cast<json_reverse_iterator&
>(base_iterator::operator++());
10980 json_reverse_iterator
const operator--(
int)
10982 return static_cast<json_reverse_iterator
>(base_iterator::operator--(1));
10986 json_reverse_iterator& operator--()
10988 return static_cast<json_reverse_iterator&
>(base_iterator::operator--());
10992 json_reverse_iterator& operator+=(difference_type i)
10994 return static_cast<json_reverse_iterator&
>(base_iterator::operator+=(i));
10998 json_reverse_iterator operator+(difference_type i)
const
11000 return static_cast<json_reverse_iterator
>(base_iterator::operator+(i));
11004 json_reverse_iterator operator-(difference_type i)
const
11006 return static_cast<json_reverse_iterator
>(base_iterator::operator-(i));
11010 difference_type operator-(
const json_reverse_iterator& other)
const
11012 return base_iterator(*
this) - base_iterator(other);
11016 reference operator[](difference_type n)
const
11018 return *(this->operator+(n));
11022 auto key() const -> decltype(std::declval<Base>().key())
11024 auto it = --this->base();
11029 reference value()
const
11031 auto it = --this->base();
11032 return it.operator * ();
11043 #include <algorithm>
11060 template<
typename BasicJsonType>
11064 NLOHMANN_BASIC_JSON_TPL_DECLARATION
11090 : reference_tokens(split(s))
11109 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
11111 [](
const std::string & a,
const std::string & b)
11113 return a +
"/" + escape(b);
11118 operator std::string()
const
11141 reference_tokens.insert(reference_tokens.end(),
11142 ptr.reference_tokens.begin(),
11143 ptr.reference_tokens.end());
11187 return *
this /= std::to_string(array_idx);
11291 if (JSON_HEDLEY_UNLIKELY(
empty()))
11293 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
11296 reference_tokens.pop_back();
11315 if (JSON_HEDLEY_UNLIKELY(
empty()))
11317 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
11320 return reference_tokens.back();
11337 reference_tokens.push_back(token);
11343 reference_tokens.push_back(std::move(token));
11362 return reference_tokens.empty();
11373 static int array_index(
const std::string& s)
11376 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 and s[0] ==
'0'))
11378 JSON_THROW(detail::parse_error::create(106, 0,
11379 "array index '" + s +
11380 "' must not begin with '0'"));
11384 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 and not (s[0] >=
'1' and s[0] <=
'9')))
11386 JSON_THROW(detail::parse_error::create(109, 0,
"array index '" + s +
"' is not a number"));
11389 std::size_t processed_chars = 0;
11393 res = std::stoi(s, &processed_chars);
11395 JSON_CATCH(std::out_of_range&)
11397 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + s +
"'"));
11401 if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
11403 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + s +
"'"));
11411 if (JSON_HEDLEY_UNLIKELY(
empty()))
11413 JSON_THROW(detail::out_of_range::create(405,
"JSON pointer has no parent"));
11417 result.reference_tokens = {reference_tokens[0]};
11429 BasicJsonType& get_and_create(BasicJsonType& j)
const
11431 using size_type =
typename BasicJsonType::size_type;
11436 for (
const auto& reference_token : reference_tokens)
11438 switch (result->type())
11440 case detail::value_t::null:
11442 if (reference_token ==
"0")
11445 result = &result->operator[](0);
11450 result = &result->operator[](reference_token);
11455 case detail::value_t::object:
11458 result = &result->operator[](reference_token);
11462 case detail::value_t::array:
11465 result = &result->operator[](
static_cast<size_type
>(array_index(reference_token)));
11476 JSON_THROW(detail::type_error::create(313,
"invalid value to unflatten"));
11502 BasicJsonType& get_unchecked(BasicJsonType* ptr)
const
11504 using size_type =
typename BasicJsonType::size_type;
11505 for (
const auto& reference_token : reference_tokens)
11508 if (ptr->is_null())
11512 std::all_of(reference_token.begin(), reference_token.end(),
11513 [](
const unsigned char x)
11515 return std::isdigit(x);
11519 *ptr = (nums or reference_token ==
"-")
11520 ? detail::value_t::array
11521 : detail::value_t::object;
11524 switch (ptr->type())
11526 case detail::value_t::object:
11529 ptr = &ptr->operator[](reference_token);
11533 case detail::value_t::array:
11535 if (reference_token ==
"-")
11538 ptr = &ptr->operator[](ptr->m_value.array->size());
11543 ptr = &ptr->operator[](
11544 static_cast<size_type
>(array_index(reference_token)));
11550 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
11563 BasicJsonType& get_checked(BasicJsonType* ptr)
const
11565 using size_type =
typename BasicJsonType::size_type;
11566 for (
const auto& reference_token : reference_tokens)
11568 switch (ptr->type())
11570 case detail::value_t::object:
11573 ptr = &ptr->at(reference_token);
11577 case detail::value_t::array:
11579 if (JSON_HEDLEY_UNLIKELY(reference_token ==
"-"))
11582 JSON_THROW(detail::out_of_range::create(402,
11583 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
11584 ") is out of range"));
11588 ptr = &ptr->at(
static_cast<size_type
>(array_index(reference_token)));
11593 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
11613 const BasicJsonType& get_unchecked(
const BasicJsonType* ptr)
const
11615 using size_type =
typename BasicJsonType::size_type;
11616 for (
const auto& reference_token : reference_tokens)
11618 switch (ptr->type())
11620 case detail::value_t::object:
11623 ptr = &ptr->operator[](reference_token);
11627 case detail::value_t::array:
11629 if (JSON_HEDLEY_UNLIKELY(reference_token ==
"-"))
11632 JSON_THROW(detail::out_of_range::create(402,
11633 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
11634 ") is out of range"));
11638 ptr = &ptr->operator[](
11639 static_cast<size_type
>(array_index(reference_token)));
11644 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
11657 const BasicJsonType& get_checked(
const BasicJsonType* ptr)
const
11659 using size_type =
typename BasicJsonType::size_type;
11660 for (
const auto& reference_token : reference_tokens)
11662 switch (ptr->type())
11664 case detail::value_t::object:
11667 ptr = &ptr->at(reference_token);
11671 case detail::value_t::array:
11673 if (JSON_HEDLEY_UNLIKELY(reference_token ==
"-"))
11676 JSON_THROW(detail::out_of_range::create(402,
11677 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
11678 ") is out of range"));
11682 ptr = &ptr->at(
static_cast<size_type
>(array_index(reference_token)));
11687 JSON_THROW(detail::out_of_range::create(404,
"unresolved reference token '" + reference_token +
"'"));
11698 bool contains(
const BasicJsonType* ptr)
const
11700 using size_type =
typename BasicJsonType::size_type;
11701 for (
const auto& reference_token : reference_tokens)
11703 switch (ptr->type())
11705 case detail::value_t::object:
11707 if (not ptr->contains(reference_token))
11713 ptr = &ptr->operator[](reference_token);
11717 case detail::value_t::array:
11719 if (JSON_HEDLEY_UNLIKELY(reference_token ==
"-"))
11724 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 and not (
"0" <= reference_token and reference_token <=
"9")))
11729 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
11731 if (JSON_HEDLEY_UNLIKELY(not (
'1' <= reference_token[0] and reference_token[0] <=
'9')))
11736 for (std::size_t i = 1; i < reference_token.size(); i++)
11738 if (JSON_HEDLEY_UNLIKELY(not (
'0' <= reference_token[i] and reference_token[i] <=
'9')))
11746 const auto idx =
static_cast<size_type
>(array_index(reference_token));
11747 if (idx >= ptr->size())
11753 ptr = &ptr->operator[](idx);
11779 static std::vector<std::string> split(
const std::string& reference_string)
11781 std::vector<std::string> result;
11784 if (reference_string.empty())
11790 if (JSON_HEDLEY_UNLIKELY(reference_string[0] !=
'/'))
11792 JSON_THROW(detail::parse_error::create(107, 1,
11793 "JSON pointer must be empty or begin with '/' - was: '" +
11794 reference_string +
"'"));
11802 std::size_t slash = reference_string.find_first_of(
'/', 1),
11809 start = (slash == std::string::npos) ? 0 : slash + 1,
11811 slash = reference_string.find_first_of(
'/', start))
11815 auto reference_token = reference_string.substr(start, slash - start);
11818 for (std::size_t pos = reference_token.find_first_of(
'~');
11819 pos != std::string::npos;
11820 pos = reference_token.find_first_of(
'~', pos + 1))
11822 assert(reference_token[pos] ==
'~');
11825 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 or
11826 (reference_token[pos + 1] !=
'0' and
11827 reference_token[pos + 1] !=
'1')))
11829 JSON_THROW(detail::parse_error::create(108, 0,
"escape character '~' must be followed with '0' or '1'"));
11834 unescape(reference_token);
11835 result.push_back(reference_token);
11854 static void replace_substring(std::string& s,
const std::string& f,
11855 const std::string& t)
11857 assert(not f.empty());
11858 for (
auto pos = s.find(f);
11859 pos != std::string::npos;
11860 s.replace(pos, f.size(), t),
11861 pos = s.find(f, pos + t.size()))
11866 static std::string escape(std::string s)
11868 replace_substring(s,
"~",
"~0");
11869 replace_substring(s,
"/",
"~1");
11874 static void unescape(std::string& s)
11876 replace_substring(s,
"~1",
"/");
11877 replace_substring(s,
"~0",
"~");
11887 static void flatten(
const std::string& reference_string,
11888 const BasicJsonType& value,
11889 BasicJsonType& result)
11891 switch (value.type())
11893 case detail::value_t::array:
11895 if (value.m_value.array->empty())
11898 result[reference_string] =
nullptr;
11903 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
11905 flatten(reference_string +
"/" + std::to_string(i),
11906 value.m_value.array->operator[](i), result);
11912 case detail::value_t::object:
11914 if (value.m_value.object->empty())
11917 result[reference_string] =
nullptr;
11922 for (
const auto& element : *value.m_value.object)
11924 flatten(reference_string +
"/" + escape(element.first), element.second, result);
11933 result[reference_string] = value;
11949 static BasicJsonType
11950 unflatten(
const BasicJsonType& value)
11952 if (JSON_HEDLEY_UNLIKELY(not value.is_object()))
11954 JSON_THROW(detail::type_error::create(314,
"only objects can be unflattened"));
11957 BasicJsonType result;
11960 for (
const auto& element : *value.m_value.object)
11962 if (JSON_HEDLEY_UNLIKELY(not element.second.is_primitive()))
11964 JSON_THROW(detail::type_error::create(315,
"values in object must be primitive"));
11971 json_pointer(element.first).get_and_create(result) = element.second;
11991 return lhs.reference_tokens == rhs.reference_tokens;
12008 return not (lhs == rhs);
12012 std::vector<std::string> reference_tokens;
12019 #include <initializer_list>
12029 template<
typename BasicJsonType>
12033 using value_type = BasicJsonType;
12035 json_ref(value_type&& value)
12036 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
12039 json_ref(
const value_type& value)
12040 : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
12043 json_ref(std::initializer_list<json_ref> init)
12044 : owned_value(init), value_ref(&owned_value), is_rvalue(true)
12049 enable_if_t<std::is_constructible<value_type, Args...>::value,
int> = 0 >
12050 json_ref(Args && ... args)
12051 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value),
12055 json_ref(json_ref&&) =
default;
12056 json_ref(
const json_ref&) =
delete;
12057 json_ref& operator=(
const json_ref&) =
delete;
12058 json_ref& operator=(json_ref&&) =
delete;
12059 ~json_ref() =
default;
12061 value_type moved_or_copied()
const
12065 return std::move(*value_ref);
12070 value_type
const& operator*()
const
12072 return *
static_cast<value_type const*
>(value_ref);
12075 value_type
const* operator->()
const
12077 return static_cast<value_type const*
>(value_ref);
12081 mutable value_type owned_value =
nullptr;
12082 value_type* value_ref =
nullptr;
12083 const bool is_rvalue;
12097 #include <algorithm>
12112 #include <algorithm>
12115 #include <iterator>
12128 template<
typename CharType>
struct output_adapter_protocol
12130 virtual void write_character(CharType c) = 0;
12131 virtual void write_characters(
const CharType* s, std::size_t length) = 0;
12132 virtual ~output_adapter_protocol() =
default;
12136 template<
typename CharType>
12137 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
12140 template<
typename CharType>
12141 class output_vector_adapter :
public output_adapter_protocol<CharType>
12144 explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
12148 void write_character(CharType c)
override
12153 JSON_HEDLEY_NON_NULL(2)
12154 void write_characters(const CharType* s, std::
size_t length)
override
12156 std::copy(s, s + length, std::back_inserter(v));
12160 std::vector<CharType>& v;
12164 template<
typename CharType>
12165 class output_stream_adapter :
public output_adapter_protocol<CharType>
12168 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
12172 void write_character(CharType c)
override
12177 JSON_HEDLEY_NON_NULL(2)
12178 void write_characters(const CharType* s, std::
size_t length)
override
12180 stream.write(s,
static_cast<std::streamsize
>(length));
12184 std::basic_ostream<CharType>& stream;
12188 template<
typename CharType,
typename StringType = std::basic_
string<CharType>>
12189 class output_string_adapter :
public output_adapter_protocol<CharType>
12192 explicit output_string_adapter(StringType& s) noexcept
12196 void write_character(CharType c)
override
12201 JSON_HEDLEY_NON_NULL(2)
12202 void write_characters(const CharType* s, std::
size_t length)
override
12204 str.append(s, length);
12211 template<
typename CharType,
typename StringType = std::basic_
string<CharType>>
12212 class output_adapter
12215 output_adapter(std::vector<CharType>& vec)
12216 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
12218 output_adapter(std::basic_ostream<CharType>& s)
12219 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
12221 output_adapter(StringType& s)
12222 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
12224 operator output_adapter_t<CharType>()
12230 output_adapter_t<CharType> oa =
nullptr;
12247 template<
typename BasicJsonType,
typename CharType>
12248 class binary_writer
12250 using string_t =
typename BasicJsonType::string_t;
12251 using binary_t =
typename BasicJsonType::binary_t;
12259 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
12268 void write_bson(
const BasicJsonType& j)
12272 case value_t::object:
12274 write_bson_object(*j.m_value.object);
12280 JSON_THROW(type_error::create(317,
"to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
12288 void write_cbor(
const BasicJsonType& j)
12292 case value_t::null:
12294 oa->write_character(to_char_type(0xF6));
12298 case value_t::boolean:
12300 oa->write_character(j.m_value.boolean
12301 ? to_char_type(0xF5)
12302 : to_char_type(0xF4));
12306 case value_t::number_integer:
12308 if (j.m_value.number_integer >= 0)
12313 if (j.m_value.number_integer <= 0x17)
12315 write_number(
static_cast<std::uint8_t
>(j.m_value.number_integer));
12317 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
12319 oa->write_character(to_char_type(0x18));
12320 write_number(
static_cast<std::uint8_t
>(j.m_value.number_integer));
12322 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
12324 oa->write_character(to_char_type(0x19));
12325 write_number(
static_cast<std::uint16_t
>(j.m_value.number_integer));
12327 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
12329 oa->write_character(to_char_type(0x1A));
12330 write_number(
static_cast<std::uint32_t
>(j.m_value.number_integer));
12334 oa->write_character(to_char_type(0x1B));
12335 write_number(
static_cast<std::uint64_t
>(j.m_value.number_integer));
12342 const auto positive_number = -1 - j.m_value.number_integer;
12343 if (j.m_value.number_integer >= -24)
12345 write_number(
static_cast<std::uint8_t
>(0x20 + positive_number));
12347 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
12349 oa->write_character(to_char_type(0x38));
12350 write_number(
static_cast<std::uint8_t
>(positive_number));
12352 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
12354 oa->write_character(to_char_type(0x39));
12355 write_number(
static_cast<std::uint16_t
>(positive_number));
12357 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
12359 oa->write_character(to_char_type(0x3A));
12360 write_number(
static_cast<std::uint32_t
>(positive_number));
12364 oa->write_character(to_char_type(0x3B));
12365 write_number(
static_cast<std::uint64_t
>(positive_number));
12371 case value_t::number_unsigned:
12373 if (j.m_value.number_unsigned <= 0x17)
12375 write_number(
static_cast<std::uint8_t
>(j.m_value.number_unsigned));
12377 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12379 oa->write_character(to_char_type(0x18));
12380 write_number(
static_cast<std::uint8_t
>(j.m_value.number_unsigned));
12382 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12384 oa->write_character(to_char_type(0x19));
12385 write_number(
static_cast<std::uint16_t
>(j.m_value.number_unsigned));
12387 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12389 oa->write_character(to_char_type(0x1A));
12390 write_number(
static_cast<std::uint32_t
>(j.m_value.number_unsigned));
12394 oa->write_character(to_char_type(0x1B));
12395 write_number(
static_cast<std::uint64_t
>(j.m_value.number_unsigned));
12400 case value_t::number_float:
12402 if (std::isnan(j.m_value.number_float))
12405 oa->write_character(to_char_type(0xF9));
12406 oa->write_character(to_char_type(0x7E));
12407 oa->write_character(to_char_type(0x00));
12409 else if (std::isinf(j.m_value.number_float))
12412 oa->write_character(to_char_type(0xf9));
12413 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
12414 oa->write_character(to_char_type(0x00));
12418 if (
static_cast<double>(j.m_value.number_float) >=
static_cast<double>(std::numeric_limits<float>::lowest()) and
12419 static_cast<double>(j.m_value.number_float) <=
static_cast<double>((std::numeric_limits<float>::max)()) and
12420 static_cast<double>(
static_cast<float>(j.m_value.number_float)) ==
static_cast<double>(j.m_value.number_float))
12422 oa->write_character(get_cbor_float_prefix(
static_cast<float>(j.m_value.number_float)));
12423 write_number(
static_cast<float>(j.m_value.number_float));
12427 oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
12428 write_number(j.m_value.number_float);
12434 case value_t::string:
12437 const auto N = j.m_value.string->size();
12440 write_number(
static_cast<std::uint8_t
>(0x60 + N));
12442 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12444 oa->write_character(to_char_type(0x78));
12445 write_number(
static_cast<std::uint8_t
>(N));
12447 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12449 oa->write_character(to_char_type(0x79));
12450 write_number(
static_cast<std::uint16_t
>(N));
12452 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12454 oa->write_character(to_char_type(0x7A));
12455 write_number(
static_cast<std::uint32_t
>(N));
12458 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12460 oa->write_character(to_char_type(0x7B));
12461 write_number(
static_cast<std::uint64_t
>(N));
12466 oa->write_characters(
12467 reinterpret_cast<const CharType*
>(j.m_value.string->c_str()),
12468 j.m_value.string->size());
12472 case value_t::array:
12475 const auto N = j.m_value.array->size();
12478 write_number(
static_cast<std::uint8_t
>(0x80 + N));
12480 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12482 oa->write_character(to_char_type(0x98));
12483 write_number(
static_cast<std::uint8_t
>(N));
12485 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12487 oa->write_character(to_char_type(0x99));
12488 write_number(
static_cast<std::uint16_t
>(N));
12490 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12492 oa->write_character(to_char_type(0x9A));
12493 write_number(
static_cast<std::uint32_t
>(N));
12496 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12498 oa->write_character(to_char_type(0x9B));
12499 write_number(
static_cast<std::uint64_t
>(N));
12504 for (
const auto& el : *j.m_value.array)
12511 case value_t::binary:
12514 const auto N = j.m_value.binary->size();
12517 write_number(
static_cast<std::uint8_t
>(0x40 + N));
12519 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12521 oa->write_character(to_char_type(0x58));
12522 write_number(
static_cast<std::uint8_t
>(N));
12524 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12526 oa->write_character(to_char_type(0x59));
12527 write_number(
static_cast<std::uint16_t
>(N));
12529 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12531 oa->write_character(to_char_type(0x5A));
12532 write_number(
static_cast<std::uint32_t
>(N));
12535 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12537 oa->write_character(to_char_type(0x5B));
12538 write_number(
static_cast<std::uint64_t
>(N));
12543 oa->write_characters(
12544 reinterpret_cast<const CharType*
>(j.m_value.binary->data()),
12550 case value_t::object:
12553 const auto N = j.m_value.object->size();
12556 write_number(
static_cast<std::uint8_t
>(0xA0 + N));
12558 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12560 oa->write_character(to_char_type(0xB8));
12561 write_number(
static_cast<std::uint8_t
>(N));
12563 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12565 oa->write_character(to_char_type(0xB9));
12566 write_number(
static_cast<std::uint16_t
>(N));
12568 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12570 oa->write_character(to_char_type(0xBA));
12571 write_number(
static_cast<std::uint32_t
>(N));
12574 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12576 oa->write_character(to_char_type(0xBB));
12577 write_number(
static_cast<std::uint64_t
>(N));
12582 for (
const auto& el : *j.m_value.object)
12584 write_cbor(el.first);
12585 write_cbor(el.second);
12598 void write_msgpack(
const BasicJsonType& j)
12602 case value_t::null:
12604 oa->write_character(to_char_type(0xC0));
12608 case value_t::boolean:
12610 oa->write_character(j.m_value.boolean
12611 ? to_char_type(0xC3)
12612 : to_char_type(0xC2));
12616 case value_t::number_integer:
12618 if (j.m_value.number_integer >= 0)
12623 if (j.m_value.number_unsigned < 128)
12626 write_number(
static_cast<std::uint8_t
>(j.m_value.number_integer));
12628 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12631 oa->write_character(to_char_type(0xCC));
12632 write_number(
static_cast<std::uint8_t
>(j.m_value.number_integer));
12634 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12637 oa->write_character(to_char_type(0xCD));
12638 write_number(
static_cast<std::uint16_t
>(j.m_value.number_integer));
12640 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12643 oa->write_character(to_char_type(0xCE));
12644 write_number(
static_cast<std::uint32_t
>(j.m_value.number_integer));
12646 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
12649 oa->write_character(to_char_type(0xCF));
12650 write_number(
static_cast<std::uint64_t
>(j.m_value.number_integer));
12655 if (j.m_value.number_integer >= -32)
12658 write_number(
static_cast<std::int8_t
>(j.m_value.number_integer));
12660 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() and
12661 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
12664 oa->write_character(to_char_type(0xD0));
12665 write_number(
static_cast<std::int8_t
>(j.m_value.number_integer));
12667 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() and
12668 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
12671 oa->write_character(to_char_type(0xD1));
12672 write_number(
static_cast<std::int16_t
>(j.m_value.number_integer));
12674 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() and
12675 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
12678 oa->write_character(to_char_type(0xD2));
12679 write_number(
static_cast<std::int32_t
>(j.m_value.number_integer));
12681 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() and
12682 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
12685 oa->write_character(to_char_type(0xD3));
12686 write_number(
static_cast<std::int64_t
>(j.m_value.number_integer));
12692 case value_t::number_unsigned:
12694 if (j.m_value.number_unsigned < 128)
12697 write_number(
static_cast<std::uint8_t
>(j.m_value.number_integer));
12699 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12702 oa->write_character(to_char_type(0xCC));
12703 write_number(
static_cast<std::uint8_t
>(j.m_value.number_integer));
12705 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12708 oa->write_character(to_char_type(0xCD));
12709 write_number(
static_cast<std::uint16_t
>(j.m_value.number_integer));
12711 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12714 oa->write_character(to_char_type(0xCE));
12715 write_number(
static_cast<std::uint32_t
>(j.m_value.number_integer));
12717 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
12720 oa->write_character(to_char_type(0xCF));
12721 write_number(
static_cast<std::uint64_t
>(j.m_value.number_integer));
12726 case value_t::number_float:
12728 oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
12729 write_number(j.m_value.number_float);
12733 case value_t::string:
12736 const auto N = j.m_value.string->size();
12740 write_number(
static_cast<std::uint8_t
>(0xA0 | N));
12742 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12745 oa->write_character(to_char_type(0xD9));
12746 write_number(
static_cast<std::uint8_t
>(N));
12748 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12751 oa->write_character(to_char_type(0xDA));
12752 write_number(
static_cast<std::uint16_t
>(N));
12754 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12757 oa->write_character(to_char_type(0xDB));
12758 write_number(
static_cast<std::uint32_t
>(N));
12762 oa->write_characters(
12763 reinterpret_cast<const CharType*
>(j.m_value.string->c_str()),
12764 j.m_value.string->size());
12768 case value_t::array:
12771 const auto N = j.m_value.array->size();
12775 write_number(
static_cast<std::uint8_t
>(0x90 | N));
12777 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12780 oa->write_character(to_char_type(0xDC));
12781 write_number(
static_cast<std::uint16_t
>(N));
12783 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12786 oa->write_character(to_char_type(0xDD));
12787 write_number(
static_cast<std::uint32_t
>(N));
12791 for (
const auto& el : *j.m_value.array)
12798 case value_t::binary:
12802 const bool use_ext = j.m_value.binary->has_subtype();
12805 const auto N = j.m_value.binary->size();
12806 if (N <= (std::numeric_limits<std::uint8_t>::max)())
12808 std::uint8_t output_type;
12815 output_type = 0xD4;
12818 output_type = 0xD5;
12821 output_type = 0xD6;
12824 output_type = 0xD7;
12827 output_type = 0xD8;
12830 output_type = 0xC7;
12838 output_type = 0xC4;
12842 oa->write_character(to_char_type(output_type));
12845 write_number(
static_cast<std::uint8_t
>(N));
12848 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12850 std::uint8_t output_type;
12853 output_type = 0xC8;
12857 output_type = 0xC5;
12860 oa->write_character(to_char_type(output_type));
12861 write_number(
static_cast<std::uint16_t
>(N));
12863 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12865 std::uint8_t output_type;
12868 output_type = 0xC9;
12872 output_type = 0xC6;
12875 oa->write_character(to_char_type(output_type));
12876 write_number(
static_cast<std::uint32_t
>(N));
12882 write_number(
static_cast<std::int8_t
>(j.m_value.binary->subtype()));
12886 oa->write_characters(
12887 reinterpret_cast<const CharType*
>(j.m_value.binary->data()),
12893 case value_t::object:
12896 const auto N = j.m_value.object->size();
12900 write_number(
static_cast<std::uint8_t
>(0x80 | (N & 0xF)));
12902 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12905 oa->write_character(to_char_type(0xDE));
12906 write_number(
static_cast<std::uint16_t
>(N));
12908 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12911 oa->write_character(to_char_type(0xDF));
12912 write_number(
static_cast<std::uint32_t
>(N));
12916 for (
const auto& el : *j.m_value.object)
12918 write_msgpack(el.first);
12919 write_msgpack(el.second);
12935 void write_ubjson(
const BasicJsonType& j,
const bool use_count,
12936 const bool use_type,
const bool add_prefix =
true)
12940 case value_t::null:
12944 oa->write_character(to_char_type(
'Z'));
12949 case value_t::boolean:
12953 oa->write_character(j.m_value.boolean
12954 ? to_char_type(
'T')
12955 : to_char_type(
'F'));
12960 case value_t::number_integer:
12962 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
12966 case value_t::number_unsigned:
12968 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
12972 case value_t::number_float:
12974 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
12978 case value_t::string:
12982 oa->write_character(to_char_type(
'S'));
12984 write_number_with_ubjson_prefix(j.m_value.string->size(),
true);
12985 oa->write_characters(
12986 reinterpret_cast<const CharType*
>(j.m_value.string->c_str()),
12987 j.m_value.string->size());
12991 case value_t::array:
12995 oa->write_character(to_char_type(
'['));
12998 bool prefix_required =
true;
12999 if (use_type and not j.m_value.array->empty())
13002 const CharType first_prefix = ubjson_prefix(j.front());
13003 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
13004 [
this, first_prefix](
const BasicJsonType & v)
13006 return ubjson_prefix(v) == first_prefix;
13011 prefix_required =
false;
13012 oa->write_character(to_char_type(
'$'));
13013 oa->write_character(first_prefix);
13019 oa->write_character(to_char_type(
'#'));
13020 write_number_with_ubjson_prefix(j.m_value.array->size(),
true);
13023 for (
const auto& el : *j.m_value.array)
13025 write_ubjson(el, use_count, use_type, prefix_required);
13030 oa->write_character(to_char_type(
']'));
13036 case value_t::binary:
13040 oa->write_character(to_char_type(
'['));
13043 if (use_type and not j.m_value.binary->empty())
13046 oa->write_character(to_char_type(
'$'));
13047 oa->write_character(
'U');
13052 oa->write_character(to_char_type(
'#'));
13053 write_number_with_ubjson_prefix(j.m_value.binary->size(),
true);
13058 oa->write_characters(
13059 reinterpret_cast<const CharType*
>(j.m_value.binary->data()),
13060 j.m_value.binary->size());
13064 for (
size_t i = 0; i < j.m_value.binary->size(); ++i)
13066 oa->write_character(to_char_type(
'U'));
13067 oa->write_character(j.m_value.binary->data()[i]);
13073 oa->write_character(to_char_type(
']'));
13079 case value_t::object:
13083 oa->write_character(to_char_type(
'{'));
13086 bool prefix_required =
true;
13087 if (use_type and not j.m_value.object->empty())
13090 const CharType first_prefix = ubjson_prefix(j.front());
13091 const bool same_prefix = std::all_of(j.begin(), j.end(),
13092 [
this, first_prefix](
const BasicJsonType & v)
13094 return ubjson_prefix(v) == first_prefix;
13099 prefix_required =
false;
13100 oa->write_character(to_char_type(
'$'));
13101 oa->write_character(first_prefix);
13107 oa->write_character(to_char_type(
'#'));
13108 write_number_with_ubjson_prefix(j.m_value.object->size(),
true);
13111 for (
const auto& el : *j.m_value.object)
13113 write_number_with_ubjson_prefix(el.first.size(),
true);
13114 oa->write_characters(
13115 reinterpret_cast<const CharType*
>(el.first.c_str()),
13117 write_ubjson(el.second, use_count, use_type, prefix_required);
13122 oa->write_character(to_char_type(
'}'));
13142 static std::size_t calc_bson_entry_header_size(
const string_t& name)
13144 const auto it = name.find(
static_cast<typename string_t::value_type
>(0));
13145 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
13147 JSON_THROW(out_of_range::create(409,
13148 "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) +
")"));
13151 return 1ul + name.size() + 1u;
13157 void write_bson_entry_header(
const string_t& name,
13158 const std::uint8_t element_type)
13160 oa->write_character(to_char_type(element_type));
13161 oa->write_characters(
13162 reinterpret_cast<const CharType*
>(name.c_str()),
13169 void write_bson_boolean(
const string_t& name,
13172 write_bson_entry_header(name, 0x08);
13173 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
13179 void write_bson_double(
const string_t& name,
13180 const double value)
13182 write_bson_entry_header(name, 0x01);
13183 write_number<double, true>(value);
13189 static std::size_t calc_bson_string_size(
const string_t& value)
13191 return sizeof(std::int32_t) + value.size() + 1ul;
13197 void write_bson_string(
const string_t& name,
13198 const string_t& value)
13200 write_bson_entry_header(name, 0x02);
13202 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(value.size() + 1ul));
13203 oa->write_characters(
13204 reinterpret_cast<const CharType*
>(value.c_str()),
13211 void write_bson_null(
const string_t& name)
13213 write_bson_entry_header(name, 0x0A);
13219 static std::size_t calc_bson_integer_size(
const std::int64_t value)
13221 return (std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)()
13222 ?
sizeof(std::int32_t)
13223 :
sizeof(std::int64_t);
13229 void write_bson_integer(
const string_t& name,
13230 const std::int64_t value)
13232 if ((std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)())
13234 write_bson_entry_header(name, 0x10);
13235 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(value));
13239 write_bson_entry_header(name, 0x12);
13240 write_number<std::int64_t, true>(
static_cast<std::int64_t
>(value));
13247 static constexpr std::size_t calc_bson_unsigned_size(
const std::uint64_t value) noexcept
13249 return (value <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int32_t>::max)()))
13250 ?
sizeof(std::int32_t)
13251 :
sizeof(std::int64_t);
13257 void write_bson_unsigned(
const string_t& name,
13258 const std::uint64_t value)
13260 if (value <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int32_t>::max)()))
13262 write_bson_entry_header(name, 0x10 );
13263 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(value));
13265 else if (value <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int64_t>::max)()))
13267 write_bson_entry_header(name, 0x12 );
13268 write_number<std::int64_t, true>(
static_cast<std::int64_t
>(value));
13272 JSON_THROW(out_of_range::create(407,
"integer number " + std::to_string(value) +
" cannot be represented by BSON as it does not fit int64"));
13279 void write_bson_object_entry(
const string_t& name,
13280 const typename BasicJsonType::object_t& value)
13282 write_bson_entry_header(name, 0x03);
13283 write_bson_object(value);
13289 static std::size_t calc_bson_array_size(
const typename BasicJsonType::array_t& value)
13291 std::size_t array_index = 0ul;
13293 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)
13295 return result + calc_bson_element_size(std::to_string(array_index++), el);
13298 return sizeof(std::int32_t) + embedded_document_size + 1ul;
13304 static std::size_t calc_bson_binary_size(
const typename BasicJsonType::binary_t& value)
13306 return sizeof(std::int32_t) + value.size() + 1ul;
13312 void write_bson_array(
const string_t& name,
13313 const typename BasicJsonType::array_t& value)
13315 write_bson_entry_header(name, 0x04);
13316 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(calc_bson_array_size(value)));
13318 std::size_t array_index = 0ul;
13320 for (
const auto& el : value)
13322 write_bson_element(std::to_string(array_index++), el);
13325 oa->write_character(to_char_type(0x00));
13331 void write_bson_binary(
const string_t& name,
13332 const binary_t& value)
13334 write_bson_entry_header(name, 0x05);
13336 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(value.size()));
13337 write_number(value.has_subtype() ? value.subtype() : std::uint8_t(0x00));
13339 oa->write_characters(
reinterpret_cast<const CharType*
>(value.data()), value.size());
13346 static std::size_t calc_bson_element_size(
const string_t& name,
13347 const BasicJsonType& j)
13349 const auto header_size = calc_bson_entry_header_size(name);
13352 case value_t::object:
13353 return header_size + calc_bson_object_size(*j.m_value.object);
13355 case value_t::array:
13356 return header_size + calc_bson_array_size(*j.m_value.array);
13358 case value_t::binary:
13359 return header_size + calc_bson_binary_size(*j.m_value.binary);
13361 case value_t::boolean:
13362 return header_size + 1ul;
13364 case value_t::number_float:
13365 return header_size + 8ul;
13367 case value_t::number_integer:
13368 return header_size + calc_bson_integer_size(j.m_value.number_integer);
13370 case value_t::number_unsigned:
13371 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
13373 case value_t::string:
13374 return header_size + calc_bson_string_size(*j.m_value.string);
13376 case value_t::null:
13377 return header_size + 0ul;
13394 void write_bson_element(
const string_t& name,
13395 const BasicJsonType& j)
13399 case value_t::object:
13400 return write_bson_object_entry(name, *j.m_value.object);
13402 case value_t::array:
13403 return write_bson_array(name, *j.m_value.array);
13405 case value_t::binary:
13406 return write_bson_binary(name, *j.m_value.binary);
13408 case value_t::boolean:
13409 return write_bson_boolean(name, j.m_value.boolean);
13411 case value_t::number_float:
13412 return write_bson_double(name, j.m_value.number_float);
13414 case value_t::number_integer:
13415 return write_bson_integer(name, j.m_value.number_integer);
13417 case value_t::number_unsigned:
13418 return write_bson_unsigned(name, j.m_value.number_unsigned);
13420 case value_t::string:
13421 return write_bson_string(name, *j.m_value.string);
13423 case value_t::null:
13424 return write_bson_null(name);
13440 static std::size_t calc_bson_object_size(
const typename BasicJsonType::object_t& value)
13442 std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
13443 [](
size_t result,
const typename BasicJsonType::object_t::value_type & el)
13445 return result += calc_bson_element_size(el.first, el.second);
13448 return sizeof(std::int32_t) + document_size + 1ul;
13455 void write_bson_object(
const typename BasicJsonType::object_t& value)
13457 write_number<std::int32_t, true>(
static_cast<std::int32_t
>(calc_bson_object_size(value)));
13459 for (
const auto& el : value)
13461 write_bson_element(el.first, el.second);
13464 oa->write_character(to_char_type(0x00));
13471 static constexpr CharType get_cbor_float_prefix(
float )
13473 return to_char_type(0xFA);
13476 static constexpr CharType get_cbor_float_prefix(
double )
13478 return to_char_type(0xFB);
13485 static constexpr CharType get_msgpack_float_prefix(
float )
13487 return to_char_type(0xCA);
13490 static constexpr CharType get_msgpack_float_prefix(
double )
13492 return to_char_type(0xCB);
13500 template<
typename NumberType,
typename std::enable_if<
13501 std::is_floating_point<NumberType>::value,
int>::type = 0>
13502 void write_number_with_ubjson_prefix(
const NumberType n,
13503 const bool add_prefix)
13507 oa->write_character(get_ubjson_float_prefix(n));
13513 template<
typename NumberType,
typename std::enable_if<
13514 std::is_unsigned<NumberType>::value,
int>::type = 0>
13515 void write_number_with_ubjson_prefix(
const NumberType n,
13516 const bool add_prefix)
13518 if (n <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int8_t>::max)()))
13522 oa->write_character(to_char_type(
'i'));
13524 write_number(
static_cast<std::uint8_t
>(n));
13526 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
13530 oa->write_character(to_char_type(
'U'));
13532 write_number(
static_cast<std::uint8_t
>(n));
13534 else if (n <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int16_t>::max)()))
13538 oa->write_character(to_char_type(
'I'));
13540 write_number(
static_cast<std::int16_t
>(n));
13542 else if (n <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int32_t>::max)()))
13546 oa->write_character(to_char_type(
'l'));
13548 write_number(
static_cast<std::int32_t
>(n));
13550 else if (n <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int64_t>::max)()))
13554 oa->write_character(to_char_type(
'L'));
13556 write_number(
static_cast<std::int64_t
>(n));
13560 JSON_THROW(out_of_range::create(407,
"integer number " + std::to_string(n) +
" cannot be represented by UBJSON as it does not fit int64"));
13565 template<
typename NumberType,
typename std::enable_if<
13566 std::is_signed<NumberType>::value and
13567 not std::is_floating_point<NumberType>::value,
int>::type = 0>
13568 void write_number_with_ubjson_prefix(
const NumberType n,
13569 const bool add_prefix)
13571 if ((std::numeric_limits<std::int8_t>::min)() <= n and n <= (std::numeric_limits<std::int8_t>::max)())
13575 oa->write_character(to_char_type(
'i'));
13577 write_number(
static_cast<std::int8_t
>(n));
13579 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)()))
13583 oa->write_character(to_char_type(
'U'));
13585 write_number(
static_cast<std::uint8_t
>(n));
13587 else if ((std::numeric_limits<std::int16_t>::min)() <= n and n <= (std::numeric_limits<std::int16_t>::max)())
13591 oa->write_character(to_char_type(
'I'));
13593 write_number(
static_cast<std::int16_t
>(n));
13595 else if ((std::numeric_limits<std::int32_t>::min)() <= n and n <= (std::numeric_limits<std::int32_t>::max)())
13599 oa->write_character(to_char_type(
'l'));
13601 write_number(
static_cast<std::int32_t
>(n));
13603 else if ((std::numeric_limits<std::int64_t>::min)() <= n and n <= (std::numeric_limits<std::int64_t>::max)())
13607 oa->write_character(to_char_type(
'L'));
13609 write_number(
static_cast<std::int64_t
>(n));
13614 JSON_THROW(out_of_range::create(407,
"integer number " + std::to_string(n) +
" cannot be represented by UBJSON as it does not fit int64"));
13628 CharType ubjson_prefix(
const BasicJsonType& j)
const noexcept
13632 case value_t::null:
13635 case value_t::boolean:
13636 return j.m_value.boolean ?
'T' :
'F';
13638 case value_t::number_integer:
13640 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)())
13644 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)())
13648 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)())
13652 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)())
13660 case value_t::number_unsigned:
13662 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int8_t>::max)()))
13666 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t
>((std::numeric_limits<std::uint8_t>::max)()))
13670 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int16_t>::max)()))
13674 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int32_t>::max)()))
13682 case value_t::number_float:
13683 return get_ubjson_float_prefix(j.m_value.number_float);
13685 case value_t::string:
13688 case value_t::array:
13689 case value_t::binary:
13692 case value_t::object:
13700 static constexpr CharType get_ubjson_float_prefix(
float )
13705 static constexpr CharType get_ubjson_float_prefix(
double )
13725 template<
typename NumberType,
bool OutputIsLittleEndian = false>
13726 void write_number(
const NumberType n)
13729 std::array<CharType,
sizeof(NumberType)> vec;
13730 std::memcpy(vec.data(), &n,
sizeof(NumberType));
13733 if (is_little_endian != OutputIsLittleEndian)
13736 std::reverse(vec.begin(), vec.end());
13739 oa->write_characters(vec.data(),
sizeof(NumberType));
13747 template <
typename C = CharType,
13748 enable_if_t < std::is_signed<C>::value and std::is_signed<char>::value > * =
nullptr >
13749 static constexpr CharType to_char_type(std::uint8_t x) noexcept
13751 return *
reinterpret_cast<char*
>(&x);
13754 template <
typename C = CharType,
13755 enable_if_t < std::is_signed<C>::value and std::is_unsigned<char>::value > * =
nullptr >
13756 static CharType to_char_type(std::uint8_t x) noexcept
13758 static_assert(
sizeof(std::uint8_t) ==
sizeof(CharType),
"size of CharType must be equal to std::uint8_t");
13759 static_assert(std::is_trivial<CharType>::value,
"CharType must be trivial");
13761 std::memcpy(&result, &x,
sizeof(x));
13765 template<
typename C = CharType,
13766 enable_if_t<std::is_unsigned<C>::value>* =
nullptr>
13767 static constexpr CharType to_char_type(std::uint8_t x) noexcept
13772 template <
typename InputCharType,
typename C = CharType,
13774 std::is_signed<C>::value and
13775 std::is_signed<char>::value and
13776 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
13778 static constexpr CharType to_char_type(InputCharType x) noexcept
13785 const bool is_little_endian = little_endianess();
13788 output_adapter_t<CharType> oa =
nullptr;
13798 #include <algorithm>
13808 #include <type_traits>
13822 #include <type_traits>
13853 namespace dtoa_impl
13856 template <
typename Target,
typename Source>
13857 Target reinterpret_bits(
const Source source)
13859 static_assert(
sizeof(Target) ==
sizeof(Source),
"size mismatch");
13862 std::memcpy(&target, &source,
sizeof(Source));
13868 static constexpr
int kPrecision = 64;
13870 std::uint64_t f = 0;
13873 constexpr diyfp(std::uint64_t f_,
int e_) noexcept : f(f_), e(e_) {}
13879 static diyfp sub(
const diyfp& x,
const diyfp& y) noexcept
13881 assert(x.e == y.e);
13882 assert(x.f >= y.f);
13884 return {x.f - y.f, x.e};
13891 static diyfp mul(
const diyfp& x,
const diyfp& y) noexcept
13893 static_assert(kPrecision == 64,
"internal error");
13918 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
13919 const std::uint64_t u_hi = x.f >> 32u;
13920 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
13921 const std::uint64_t v_hi = y.f >> 32u;
13923 const std::uint64_t p0 = u_lo * v_lo;
13924 const std::uint64_t p1 = u_lo * v_hi;
13925 const std::uint64_t p2 = u_hi * v_lo;
13926 const std::uint64_t p3 = u_hi * v_hi;
13928 const std::uint64_t p0_hi = p0 >> 32u;
13929 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
13930 const std::uint64_t p1_hi = p1 >> 32u;
13931 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
13932 const std::uint64_t p2_hi = p2 >> 32u;
13934 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
13945 Q += std::uint64_t{1} << (64u - 32u - 1u);
13947 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
13949 return {h, x.e + y.e + 64};
13956 static diyfp normalize(diyfp x) noexcept
13960 while ((x.f >> 63u) == 0)
13973 static diyfp normalize_to(
const diyfp& x,
const int target_exponent) noexcept
13975 const int delta = x.e - target_exponent;
13977 assert(delta >= 0);
13978 assert(((x.f << delta) >> delta) == x.f);
13980 return {x.f << delta, target_exponent};
13997 template <
typename FloatType>
13998 boundaries compute_boundaries(FloatType value)
14000 assert(std::isfinite(value));
14010 static_assert(std::numeric_limits<FloatType>::is_iec559,
14011 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
14013 constexpr
int kPrecision = std::numeric_limits<FloatType>::digits;
14014 constexpr
int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
14015 constexpr
int kMinExp = 1 - kBias;
14016 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1);
14018 using bits_type =
typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
14020 const std::uint64_t bits = reinterpret_bits<bits_type>(value);
14021 const std::uint64_t E = bits >> (kPrecision - 1);
14022 const std::uint64_t F = bits & (kHiddenBit - 1);
14024 const bool is_denormal = E == 0;
14025 const diyfp v = is_denormal
14026 ? diyfp(F, kMinExp)
14027 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
14050 const bool lower_boundary_is_closer = F == 0 and E > 1;
14051 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
14052 const diyfp m_minus = lower_boundary_is_closer
14053 ? diyfp(4 * v.f - 1, v.e - 2)
14054 : diyfp(2 * v.f - 1, v.e - 1);
14057 const diyfp w_plus = diyfp::normalize(m_plus);
14060 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
14062 return {diyfp::normalize(v), w_minus, w_plus};
14120 constexpr
int kAlpha = -60;
14121 constexpr
int kGamma = -32;
14123 struct cached_power
14137 inline cached_power get_cached_power_for_binary_exponent(
int e)
14189 constexpr
int kCachedPowersMinDecExp = -300;
14190 constexpr
int kCachedPowersDecStep = 8;
14192 static constexpr std::array<cached_power, 79> kCachedPowers =
14195 { 0xAB70FE17C79AC6CA, -1060, -300 },
14196 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
14197 { 0xBE5691EF416BD60C, -1007, -284 },
14198 { 0x8DD01FAD907FFC3C, -980, -276 },
14199 { 0xD3515C2831559A83, -954, -268 },
14200 { 0x9D71AC8FADA6C9B5, -927, -260 },
14201 { 0xEA9C227723EE8BCB, -901, -252 },
14202 { 0xAECC49914078536D, -874, -244 },
14203 { 0x823C12795DB6CE57, -847, -236 },
14204 { 0xC21094364DFB5637, -821, -228 },
14205 { 0x9096EA6F3848984F, -794, -220 },
14206 { 0xD77485CB25823AC7, -768, -212 },
14207 { 0xA086CFCD97BF97F4, -741, -204 },
14208 { 0xEF340A98172AACE5, -715, -196 },
14209 { 0xB23867FB2A35B28E, -688, -188 },
14210 { 0x84C8D4DFD2C63F3B, -661, -180 },
14211 { 0xC5DD44271AD3CDBA, -635, -172 },
14212 { 0x936B9FCEBB25C996, -608, -164 },
14213 { 0xDBAC6C247D62A584, -582, -156 },
14214 { 0xA3AB66580D5FDAF6, -555, -148 },
14215 { 0xF3E2F893DEC3F126, -529, -140 },
14216 { 0xB5B5ADA8AAFF80B8, -502, -132 },
14217 { 0x87625F056C7C4A8B, -475, -124 },
14218 { 0xC9BCFF6034C13053, -449, -116 },
14219 { 0x964E858C91BA2655, -422, -108 },
14220 { 0xDFF9772470297EBD, -396, -100 },
14221 { 0xA6DFBD9FB8E5B88F, -369, -92 },
14222 { 0xF8A95FCF88747D94, -343, -84 },
14223 { 0xB94470938FA89BCF, -316, -76 },
14224 { 0x8A08F0F8BF0F156B, -289, -68 },
14225 { 0xCDB02555653131B6, -263, -60 },
14226 { 0x993FE2C6D07B7FAC, -236, -52 },
14227 { 0xE45C10C42A2B3B06, -210, -44 },
14228 { 0xAA242499697392D3, -183, -36 },
14229 { 0xFD87B5F28300CA0E, -157, -28 },
14230 { 0xBCE5086492111AEB, -130, -20 },
14231 { 0x8CBCCC096F5088CC, -103, -12 },
14232 { 0xD1B71758E219652C, -77, -4 },
14233 { 0x9C40000000000000, -50, 4 },
14234 { 0xE8D4A51000000000, -24, 12 },
14235 { 0xAD78EBC5AC620000, 3, 20 },
14236 { 0x813F3978F8940984, 30, 28 },
14237 { 0xC097CE7BC90715B3, 56, 36 },
14238 { 0x8F7E32CE7BEA5C70, 83, 44 },
14239 { 0xD5D238A4ABE98068, 109, 52 },
14240 { 0x9F4F2726179A2245, 136, 60 },
14241 { 0xED63A231D4C4FB27, 162, 68 },
14242 { 0xB0DE65388CC8ADA8, 189, 76 },
14243 { 0x83C7088E1AAB65DB, 216, 84 },
14244 { 0xC45D1DF942711D9A, 242, 92 },
14245 { 0x924D692CA61BE758, 269, 100 },
14246 { 0xDA01EE641A708DEA, 295, 108 },
14247 { 0xA26DA3999AEF774A, 322, 116 },
14248 { 0xF209787BB47D6B85, 348, 124 },
14249 { 0xB454E4A179DD1877, 375, 132 },
14250 { 0x865B86925B9BC5C2, 402, 140 },
14251 { 0xC83553C5C8965D3D, 428, 148 },
14252 { 0x952AB45CFA97A0B3, 455, 156 },
14253 { 0xDE469FBD99A05FE3, 481, 164 },
14254 { 0xA59BC234DB398C25, 508, 172 },
14255 { 0xF6C69A72A3989F5C, 534, 180 },
14256 { 0xB7DCBF5354E9BECE, 561, 188 },
14257 { 0x88FCF317F22241E2, 588, 196 },
14258 { 0xCC20CE9BD35C78A5, 614, 204 },
14259 { 0x98165AF37B2153DF, 641, 212 },
14260 { 0xE2A0B5DC971F303A, 667, 220 },
14261 { 0xA8D9D1535CE3B396, 694, 228 },
14262 { 0xFB9B7CD9A4A7443C, 720, 236 },
14263 { 0xBB764C4CA7A44410, 747, 244 },
14264 { 0x8BAB8EEFB6409C1A, 774, 252 },
14265 { 0xD01FEF10A657842C, 800, 260 },
14266 { 0x9B10A4E5E9913129, 827, 268 },
14267 { 0xE7109BFBA19C0C9D, 853, 276 },
14268 { 0xAC2820D9623BF429, 880, 284 },
14269 { 0x80444B5E7AA7CF85, 907, 292 },
14270 { 0xBF21E44003ACDD2D, 933, 300 },
14271 { 0x8E679C2F5E44FF8F, 960, 308 },
14272 { 0xD433179D9C8CB841, 986, 316 },
14273 { 0x9E19DB92B4E31BA9, 1013, 324 },
14281 assert(e >= -1500);
14283 const int f = kAlpha - e - 1;
14284 const int k = (f * 78913) / (1 << 18) +
static_cast<int>(f > 0);
14286 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
14287 assert(index >= 0);
14288 assert(
static_cast<std::size_t
>(index) < kCachedPowers.size());
14290 const cached_power cached = kCachedPowers[
static_cast<std::size_t
>(index)];
14291 assert(kAlpha <= cached.e + e + 64);
14292 assert(kGamma >= cached.e + e + 64);
14301 inline int find_largest_pow10(
const std::uint32_t n, std::uint32_t& pow10)
14304 if (n >= 1000000000)
14306 pow10 = 1000000000;
14310 else if (n >= 100000000)
14315 else if (n >= 10000000)
14320 else if (n >= 1000000)
14325 else if (n >= 100000)
14330 else if (n >= 10000)
14335 else if (n >= 1000)
14357 inline void grisu2_round(
char* buf,
int len, std::uint64_t dist, std::uint64_t delta,
14358 std::uint64_t rest, std::uint64_t ten_k)
14361 assert(dist <= delta);
14362 assert(rest <= delta);
14385 and delta - rest >= ten_k
14386 and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
14388 assert(buf[len - 1] !=
'0');
14398 inline void grisu2_digit_gen(
char* buffer,
int& length,
int& decimal_exponent,
14399 diyfp M_minus, diyfp w, diyfp M_plus)
14401 static_assert(kAlpha >= -60,
"internal error");
14402 static_assert(kGamma <= -32,
"internal error");
14416 assert(M_plus.e >= kAlpha);
14417 assert(M_plus.e <= kGamma);
14419 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f;
14420 std::uint64_t dist = diyfp::sub(M_plus, w ).f;
14429 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
14431 auto p1 =
static_cast<std::uint32_t
>(M_plus.f >> -one.e);
14432 std::uint64_t p2 = M_plus.f & (one.f - 1);
14440 std::uint32_t pow10;
14441 const int k = find_largest_pow10(p1, pow10);
14468 const std::uint32_t d = p1 / pow10;
14469 const std::uint32_t r = p1 % pow10;
14475 buffer[length++] =
static_cast<char>(
'0' + d);
14494 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
14499 decimal_exponent += n;
14510 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
14511 grisu2_round(buffer, length, dist, delta, rest, ten_n);
14561 assert(p2 > delta);
14572 assert(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
14574 const std::uint64_t d = p2 >> -one.e;
14575 const std::uint64_t r = p2 & (one.f - 1);
14582 buffer[length++] =
static_cast<char>(
'0' + d);
14607 decimal_exponent -= m;
14615 const std::uint64_t ten_m = one.f;
14616 grisu2_round(buffer, length, dist, delta, p2, ten_m);
14638 JSON_HEDLEY_NON_NULL(1)
14639 inline
void grisu2(
char* buf,
int& len,
int& decimal_exponent,
14640 diyfp m_minus, diyfp v, diyfp m_plus)
14642 assert(m_plus.e == m_minus.e);
14643 assert(m_plus.e == v.e);
14654 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
14656 const diyfp c_minus_k(cached.f, cached.e);
14659 const diyfp w = diyfp::mul(v, c_minus_k);
14660 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
14661 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
14684 const diyfp M_minus(w_minus.f + 1, w_minus.e);
14685 const diyfp M_plus (w_plus.f - 1, w_plus.e );
14687 decimal_exponent = -cached.k;
14689 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
14697 template <
typename FloatType>
14698 JSON_HEDLEY_NON_NULL(1)
14699 void grisu2(
char* buf,
int& len,
int& decimal_exponent, FloatType value)
14701 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
14702 "internal error: not enough precision");
14704 assert(std::isfinite(value));
14724 const boundaries w = compute_boundaries(
static_cast<double>(value));
14726 const boundaries w = compute_boundaries(value);
14729 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
14737 JSON_HEDLEY_NON_NULL(1)
14739 inline
char* append_exponent(
char* buf,
int e)
14754 auto k =
static_cast<std::uint32_t
>(e);
14760 *buf++ =
static_cast<char>(
'0' + k);
14764 *buf++ =
static_cast<char>(
'0' + k / 10);
14766 *buf++ =
static_cast<char>(
'0' + k);
14770 *buf++ =
static_cast<char>(
'0' + k / 100);
14772 *buf++ =
static_cast<char>(
'0' + k / 10);
14774 *buf++ =
static_cast<char>(
'0' + k);
14789 JSON_HEDLEY_NON_NULL(1)
14791 inline
char* format_buffer(
char* buf,
int len,
int decimal_exponent,
14792 int min_exp,
int max_exp)
14794 assert(min_exp < 0);
14795 assert(max_exp > 0);
14798 const int n = len + decimal_exponent;
14804 if (k <= n and n <= max_exp)
14809 std::memset(buf + k,
'0',
static_cast<size_t>(n) -
static_cast<size_t>(k));
14813 return buf + (
static_cast<size_t>(n) + 2);
14816 if (0 < n and n <= max_exp)
14823 std::memmove(buf + (
static_cast<size_t>(n) + 1), buf + n,
static_cast<size_t>(k) -
static_cast<size_t>(n));
14825 return buf + (
static_cast<size_t>(k) + 1U);
14828 if (min_exp < n and n <= 0)
14833 std::memmove(buf + (2 +
static_cast<size_t>(-n)), buf,
static_cast<size_t>(k));
14836 std::memset(buf + 2,
'0',
static_cast<size_t>(-n));
14837 return buf + (2U +
static_cast<size_t>(-n) +
static_cast<size_t>(k));
14852 std::memmove(buf + 2, buf + 1,
static_cast<size_t>(k) - 1);
14854 buf += 1 +
static_cast<size_t>(k);
14858 return append_exponent(buf, n - 1);
14873 template <
typename FloatType>
14874 JSON_HEDLEY_NON_NULL(1, 2)
14876 char* to_chars(
char* first, const
char* last, FloatType value)
14878 static_cast<void>(last);
14879 assert(std::isfinite(value));
14882 if (std::signbit(value))
14897 assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
14904 int decimal_exponent = 0;
14905 dtoa_impl::grisu2(first, len, decimal_exponent, value);
14907 assert(len <= std::numeric_limits<FloatType>::max_digits10);
14910 constexpr
int kMinExp = -4;
14912 constexpr
int kMaxExp = std::numeric_limits<FloatType>::digits10;
14914 assert(last - first >= kMaxExp + 2);
14915 assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
14916 assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
14918 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
14946 enum class error_handler_t
14953 template<
typename BasicJsonType>
14956 using string_t =
typename BasicJsonType::string_t;
14957 using number_float_t =
typename BasicJsonType::number_float_t;
14958 using number_integer_t =
typename BasicJsonType::number_integer_t;
14959 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
14960 using binary_char_t =
typename BasicJsonType::binary_t::value_type;
14961 static constexpr std::uint8_t UTF8_ACCEPT = 0;
14962 static constexpr std::uint8_t UTF8_REJECT = 1;
14970 serializer(output_adapter_t<char> s,
const char ichar,
14971 error_handler_t error_handler_ = error_handler_t::strict)
14973 , loc(std::localeconv())
14974 , thousands_sep(loc->thousands_sep == nullptr ?
'\0' : * (loc->thousands_sep))
14975 , decimal_point(loc->decimal_point == nullptr ?
'\0' : * (loc->decimal_point))
14976 , indent_char(ichar)
14977 , indent_string(512, indent_char)
14978 , error_handler(error_handler_)
14982 serializer(
const serializer&) =
delete;
14983 serializer& operator=(
const serializer&) =
delete;
14984 serializer(serializer&&) =
delete;
14985 serializer& operator=(serializer&&) =
delete;
14986 ~serializer() =
default;
15010 void dump(
const BasicJsonType& val,
15011 const bool pretty_print,
15012 const bool ensure_ascii,
15013 const unsigned int indent_step,
15014 const unsigned int current_indent = 0)
15016 switch (val.m_type)
15018 case value_t::object:
15020 if (val.m_value.object->empty())
15022 o->write_characters(
"{}", 2);
15028 o->write_characters(
"{\n", 2);
15031 const auto new_indent = current_indent + indent_step;
15032 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15034 indent_string.resize(indent_string.size() * 2,
' ');
15038 auto i = val.m_value.object->cbegin();
15039 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
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);
15046 o->write_characters(
",\n", 2);
15050 assert(i != val.m_value.object->cend());
15051 assert(std::next(i) == val.m_value.object->cend());
15052 o->write_characters(indent_string.c_str(), new_indent);
15053 o->write_character(
'\"');
15054 dump_escaped(i->first, ensure_ascii);
15055 o->write_characters(
"\": ", 3);
15056 dump(i->second,
true, ensure_ascii, indent_step, new_indent);
15058 o->write_character(
'\n');
15059 o->write_characters(indent_string.c_str(), current_indent);
15060 o->write_character(
'}');
15064 o->write_character(
'{');
15067 auto i = val.m_value.object->cbegin();
15068 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15070 o->write_character(
'\"');
15071 dump_escaped(i->first, ensure_ascii);
15072 o->write_characters(
"\":", 2);
15073 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
15074 o->write_character(
',');
15078 assert(i != val.m_value.object->cend());
15079 assert(std::next(i) == val.m_value.object->cend());
15080 o->write_character(
'\"');
15081 dump_escaped(i->first, ensure_ascii);
15082 o->write_characters(
"\":", 2);
15083 dump(i->second,
false, ensure_ascii, indent_step, current_indent);
15085 o->write_character(
'}');
15091 case value_t::array:
15093 if (val.m_value.array->empty())
15095 o->write_characters(
"[]", 2);
15101 o->write_characters(
"[\n", 2);
15104 const auto new_indent = current_indent + indent_step;
15105 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15107 indent_string.resize(indent_string.size() * 2,
' ');
15111 for (
auto i = val.m_value.array->cbegin();
15112 i != val.m_value.array->cend() - 1; ++i)
15114 o->write_characters(indent_string.c_str(), new_indent);
15115 dump(*i,
true, ensure_ascii, indent_step, new_indent);
15116 o->write_characters(
",\n", 2);
15120 assert(not val.m_value.array->empty());
15121 o->write_characters(indent_string.c_str(), new_indent);
15122 dump(val.m_value.array->back(),
true, ensure_ascii, indent_step, new_indent);
15124 o->write_character(
'\n');
15125 o->write_characters(indent_string.c_str(), current_indent);
15126 o->write_character(
']');
15130 o->write_character(
'[');
15133 for (
auto i = val.m_value.array->cbegin();
15134 i != val.m_value.array->cend() - 1; ++i)
15136 dump(*i,
false, ensure_ascii, indent_step, current_indent);
15137 o->write_character(
',');
15141 assert(not val.m_value.array->empty());
15142 dump(val.m_value.array->back(),
false, ensure_ascii, indent_step, current_indent);
15144 o->write_character(
']');
15150 case value_t::string:
15152 o->write_character(
'\"');
15153 dump_escaped(*val.m_value.string, ensure_ascii);
15154 o->write_character(
'\"');
15158 case value_t::binary:
15162 o->write_characters(
"{\n", 2);
15165 const auto new_indent = current_indent + indent_step;
15166 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15168 indent_string.resize(indent_string.size() * 2,
' ');
15171 o->write_characters(indent_string.c_str(), new_indent);
15173 o->write_characters(
"\"bytes\": [", 10);
15175 if (not val.m_value.binary->empty())
15177 for (
auto i = val.m_value.binary->cbegin();
15178 i != val.m_value.binary->cend() - 1; ++i)
15181 o->write_characters(
", ", 2);
15183 dump_integer(val.m_value.binary->back());
15186 o->write_characters(
"],\n", 3);
15187 o->write_characters(indent_string.c_str(), new_indent);
15189 o->write_characters(
"\"subtype\": ", 11);
15190 if (val.m_value.binary->has_subtype())
15192 dump_integer(val.m_value.binary->subtype());
15196 o->write_characters(
"null", 4);
15198 o->write_character(
'\n');
15199 o->write_characters(indent_string.c_str(), current_indent);
15200 o->write_character(
'}');
15204 o->write_characters(
"{\"bytes\":[", 10);
15206 if (not val.m_value.binary->empty())
15208 for (
auto i = val.m_value.binary->cbegin();
15209 i != val.m_value.binary->cend() - 1; ++i)
15212 o->write_character(
',');
15214 dump_integer(val.m_value.binary->back());
15217 o->write_characters(
"],\"subtype\":", 12);
15218 if (val.m_value.binary->has_subtype())
15220 dump_integer(val.m_value.binary->subtype());
15221 o->write_character(
'}');
15225 o->write_characters(
"null}", 5);
15231 case value_t::boolean:
15233 if (val.m_value.boolean)
15235 o->write_characters(
"true", 4);
15239 o->write_characters(
"false", 5);
15244 case value_t::number_integer:
15246 dump_integer(val.m_value.number_integer);
15250 case value_t::number_unsigned:
15252 dump_integer(val.m_value.number_unsigned);
15256 case value_t::number_float:
15258 dump_float(val.m_value.number_float);
15262 case value_t::discarded:
15264 o->write_characters(
"<discarded>", 11);
15268 case value_t::null:
15270 o->write_characters(
"null", 4);
15294 void dump_escaped(
const string_t& s,
const bool ensure_ascii)
15296 std::uint32_t codepoint;
15297 std::uint8_t state = UTF8_ACCEPT;
15298 std::size_t bytes = 0;
15301 std::size_t bytes_after_last_accept = 0;
15302 std::size_t undumped_chars = 0;
15304 for (std::size_t i = 0; i < s.size(); ++i)
15306 const auto byte =
static_cast<uint8_t
>(s[i]);
15308 switch (decode(state, codepoint,
byte))
15316 string_buffer[bytes++] =
'\\';
15317 string_buffer[bytes++] =
'b';
15323 string_buffer[bytes++] =
'\\';
15324 string_buffer[bytes++] =
't';
15330 string_buffer[bytes++] =
'\\';
15331 string_buffer[bytes++] =
'n';
15337 string_buffer[bytes++] =
'\\';
15338 string_buffer[bytes++] =
'f';
15344 string_buffer[bytes++] =
'\\';
15345 string_buffer[bytes++] =
'r';
15351 string_buffer[bytes++] =
'\\';
15352 string_buffer[bytes++] =
'\"';
15358 string_buffer[bytes++] =
'\\';
15359 string_buffer[bytes++] =
'\\';
15367 if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
15369 if (codepoint <= 0xFFFF)
15371 (std::snprintf)(string_buffer.data() + bytes, 7,
"\\u%04x",
15372 static_cast<std::uint16_t
>(codepoint));
15377 (std::snprintf)(string_buffer.data() + bytes, 13,
"\\u%04x\\u%04x",
15378 static_cast<std::uint16_t
>(0xD7C0u + (codepoint >> 10u)),
15379 static_cast<std::uint16_t
>(0xDC00u + (codepoint & 0x3FFu)));
15387 string_buffer[bytes++] = s[i];
15396 if (string_buffer.size() - bytes < 13)
15398 o->write_characters(string_buffer.data(), bytes);
15403 bytes_after_last_accept = bytes;
15404 undumped_chars = 0;
15410 switch (error_handler)
15412 case error_handler_t::strict:
15414 std::string sn(3,
'\0');
15415 (std::snprintf)(&sn[0], sn.size(),
"%.2X", byte);
15416 JSON_THROW(type_error::create(316,
"invalid UTF-8 byte at index " + std::to_string(i) +
": 0x" + sn));
15419 case error_handler_t::ignore:
15420 case error_handler_t::replace:
15426 if (undumped_chars > 0)
15433 bytes = bytes_after_last_accept;
15435 if (error_handler == error_handler_t::replace)
15440 string_buffer[bytes++] =
'\\';
15441 string_buffer[bytes++] =
'u';
15442 string_buffer[bytes++] =
'f';
15443 string_buffer[bytes++] =
'f';
15444 string_buffer[bytes++] =
'f';
15445 string_buffer[bytes++] =
'd';
15449 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type(
'\xEF');
15450 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type(
'\xBF');
15451 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type(
'\xBD');
15457 if (string_buffer.size() - bytes < 13)
15459 o->write_characters(string_buffer.data(), bytes);
15463 bytes_after_last_accept = bytes;
15466 undumped_chars = 0;
15469 state = UTF8_ACCEPT;
15481 if (not ensure_ascii)
15484 string_buffer[bytes++] = s[i];
15493 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
15498 o->write_characters(string_buffer.data(), bytes);
15504 switch (error_handler)
15506 case error_handler_t::strict:
15508 std::string sn(3,
'\0');
15509 (std::snprintf)(&sn[0], sn.size(),
"%.2X",
static_cast<std::uint8_t
>(s.back()));
15510 JSON_THROW(type_error::create(316,
"incomplete UTF-8 string; last byte: 0x" + sn));
15513 case error_handler_t::ignore:
15516 o->write_characters(string_buffer.data(), bytes_after_last_accept);
15520 case error_handler_t::replace:
15523 o->write_characters(string_buffer.data(), bytes_after_last_accept);
15527 o->write_characters(
"\\ufffd", 6);
15531 o->write_characters(
"\xEF\xBF\xBD", 3);
15550 inline unsigned int count_digits(number_unsigned_t x) noexcept
15552 unsigned int n_digits = 1;
15561 return n_digits + 1;
15565 return n_digits + 2;
15569 return n_digits + 3;
15585 template<
typename NumberType, detail::enable_if_t<
15586 std::is_same<NumberType, number_unsigned_t>::value or
15587 std::is_same<NumberType, number_integer_t>::value or
15588 std::is_same<NumberType, binary_char_t>::value,
15590 void dump_integer(NumberType x)
15592 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
15595 {{
'0',
'0'}}, {{
'0',
'1'}}, {{
'0',
'2'}}, {{
'0',
'3'}}, {{
'0',
'4'}}, {{
'0',
'5'}}, {{
'0',
'6'}}, {{
'0',
'7'}}, {{
'0',
'8'}}, {{
'0',
'9'}},
15596 {{
'1',
'0'}}, {{
'1',
'1'}}, {{
'1',
'2'}}, {{
'1',
'3'}}, {{
'1',
'4'}}, {{
'1',
'5'}}, {{
'1',
'6'}}, {{
'1',
'7'}}, {{
'1',
'8'}}, {{
'1',
'9'}},
15597 {{
'2',
'0'}}, {{
'2',
'1'}}, {{
'2',
'2'}}, {{
'2',
'3'}}, {{
'2',
'4'}}, {{
'2',
'5'}}, {{
'2',
'6'}}, {{
'2',
'7'}}, {{
'2',
'8'}}, {{
'2',
'9'}},
15598 {{
'3',
'0'}}, {{
'3',
'1'}}, {{
'3',
'2'}}, {{
'3',
'3'}}, {{
'3',
'4'}}, {{
'3',
'5'}}, {{
'3',
'6'}}, {{
'3',
'7'}}, {{
'3',
'8'}}, {{
'3',
'9'}},
15599 {{
'4',
'0'}}, {{
'4',
'1'}}, {{
'4',
'2'}}, {{
'4',
'3'}}, {{
'4',
'4'}}, {{
'4',
'5'}}, {{
'4',
'6'}}, {{
'4',
'7'}}, {{
'4',
'8'}}, {{
'4',
'9'}},
15600 {{
'5',
'0'}}, {{
'5',
'1'}}, {{
'5',
'2'}}, {{
'5',
'3'}}, {{
'5',
'4'}}, {{
'5',
'5'}}, {{
'5',
'6'}}, {{
'5',
'7'}}, {{
'5',
'8'}}, {{
'5',
'9'}},
15601 {{
'6',
'0'}}, {{
'6',
'1'}}, {{
'6',
'2'}}, {{
'6',
'3'}}, {{
'6',
'4'}}, {{
'6',
'5'}}, {{
'6',
'6'}}, {{
'6',
'7'}}, {{
'6',
'8'}}, {{
'6',
'9'}},
15602 {{
'7',
'0'}}, {{
'7',
'1'}}, {{
'7',
'2'}}, {{
'7',
'3'}}, {{
'7',
'4'}}, {{
'7',
'5'}}, {{
'7',
'6'}}, {{
'7',
'7'}}, {{
'7',
'8'}}, {{
'7',
'9'}},
15603 {{
'8',
'0'}}, {{
'8',
'1'}}, {{
'8',
'2'}}, {{
'8',
'3'}}, {{
'8',
'4'}}, {{
'8',
'5'}}, {{
'8',
'6'}}, {{
'8',
'7'}}, {{
'8',
'8'}}, {{
'8',
'9'}},
15604 {{
'9',
'0'}}, {{
'9',
'1'}}, {{
'9',
'2'}}, {{
'9',
'3'}}, {{
'9',
'4'}}, {{
'9',
'5'}}, {{
'9',
'6'}}, {{
'9',
'7'}}, {{
'9',
'8'}}, {{
'9',
'9'}},
15611 o->write_character(
'0');
15616 auto buffer_ptr = number_buffer.begin();
15618 const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not(x >= 0);
15619 number_unsigned_t abs_value;
15621 unsigned int n_chars;
15626 abs_value = remove_sign(
static_cast<number_integer_t
>(x));
15629 n_chars = 1 + count_digits(abs_value);
15633 abs_value =
static_cast<number_unsigned_t
>(x);
15634 n_chars = count_digits(abs_value);
15638 assert(n_chars < number_buffer.size() - 1);
15642 buffer_ptr += n_chars;
15646 while (abs_value >= 100)
15648 const auto digits_index =
static_cast<unsigned>((abs_value % 100));
15650 *(--buffer_ptr) = digits_to_99[digits_index][1];
15651 *(--buffer_ptr) = digits_to_99[digits_index][0];
15654 if (abs_value >= 10)
15656 const auto digits_index =
static_cast<unsigned>(abs_value);
15657 *(--buffer_ptr) = digits_to_99[digits_index][1];
15658 *(--buffer_ptr) = digits_to_99[digits_index][0];
15662 *(--buffer_ptr) =
static_cast<char>(
'0' + abs_value);
15665 o->write_characters(number_buffer.data(), n_chars);
15676 void dump_float(number_float_t x)
15679 if (not std::isfinite(x))
15681 o->write_characters(
"null", 4);
15690 static constexpr
bool is_ieee_single_or_double
15691 = (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
15692 (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);
15694 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
15697 void dump_float(number_float_t x, std::true_type )
15699 char* begin = number_buffer.data();
15700 char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
15702 o->write_characters(begin,
static_cast<size_t>(end - begin));
15705 void dump_float(number_float_t x, std::false_type )
15708 static constexpr
auto d = std::numeric_limits<number_float_t>::max_digits10;
15711 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(),
"%.*g", d, x);
15716 assert(
static_cast<std::size_t
>(len) < number_buffer.size());
15719 if (thousands_sep !=
'\0')
15721 const auto end = std::remove(number_buffer.begin(),
15722 number_buffer.begin() + len, thousands_sep);
15723 std::fill(end, number_buffer.end(),
'\0');
15724 assert((end - number_buffer.begin()) <= len);
15725 len = (end - number_buffer.begin());
15729 if (decimal_point !=
'\0' and decimal_point !=
'.')
15731 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
15732 if (dec_pos != number_buffer.end())
15738 o->write_characters(number_buffer.data(),
static_cast<std::size_t
>(len));
15741 const bool value_is_int_like =
15742 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
15745 return c ==
'.' or c ==
'e';
15748 if (value_is_int_like)
15750 o->write_characters(
".0", 2);
15775 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep,
const std::uint8_t
byte) noexcept
15777 static const std::array<std::uint8_t, 400> utf8d =
15780 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,
15781 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,
15782 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,
15783 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,
15784 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,
15785 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,
15786 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,
15787 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3,
15788 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
15789 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1,
15790 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,
15791 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,
15792 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,
15793 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
15797 const std::uint8_t type = utf8d[byte];
15799 codep = (state != UTF8_ACCEPT)
15800 ? (
byte & 0x3fu) | (codep << 6u)
15801 : (0xFFu >> type) & (byte);
15803 std::size_t index = 256u +
static_cast<size_t>(state) * 16u +
static_cast<size_t>(type);
15804 assert(index < 400);
15805 state = utf8d[index];
15814 number_unsigned_t remove_sign(number_unsigned_t x)
15829 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
15831 assert(x < 0 and x < (std::numeric_limits<number_integer_t>::max)());
15832 return static_cast<number_unsigned_t
>(-(x + 1)) + 1;
15837 output_adapter_t<char> o =
nullptr;
15840 std::array<char, 64> number_buffer{{}};
15843 const std::lconv* loc =
nullptr;
15845 const char thousands_sep =
'\0';
15847 const char decimal_point =
'\0';
15850 std::array<char, 512> string_buffer{{}};
15853 const char indent_char;
15855 string_t indent_string;
15858 const error_handler_t error_handler;
15960 NLOHMANN_BASIC_JSON_TPL_DECLARATION
15965 friend ::nlohmann::json_pointer<basic_json>;
15967 template<
typename BasicJsonType,
typename InputType>
15968 friend class ::nlohmann::detail::parser;
15969 friend ::nlohmann::detail::serializer<basic_json>;
15970 template<
typename BasicJsonType>
15971 friend class ::nlohmann::detail::iter_impl;
15972 template<
typename BasicJsonType,
typename CharType>
15973 friend class ::nlohmann::detail::binary_writer;
15974 template<
typename BasicJsonType,
typename InputType,
typename SAX>
15975 friend class ::nlohmann::detail::binary_reader;
15976 template<
typename BasicJsonType>
15977 friend class ::nlohmann::detail::json_sax_dom_parser;
15978 template<
typename BasicJsonType>
15979 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
15982 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
15985 using lexer = ::nlohmann::detail::lexer_base<basic_json>;
15987 template<
typename InputAdapterType>
15988 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
15989 InputAdapterType adapter,
15990 detail::parser_callback_t<basic_json>cb =
nullptr,
15991 bool allow_exceptions =
true
15994 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter), std::move(cb), allow_exceptions);
15997 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
15998 template<
typename BasicJsonType>
15999 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
16000 template<
typename BasicJsonType>
16001 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
16002 template<
typename Iterator>
16003 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
16004 template<
typename Base>
using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
16006 template<
typename CharType>
16007 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
16009 template<
typename InputType>
16010 using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
16011 template<
typename CharType>
using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
16013 using serializer = ::nlohmann::detail::serializer<basic_json>;
16016 using value_t = detail::value_t;
16019 template<
typename T,
typename SFINAE>
16022 using error_handler_t = detail::error_handler_t;
16026 using input_format_t = detail::input_format_t;
16080 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
16082 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
16135 result[
"copyright"] =
"(C) 2013-2017 Niels Lohmann";
16136 result[
"name"] =
"JSON for Modern C++";
16137 result[
"url"] =
"https://github.com/nlohmann/json";
16138 result[
"version"][
"string"] =
16139 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) +
"." +
16140 std::to_string(NLOHMANN_JSON_VERSION_MINOR) +
"." +
16141 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
16142 result[
"version"][
"major"] = NLOHMANN_JSON_VERSION_MAJOR;
16143 result[
"version"][
"minor"] = NLOHMANN_JSON_VERSION_MINOR;
16144 result[
"version"][
"patch"] = NLOHMANN_JSON_VERSION_PATCH;
16147 result[
"platform"] =
"win32";
16148 #elif defined __linux__
16149 result[
"platform"] =
"linux";
16150 #elif defined __APPLE__
16151 result[
"platform"] =
"apple";
16152 #elif defined __unix__
16153 result[
"platform"] =
"unix";
16155 result[
"platform"] =
"unknown";
16158 #if defined(__ICC) || defined(__INTEL_COMPILER)
16159 result[
"compiler"] = {{
"family",
"icc"}, {
"version", __INTEL_COMPILER}};
16160 #elif defined(__clang__)
16161 result[
"compiler"] = {{
"family",
"clang"}, {
"version", __clang_version__}};
16162 #elif defined(__GNUC__) || defined(__GNUG__)
16163 result[
"compiler"] = {{
"family",
"gcc"}, {
"version", std::to_string(__GNUC__) +
"." + std::to_string(__GNUC_MINOR__) +
"." + std::to_string(__GNUC_PATCHLEVEL__)}};
16164 #elif defined(__HP_cc) || defined(__HP_aCC)
16165 result[
"compiler"] =
"hp"
16166 #elif defined(__IBMCPP__)
16167 result[
"compiler"] = {{
"family",
"ilecpp"}, {
"version", __IBMCPP__}};
16168 #elif defined(_MSC_VER)
16169 result[
"compiler"] = {{
"family",
"msvc"}, {
"version", _MSC_VER}};
16170 #elif defined(__PGI)
16171 result[
"compiler"] = {{
"family",
"pgcpp"}, {
"version", __PGI}};
16172 #elif defined(__SUNPRO_CC)
16173 result[
"compiler"] = {{
"family",
"sunpro"}, {
"version", __SUNPRO_CC}};
16175 result[
"compiler"] = {{
"family",
"unknown"}, {
"version",
"unknown"}};
16179 result[
"compiler"][
"c++"] = std::to_string(__cplusplus);
16181 result[
"compiler"][
"c++"] =
"unknown";
16196 #if defined(JSON_HAS_CPP_14)
16290 AllocatorType<std::pair<
const StringType,
16337 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
16704 template<
typename T,
typename... Args>
16706 static T* create(Args&& ... args)
16708 AllocatorType<T> alloc;
16709 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
16711 auto deleter = [&](T *
object)
16713 AllocatorTraits::deallocate(alloc,
object, 1);
16715 std::unique_ptr<T, decltype(deleter)>
object(AllocatorTraits::allocate(alloc, 1), deleter);
16716 AllocatorTraits::construct(alloc,
object.
get(), std::forward<Args>(args)...);
16717 assert(
object !=
nullptr);
16718 return object.release();
16770 json_value() =
default;
16772 json_value(
boolean_t v) noexcept : boolean(v) {}
16784 case value_t::object:
16786 object = create<object_t>();
16790 case value_t::array:
16792 array = create<array_t>();
16796 case value_t::string:
16798 string = create<string_t>(
"");
16802 case value_t::binary:
16804 binary = create<binary_t>();
16808 case value_t::boolean:
16814 case value_t::number_integer:
16820 case value_t::number_unsigned:
16826 case value_t::number_float:
16832 case value_t::null:
16841 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
16843 JSON_THROW(other_error::create(500,
"961c151d2e87f2686a955a9be24d316f1362bf21 3.7.3"));
16853 string = create<string_t>(
value);
16859 string = create<string_t>(std::move(
value));
16865 object = create<object_t>(
value);
16871 object = create<object_t>(std::move(
value));
16910 void destroy(
value_t t) noexcept
16913 std::vector<basic_json> stack;
16916 if (t == value_t::array)
16921 else if (t == value_t::object)
16924 for (
auto&& it : *
object)
16926 stack.push_back(std::move(it.second));
16930 while (not stack.empty())
16933 basic_json current_item(std::move(stack.back()));
16938 if (current_item.is_array())
16940 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
16941 std::back_inserter(stack));
16943 current_item.m_value.array->clear();
16945 else if (current_item.is_object())
16947 for (
auto&& it : *current_item.m_value.object)
16949 stack.push_back(std::move(it.second));
16952 current_item.m_value.object->clear();
16961 case value_t::object:
16963 AllocatorType<object_t> alloc;
16964 std::allocator_traits<decltype(alloc)>::destroy(alloc,
object);
16965 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
object, 1);
16969 case value_t::array:
16971 AllocatorType<array_t> alloc;
16972 std::allocator_traits<decltype(alloc)>::destroy(alloc,
array);
16973 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
array, 1);
16977 case value_t::string:
16979 AllocatorType<string_t> alloc;
16980 std::allocator_traits<decltype(alloc)>::destroy(alloc,
string);
16981 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
string, 1);
16985 case value_t::binary:
16987 AllocatorType<binary_t> alloc;
16988 std::allocator_traits<decltype(alloc)>::destroy(alloc,
binary);
16989 std::allocator_traits<decltype(alloc)>::deallocate(alloc,
binary, 1);
17010 void assert_invariant() const noexcept
17012 assert(m_type != value_t::object or m_value.object !=
nullptr);
17013 assert(m_type != value_t::array or m_value.array !=
nullptr);
17014 assert(m_type != value_t::string or m_value.string !=
nullptr);
17015 assert(m_type != value_t::binary or m_value.binary !=
nullptr);
17038 using parse_event_t = detail::parse_event_t;
17131 : m_type(v), m_value(v)
17133 assert_invariant();
17157 assert_invariant();
17223 template <
typename CompatibleType,
17224 typename U = detail::uncvref_t<CompatibleType>,
17225 detail::enable_if_t<
17226 not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value,
int> = 0>
17228 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
17229 std::forward<CompatibleType>(val))))
17231 JSONSerializer<U>::to_json(*
this, std::forward<CompatibleType>(val));
17232 assert_invariant();
17261 template <
typename BasicJsonType,
17262 detail::enable_if_t<
17263 detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value,
int> = 0>
17266 using other_boolean_t =
typename BasicJsonType::boolean_t;
17267 using other_number_float_t =
typename BasicJsonType::number_float_t;
17268 using other_number_integer_t =
typename BasicJsonType::number_integer_t;
17269 using other_number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
17270 using other_string_t =
typename BasicJsonType::string_t;
17271 using other_object_t =
typename BasicJsonType::object_t;
17272 using other_array_t =
typename BasicJsonType::array_t;
17273 using other_binary_t =
typename BasicJsonType::binary_t;
17275 switch (val.type())
17277 case value_t::boolean:
17278 JSONSerializer<other_boolean_t>::to_json(*
this, val.template get<other_boolean_t>());
17280 case value_t::number_float:
17281 JSONSerializer<other_number_float_t>::to_json(*
this, val.template get<other_number_float_t>());
17283 case value_t::number_integer:
17284 JSONSerializer<other_number_integer_t>::to_json(*
this, val.template get<other_number_integer_t>());
17286 case value_t::number_unsigned:
17287 JSONSerializer<other_number_unsigned_t>::to_json(*
this, val.template get<other_number_unsigned_t>());
17289 case value_t::string:
17290 JSONSerializer<other_string_t>::to_json(*
this, val.template get_ref<const other_string_t&>());
17292 case value_t::object:
17293 JSONSerializer<other_object_t>::to_json(*
this, val.template get_ref<const other_object_t&>());
17295 case value_t::array:
17296 JSONSerializer<other_array_t>::to_json(*
this, val.template get_ref<const other_array_t&>());
17298 case value_t::binary:
17299 JSONSerializer<other_binary_t>::to_json(*
this, val.template get_ref<const other_binary_t&>());
17301 case value_t::null:
17304 case value_t::discarded:
17305 m_type = value_t::discarded;
17310 assert_invariant();
17388 bool type_deduction =
true,
17389 value_t manual_type = value_t::array)
17393 bool is_an_object = std::all_of(init.begin(), init.end(),
17394 [](
const detail::json_ref<basic_json>& element_ref)
17396 return element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string();
17400 if (not type_deduction)
17403 if (manual_type == value_t::array)
17405 is_an_object =
false;
17409 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object and not is_an_object))
17411 JSON_THROW(type_error::create(301,
"cannot create object from initializer list"));
17418 m_type = value_t::object;
17419 m_value = value_t::object;
17421 std::for_each(init.begin(), init.end(), [
this](
const detail::json_ref<basic_json>& element_ref)
17423 auto element = element_ref.moved_or_copied();
17424 m_value.object->emplace(
17425 std::move(*((*element.m_value.array)[0].m_value.string)),
17426 std::move((*element.m_value.array)[1]));
17432 m_type = value_t::array;
17433 m_value.array = create<array_t>(init.begin(), init.end());
17436 assert_invariant();
17470 res.m_type = value_t::binary;
17471 res.m_value = init;
17507 res.m_type = value_t::binary;
17508 res.m_value =
binary_t(init, subtype);
17517 res.m_type = value_t::binary;
17518 res.m_value = std::move(init);
17527 res.m_type = value_t::binary;
17528 res.m_value =
binary_t(std::move(init), subtype);
17572 return basic_json(init,
false, value_t::array);
17616 return basic_json(init,
false, value_t::object);
17642 : m_type(value_t::
array)
17644 m_value.array = create<array_t>(cnt, val);
17645 assert_invariant();
17703 template<
class InputIT,
typename std::enable_if<
17704 std::is_same<InputIT, typename basic_json_t::iterator>::value or
17705 std::is_same<InputIT, typename basic_json_t::const_iterator>::value,
int>
::type = 0>
17708 assert(first.m_object !=
nullptr);
17709 assert(last.m_object !=
nullptr);
17712 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
17714 JSON_THROW(invalid_iterator::create(201,
"iterators are not compatible"));
17718 m_type = first.m_object->m_type;
17723 case value_t::boolean:
17724 case value_t::number_float:
17725 case value_t::number_integer:
17726 case value_t::number_unsigned:
17727 case value_t::string:
17729 if (JSON_HEDLEY_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
17730 or not last.m_it.primitive_iterator.is_end()))
17732 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
17743 case value_t::number_integer:
17745 m_value.number_integer = first.m_object->m_value.number_integer;
17749 case value_t::number_unsigned:
17751 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
17755 case value_t::number_float:
17757 m_value.number_float = first.m_object->m_value.number_float;
17761 case value_t::boolean:
17763 m_value.boolean = first.m_object->m_value.boolean;
17767 case value_t::string:
17769 m_value = *first.m_object->m_value.string;
17773 case value_t::object:
17775 m_value.object = create<object_t>(first.m_it.object_iterator,
17776 last.m_it.object_iterator);
17780 case value_t::array:
17782 m_value.array = create<array_t>(first.m_it.array_iterator,
17783 last.m_it.array_iterator);
17787 case value_t::binary:
17789 m_value = *first.m_object->m_value.binary;
17794 JSON_THROW(invalid_iterator::create(206,
"cannot construct with iterators from " +
17795 std::string(first.m_object->type_name())));
17798 assert_invariant();
17806 template <
typename JsonRef,
17807 detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
17808 std::is_same<typename JsonRef::value_type, basic_json>>
::value,
int> = 0 >
17837 : m_type(other.m_type)
17840 other.assert_invariant();
17844 case value_t::object:
17846 m_value = *other.m_value.object;
17850 case value_t::array:
17852 m_value = *other.m_value.array;
17856 case value_t::string:
17858 m_value = *other.m_value.string;
17862 case value_t::boolean:
17864 m_value = other.m_value.boolean;
17868 case value_t::number_integer:
17870 m_value = other.m_value.number_integer;
17874 case value_t::number_unsigned:
17876 m_value = other.m_value.number_unsigned;
17880 case value_t::number_float:
17882 m_value = other.m_value.number_float;
17886 case value_t::binary:
17888 m_value = *other.m_value.binary;
17896 assert_invariant();
17926 : m_type(std::move(other.m_type)),
17927 m_value(std::move(other.m_value))
17930 other.assert_invariant();
17933 other.m_type = value_t::null;
17934 other.m_value = {};
17936 assert_invariant();
17963 std::is_nothrow_move_constructible<value_t>::value and
17964 std::is_nothrow_move_assignable<value_t>::value and
17965 std::is_nothrow_move_constructible<json_value>::value and
17966 std::is_nothrow_move_assignable<json_value>::value
17970 other.assert_invariant();
17973 swap(m_type, other.m_type);
17974 swap(m_value, other.m_value);
17976 assert_invariant();
17997 assert_invariant();
17998 m_value.destroy(m_type);
18059 const char indent_char =
' ',
18060 const bool ensure_ascii =
false,
18061 const error_handler_t error_handler = error_handler_t::strict)
const
18064 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
18068 s.dump(*
this,
true, ensure_ascii,
static_cast<unsigned int>(indent));
18072 s.dump(*
this,
false, ensure_ascii, 0);
18111 constexpr value_t
type() const noexcept
18193 return m_type == value_t::null;
18215 return m_type == value_t::boolean;
18274 return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
18302 return m_type == value_t::number_unsigned;
18330 return m_type == value_t::number_float;
18352 return m_type == value_t::object;
18374 return m_type == value_t::array;
18396 return m_type == value_t::string;
18418 return m_type == value_t::binary;
18445 return m_type == value_t::discarded;
18486 return m_value.boolean;
18489 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(
type_name())));
18495 return is_object() ? m_value.object :
nullptr;
18501 return is_object() ? m_value.object :
nullptr;
18507 return is_array() ? m_value.array :
nullptr;
18511 constexpr
const array_t* get_impl_ptr(
const array_t* )
const noexcept
18513 return is_array() ? m_value.array :
nullptr;
18519 return is_string() ? m_value.string :
nullptr;
18525 return is_string() ? m_value.string :
nullptr;
18531 return is_boolean() ? &m_value.boolean :
nullptr;
18537 return is_boolean() ? &m_value.boolean :
nullptr;
18579 return is_binary() ? m_value.binary :
nullptr;
18585 return is_binary() ? m_value.binary :
nullptr;
18599 template<
typename ReferenceType,
typename ThisType>
18600 static ReferenceType get_ref_impl(ThisType& obj)
18603 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
18605 if (JSON_HEDLEY_LIKELY(ptr !=
nullptr))
18610 JSON_THROW(type_error::create(303,
"incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
18632 template<
typename BasicJsonType, detail::enable_if_t<
18633 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>
::value,
18655 template<
typename BasicJsonType, detail::enable_if_t<
18656 not std::is_same<BasicJsonType, basic_json>::value and
18657 detail::is_basic_json<BasicJsonType>::value,
int> = 0>
18702 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
18703 detail::enable_if_t <
18704 not detail::is_basic_json<ValueType>::value and
18705 detail::has_from_json<basic_json_t, ValueType>::value and
18706 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
18708 ValueType
get() const noexcept(noexcept(
18709 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
18714 static_assert(not std::is_reference<ValueTypeCV>::value,
18715 "get() cannot be used with reference types, you might want to use get_ref()");
18716 static_assert(std::is_default_constructible<ValueType>::value,
18717 "types must be DefaultConstructible when used with get()");
18720 JSONSerializer<ValueType>::from_json(*
this, ret);
18755 template<
typename ValueTypeCV,
typename ValueType = detail::uncvref_t<ValueTypeCV>,
18756 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
18757 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
18759 ValueType
get() const noexcept(noexcept(
18760 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
18762 static_assert(not std::is_reference<ValueTypeCV>::value,
18763 "get() cannot be used with reference types, you might want to use get_ref()");
18764 return JSONSerializer<ValueType>::from_json(*
this);
18800 template<
typename ValueType,
18801 detail::enable_if_t <
18802 not detail::is_basic_json<ValueType>::value and
18803 detail::has_from_json<basic_json_t, ValueType>::value,
18805 ValueType &
get_to(ValueType& v)
const noexcept(noexcept(
18806 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
18808 JSONSerializer<ValueType>::from_json(*
this, v);
18813 typename T, std::size_t N,
18814 typename Array = T (&)[N],
18815 detail::enable_if_t <
18816 detail::has_from_json<basic_json_t, Array>::value,
int > = 0 >
18818 noexcept(noexcept(JSONSerializer<Array>::from_json(
18819 std::declval<const basic_json_t&>(), v)))
18821 JSONSerializer<Array>::from_json(*
this, v);
18852 template<
typename PointerType,
typename std::enable_if<
18853 std::is_pointer<PointerType>::value,
int>
::type = 0>
18854 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
18857 return get_impl_ptr(
static_cast<PointerType
>(
nullptr));
18864 template<
typename PointerType,
typename std::enable_if<
18865 std::is_pointer<PointerType>::value and
18866 std::is_const<typename std::remove_pointer<PointerType>::type>
::value,
int>
::type = 0>
18867 constexpr
auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
18870 return get_impl_ptr(
static_cast<PointerType
>(
nullptr));
18900 template<
typename PointerType,
typename std::enable_if<
18901 std::is_pointer<PointerType>::value,
int>
::type = 0>
18902 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template
get_ptr<PointerType>())
18905 return get_ptr<PointerType>();
18912 template<
typename PointerType,
typename std::enable_if<
18913 std::is_pointer<PointerType>::value,
int>
::type = 0>
18914 constexpr
auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template
get_ptr<PointerType>())
18917 return get_ptr<PointerType>();
18946 template<
typename ReferenceType,
typename std::enable_if<
18947 std::is_reference<ReferenceType>::value,
int>
::type = 0>
18951 return get_ref_impl<ReferenceType>(*
this);
18958 template<
typename ReferenceType,
typename std::enable_if<
18959 std::is_reference<ReferenceType>::value and
18960 std::is_const<typename std::remove_reference<ReferenceType>::type>
::value,
int>
::type = 0>
18964 return get_ref_impl<ReferenceType>(*
this);
18996 template <
typename ValueType,
typename std::enable_if <
18997 not std::is_pointer<ValueType>::value and
18998 not std::is_same<ValueType, detail::json_ref<basic_json>>
::value and
18999 not std::is_same<ValueType, typename string_t::value_type>::value and
19000 not detail::is_basic_json<ValueType>::value
19001 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>
::value
19002 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) and _MSC_VER <= 1914))
19003 and not std::is_same<ValueType, typename std::string_view>::value
19005 and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
19007 operator ValueType()
const
19010 return get<ValueType>();
19026 JSON_THROW(type_error::create(302,
"type must be binary, but is " + std::string(
type_name())));
19029 return *get_ptr<binary_t*>();
19037 JSON_THROW(type_error::create(302,
"type must be binary, but is " + std::string(
type_name())));
19040 return *get_ptr<const binary_t*>();
19083 if (JSON_HEDLEY_LIKELY(
is_array()))
19087 return m_value.array->at(idx);
19089 JSON_CATCH (std::out_of_range&)
19092 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
19097 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(
type_name())));
19130 if (JSON_HEDLEY_LIKELY(
is_array()))
19134 return m_value.array->at(idx);
19136 JSON_CATCH (std::out_of_range&)
19139 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
19144 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(
type_name())));
19178 reference at(
const typename object_t::key_type& key)
19185 return m_value.object->at(key);
19187 JSON_CATCH (std::out_of_range&)
19190 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
19195 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(
type_name())));
19236 return m_value.object->at(key);
19238 JSON_CATCH (std::out_of_range&)
19241 JSON_THROW(out_of_range::create(403,
"key '" + key +
"' not found"));
19246 JSON_THROW(type_error::create(304,
"cannot use at() with " + std::string(
type_name())));
19280 m_type = value_t::array;
19281 m_value.array = create<array_t>();
19282 assert_invariant();
19286 if (JSON_HEDLEY_LIKELY(
is_array()))
19289 if (idx >= m_value.array->size())
19291 m_value.array->insert(m_value.array->end(),
19292 idx - m_value.array->size() + 1,
19296 return m_value.array->operator[](idx);
19299 JSON_THROW(type_error::create(305,
"cannot use operator[] with a numeric argument with " + std::string(
type_name())));
19324 if (JSON_HEDLEY_LIKELY(
is_array()))
19326 return m_value.array->operator[](idx);
19329 JSON_THROW(type_error::create(305,
"cannot use operator[] with a numeric argument with " + std::string(
type_name())));
19364 m_type = value_t::object;
19365 m_value.object = create<object_t>();
19366 assert_invariant();
19372 return m_value.object->operator[](key);
19375 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(
type_name())));
19413 assert(m_value.object->find(key) != m_value.object->end());
19414 return m_value.object->find(key)->second;
19417 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(
type_name())));
19447 template<
typename T>
19448 JSON_HEDLEY_NON_NULL(2)
19454 m_type = value_t::object;
19455 m_value = value_t::object;
19456 assert_invariant();
19462 return m_value.object->operator[](key);
19465 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(
type_name())));
19498 template<
typename T>
19499 JSON_HEDLEY_NON_NULL(2)
19505 assert(m_value.object->find(key) != m_value.object->end());
19506 return m_value.object->find(key)->second;
19509 JSON_THROW(type_error::create(305,
"cannot use operator[] with a string argument with " + std::string(
type_name())));
19562 template<
class ValueType,
typename std::enable_if<
19563 std::is_convertible<basic_json_t, ValueType>::value,
int>
::type = 0>
19564 ValueType
value(
const typename object_t::key_type& key,
const ValueType& default_value)
const
19570 const auto it =
find(key);
19576 return default_value;
19579 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(
type_name())));
19586 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const
19634 template<
class ValueType,
typename std::enable_if<
19635 std::is_convertible<basic_json_t, ValueType>::value,
int>
::type = 0>
19644 return ptr.get_checked(
this);
19648 return default_value;
19652 JSON_THROW(type_error::create(306,
"cannot use value() with " + std::string(
type_name())));
19659 JSON_HEDLEY_NON_NULL(3)
19797 template<
class IteratorType,
typename std::enable_if<
19798 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
19799 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>
::type
19801 IteratorType
erase(IteratorType pos)
19804 if (JSON_HEDLEY_UNLIKELY(
this != pos.m_object))
19806 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
19809 IteratorType result =
end();
19813 case value_t::boolean:
19814 case value_t::number_float:
19815 case value_t::number_integer:
19816 case value_t::number_unsigned:
19817 case value_t::string:
19818 case value_t::binary:
19820 if (JSON_HEDLEY_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
19822 JSON_THROW(invalid_iterator::create(205,
"iterator out of range"));
19827 AllocatorType<string_t> alloc;
19828 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
19829 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
19830 m_value.string =
nullptr;
19834 AllocatorType<binary_t> alloc;
19835 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
19836 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
19837 m_value.binary =
nullptr;
19840 m_type = value_t::null;
19841 assert_invariant();
19845 case value_t::object:
19847 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
19851 case value_t::array:
19853 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
19858 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(
type_name())));
19910 template<
class IteratorType,
typename std::enable_if<
19911 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
19912 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>
::type
19914 IteratorType
erase(IteratorType first, IteratorType last)
19917 if (JSON_HEDLEY_UNLIKELY(
this != first.m_object or
this != last.m_object))
19919 JSON_THROW(invalid_iterator::create(203,
"iterators do not fit current value"));
19922 IteratorType result =
end();
19926 case value_t::boolean:
19927 case value_t::number_float:
19928 case value_t::number_integer:
19929 case value_t::number_unsigned:
19930 case value_t::string:
19931 case value_t::binary:
19933 if (JSON_HEDLEY_LIKELY(not first.m_it.primitive_iterator.is_begin()
19934 or not last.m_it.primitive_iterator.is_end()))
19936 JSON_THROW(invalid_iterator::create(204,
"iterators out of range"));
19941 AllocatorType<string_t> alloc;
19942 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
19943 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
19944 m_value.string =
nullptr;
19948 AllocatorType<binary_t> alloc;
19949 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
19950 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
19951 m_value.binary =
nullptr;
19954 m_type = value_t::null;
19955 assert_invariant();
19959 case value_t::object:
19961 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
19962 last.m_it.object_iterator);
19966 case value_t::array:
19968 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
19969 last.m_it.array_iterator);
19974 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(
type_name())));
20014 return m_value.object->erase(key);
20017 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(
type_name())));
20047 if (JSON_HEDLEY_LIKELY(
is_array()))
20049 if (JSON_HEDLEY_UNLIKELY(idx >=
size()))
20051 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
20058 JSON_THROW(type_error::create(307,
"cannot use erase() with " + std::string(
type_name())));
20096 template<
typename KeyT>
20099 auto result =
end();
20103 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20113 template<
typename KeyT>
20116 auto result =
cend();
20120 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20147 template<
typename KeyT>
20151 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
20179 template<
typename KeyT,
typename std::enable_if<
20183 return is_object() and m_value.
object->
find(std::forward<KeyT>(key)) != m_value.
object->
end();
20214 return ptr.contains(
this);
20254 result.set_begin();
20294 result.set_begin();
20558 JSON_HEDLEY_DEPRECATED(3.1.0)
20561 return ref.items();
20567 JSON_HEDLEY_DEPRECATED(3.1.0)
20570 return ref.items();
20641 iteration_proxy<iterator>
items() noexcept
20643 return iteration_proxy<iterator>(*
this);
20649 iteration_proxy<const_iterator>
items() const noexcept
20651 return iteration_proxy<const_iterator>(*
this);
20706 bool empty() const noexcept
20710 case value_t::null:
20716 case value_t::array:
20719 return m_value.array->empty();
20722 case value_t::object:
20725 return m_value.object->empty();
20783 case value_t::null:
20789 case value_t::array:
20792 return m_value.array->size();
20795 case value_t::object:
20798 return m_value.object->size();
20854 case value_t::array:
20857 return m_value.array->max_size();
20860 case value_t::object:
20863 return m_value.object->max_size();
20921 void clear() noexcept
20925 case value_t::number_integer:
20927 m_value.number_integer = 0;
20931 case value_t::number_unsigned:
20933 m_value.number_unsigned = 0;
20937 case value_t::number_float:
20939 m_value.number_float = 0.0;
20943 case value_t::boolean:
20945 m_value.boolean =
false;
20949 case value_t::string:
20951 m_value.string->clear();
20955 case value_t::binary:
20957 m_value.binary->clear();
20961 case value_t::array:
20963 m_value.array->clear();
20967 case value_t::object:
20969 m_value.object->clear();
21003 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(
type_name())));
21009 m_type = value_t::array;
21010 m_value = value_t::array;
21011 assert_invariant();
21015 m_value.array->push_back(std::move(val));
21038 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(
type_name())));
21044 m_type = value_t::array;
21045 m_value = value_t::array;
21046 assert_invariant();
21050 m_value.array->push_back(val);
21083 void push_back(
const typename object_t::value_type& val)
21088 JSON_THROW(type_error::create(308,
"cannot use push_back() with " + std::string(
type_name())));
21094 m_type = value_t::object;
21095 m_value = value_t::object;
21096 assert_invariant();
21100 m_value.object->insert(val);
21140 if (
is_object() and init.size() == 2 and (*init.begin())->is_string())
21142 basic_json&& key = init.begin()->moved_or_copied();
21143 push_back(
typename object_t::value_type(
21144 std::move(key.get_ref<
string_t&>()), (init.begin() + 1)->moved_or_copied()));
21185 template<
class... Args>
21191 JSON_THROW(type_error::create(311,
"cannot use emplace_back() with " + std::string(
type_name())));
21197 m_type = value_t::array;
21198 m_value = value_t::array;
21199 assert_invariant();
21203 #ifdef JSON_HAS_CPP_17
21204 return m_value.array->emplace_back(std::forward<Args>(args)...);
21206 m_value.array->emplace_back(std::forward<Args>(args)...);
21207 return m_value.array->back();
21238 template<
class... Args>
21239 std::pair<iterator, bool>
emplace(Args&& ... args)
21244 JSON_THROW(type_error::create(311,
"cannot use emplace() with " + std::string(
type_name())));
21250 m_type = value_t::object;
21251 m_value = value_t::object;
21252 assert_invariant();
21256 auto res = m_value.object->emplace(std::forward<Args>(args)...);
21259 it.m_it.object_iterator = res.first;
21262 return {it, res.second};
21268 template<
typename... Args>
21272 assert(m_value.array !=
nullptr);
21274 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
21275 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
21276 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
21310 if (JSON_HEDLEY_LIKELY(
is_array()))
21313 if (JSON_HEDLEY_UNLIKELY(pos.m_object !=
this))
21315 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
21322 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(
type_name())));
21331 return insert(pos, val);
21361 if (JSON_HEDLEY_LIKELY(
is_array()))
21364 if (JSON_HEDLEY_UNLIKELY(pos.m_object !=
this))
21366 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
21373 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(
type_name())));
21409 if (JSON_HEDLEY_UNLIKELY(not
is_array()))
21411 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(
type_name())));
21415 if (JSON_HEDLEY_UNLIKELY(pos.m_object !=
this))
21417 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
21421 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21423 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
21426 if (JSON_HEDLEY_UNLIKELY(first.m_object ==
this))
21428 JSON_THROW(invalid_iterator::create(211,
"passed iterators may not belong to container"));
21432 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
21462 if (JSON_HEDLEY_UNLIKELY(not
is_array()))
21464 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(
type_name())));
21468 if (JSON_HEDLEY_UNLIKELY(pos.m_object !=
this))
21470 JSON_THROW(invalid_iterator::create(202,
"iterator does not fit current value"));
21503 if (JSON_HEDLEY_UNLIKELY(not
is_object()))
21505 JSON_THROW(type_error::create(309,
"cannot use insert() with " + std::string(
type_name())));
21509 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21511 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
21515 if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object()))
21517 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
21520 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
21547 m_type = value_t::object;
21548 m_value.object = create<object_t>();
21549 assert_invariant();
21554 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(
type_name())));
21556 if (JSON_HEDLEY_UNLIKELY(not j.is_object()))
21558 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(j.type_name())));
21561 for (
auto it = j.cbegin(); it != j.cend(); ++it)
21563 m_value.object->operator[](it.key()) = it.value();
21598 m_type = value_t::object;
21599 m_value.object = create<object_t>();
21600 assert_invariant();
21605 JSON_THROW(type_error::create(312,
"cannot use update() with " + std::string(
type_name())));
21609 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21611 JSON_THROW(invalid_iterator::create(210,
"iterators do not fit"));
21615 if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object()
21616 or not last.m_object->is_object()))
21618 JSON_THROW(invalid_iterator::create(202,
"iterators first and last must point to objects"));
21621 for (
auto it = first; it != last; ++it)
21623 m_value.object->operator[](it.key()) = it.value();
21645 std::is_nothrow_move_constructible<value_t>::value and
21646 std::is_nothrow_move_assignable<value_t>::value and
21647 std::is_nothrow_move_constructible<json_value>::value and
21648 std::is_nothrow_move_assignable<json_value>::value
21651 std::swap(m_type, other.m_type);
21652 std::swap(m_value, other.m_value);
21653 assert_invariant();
21679 if (JSON_HEDLEY_LIKELY(
is_array()))
21681 std::swap(*(m_value.array), other);
21685 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(
type_name())));
21714 std::swap(*(m_value.object), other);
21718 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(
type_name())));
21747 std::swap(*(m_value.string), other);
21751 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(
type_name())));
21780 std::swap(*(m_value.binary), other);
21784 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(
type_name())));
21794 std::swap(*(m_value.binary), other);
21798 JSON_THROW(type_error::create(310,
"cannot use swap() with " + std::string(
type_name())));
21869 const auto lhs_type = lhs.type();
21870 const auto rhs_type = rhs.type();
21872 if (lhs_type == rhs_type)
21876 case value_t::array:
21877 return *lhs.m_value.array == *rhs.m_value.array;
21879 case value_t::object:
21880 return *lhs.m_value.object == *rhs.m_value.object;
21882 case value_t::null:
21885 case value_t::string:
21886 return *lhs.m_value.string == *rhs.m_value.string;
21888 case value_t::boolean:
21889 return lhs.m_value.boolean == rhs.m_value.boolean;
21891 case value_t::number_integer:
21892 return lhs.m_value.number_integer == rhs.m_value.number_integer;
21894 case value_t::number_unsigned:
21895 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
21897 case value_t::number_float:
21898 return lhs.m_value.number_float == rhs.m_value.number_float;
21900 case value_t::binary:
21901 return *lhs.m_value.binary == *rhs.m_value.binary;
21907 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
21909 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
21911 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
21913 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer);
21915 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
21917 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
21919 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
21921 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned);
21923 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
21925 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
21927 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
21929 return lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
21939 template<
typename ScalarType,
typename std::enable_if<
21940 std::is_scalar<ScalarType>::value,
int>
::type = 0>
21950 template<
typename ScalarType,
typename std::enable_if<
21951 std::is_scalar<ScalarType>::value,
int>
::type = 0>
21977 return not (lhs == rhs);
21984 template<
typename ScalarType,
typename std::enable_if<
21985 std::is_scalar<ScalarType>::value,
int>
::type = 0>
21995 template<
typename ScalarType,
typename std::enable_if<
21996 std::is_scalar<ScalarType>::value,
int>
::type = 0>
22030 const auto lhs_type = lhs.type();
22031 const auto rhs_type = rhs.type();
22033 if (lhs_type == rhs_type)
22037 case value_t::array:
22040 return (*lhs.m_value.array) < (*rhs.m_value.array);
22042 case value_t::object:
22043 return (*lhs.m_value.object) < (*rhs.m_value.object);
22045 case value_t::null:
22048 case value_t::string:
22049 return (*lhs.m_value.string) < (*rhs.m_value.string);
22051 case value_t::boolean:
22052 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
22054 case value_t::number_integer:
22055 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
22057 case value_t::number_unsigned:
22058 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
22060 case value_t::number_float:
22061 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
22063 case value_t::binary:
22064 return (*lhs.m_value.binary) < (*rhs.m_value.binary);
22070 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
22072 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
22074 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
22076 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
22078 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
22080 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
22082 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
22084 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
22086 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
22088 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22090 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
22092 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
22105 template<
typename ScalarType,
typename std::enable_if<
22106 std::is_scalar<ScalarType>::value,
int>
::type = 0>
22116 template<
typename ScalarType,
typename std::enable_if<
22117 std::is_scalar<ScalarType>::value,
int>
::type = 0>
22144 return not (rhs < lhs);
22151 template<
typename ScalarType,
typename std::enable_if<
22152 std::is_scalar<ScalarType>::value,
int>
::type = 0>
22162 template<
typename ScalarType,
typename std::enable_if<
22163 std::is_scalar<ScalarType>::value,
int>
::type = 0>
22190 return not (lhs <= rhs);
22197 template<
typename ScalarType,
typename std::enable_if<
22198 std::is_scalar<ScalarType>::value,
int>
::type = 0>
22208 template<
typename ScalarType,
typename std::enable_if<
22209 std::is_scalar<ScalarType>::value,
int>
::type = 0>
22236 return not (lhs < rhs);
22243 template<
typename ScalarType,
typename std::enable_if<
22244 std::is_scalar<ScalarType>::value,
int>
::type = 0>
22254 template<
typename ScalarType,
typename std::enable_if<
22255 std::is_scalar<ScalarType>::value,
int>
::type = 0>
22304 const bool pretty_print = o.width() > 0;
22305 const auto indentation = pretty_print ? o.width() : 0;
22311 serializer s(detail::output_adapter<char>(o), o.fill());
22312 s.dump(j, pretty_print,
false,
static_cast<unsigned int>(indentation));
22324 JSON_HEDLEY_DEPRECATED(3.0.0)
22325 friend std::ostream& operator>>(const
basic_json& j, std::ostream& o)
22403 template<
typename InputType>
22407 const bool allow_exceptions =
true)
22410 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions).parse(
true, result);
22419 const bool allow_exceptions =
true)
22422 parser(i.get(), cb, allow_exceptions).parse(
true, result);
22426 template<
typename InputType>
22429 return parser(detail::input_adapter(std::forward<InputType>(i))).accept(
true);
22432 static bool accept(detail::span_input_adapter&& i)
22434 return parser(i.get()).accept(
true);
22489 template <
typename SAX,
typename InputType>
22490 JSON_HEDLEY_NON_NULL(2)
22491 static
bool sax_parse(InputType&& i, SAX* sax,
22493 const
bool strict = true)
22495 auto ia = detail::input_adapter(std::forward<InputType>(i));
22496 return format == input_format_t::json
22497 ? parser(std::move(ia)).sax_parse(sax, strict)
22498 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
22501 template <
typename SAX>
22502 JSON_HEDLEY_NON_NULL(2)
22503 static
bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
22504 input_format_t format = input_format_t::
json,
22505 const
bool strict = true)
22508 return format == input_format_t::json
22509 ? parser(std::move(ia)).sax_parse(sax, strict)
22510 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
22563 template<
class IteratorType,
typename std::enable_if<
22565 std::random_access_iterator_tag,
22566 typename std::iterator_traits<IteratorType>::iterator_category>
::value,
int>
::type = 0>
22569 const bool allow_exceptions =
true)
22572 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(
true, result);
22576 template<
class IteratorType,
typename std::enable_if<
22578 std::random_access_iterator_tag,
22579 typename std::iterator_traits<IteratorType>::iterator_category>
::value,
int>
::type = 0>
22580 static bool accept(IteratorType first, IteratorType last)
22582 return parser(detail::input_adapter(first, last)).accept(
true);
22585 template<
class IteratorType,
class SAX,
typename std::enable_if<
22587 std::random_access_iterator_tag,
22588 typename std::iterator_traits<IteratorType>::iterator_category>
::value,
int>
::type = 0>
22589 JSON_HEDLEY_NON_NULL(3)
22590 static
bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
22592 return parser(detail::input_adapter(first, last)).sax_parse(sax);
22603 JSON_HEDLEY_DEPRECATED(3.0.0)
22604 friend std::istream& operator<<(
basic_json& j, std::istream& i)
22636 parser(detail::input_adapter(i)).parse(
false, j);
22683 case value_t::null:
22685 case value_t::object:
22687 case value_t::array:
22689 case value_t::string:
22691 case value_t::boolean:
22693 case value_t::binary:
22695 case value_t::discarded:
22696 return "discarded";
22710 value_t m_type = value_t::null;
22713 json_value m_value = {};
22820 std::vector<uint8_t> result;
22827 binary_writer<uint8_t>(o).write_cbor(j);
22832 binary_writer<char>(o).write_cbor(j);
22917 std::vector<uint8_t> result;
22924 binary_writer<uint8_t>(o).write_msgpack(j);
22929 binary_writer<char>(o).write_msgpack(j);
23019 const bool use_size =
false,
23020 const bool use_type =
false)
23022 std::vector<uint8_t> result;
23023 to_ubjson(j, result, use_size, use_type);
23028 const bool use_size =
false,
const bool use_type =
false)
23030 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
23034 const bool use_size =
false,
const bool use_type =
false)
23036 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23098 std::vector<uint8_t> result;
23113 binary_writer<uint8_t>(o).write_bson(j);
23121 binary_writer<char>(o).write_bson(j);
23227 template<
typename InputType>
23230 const bool strict =
true,
23231 const bool allow_exceptions =
true)
23234 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23235 auto ia = detail::input_adapter(std::forward<InputType>(i));
23236 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict);
23237 return res ? result :
basic_json(value_t::discarded);
23243 template<
typename A1,
typename A2,
23244 detail::enable_if_t<std::is_constructible<detail::span_input_adapter, A1, A2>::value,
int> = 0>
23247 const bool strict =
true,
23248 const bool allow_exceptions =
true)
23251 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23252 const bool res = binary_reader<detail::input_buffer_adapter>(detail::span_input_adapter(std::forward<A1>(a1), std::forward<A2>(a2)).
get()).sax_parse(input_format_t::cbor, &sdp, strict);
23253 return res ? result :
basic_json(value_t::discarded);
23258 const bool strict =
true,
23259 const bool allow_exceptions =
true)
23262 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23263 const bool res = binary_reader<detail::input_buffer_adapter>(i.get()).sax_parse(input_format_t::cbor, &sdp, strict);
23264 return res ? result :
basic_json(value_t::discarded);
23353 template<
typename InputType>
23356 const bool strict =
true,
23357 const bool allow_exceptions =
true)
23360 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23361 auto ia = detail::input_adapter(std::forward<InputType>(i));
23362 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
23363 return res ? result :
basic_json(value_t::discarded);
23369 template<
typename A1,
typename A2,
23370 detail::enable_if_t<std::is_constructible<detail::span_input_adapter, A1, A2>::value,
int> = 0>
23373 const bool strict =
true,
23374 const bool allow_exceptions =
true)
23377 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23378 const bool res = binary_reader<detail::input_buffer_adapter>(detail::span_input_adapter(std::forward<A1>(a1), std::forward<A2>(a2)).
get()).sax_parse(input_format_t::msgpack, &sdp, strict);
23379 return res ? result :
basic_json(value_t::discarded);
23385 const bool strict =
true,
23386 const bool allow_exceptions =
true)
23389 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23390 const bool res = binary_reader<detail::input_buffer_adapter>(i.get()).sax_parse(input_format_t::msgpack, &sdp, strict);
23391 return res ? result :
basic_json(value_t::discarded);
23456 template<
typename InputType>
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::forward<InputType>(i));
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);
23472 template<
typename A1,
typename A2,
23473 detail::enable_if_t<std::is_constructible<detail::span_input_adapter, A1, A2>::value,
int> = 0>
23476 const bool strict =
true,
23477 const bool allow_exceptions =
true)
23480 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23481 const bool res = binary_reader<detail::input_buffer_adapter>(detail::span_input_adapter(std::forward<A1>(a1), std::forward<A2>(a2)).
get()).sax_parse(input_format_t::ubjson, &sdp, strict);
23482 return res ? result :
basic_json(value_t::discarded);
23487 const bool strict =
true,
23488 const bool allow_exceptions =
true)
23491 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23492 const bool res = binary_reader<detail::input_buffer_adapter>(i.get()).sax_parse(input_format_t::ubjson, &sdp, strict);
23493 return res ? result :
basic_json(value_t::discarded);
23557 template<
typename InputType>
23560 const bool strict =
true,
23561 const bool allow_exceptions =
true)
23564 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23565 auto ia = detail::input_adapter(std::forward<InputType>(i));
23566 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
23567 return res ? result :
basic_json(value_t::discarded);
23573 template<
typename A1,
typename A2,
23574 detail::enable_if_t<std::is_constructible<detail::span_input_adapter, A1, A2>::value,
int> = 0>
23577 const bool strict =
true,
23578 const bool allow_exceptions =
true)
23581 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23582 const bool res = binary_reader<detail::input_buffer_adapter>(detail::span_input_adapter(std::forward<A1>(a1), std::forward<A2>(a2)).
get()).sax_parse(input_format_t::bson, &sdp, strict);
23583 return res ? result :
basic_json(value_t::discarded);
23588 const bool strict =
true,
23589 const bool allow_exceptions =
true)
23592 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23593 const bool res = binary_reader<detail::input_buffer_adapter>(i.get()).sax_parse(input_format_t::bson, &sdp, strict);
23594 return res ? result :
basic_json(value_t::discarded);
23640 return ptr.get_unchecked(
this);
23668 return ptr.get_unchecked(
this);
23711 return ptr.get_checked(
this);
23754 return ptr.get_checked(
this);
23782 json_pointer::flatten(
"", *
this, result);
23818 return json_pointer::unflatten(*
this);
23883 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
23885 const auto get_op = [](
const std::string & op)
23889 return patch_operations::add;
23891 if (op ==
"remove")
23893 return patch_operations::remove;
23895 if (op ==
"replace")
23897 return patch_operations::replace;
23901 return patch_operations::move;
23905 return patch_operations::copy;
23909 return patch_operations::test;
23912 return patch_operations::invalid;
23927 if (top_pointer != ptr)
23929 result.
at(top_pointer);
23933 const auto last_path = ptr.
back();
23937 switch (parent.m_type)
23939 case value_t::null:
23940 case value_t::object:
23943 parent[last_path] = val;
23947 case value_t::array:
23949 if (last_path ==
"-")
23956 const auto idx = json_pointer::array_index(last_path);
23957 if (JSON_HEDLEY_UNLIKELY(
static_cast<size_type>(idx) > parent.size()))
23960 JSON_THROW(out_of_range::create(401,
"array index " + std::to_string(idx) +
" is out of range"));
23964 parent.insert(parent.begin() +
static_cast<difference_type>(idx), val);
23976 const auto operation_remove = [&result](
json_pointer & ptr)
23979 const auto last_path = ptr.back();
23984 if (parent.is_object())
23987 auto it = parent.
find(last_path);
23988 if (JSON_HEDLEY_LIKELY(it != parent.end()))
23994 JSON_THROW(out_of_range::create(403,
"key '" + last_path +
"' not found"));
23997 else if (parent.is_array())
24000 parent.erase(
static_cast<size_type>(json_pointer::array_index(last_path)));
24005 if (JSON_HEDLEY_UNLIKELY(not json_patch.
is_array()))
24007 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
24011 for (
const auto& val : json_patch)
24014 const auto get_value = [&val](
const std::string & op,
24015 const std::string & member,
24019 auto it = val.m_value.object->find(member);
24022 const auto error_msg = (op ==
"op") ?
"operation" :
"operation '" + op +
"'";
24025 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
24027 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have member '" + member +
"'"));
24031 if (JSON_HEDLEY_UNLIKELY(string_type and not it->second.is_string()))
24033 JSON_THROW(parse_error::create(105, 0, error_msg +
" must have string member '" + member +
"'"));
24041 if (JSON_HEDLEY_UNLIKELY(not val.is_object()))
24043 JSON_THROW(parse_error::create(104, 0,
"JSON patch must be an array of objects"));
24047 const std::string op = get_value(
"op",
"op",
true);
24048 const std::string path = get_value(op,
"path",
true);
24051 switch (get_op(op))
24053 case patch_operations::add:
24055 operation_add(ptr, get_value(
"add",
"value",
false));
24059 case patch_operations::remove:
24061 operation_remove(ptr);
24065 case patch_operations::replace:
24068 result.
at(ptr) = get_value(
"replace",
"value",
false);
24072 case patch_operations::move:
24074 const std::string from_path = get_value(
"move",
"from",
true);
24084 operation_remove(from_ptr);
24085 operation_add(ptr, v);
24089 case patch_operations::copy:
24091 const std::string from_path = get_value(
"copy",
"from",
true);
24100 operation_add(ptr, v);
24104 case patch_operations::test:
24106 bool success =
false;
24111 success = (result.
at(ptr) == get_value(
"test",
"value",
false));
24119 if (JSON_HEDLEY_UNLIKELY(not success))
24121 JSON_THROW(other_error::create(501,
"unsuccessful: " + val.dump()));
24131 JSON_THROW(parse_error::create(105, 0,
"operation value '" + op +
"' is invalid"));
24174 const std::string& path =
"")
24180 if (source == target)
24185 if (source.type() != target.type())
24190 {
"op",
"replace"}, {
"path", path}, {
"value", target}
24195 switch (source.type())
24197 case value_t::array:
24201 while (i < source.size() and i < target.size())
24204 auto temp_diff =
diff(source[i], target[i], path +
"/" + std::to_string(i));
24205 result.
insert(result.
end(), temp_diff.begin(), temp_diff.end());
24214 while (i < source.size())
24221 {
"path", path +
"/" + std::to_string(i)}
24227 while (i < target.size())
24232 {
"path", path +
"/-"},
24233 {
"value", target[i]}
24241 case value_t::object:
24244 for (
auto it = source.cbegin(); it != source.cend(); ++it)
24247 const auto key = json_pointer::escape(it.key());
24249 if (target.find(it.key()) != target.end())
24252 auto temp_diff =
diff(it.value(), target[it.key()], path +
"/" + key);
24253 result.
insert(result.
end(), temp_diff.begin(), temp_diff.end());
24260 {
"op",
"remove"}, {
"path", path +
"/" + key}
24266 for (
auto it = target.cbegin(); it != target.cend(); ++it)
24268 if (source.find(it.key()) == source.end())
24271 const auto key = json_pointer::escape(it.key());
24274 {
"op",
"add"}, {
"path", path +
"/" + key},
24275 {
"value", it.value()}
24288 {
"op",
"replace"}, {
"path", path}, {
"value", target}
24350 if (apply_patch.is_object())
24356 for (
auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
24358 if (it.value().is_null())
24370 *
this = apply_patch;
24386 NLOHMANN_BASIC_JSON_TPL_DECLARATION
24387 std::string
to_string(
const NLOHMANN_BASIC_JSON_TPL& j)
24413 const auto& h = hash<nlohmann::json::string_t>();
24414 return h(j.
dump());
24422 struct less<::nlohmann::detail::value_t>
24428 bool operator()(nlohmann::detail::value_t lhs,
24429 nlohmann::detail::value_t rhs)
const noexcept
24431 return nlohmann::detail::operator<(lhs, rhs);
24442 is_nothrow_move_constructible<nlohmann::json>::value and
24443 is_nothrow_move_assignable<nlohmann::json>::value
24464 JSON_HEDLEY_NON_NULL(1)
24465 inline
nlohmann::
json operator "" _json(const
char* s, std::
size_t n)
24483 JSON_HEDLEY_NON_NULL(1)
24484 inline
nlohmann::
json::json_pointer operator "" _json_pointer(const
char* s, std::
size_t n)
24493 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
24494 #pragma GCC diagnostic pop
24496 #if defined(__clang__)
24497 #pragma GCC diagnostic pop
24501 #undef JSON_INTERNAL_CATCH
24505 #undef JSON_HAS_CPP_14
24506 #undef JSON_HAS_CPP_17
24507 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
24508 #undef NLOHMANN_BASIC_JSON_TPL
24511 #undef JSON_HEDLEY_ALWAYS_INLINE
24512 #undef JSON_HEDLEY_ARM_VERSION
24513 #undef JSON_HEDLEY_ARM_VERSION_CHECK
24514 #undef JSON_HEDLEY_ARRAY_PARAM
24515 #undef JSON_HEDLEY_ASSUME
24516 #undef JSON_HEDLEY_BEGIN_C_DECLS
24517 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
24518 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
24519 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
24520 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
24521 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
24522 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
24523 #undef JSON_HEDLEY_CLANG_HAS_WARNING
24524 #undef JSON_HEDLEY_COMPCERT_VERSION
24525 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
24526 #undef JSON_HEDLEY_CONCAT
24527 #undef JSON_HEDLEY_CONCAT3
24528 #undef JSON_HEDLEY_CONCAT3_EX
24529 #undef JSON_HEDLEY_CONCAT_EX
24530 #undef JSON_HEDLEY_CONST
24531 #undef JSON_HEDLEY_CONSTEXPR
24532 #undef JSON_HEDLEY_CONST_CAST
24533 #undef JSON_HEDLEY_CPP_CAST
24534 #undef JSON_HEDLEY_CRAY_VERSION
24535 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
24536 #undef JSON_HEDLEY_C_DECL
24537 #undef JSON_HEDLEY_DEPRECATED
24538 #undef JSON_HEDLEY_DEPRECATED_FOR
24539 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
24540 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
24541 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
24542 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
24543 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
24544 #undef JSON_HEDLEY_DIAGNOSTIC_POP
24545 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
24546 #undef JSON_HEDLEY_DMC_VERSION
24547 #undef JSON_HEDLEY_DMC_VERSION_CHECK
24548 #undef JSON_HEDLEY_EMPTY_BASES
24549 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
24550 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
24551 #undef JSON_HEDLEY_END_C_DECLS
24552 #undef JSON_HEDLEY_FLAGS
24553 #undef JSON_HEDLEY_FLAGS_CAST
24554 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
24555 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
24556 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
24557 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
24558 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
24559 #undef JSON_HEDLEY_GCC_HAS_FEATURE
24560 #undef JSON_HEDLEY_GCC_HAS_WARNING
24561 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
24562 #undef JSON_HEDLEY_GCC_VERSION
24563 #undef JSON_HEDLEY_GCC_VERSION_CHECK
24564 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
24565 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
24566 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
24567 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
24568 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
24569 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
24570 #undef JSON_HEDLEY_GNUC_HAS_WARNING
24571 #undef JSON_HEDLEY_GNUC_VERSION
24572 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
24573 #undef JSON_HEDLEY_HAS_ATTRIBUTE
24574 #undef JSON_HEDLEY_HAS_BUILTIN
24575 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
24576 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
24577 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
24578 #undef JSON_HEDLEY_HAS_EXTENSION
24579 #undef JSON_HEDLEY_HAS_FEATURE
24580 #undef JSON_HEDLEY_HAS_WARNING
24581 #undef JSON_HEDLEY_IAR_VERSION
24582 #undef JSON_HEDLEY_IAR_VERSION_CHECK
24583 #undef JSON_HEDLEY_IBM_VERSION
24584 #undef JSON_HEDLEY_IBM_VERSION_CHECK
24585 #undef JSON_HEDLEY_IMPORT
24586 #undef JSON_HEDLEY_INLINE
24587 #undef JSON_HEDLEY_INTEL_VERSION
24588 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
24589 #undef JSON_HEDLEY_IS_CONSTANT
24590 #undef JSON_HEDLEY_IS_CONSTEXPR_
24591 #undef JSON_HEDLEY_LIKELY
24592 #undef JSON_HEDLEY_MALLOC
24593 #undef JSON_HEDLEY_MESSAGE
24594 #undef JSON_HEDLEY_MSVC_VERSION
24595 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
24596 #undef JSON_HEDLEY_NEVER_INLINE
24597 #undef JSON_HEDLEY_NON_NULL
24598 #undef JSON_HEDLEY_NO_ESCAPE
24599 #undef JSON_HEDLEY_NO_RETURN
24600 #undef JSON_HEDLEY_NO_THROW
24601 #undef JSON_HEDLEY_NULL
24602 #undef JSON_HEDLEY_PELLES_VERSION
24603 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
24604 #undef JSON_HEDLEY_PGI_VERSION
24605 #undef JSON_HEDLEY_PGI_VERSION_CHECK
24606 #undef JSON_HEDLEY_PREDICT
24607 #undef JSON_HEDLEY_PRINTF_FORMAT
24608 #undef JSON_HEDLEY_PRIVATE
24609 #undef JSON_HEDLEY_PUBLIC
24610 #undef JSON_HEDLEY_PURE
24611 #undef JSON_HEDLEY_REINTERPRET_CAST
24612 #undef JSON_HEDLEY_REQUIRE
24613 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
24614 #undef JSON_HEDLEY_REQUIRE_MSG
24615 #undef JSON_HEDLEY_RESTRICT
24617 #undef JSON_HEDLEY_SENTINEL
24618 #undef JSON_HEDLEY_STATIC_ASSERT
24619 #undef JSON_HEDLEY_STATIC_CAST
24620 #undef JSON_HEDLEY_STRINGIFY
24621 #undef JSON_HEDLEY_STRINGIFY_EX
24622 #undef JSON_HEDLEY_SUNPRO_VERSION
24623 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
24624 #undef JSON_HEDLEY_TINYC_VERSION
24625 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
24626 #undef JSON_HEDLEY_TI_ARMCL_VERSION
24627 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
24628 #undef JSON_HEDLEY_TI_CL2000_VERSION
24629 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
24630 #undef JSON_HEDLEY_TI_CL430_VERSION
24631 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
24632 #undef JSON_HEDLEY_TI_CL6X_VERSION
24633 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
24634 #undef JSON_HEDLEY_TI_CL7X_VERSION
24635 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
24636 #undef JSON_HEDLEY_TI_CLPRU_VERSION
24637 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
24638 #undef JSON_HEDLEY_TI_VERSION
24639 #undef JSON_HEDLEY_TI_VERSION_CHECK
24640 #undef JSON_HEDLEY_UNAVAILABLE
24641 #undef JSON_HEDLEY_UNLIKELY
24642 #undef JSON_HEDLEY_UNPREDICTABLE
24643 #undef JSON_HEDLEY_UNREACHABLE
24644 #undef JSON_HEDLEY_UNREACHABLE_RETURN
24645 #undef JSON_HEDLEY_VERSION
24646 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
24647 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
24648 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
24649 #undef JSON_HEDLEY_VERSION_ENCODE
24650 #undef JSON_HEDLEY_WARNING
24653 #undef JSON_HEDLEY_FALL_THROUGH
24657 #endif // INCLUDE_NLOHMANN_JSON_HPP_