3 __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.7.3
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
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
37 #include <algorithm> // all_of, find, for_each
38 #include <cassert> // assert
39 #include <ciso646> // and, not, or
40 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
41 #include <functional> // hash, less
42 #include <initializer_list> // initializer_list
43 #include <iosfwd> // istream, ostream
44 #include <iterator> // random_access_iterator_tag
45 #include <memory> // unique_ptr
46 #include <numeric> // accumulate
47 #include <string> // string, stoi, to_string
48 #include <utility> // declval, forward, move, pair, swap
49 #include <vector> // vector
51 // #include <nlohmann/adl_serializer.hpp>
56 // #include <nlohmann/detail/conversions/from_json.hpp>
59 #include <algorithm> // transform
60 #include <array> // array
61 #include <ciso646> // and, not
62 #include <forward_list> // forward_list
63 #include <iterator> // inserter, front_inserter, end
65 #include <string> // string
66 #include <tuple> // tuple, make_tuple
67 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
68 #include <unordered_map> // unordered_map
69 #include <utility> // pair, declval
70 #include <valarray> // valarray
72 // #include <nlohmann/detail/exceptions.hpp>
75 #include <exception> // exception
76 #include <stdexcept> // runtime_error
77 #include <string> // to_string
79 // #include <nlohmann/detail/input/position_t.hpp>
82 #include <cstddef> // size_t
88 /// struct to capture the start position of the current token
91 /// the total number of characters read
92 std::size_t chars_read_total = 0;
93 /// the number of characters read in the current line
94 std::size_t chars_read_current_line = 0;
95 /// the number of lines read
96 std::size_t lines_read = 0;
98 /// conversion to size_t to preserve SAX interface
99 constexpr operator size_t() const
101 return chars_read_total;
105 } // namespace detail
106 } // namespace nlohmann
108 // #include <nlohmann/detail/macro_scope.hpp>
111 #include <utility> // pair
112 // #include <nlohmann/thirdparty/hedley/hedley.hpp>
113 /* Hedley - https://nemequ.github.io/hedley
114 * Created by Evan Nemerson <evan@nemerson.com>
116 * To the extent possible under law, the author(s) have dedicated all
117 * copyright and related and neighboring rights to this software to
118 * the public domain worldwide. This software is distributed without
121 * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
122 * SPDX-License-Identifier: CC0-1.0
125 #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 11)
126 #if defined(JSON_HEDLEY_VERSION)
127 #undef JSON_HEDLEY_VERSION
129 #define JSON_HEDLEY_VERSION 11
131 #if defined(JSON_HEDLEY_STRINGIFY_EX)
132 #undef JSON_HEDLEY_STRINGIFY_EX
134 #define JSON_HEDLEY_STRINGIFY_EX(x) #x
136 #if defined(JSON_HEDLEY_STRINGIFY)
137 #undef JSON_HEDLEY_STRINGIFY
139 #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
141 #if defined(JSON_HEDLEY_CONCAT_EX)
142 #undef JSON_HEDLEY_CONCAT_EX
144 #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
146 #if defined(JSON_HEDLEY_CONCAT)
147 #undef JSON_HEDLEY_CONCAT
149 #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
151 #if defined(JSON_HEDLEY_VERSION_ENCODE)
152 #undef JSON_HEDLEY_VERSION_ENCODE
154 #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
156 #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
157 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
159 #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
161 #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
162 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
164 #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
166 #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
167 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
169 #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
171 #if defined(JSON_HEDLEY_GNUC_VERSION)
172 #undef JSON_HEDLEY_GNUC_VERSION
174 #if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
175 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
176 #elif defined(__GNUC__)
177 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
180 #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
181 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
183 #if defined(JSON_HEDLEY_GNUC_VERSION)
184 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
186 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
189 #if defined(JSON_HEDLEY_MSVC_VERSION)
190 #undef JSON_HEDLEY_MSVC_VERSION
192 #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000)
193 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
194 #elif defined(_MSC_FULL_VER)
195 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
196 #elif defined(_MSC_VER)
197 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
200 #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
201 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
203 #if !defined(_MSC_VER)
204 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
205 #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
206 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
207 #elif defined(_MSC_VER) && (_MSC_VER >= 1200)
208 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
210 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
213 #if defined(JSON_HEDLEY_INTEL_VERSION)
214 #undef JSON_HEDLEY_INTEL_VERSION
216 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE)
217 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
218 #elif defined(__INTEL_COMPILER)
219 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
222 #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
223 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
225 #if defined(JSON_HEDLEY_INTEL_VERSION)
226 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
228 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
231 #if defined(JSON_HEDLEY_PGI_VERSION)
232 #undef JSON_HEDLEY_PGI_VERSION
234 #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
235 #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
238 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
239 #undef JSON_HEDLEY_PGI_VERSION_CHECK
241 #if defined(JSON_HEDLEY_PGI_VERSION)
242 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
244 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
247 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
248 #undef JSON_HEDLEY_SUNPRO_VERSION
250 #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
251 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)
252 #elif defined(__SUNPRO_C)
253 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
254 #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
255 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)
256 #elif defined(__SUNPRO_CC)
257 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
260 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
261 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
263 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
264 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
266 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
269 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
270 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
272 #if defined(__EMSCRIPTEN__)
273 #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
276 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
277 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
279 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
280 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
282 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
285 #if defined(JSON_HEDLEY_ARM_VERSION)
286 #undef JSON_HEDLEY_ARM_VERSION
288 #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
289 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
290 #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
291 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
294 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
295 #undef JSON_HEDLEY_ARM_VERSION_CHECK
297 #if defined(JSON_HEDLEY_ARM_VERSION)
298 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
300 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
303 #if defined(JSON_HEDLEY_IBM_VERSION)
304 #undef JSON_HEDLEY_IBM_VERSION
306 #if defined(__ibmxl__)
307 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
308 #elif defined(__xlC__) && defined(__xlC_ver__)
309 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
310 #elif defined(__xlC__)
311 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
314 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
315 #undef JSON_HEDLEY_IBM_VERSION_CHECK
317 #if defined(JSON_HEDLEY_IBM_VERSION)
318 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
320 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
323 #if defined(JSON_HEDLEY_TI_VERSION)
324 #undef JSON_HEDLEY_TI_VERSION
326 #if defined(__TI_COMPILER_VERSION__)
327 #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
330 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
331 #undef JSON_HEDLEY_TI_VERSION_CHECK
333 #if defined(JSON_HEDLEY_TI_VERSION)
334 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
336 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
339 #if defined(JSON_HEDLEY_CRAY_VERSION)
340 #undef JSON_HEDLEY_CRAY_VERSION
343 #if defined(_RELEASE_PATCHLEVEL)
344 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
346 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
350 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
351 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
353 #if defined(JSON_HEDLEY_CRAY_VERSION)
354 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
356 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
359 #if defined(JSON_HEDLEY_IAR_VERSION)
360 #undef JSON_HEDLEY_IAR_VERSION
362 #if defined(__IAR_SYSTEMS_ICC__)
364 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
366 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(VER / 100, __VER__ % 100, 0)
370 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
371 #undef JSON_HEDLEY_IAR_VERSION_CHECK
373 #if defined(JSON_HEDLEY_IAR_VERSION)
374 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
376 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
379 #if defined(JSON_HEDLEY_TINYC_VERSION)
380 #undef JSON_HEDLEY_TINYC_VERSION
382 #if defined(__TINYC__)
383 #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
386 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
387 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
389 #if defined(JSON_HEDLEY_TINYC_VERSION)
390 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
392 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
395 #if defined(JSON_HEDLEY_DMC_VERSION)
396 #undef JSON_HEDLEY_DMC_VERSION
399 #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
402 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
403 #undef JSON_HEDLEY_DMC_VERSION_CHECK
405 #if defined(JSON_HEDLEY_DMC_VERSION)
406 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
408 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
411 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
412 #undef JSON_HEDLEY_COMPCERT_VERSION
414 #if defined(__COMPCERT_VERSION__)
415 #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
418 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
419 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
421 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
422 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
424 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
427 #if defined(JSON_HEDLEY_PELLES_VERSION)
428 #undef JSON_HEDLEY_PELLES_VERSION
430 #if defined(__POCC__)
431 #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
434 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
435 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
437 #if defined(JSON_HEDLEY_PELLES_VERSION)
438 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
440 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
443 #if defined(JSON_HEDLEY_GCC_VERSION)
444 #undef JSON_HEDLEY_GCC_VERSION
447 defined(JSON_HEDLEY_GNUC_VERSION) && \
448 !defined(__clang__) && \
449 !defined(JSON_HEDLEY_INTEL_VERSION) && \
450 !defined(JSON_HEDLEY_PGI_VERSION) && \
451 !defined(JSON_HEDLEY_ARM_VERSION) && \
452 !defined(JSON_HEDLEY_TI_VERSION) && \
453 !defined(__COMPCERT__)
454 #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
457 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
458 #undef JSON_HEDLEY_GCC_VERSION_CHECK
460 #if defined(JSON_HEDLEY_GCC_VERSION)
461 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
463 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
466 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
467 #undef JSON_HEDLEY_HAS_ATTRIBUTE
469 #if defined(__has_attribute)
470 #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
472 #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
475 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
476 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
478 #if defined(__has_attribute)
479 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
481 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
484 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
485 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
487 #if defined(__has_attribute)
488 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
490 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
493 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
494 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
497 defined(__has_cpp_attribute) && \
498 defined(__cplusplus) && \
499 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
500 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
502 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
505 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
506 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
508 #if !defined(__cplusplus) || !defined(__has_cpp_attribute)
509 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
511 !defined(JSON_HEDLEY_PGI_VERSION) && \
512 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
513 (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
514 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
516 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
519 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
520 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
522 #if defined(__has_cpp_attribute) && defined(__cplusplus)
523 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
525 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
528 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
529 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
531 #if defined(__has_cpp_attribute) && defined(__cplusplus)
532 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
534 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
537 #if defined(JSON_HEDLEY_HAS_BUILTIN)
538 #undef JSON_HEDLEY_HAS_BUILTIN
540 #if defined(__has_builtin)
541 #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
543 #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
546 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
547 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
549 #if defined(__has_builtin)
550 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
552 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
555 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
556 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
558 #if defined(__has_builtin)
559 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
561 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
564 #if defined(JSON_HEDLEY_HAS_FEATURE)
565 #undef JSON_HEDLEY_HAS_FEATURE
567 #if defined(__has_feature)
568 #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
570 #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
573 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
574 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
576 #if defined(__has_feature)
577 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
579 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
582 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
583 #undef JSON_HEDLEY_GCC_HAS_FEATURE
585 #if defined(__has_feature)
586 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
588 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
591 #if defined(JSON_HEDLEY_HAS_EXTENSION)
592 #undef JSON_HEDLEY_HAS_EXTENSION
594 #if defined(__has_extension)
595 #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
597 #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
600 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
601 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
603 #if defined(__has_extension)
604 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
606 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
609 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
610 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
612 #if defined(__has_extension)
613 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
615 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
618 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
619 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
621 #if defined(__has_declspec_attribute)
622 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
624 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
627 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
628 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
630 #if defined(__has_declspec_attribute)
631 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
633 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
636 #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
637 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
639 #if defined(__has_declspec_attribute)
640 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
642 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
645 #if defined(JSON_HEDLEY_HAS_WARNING)
646 #undef JSON_HEDLEY_HAS_WARNING
648 #if defined(__has_warning)
649 #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
651 #define JSON_HEDLEY_HAS_WARNING(warning) (0)
654 #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
655 #undef JSON_HEDLEY_GNUC_HAS_WARNING
657 #if defined(__has_warning)
658 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
660 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
663 #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
664 #undef JSON_HEDLEY_GCC_HAS_WARNING
666 #if defined(__has_warning)
667 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
669 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
672 /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
673 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
674 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
675 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
677 #if defined(__cplusplus) && JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
678 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
679 JSON_HEDLEY_DIAGNOSTIC_PUSH \
680 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
682 JSON_HEDLEY_DIAGNOSTIC_POP
684 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
688 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
689 defined(__clang__) || \
690 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
691 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
692 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
693 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
694 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
695 JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) || \
696 JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
697 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
698 JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
699 (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
700 #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
701 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
702 #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
704 #define JSON_HEDLEY_PRAGMA(value)
707 #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
708 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
710 #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
711 #undef JSON_HEDLEY_DIAGNOSTIC_POP
713 #if defined(__clang__)
714 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
715 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
716 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
717 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
718 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
719 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
720 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
721 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
722 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
723 #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
724 #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
725 #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
726 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
727 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
728 #elif JSON_HEDLEY_TI_VERSION_CHECK(8,1,0)
729 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
730 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
731 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
732 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
733 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
735 #define JSON_HEDLEY_DIAGNOSTIC_PUSH
736 #define JSON_HEDLEY_DIAGNOSTIC_POP
739 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
740 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
742 #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
743 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
744 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
745 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
746 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
747 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
748 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
749 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
750 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
751 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
752 #elif JSON_HEDLEY_TI_VERSION_CHECK(8,0,0)
753 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
754 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
755 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
756 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
757 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
758 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
759 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
760 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
761 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
763 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
766 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
767 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
769 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
770 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
771 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
772 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
773 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
774 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
775 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
776 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
777 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
778 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
779 #elif JSON_HEDLEY_TI_VERSION_CHECK(8,0,0)
780 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
781 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
782 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
784 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
787 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
788 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
790 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
791 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
792 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
793 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
794 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
795 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
796 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
797 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
798 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
799 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
800 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
801 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
802 #elif JSON_HEDLEY_TI_VERSION_CHECK(8,0,0)
803 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
805 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
808 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
809 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
811 #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
812 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
813 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
814 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
815 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
816 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
818 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
821 #if defined(JSON_HEDLEY_DEPRECATED)
822 #undef JSON_HEDLEY_DEPRECATED
824 #if defined(JSON_HEDLEY_DEPRECATED_FOR)
825 #undef JSON_HEDLEY_DEPRECATED_FOR
827 #if defined(__cplusplus) && (__cplusplus >= 201402L)
828 #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
829 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
831 JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) || \
832 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
833 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
834 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
835 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
836 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
837 JSON_HEDLEY_TI_VERSION_CHECK(8,3,0)
838 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
839 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
841 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
842 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
843 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
844 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
845 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
846 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
847 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
848 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0)
849 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
850 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
852 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
853 JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0)
854 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
855 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
856 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
857 #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
858 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
860 #define JSON_HEDLEY_DEPRECATED(since)
861 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
864 #if defined(JSON_HEDLEY_UNAVAILABLE)
865 #undef JSON_HEDLEY_UNAVAILABLE
868 JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
869 JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
870 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
871 #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
873 #define JSON_HEDLEY_UNAVAILABLE(available_since)
876 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
877 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
879 #if defined(__cplusplus) && (__cplusplus >= 201703L)
880 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
882 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
883 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
884 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
885 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
886 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
887 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
888 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
889 #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
890 #elif defined(_Check_return_) /* SAL */
891 #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
893 #define JSON_HEDLEY_WARN_UNUSED_RESULT
896 #if defined(JSON_HEDLEY_SENTINEL)
897 #undef JSON_HEDLEY_SENTINEL
900 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
901 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
902 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
903 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0)
904 #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
906 #define JSON_HEDLEY_SENTINEL(position)
909 #if defined(JSON_HEDLEY_NO_RETURN)
910 #undef JSON_HEDLEY_NO_RETURN
912 #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
913 #define JSON_HEDLEY_NO_RETURN __noreturn
914 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
915 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
916 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
917 #define JSON_HEDLEY_NO_RETURN _Noreturn
918 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
919 #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
921 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
922 JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
923 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
924 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
925 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
926 JSON_HEDLEY_TI_VERSION_CHECK(18,0,0) || \
927 (JSON_HEDLEY_TI_VERSION_CHECK(17,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
928 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
929 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
930 #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
931 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
932 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
933 #elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus)
934 #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
935 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
936 #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
937 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
938 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
940 #define JSON_HEDLEY_NO_RETURN
943 #if defined(JSON_HEDLEY_NO_ESCAPE)
944 #undef JSON_HEDLEY_NO_ESCAPE
946 #if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
947 #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
949 #define JSON_HEDLEY_NO_ESCAPE
952 #if defined(JSON_HEDLEY_UNREACHABLE)
953 #undef JSON_HEDLEY_UNREACHABLE
955 #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
956 #undef JSON_HEDLEY_UNREACHABLE_RETURN
959 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
960 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
961 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
962 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5)
963 #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
964 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
965 #define JSON_HEDLEY_UNREACHABLE() __assume(0)
966 #elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0)
967 #if defined(__cplusplus)
968 #define JSON_HEDLEY_UNREACHABLE() std::_nassert(0)
970 #define JSON_HEDLEY_UNREACHABLE() _nassert(0)
972 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return value
973 #elif defined(EXIT_FAILURE)
974 #define JSON_HEDLEY_UNREACHABLE() abort()
976 #define JSON_HEDLEY_UNREACHABLE()
977 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return value
979 #if !defined(JSON_HEDLEY_UNREACHABLE_RETURN)
980 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
983 #if defined(JSON_HEDLEY_ASSUME)
984 #undef JSON_HEDLEY_ASSUME
987 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
988 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
989 #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
990 #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
991 #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
992 #elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0)
993 #if defined(__cplusplus)
994 #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
996 #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
999 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && !defined(JSON_HEDLEY_ARM_VERSION)) || \
1000 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1001 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1002 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5)
1003 #define JSON_HEDLEY_ASSUME(expr) ((void) ((expr) ? 1 : (__builtin_unreachable(), 1)))
1005 #define JSON_HEDLEY_ASSUME(expr) ((void) (expr))
1008 JSON_HEDLEY_DIAGNOSTIC_PUSH
1009 #if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1010 #pragma clang diagnostic ignored "-Wpedantic"
1012 #if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1013 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1015 #if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1016 #if defined(__clang__)
1017 #pragma clang diagnostic ignored "-Wvariadic-macros"
1018 #elif defined(JSON_HEDLEY_GCC_VERSION)
1019 #pragma GCC diagnostic ignored "-Wvariadic-macros"
1022 #if defined(JSON_HEDLEY_NON_NULL)
1023 #undef JSON_HEDLEY_NON_NULL
1026 JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1027 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1028 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1029 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1030 #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1032 #define JSON_HEDLEY_NON_NULL(...)
1034 JSON_HEDLEY_DIAGNOSTIC_POP
1036 #if defined(JSON_HEDLEY_PRINTF_FORMAT)
1037 #undef JSON_HEDLEY_PRINTF_FORMAT
1039 #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1040 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1041 #elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1042 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1044 JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1045 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1046 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1047 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1048 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1049 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
1050 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
1051 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1052 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1053 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1055 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1058 #if defined(JSON_HEDLEY_CONSTEXPR)
1059 #undef JSON_HEDLEY_CONSTEXPR
1061 #if defined(__cplusplus)
1062 #if __cplusplus >= 201103L
1063 #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1066 #if !defined(JSON_HEDLEY_CONSTEXPR)
1067 #define JSON_HEDLEY_CONSTEXPR
1070 #if defined(JSON_HEDLEY_PREDICT)
1071 #undef JSON_HEDLEY_PREDICT
1073 #if defined(JSON_HEDLEY_LIKELY)
1074 #undef JSON_HEDLEY_LIKELY
1076 #if defined(JSON_HEDLEY_UNLIKELY)
1077 #undef JSON_HEDLEY_UNLIKELY
1079 #if defined(JSON_HEDLEY_UNPREDICTABLE)
1080 #undef JSON_HEDLEY_UNPREDICTABLE
1082 #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1083 #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable(!!(expr))
1086 JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) || \
1087 JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0)
1088 # define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability(expr, value, probability)
1089 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1, probability)
1090 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0, probability)
1091 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1092 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1093 #if !defined(JSON_HEDLEY_BUILTIN_UNPREDICTABLE)
1094 #define JSON_HEDLEY_BUILTIN_UNPREDICTABLE(expr) __builtin_expect_with_probability(!!(expr), 1, 0.5)
1097 JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) || \
1098 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1099 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1100 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1101 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1102 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1103 JSON_HEDLEY_TI_VERSION_CHECK(6,1,0) || \
1104 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27)
1105 # define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1106 (((probability) >= 0.9) ? __builtin_expect(!!(expr), (expected)) : (((void) (expected)), !!(expr)))
1107 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1109 JSON_HEDLEY_CONSTEXPR double hedley_probability_ = (probability); \
1110 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1112 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1114 JSON_HEDLEY_CONSTEXPR double hedley_probability_ = (probability); \
1115 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1117 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1118 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1120 # define JSON_HEDLEY_PREDICT(expr, expected, probability) (((void) (expected)), !!(expr))
1121 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1122 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1123 # define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1124 # define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1126 #if !defined(JSON_HEDLEY_UNPREDICTABLE)
1127 #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1130 #if defined(JSON_HEDLEY_MALLOC)
1131 #undef JSON_HEDLEY_MALLOC
1134 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1135 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1136 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1137 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1138 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1139 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1140 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
1141 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
1142 #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1143 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1144 #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1145 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(14, 0, 0)
1146 #define JSON_HEDLEY_MALLOC __declspec(restrict)
1148 #define JSON_HEDLEY_MALLOC
1151 #if defined(JSON_HEDLEY_PURE)
1152 #undef JSON_HEDLEY_PURE
1155 JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1156 JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1157 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1158 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1159 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1160 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1161 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
1162 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1163 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1164 #define JSON_HEDLEY_PURE __attribute__((__pure__))
1165 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1166 #define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1167 #elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1168 #define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1170 #define JSON_HEDLEY_PURE
1173 #if defined(JSON_HEDLEY_CONST)
1174 #undef JSON_HEDLEY_CONST
1177 JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1178 JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1179 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1180 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1181 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1182 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1183 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
1184 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1185 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1186 #define JSON_HEDLEY_CONST __attribute__((__const__))
1188 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1189 #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1191 #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1194 #if defined(JSON_HEDLEY_RESTRICT)
1195 #undef JSON_HEDLEY_RESTRICT
1197 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1198 #define JSON_HEDLEY_RESTRICT restrict
1200 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1201 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1202 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1203 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1204 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1205 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1206 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
1207 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1208 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1210 #define JSON_HEDLEY_RESTRICT __restrict
1211 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1212 #define JSON_HEDLEY_RESTRICT _Restrict
1214 #define JSON_HEDLEY_RESTRICT
1217 #if defined(JSON_HEDLEY_INLINE)
1218 #undef JSON_HEDLEY_INLINE
1221 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1222 (defined(__cplusplus) && (__cplusplus >= 199711L))
1223 #define JSON_HEDLEY_INLINE inline
1225 defined(JSON_HEDLEY_GCC_VERSION) || \
1226 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1227 #define JSON_HEDLEY_INLINE __inline__
1229 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1230 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1231 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0)
1232 #define JSON_HEDLEY_INLINE __inline
1234 #define JSON_HEDLEY_INLINE
1237 #if defined(JSON_HEDLEY_ALWAYS_INLINE)
1238 #undef JSON_HEDLEY_ALWAYS_INLINE
1241 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1242 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1243 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1244 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1245 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1246 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1247 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
1248 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
1249 #define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1250 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0)
1251 #define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1252 #elif JSON_HEDLEY_TI_VERSION_CHECK(7,0,0) && defined(__cplusplus)
1253 #define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1254 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1255 #define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1257 #define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1260 #if defined(JSON_HEDLEY_NEVER_INLINE)
1261 #undef JSON_HEDLEY_NEVER_INLINE
1264 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1265 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1266 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1267 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1268 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1269 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1270 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
1271 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
1272 #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1273 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
1274 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1275 #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1276 #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1277 #elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1278 #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1279 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1280 #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1281 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1282 #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1283 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1284 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1286 #define JSON_HEDLEY_NEVER_INLINE
1289 #if defined(JSON_HEDLEY_PRIVATE)
1290 #undef JSON_HEDLEY_PRIVATE
1292 #if defined(JSON_HEDLEY_PUBLIC)
1293 #undef JSON_HEDLEY_PUBLIC
1295 #if defined(JSON_HEDLEY_IMPORT)
1296 #undef JSON_HEDLEY_IMPORT
1298 #if defined(_WIN32) || defined(__CYGWIN__)
1299 #define JSON_HEDLEY_PRIVATE
1300 #define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1301 #define JSON_HEDLEY_IMPORT __declspec(dllimport)
1304 JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1305 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1306 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1307 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1308 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1309 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1310 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
1311 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_EABI__) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
1312 #define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1313 #define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1315 #define JSON_HEDLEY_PRIVATE
1316 #define JSON_HEDLEY_PUBLIC
1318 #define JSON_HEDLEY_IMPORT extern
1321 #if defined(JSON_HEDLEY_NO_THROW)
1322 #undef JSON_HEDLEY_NO_THROW
1325 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1326 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1327 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1328 #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1330 JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1331 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1332 #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1334 #define JSON_HEDLEY_NO_THROW
1337 #if defined(JSON_HEDLEY_FALL_THROUGH)
1338 #undef JSON_HEDLEY_FALL_THROUGH
1340 #if JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(fallthrough,7,0,0) && !defined(JSON_HEDLEY_PGI_VERSION)
1341 #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1342 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1343 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1344 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1345 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1346 #elif defined(__fallthrough) /* SAL */
1347 #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1349 #define JSON_HEDLEY_FALL_THROUGH
1352 #if defined(JSON_HEDLEY_RETURNS_NON_NULL)
1353 #undef JSON_HEDLEY_RETURNS_NON_NULL
1356 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1357 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
1358 #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
1359 #elif defined(_Ret_notnull_) /* SAL */
1360 #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
1362 #define JSON_HEDLEY_RETURNS_NON_NULL
1365 #if defined(JSON_HEDLEY_ARRAY_PARAM)
1366 #undef JSON_HEDLEY_ARRAY_PARAM
1369 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1370 !defined(__STDC_NO_VLA__) && \
1371 !defined(__cplusplus) && \
1372 !defined(JSON_HEDLEY_PGI_VERSION) && \
1373 !defined(JSON_HEDLEY_TINYC_VERSION)
1374 #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1376 #define JSON_HEDLEY_ARRAY_PARAM(name)
1379 #if defined(JSON_HEDLEY_IS_CONSTANT)
1380 #undef JSON_HEDLEY_IS_CONSTANT
1382 #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1383 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1385 /* JSON_HEDLEY_IS_CONSTEXPR_ is for
1386 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1387 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1388 #undef JSON_HEDLEY_IS_CONSTEXPR_
1391 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1392 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1393 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1394 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1395 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1396 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1397 JSON_HEDLEY_TI_VERSION_CHECK(6,1,0) || \
1398 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1399 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
1400 #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1402 #if !defined(__cplusplus)
1404 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1405 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1406 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1407 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1408 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1409 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1410 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1411 #if defined(__INTPTR_TYPE__)
1412 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1415 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1418 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && !defined(JSON_HEDLEY_SUNPRO_VERSION) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1419 JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) || \
1420 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1421 JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1422 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1423 JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1424 #if defined(__INTPTR_TYPE__)
1425 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1428 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1431 defined(JSON_HEDLEY_GCC_VERSION) || \
1432 defined(JSON_HEDLEY_INTEL_VERSION) || \
1433 defined(JSON_HEDLEY_TINYC_VERSION) || \
1434 defined(JSON_HEDLEY_TI_VERSION) || \
1436 # define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1440 ((void*) ((expr) * 0L) ) : \
1441 ((struct { char v[sizeof(void) * 2]; } *) 1) \
1447 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1448 #if !defined(JSON_HEDLEY_IS_CONSTANT)
1449 #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1451 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
1453 #if !defined(JSON_HEDLEY_IS_CONSTANT)
1454 #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
1456 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
1459 #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
1460 #undef JSON_HEDLEY_BEGIN_C_DECLS
1462 #if defined(JSON_HEDLEY_END_C_DECLS)
1463 #undef JSON_HEDLEY_END_C_DECLS
1465 #if defined(JSON_HEDLEY_C_DECL)
1466 #undef JSON_HEDLEY_C_DECL
1468 #if defined(__cplusplus)
1469 #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
1470 #define JSON_HEDLEY_END_C_DECLS }
1471 #define JSON_HEDLEY_C_DECL extern "C"
1473 #define JSON_HEDLEY_BEGIN_C_DECLS
1474 #define JSON_HEDLEY_END_C_DECLS
1475 #define JSON_HEDLEY_C_DECL
1478 #if defined(JSON_HEDLEY_STATIC_ASSERT)
1479 #undef JSON_HEDLEY_STATIC_ASSERT
1482 !defined(__cplusplus) && ( \
1483 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
1484 JSON_HEDLEY_HAS_FEATURE(c_static_assert) || \
1485 JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
1486 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1487 defined(_Static_assert) \
1489 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
1491 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
1492 JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
1493 (defined(__cplusplus) && JSON_HEDLEY_TI_VERSION_CHECK(8,3,0))
1494 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
1496 # define JSON_HEDLEY_STATIC_ASSERT(expr, message)
1499 #if defined(JSON_HEDLEY_CONST_CAST)
1500 #undef JSON_HEDLEY_CONST_CAST
1502 #if defined(__cplusplus)
1503 # define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1505 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1506 JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1507 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1508 # define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1509 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1510 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1512 JSON_HEDLEY_DIAGNOSTIC_POP \
1515 # define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1518 #if defined(JSON_HEDLEY_REINTERPRET_CAST)
1519 #undef JSON_HEDLEY_REINTERPRET_CAST
1521 #if defined(__cplusplus)
1522 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1524 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (*((T*) &(expr)))
1527 #if defined(JSON_HEDLEY_STATIC_CAST)
1528 #undef JSON_HEDLEY_STATIC_CAST
1530 #if defined(__cplusplus)
1531 #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1533 #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1536 #if defined(JSON_HEDLEY_CPP_CAST)
1537 #undef JSON_HEDLEY_CPP_CAST
1539 #if defined(__cplusplus)
1540 #define JSON_HEDLEY_CPP_CAST(T, expr) static_cast<T>(expr)
1542 #define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1545 #if defined(JSON_HEDLEY_NULL)
1546 #undef JSON_HEDLEY_NULL
1548 #if defined(__cplusplus)
1549 #if __cplusplus >= 201103L
1550 #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
1552 #define JSON_HEDLEY_NULL NULL
1554 #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
1557 #define JSON_HEDLEY_NULL NULL
1559 #define JSON_HEDLEY_NULL ((void*) 0)
1562 #if defined(JSON_HEDLEY_MESSAGE)
1563 #undef JSON_HEDLEY_MESSAGE
1565 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1566 # define JSON_HEDLEY_MESSAGE(msg) \
1567 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1568 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1569 JSON_HEDLEY_PRAGMA(message msg) \
1570 JSON_HEDLEY_DIAGNOSTIC_POP
1572 JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
1573 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1574 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
1575 #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
1576 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
1577 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1578 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1579 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
1580 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1582 # define JSON_HEDLEY_MESSAGE(msg)
1585 #if defined(JSON_HEDLEY_WARNING)
1586 #undef JSON_HEDLEY_WARNING
1588 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1589 # define JSON_HEDLEY_WARNING(msg) \
1590 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1591 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1592 JSON_HEDLEY_PRAGMA(clang warning msg) \
1593 JSON_HEDLEY_DIAGNOSTIC_POP
1595 JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
1596 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0)
1597 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
1598 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1599 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
1601 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
1604 #if defined(JSON_HEDLEY_REQUIRE)
1605 #undef JSON_HEDLEY_REQUIRE
1607 #if defined(JSON_HEDLEY_REQUIRE_MSG)
1608 #undef JSON_HEDLEY_REQUIRE_MSG
1610 #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
1611 # if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
1612 # define JSON_HEDLEY_REQUIRE(expr) \
1613 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1614 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1615 __attribute__((diagnose_if(!(expr), #expr, "error"))) \
1616 JSON_HEDLEY_DIAGNOSTIC_POP
1617 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
1618 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1619 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1620 __attribute__((diagnose_if(!(expr), msg, "error"))) \
1621 JSON_HEDLEY_DIAGNOSTIC_POP
1623 # define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
1624 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
1627 # define JSON_HEDLEY_REQUIRE(expr)
1628 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
1631 #if defined(JSON_HEDLEY_FLAGS)
1632 #undef JSON_HEDLEY_FLAGS
1634 #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum)
1635 #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
1638 #if defined(JSON_HEDLEY_FLAGS_CAST)
1639 #undef JSON_HEDLEY_FLAGS_CAST
1641 #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
1642 # define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
1643 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1644 _Pragma("warning(disable:188)") \
1646 JSON_HEDLEY_DIAGNOSTIC_POP \
1649 # define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
1652 #if defined(JSON_HEDLEY_EMPTY_BASES)
1653 #undef JSON_HEDLEY_EMPTY_BASES
1655 #if JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)
1656 #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
1658 #define JSON_HEDLEY_EMPTY_BASES
1661 /* Remaining macros are deprecated. */
1663 #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
1664 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
1666 #if defined(__clang__)
1667 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
1669 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1672 #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
1673 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
1675 #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
1677 #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
1678 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
1680 #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
1682 #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
1683 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
1685 #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
1687 #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
1688 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
1690 #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
1692 #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
1693 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
1695 #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
1697 #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
1698 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
1700 #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
1702 #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
1703 #undef JSON_HEDLEY_CLANG_HAS_WARNING
1705 #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
1707 #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
1710 // This file contains all internal macro definitions
1711 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
1713 // exclude unsupported compilers
1714 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
1715 #if defined(__clang__)
1716 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
1717 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
1719 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
1720 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
1721 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
1726 // C++ language standard detection
1727 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
1728 #define JSON_HAS_CPP_17
1729 #define JSON_HAS_CPP_14
1730 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
1731 #define JSON_HAS_CPP_14
1734 // disable float-equal warnings on GCC/clang
1735 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
1736 #pragma GCC diagnostic push
1737 #pragma GCC diagnostic ignored "-Wfloat-equal"
1740 // disable documentation warnings on clang
1741 #if defined(__clang__)
1742 #pragma GCC diagnostic push
1743 #pragma GCC diagnostic ignored "-Wdocumentation"
1746 // allow to disable exceptions
1747 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
1748 #define JSON_THROW(exception) throw exception
1749 #define JSON_TRY try
1750 #define JSON_CATCH(exception) catch(exception)
1751 #define JSON_INTERNAL_CATCH(exception) catch(exception)
1754 #define JSON_THROW(exception) std::abort()
1755 #define JSON_TRY if(true)
1756 #define JSON_CATCH(exception) if(false)
1757 #define JSON_INTERNAL_CATCH(exception) if(false)
1760 // override exception macros
1761 #if defined(JSON_THROW_USER)
1763 #define JSON_THROW JSON_THROW_USER
1765 #if defined(JSON_TRY_USER)
1767 #define JSON_TRY JSON_TRY_USER
1769 #if defined(JSON_CATCH_USER)
1771 #define JSON_CATCH JSON_CATCH_USER
1772 #undef JSON_INTERNAL_CATCH
1773 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
1775 #if defined(JSON_INTERNAL_CATCH_USER)
1776 #undef JSON_INTERNAL_CATCH
1777 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
1781 @brief macro to briefly define a mapping between an enum and JSON
1782 @def NLOHMANN_JSON_SERIALIZE_ENUM
1783 @since version 3.4.0
1785 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
1786 template<typename BasicJsonType> \
1787 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
1789 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
1790 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
1791 auto it = std::find_if(std::begin(m), std::end(m), \
1792 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
1794 return ej_pair.first == e; \
1796 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
1798 template<typename BasicJsonType> \
1799 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
1801 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
1802 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
1803 auto it = std::find_if(std::begin(m), std::end(m), \
1804 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
1806 return ej_pair.second == j; \
1808 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
1811 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
1812 // may be removed in the future once the class is split.
1814 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
1815 template<template<typename, typename, typename...> class ObjectType, \
1816 template<typename, typename...> class ArrayType, \
1817 class StringType, class BooleanType, class NumberIntegerType, \
1818 class NumberUnsignedType, class NumberFloatType, \
1819 template<typename> class AllocatorType, \
1820 template<typename, typename = void> class JSONSerializer>
1822 #define NLOHMANN_BASIC_JSON_TPL \
1823 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
1824 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
1825 AllocatorType, JSONSerializer>
1837 @brief general exception of the @ref basic_json class
1839 This class is an extension of `std::exception` objects with a member @a id for
1840 exception ids. It is used as the base class for all exceptions thrown by the
1841 @ref basic_json class. This class can hence be used as "wildcard" to catch
1845 - @ref parse_error for exceptions indicating a parse error
1846 - @ref invalid_iterator for exceptions indicating errors with iterators
1847 - @ref type_error for exceptions indicating executing a member function with
1849 - @ref out_of_range for exceptions indicating access out of the defined range
1850 - @ref other_error for exceptions indicating other library errors
1853 @note To have nothrow-copy-constructible exceptions, we internally use
1854 `std::runtime_error` which can cope with arbitrary-length error messages.
1855 Intermediate strings are built with static functions and then passed to
1856 the actual constructor.
1859 @liveexample{The following code shows how arbitrary library exceptions can be
1862 @since version 3.0.0
1864 class exception : public std::exception
1867 /// returns the explanatory string
1868 JSON_HEDLEY_RETURNS_NON_NULL
1869 const char* what() const noexcept override
1874 /// the id of the exception
1878 JSON_HEDLEY_NON_NULL(3)
1879 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
1881 static std::string name(const std::string& ename, int id_)
1883 return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
1887 /// an exception object as storage for error messages
1888 std::runtime_error m;
1892 @brief exception indicating a parse error
1894 This exception is thrown by the library when a parse error occurs. Parse errors
1895 can occur during the deserialization of JSON text, CBOR, MessagePack, as well
1896 as when using JSON Patch.
1898 Member @a byte holds the byte index of the last read character in the input
1901 Exceptions have ids 1xx.
1903 name / id | example message | description
1904 ------------------------------ | --------------- | -------------------------
1905 json.exception.parse_error.101 | parse error at 2: unexpected end of input; expected string literal | This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member @a byte indicates the error position.
1906 json.exception.parse_error.102 | parse error at 14: missing or wrong low surrogate | JSON uses the `\uxxxx` format to describe Unicode characters. Code points above above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point.
1907 json.exception.parse_error.103 | parse error: code points above 0x10FFFF are invalid | Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid.
1908 json.exception.parse_error.104 | parse error: JSON patch must be an array of objects | [RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects.
1909 json.exception.parse_error.105 | parse error: operation must have string member 'op' | An operation of a JSON Patch document must contain exactly one "op" member, whose value indicates the operation to perform. Its value must be one of "add", "remove", "replace", "move", "copy", or "test"; other values are errors.
1910 json.exception.parse_error.106 | parse error: array index '01' must not begin with '0' | An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`.
1911 json.exception.parse_error.107 | parse error: JSON pointer must be empty or begin with '/' - was: 'foo' | A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character.
1912 json.exception.parse_error.108 | parse error: escape character '~' must be followed with '0' or '1' | In a JSON Pointer, only `~0` and `~1` are valid escape sequences.
1913 json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
1914 json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read.
1915 json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xF8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read.
1916 json.exception.parse_error.113 | parse error at 2: expected a CBOR string; last byte: 0x98 | While parsing a map key, a value that is not a string has been read.
1917 json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet).
1919 @note For an input with n bytes, 1 is the index of the first character and n+1
1920 is the index of the terminating null byte or the end of file. This also
1921 holds true when reading a byte vector (CBOR or MessagePack).
1923 @liveexample{The following code shows how a `parse_error` exception can be
1924 caught.,parse_error}
1926 @sa - @ref exception for the base class of the library exceptions
1927 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
1928 @sa - @ref type_error for exceptions indicating executing a member function with
1930 @sa - @ref out_of_range for exceptions indicating access out of the defined range
1931 @sa - @ref other_error for exceptions indicating other library errors
1933 @since version 3.0.0
1935 class parse_error : public exception
1939 @brief create a parse error exception
1940 @param[in] id_ the id of the exception
1941 @param[in] pos the position where the error occurred (or with
1942 chars_read_total=0 if the position cannot be
1944 @param[in] what_arg the explanatory string
1945 @return parse_error object
1947 static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
1949 std::string w = exception::name("parse_error", id_) + "parse error" +
1950 position_string(pos) + ": " + what_arg;
1951 return parse_error(id_, pos.chars_read_total, w.c_str());
1954 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
1956 std::string w = exception::name("parse_error", id_) + "parse error" +
1957 (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
1959 return parse_error(id_, byte_, w.c_str());
1963 @brief byte index of the parse error
1965 The byte index of the last read character in the input file.
1967 @note For an input with n bytes, 1 is the index of the first character and
1968 n+1 is the index of the terminating null byte or the end of file.
1969 This also holds true when reading a byte vector (CBOR or MessagePack).
1971 const std::size_t byte;
1974 parse_error(int id_, std::size_t byte_, const char* what_arg)
1975 : exception(id_, what_arg), byte(byte_) {}
1977 static std::string position_string(const position_t& pos)
1979 return " at line " + std::to_string(pos.lines_read + 1) +
1980 ", column " + std::to_string(pos.chars_read_current_line);
1985 @brief exception indicating errors with iterators
1987 This exception is thrown if iterators passed to a library function do not match
1988 the expected semantics.
1990 Exceptions have ids 2xx.
1992 name / id | example message | description
1993 ----------------------------------- | --------------- | -------------------------
1994 json.exception.invalid_iterator.201 | iterators are not compatible | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.
1995 json.exception.invalid_iterator.202 | iterator does not fit current value | In an erase or insert function, the passed iterator @a pos does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion.
1996 json.exception.invalid_iterator.203 | iterators do not fit current value | Either iterator passed to function @ref erase(IteratorType first, IteratorType last) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from.
1997 json.exception.invalid_iterator.204 | iterators out of range | When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase function, this range has to be exactly (@ref begin(), @ref end()), because this is the only way the single stored value is expressed. All other ranges are invalid.
1998 json.exception.invalid_iterator.205 | iterator out of range | When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the @ref begin() iterator, because it is the only way to address the stored value. All other iterators are invalid.
1999 json.exception.invalid_iterator.206 | cannot construct with iterators from null | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) belong to a JSON null value and hence to not define a valid range.
2000 json.exception.invalid_iterator.207 | cannot use key() for non-object iterators | The key() member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key.
2001 json.exception.invalid_iterator.208 | cannot use operator[] for object iterators | The operator[] to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
2002 json.exception.invalid_iterator.209 | cannot use offsets with object iterators | The offset operators (+, -, +=, -=) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
2003 json.exception.invalid_iterator.210 | iterators do not fit | The iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.
2004 json.exception.invalid_iterator.211 | passed iterators may not belong to container | The iterator range passed to the insert function must not be a subrange of the container to insert to.
2005 json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
2006 json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
2007 json.exception.invalid_iterator.214 | cannot get value | Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to @ref begin().
2009 @liveexample{The following code shows how an `invalid_iterator` exception can be
2010 caught.,invalid_iterator}
2012 @sa - @ref exception for the base class of the library exceptions
2013 @sa - @ref parse_error for exceptions indicating a parse error
2014 @sa - @ref type_error for exceptions indicating executing a member function with
2016 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2017 @sa - @ref other_error for exceptions indicating other library errors
2019 @since version 3.0.0
2021 class invalid_iterator : public exception
2024 static invalid_iterator create(int id_, const std::string& what_arg)
2026 std::string w = exception::name("invalid_iterator", id_) + what_arg;
2027 return invalid_iterator(id_, w.c_str());
2031 JSON_HEDLEY_NON_NULL(3)
2032 invalid_iterator(int id_, const char* what_arg)
2033 : exception(id_, what_arg) {}
2037 @brief exception indicating executing a member function with a wrong type
2039 This exception is thrown in case of a type error; that is, a library function is
2040 executed on a JSON value whose type does not match the expected semantics.
2042 Exceptions have ids 3xx.
2044 name / id | example message | description
2045 ----------------------------- | --------------- | -------------------------
2046 json.exception.type_error.301 | cannot create object from initializer list | To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead.
2047 json.exception.type_error.302 | type must be object, but is array | During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types.
2048 json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t &.
2049 json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
2050 json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
2051 json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
2052 json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
2053 json.exception.type_error.308 | cannot use push_back() with string | The @ref push_back() and @ref operator+= member functions can only be executed for certain JSON types.
2054 json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
2055 json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
2056 json.exception.type_error.311 | cannot use emplace_back() with string | The @ref emplace_back() member function can only be executed for certain JSON types.
2057 json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
2058 json.exception.type_error.313 | invalid value to unflatten | The @ref unflatten function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well defined.
2059 json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
2060 json.exception.type_error.315 | values in object must be primitive | The @ref unflatten function only works for an object whose keys are JSON Pointers and whose values are primitive.
2061 json.exception.type_error.316 | invalid UTF-8 byte at index 10: 0x7E | The @ref dump function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. |
2062 json.exception.type_error.317 | JSON value cannot be serialized to requested format | The dynamic type of the object cannot be represented in the requested serialization format (e.g. a raw `true` or `null` JSON object cannot be serialized to BSON) |
2064 @liveexample{The following code shows how a `type_error` exception can be
2067 @sa - @ref exception for the base class of the library exceptions
2068 @sa - @ref parse_error for exceptions indicating a parse error
2069 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2070 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2071 @sa - @ref other_error for exceptions indicating other library errors
2073 @since version 3.0.0
2075 class type_error : public exception
2078 static type_error create(int id_, const std::string& what_arg)
2080 std::string w = exception::name("type_error", id_) + what_arg;
2081 return type_error(id_, w.c_str());
2085 JSON_HEDLEY_NON_NULL(3)
2086 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2090 @brief exception indicating access out of the defined range
2092 This exception is thrown in case a library function is called on an input
2093 parameter that exceeds the expected range, for instance in case of array
2094 indices or nonexisting object keys.
2096 Exceptions have ids 4xx.
2098 name / id | example message | description
2099 ------------------------------- | --------------- | -------------------------
2100 json.exception.out_of_range.401 | array index 3 is out of range | The provided array index @a i is larger than @a size-1.
2101 json.exception.out_of_range.402 | array index '-' (3) is out of range | The special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it.
2102 json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
2103 json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
2104 json.exception.out_of_range.405 | JSON pointer has no parent | The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value.
2105 json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF.
2106 json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. |
2107 json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |
2108 json.exception.out_of_range.409 | BSON key cannot contain code point U+0000 (at byte 2) | Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string |
2110 @liveexample{The following code shows how an `out_of_range` exception can be
2111 caught.,out_of_range}
2113 @sa - @ref exception for the base class of the library exceptions
2114 @sa - @ref parse_error for exceptions indicating a parse error
2115 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2116 @sa - @ref type_error for exceptions indicating executing a member function with
2118 @sa - @ref other_error for exceptions indicating other library errors
2120 @since version 3.0.0
2122 class out_of_range : public exception
2125 static out_of_range create(int id_, const std::string& what_arg)
2127 std::string w = exception::name("out_of_range", id_) + what_arg;
2128 return out_of_range(id_, w.c_str());
2132 JSON_HEDLEY_NON_NULL(3)
2133 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
2137 @brief exception indicating other library errors
2139 This exception is thrown in case of errors that cannot be classified with the
2140 other exception types.
2142 Exceptions have ids 5xx.
2144 name / id | example message | description
2145 ------------------------------ | --------------- | -------------------------
2146 json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
2148 @sa - @ref exception for the base class of the library exceptions
2149 @sa - @ref parse_error for exceptions indicating a parse error
2150 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2151 @sa - @ref type_error for exceptions indicating executing a member function with
2153 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2155 @liveexample{The following code shows how an `other_error` exception can be
2156 caught.,other_error}
2158 @since version 3.0.0
2160 class other_error : public exception
2163 static other_error create(int id_, const std::string& what_arg)
2165 std::string w = exception::name("other_error", id_) + what_arg;
2166 return other_error(id_, w.c_str());
2170 JSON_HEDLEY_NON_NULL(3)
2171 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2173 } // namespace detail
2174 } // namespace nlohmann
2176 // #include <nlohmann/detail/macro_scope.hpp>
2178 // #include <nlohmann/detail/meta/cpp_future.hpp>
2181 #include <ciso646> // not
2182 #include <cstddef> // size_t
2183 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
2189 // alias templates to reduce boilerplate
2190 template<bool B, typename T = void>
2191 using enable_if_t = typename std::enable_if<B, T>::type;
2193 template<typename T>
2194 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
2196 // implementation of C++14 index_sequence and affiliates
2197 // source: https://stackoverflow.com/a/32223343
2198 template<std::size_t... Ints>
2199 struct index_sequence
2201 using type = index_sequence;
2202 using value_type = std::size_t;
2203 static constexpr std::size_t size() noexcept
2205 return sizeof...(Ints);
2209 template<class Sequence1, class Sequence2>
2210 struct merge_and_renumber;
2212 template<std::size_t... I1, std::size_t... I2>
2213 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
2214 : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
2216 template<std::size_t N>
2217 struct make_index_sequence
2218 : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
2219 typename make_index_sequence < N - N / 2 >::type > {};
2221 template<> struct make_index_sequence<0> : index_sequence<> {};
2222 template<> struct make_index_sequence<1> : index_sequence<0> {};
2224 template<typename... Ts>
2225 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
2227 // dispatch utility (taken from ranges-v3)
2228 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
2229 template<> struct priority_tag<0> {};
2231 // taken from ranges-v3
2232 template<typename T>
2235 static constexpr T value{};
2238 template<typename T>
2239 constexpr T static_const<T>::value;
2240 } // namespace detail
2241 } // namespace nlohmann
2243 // #include <nlohmann/detail/meta/type_traits.hpp>
2246 #include <ciso646> // not
2247 #include <limits> // numeric_limits
2248 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
2249 #include <utility> // declval
2251 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
2254 #include <iterator> // random_access_iterator_tag
2256 // #include <nlohmann/detail/meta/void_t.hpp>
2263 template <typename ...Ts> struct make_void
2267 template <typename ...Ts> using void_t = typename make_void<Ts...>::type;
2268 } // namespace detail
2269 } // namespace nlohmann
2271 // #include <nlohmann/detail/meta/cpp_future.hpp>
2278 template <typename It, typename = void>
2279 struct iterator_types {};
2281 template <typename It>
2282 struct iterator_types <
2284 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
2285 typename It::reference, typename It::iterator_category >>
2287 using difference_type = typename It::difference_type;
2288 using value_type = typename It::value_type;
2289 using pointer = typename It::pointer;
2290 using reference = typename It::reference;
2291 using iterator_category = typename It::iterator_category;
2294 // This is required as some compilers implement std::iterator_traits in a way that
2295 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
2296 template <typename T, typename = void>
2297 struct iterator_traits
2301 template <typename T>
2302 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
2307 template <typename T>
2308 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
2310 using iterator_category = std::random_access_iterator_tag;
2311 using value_type = T;
2312 using difference_type = ptrdiff_t;
2314 using reference = T&;
2316 } // namespace detail
2317 } // namespace nlohmann
2319 // #include <nlohmann/detail/macro_scope.hpp>
2321 // #include <nlohmann/detail/meta/cpp_future.hpp>
2323 // #include <nlohmann/detail/meta/detected.hpp>
2326 #include <type_traits>
2328 // #include <nlohmann/detail/meta/void_t.hpp>
2331 // http://en.cppreference.com/w/cpp/experimental/is_detected
2338 nonesuch() = delete;
2339 ~nonesuch() = delete;
2340 nonesuch(nonesuch const&) = delete;
2341 nonesuch(nonesuch const&&) = delete;
2342 void operator=(nonesuch const&) = delete;
2343 void operator=(nonesuch&&) = delete;
2346 template <class Default,
2348 template <class...> class Op,
2352 using value_t = std::false_type;
2353 using type = Default;
2356 template <class Default, template <class...> class Op, class... Args>
2357 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2359 using value_t = std::true_type;
2360 using type = Op<Args...>;
2363 template <template <class...> class Op, class... Args>
2364 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2366 template <template <class...> class Op, class... Args>
2367 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2369 template <class Default, template <class...> class Op, class... Args>
2370 using detected_or = detector<Default, void, Op, Args...>;
2372 template <class Default, template <class...> class Op, class... Args>
2373 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2375 template <class Expected, template <class...> class Op, class... Args>
2376 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2378 template <class To, template <class...> class Op, class... Args>
2379 using is_detected_convertible =
2380 std::is_convertible<detected_t<Op, Args...>, To>;
2381 } // namespace detail
2382 } // namespace nlohmann
2384 // #include <nlohmann/json_fwd.hpp>
2385 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
2386 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
2388 #include <cstdint> // int64_t, uint64_t
2389 #include <map> // map
2390 #include <memory> // allocator
2391 #include <string> // string
2392 #include <vector> // vector
2395 @brief namespace for Niels Lohmann
2396 @see https://github.com/nlohmann
2397 @since version 1.0.0
2402 @brief default JSONSerializer template argument
2404 This serializer ignores the template arguments and uses ADL
2405 ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
2408 template<typename T = void, typename SFINAE = void>
2409 struct adl_serializer;
2411 template<template<typename U, typename V, typename... Args> class ObjectType =
2413 template<typename U, typename... Args> class ArrayType = std::vector,
2414 class StringType = std::string, class BooleanType = bool,
2415 class NumberIntegerType = std::int64_t,
2416 class NumberUnsignedType = std::uint64_t,
2417 class NumberFloatType = double,
2418 template<typename U> class AllocatorType = std::allocator,
2419 template<typename T, typename SFINAE = void> class JSONSerializer =
2426 A JSON pointer defines a string syntax for identifying a specific value
2427 within a JSON document. It can be used with functions `at` and
2428 `operator[]`. Furthermore, JSON pointers are the base for JSON patches.
2430 @sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
2432 @since version 2.0.0
2434 template<typename BasicJsonType>
2438 @brief default JSON class
2440 This type is the default specialization of the @ref basic_json class which
2441 uses the standard template types.
2443 @since version 1.0.0
2445 using json = basic_json<>;
2446 } // namespace nlohmann
2448 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
2454 @brief detail namespace with internal helper functions
2456 This namespace collects functions that should not be exposed,
2457 implementations of some @ref basic_json methods, and meta-programming helpers.
2459 @since version 2.1.0
2467 // Note to maintainers:
2469 // Every trait in this file expects a non CV-qualified type.
2470 // The only exceptions are in the 'aliases for detected' section
2471 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
2473 // In this case, T has to be properly CV-qualified to constraint the function arguments
2474 // (e.g. to_json(BasicJsonType&, const T&))
2476 template<typename> struct is_basic_json : std::false_type {};
2478 NLOHMANN_BASIC_JSON_TPL_DECLARATION
2479 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
2481 //////////////////////////
2482 // aliases for detected //
2483 //////////////////////////
2485 template <typename T>
2486 using mapped_type_t = typename T::mapped_type;
2488 template <typename T>
2489 using key_type_t = typename T::key_type;
2491 template <typename T>
2492 using value_type_t = typename T::value_type;
2494 template <typename T>
2495 using difference_type_t = typename T::difference_type;
2497 template <typename T>
2498 using pointer_t = typename T::pointer;
2500 template <typename T>
2501 using reference_t = typename T::reference;
2503 template <typename T>
2504 using iterator_category_t = typename T::iterator_category;
2506 template <typename T>
2507 using iterator_t = typename T::iterator;
2509 template <typename T, typename... Args>
2510 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
2512 template <typename T, typename... Args>
2513 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
2515 template <typename T, typename U>
2516 using get_template_function = decltype(std::declval<T>().template get<U>());
2518 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
2519 template <typename BasicJsonType, typename T, typename = void>
2520 struct has_from_json : std::false_type {};
2522 template <typename BasicJsonType, typename T>
2523 struct has_from_json<BasicJsonType, T,
2524 enable_if_t<not is_basic_json<T>::value>>
2526 using serializer = typename BasicJsonType::template json_serializer<T, void>;
2528 static constexpr bool value =
2529 is_detected_exact<void, from_json_function, serializer,
2530 const BasicJsonType&, T&>::value;
2533 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
2534 // this overload is used for non-default-constructible user-defined-types
2535 template <typename BasicJsonType, typename T, typename = void>
2536 struct has_non_default_from_json : std::false_type {};
2538 template<typename BasicJsonType, typename T>
2539 struct has_non_default_from_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
2541 using serializer = typename BasicJsonType::template json_serializer<T, void>;
2543 static constexpr bool value =
2544 is_detected_exact<T, from_json_function, serializer,
2545 const BasicJsonType&>::value;
2548 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
2549 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
2550 template <typename BasicJsonType, typename T, typename = void>
2551 struct has_to_json : std::false_type {};
2553 template <typename BasicJsonType, typename T>
2554 struct has_to_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
2556 using serializer = typename BasicJsonType::template json_serializer<T, void>;
2558 static constexpr bool value =
2559 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
2568 template <typename T, typename = void>
2569 struct is_iterator_traits : std::false_type {};
2571 template <typename T>
2572 struct is_iterator_traits<iterator_traits<T>>
2575 using traits = iterator_traits<T>;
2578 static constexpr auto value =
2579 is_detected<value_type_t, traits>::value &&
2580 is_detected<difference_type_t, traits>::value &&
2581 is_detected<pointer_t, traits>::value &&
2582 is_detected<iterator_category_t, traits>::value &&
2583 is_detected<reference_t, traits>::value;
2586 // source: https://stackoverflow.com/a/37193089/4116453
2588 template <typename T, typename = void>
2589 struct is_complete_type : std::false_type {};
2591 template <typename T>
2592 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
2594 template <typename BasicJsonType, typename CompatibleObjectType,
2596 struct is_compatible_object_type_impl : std::false_type {};
2598 template <typename BasicJsonType, typename CompatibleObjectType>
2599 struct is_compatible_object_type_impl <
2600 BasicJsonType, CompatibleObjectType,
2601 enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value and
2602 is_detected<key_type_t, CompatibleObjectType>::value >>
2605 using object_t = typename BasicJsonType::object_t;
2607 // macOS's is_constructible does not play well with nonesuch...
2608 static constexpr bool value =
2609 std::is_constructible<typename object_t::key_type,
2610 typename CompatibleObjectType::key_type>::value and
2611 std::is_constructible<typename object_t::mapped_type,
2612 typename CompatibleObjectType::mapped_type>::value;
2615 template <typename BasicJsonType, typename CompatibleObjectType>
2616 struct is_compatible_object_type
2617 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
2619 template <typename BasicJsonType, typename ConstructibleObjectType,
2621 struct is_constructible_object_type_impl : std::false_type {};
2623 template <typename BasicJsonType, typename ConstructibleObjectType>
2624 struct is_constructible_object_type_impl <
2625 BasicJsonType, ConstructibleObjectType,
2626 enable_if_t<is_detected<mapped_type_t, ConstructibleObjectType>::value and
2627 is_detected<key_type_t, ConstructibleObjectType>::value >>
2629 using object_t = typename BasicJsonType::object_t;
2631 static constexpr bool value =
2632 (std::is_default_constructible<ConstructibleObjectType>::value and
2633 (std::is_move_assignable<ConstructibleObjectType>::value or
2634 std::is_copy_assignable<ConstructibleObjectType>::value) and
2635 (std::is_constructible<typename ConstructibleObjectType::key_type,
2636 typename object_t::key_type>::value and
2638 typename object_t::mapped_type,
2639 typename ConstructibleObjectType::mapped_type >::value)) or
2640 (has_from_json<BasicJsonType,
2641 typename ConstructibleObjectType::mapped_type>::value or
2642 has_non_default_from_json <
2644 typename ConstructibleObjectType::mapped_type >::value);
2647 template <typename BasicJsonType, typename ConstructibleObjectType>
2648 struct is_constructible_object_type
2649 : is_constructible_object_type_impl<BasicJsonType,
2650 ConstructibleObjectType> {};
2652 template <typename BasicJsonType, typename CompatibleStringType,
2654 struct is_compatible_string_type_impl : std::false_type {};
2656 template <typename BasicJsonType, typename CompatibleStringType>
2657 struct is_compatible_string_type_impl <
2658 BasicJsonType, CompatibleStringType,
2659 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
2660 value_type_t, CompatibleStringType>::value >>
2662 static constexpr auto value =
2663 std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
2666 template <typename BasicJsonType, typename ConstructibleStringType>
2667 struct is_compatible_string_type
2668 : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
2670 template <typename BasicJsonType, typename ConstructibleStringType,
2672 struct is_constructible_string_type_impl : std::false_type {};
2674 template <typename BasicJsonType, typename ConstructibleStringType>
2675 struct is_constructible_string_type_impl <
2676 BasicJsonType, ConstructibleStringType,
2677 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
2678 value_type_t, ConstructibleStringType>::value >>
2680 static constexpr auto value =
2681 std::is_constructible<ConstructibleStringType,
2682 typename BasicJsonType::string_t>::value;
2685 template <typename BasicJsonType, typename ConstructibleStringType>
2686 struct is_constructible_string_type
2687 : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
2689 template <typename BasicJsonType, typename CompatibleArrayType, typename = void>
2690 struct is_compatible_array_type_impl : std::false_type {};
2692 template <typename BasicJsonType, typename CompatibleArrayType>
2693 struct is_compatible_array_type_impl <
2694 BasicJsonType, CompatibleArrayType,
2695 enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value and
2696 is_detected<iterator_t, CompatibleArrayType>::value and
2697 // This is needed because json_reverse_iterator has a ::iterator type...
2698 // Therefore it is detected as a CompatibleArrayType.
2699 // The real fix would be to have an Iterable concept.
2700 not is_iterator_traits<
2701 iterator_traits<CompatibleArrayType>>::value >>
2703 static constexpr bool value =
2704 std::is_constructible<BasicJsonType,
2705 typename CompatibleArrayType::value_type>::value;
2708 template <typename BasicJsonType, typename CompatibleArrayType>
2709 struct is_compatible_array_type
2710 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
2712 template <typename BasicJsonType, typename ConstructibleArrayType, typename = void>
2713 struct is_constructible_array_type_impl : std::false_type {};
2715 template <typename BasicJsonType, typename ConstructibleArrayType>
2716 struct is_constructible_array_type_impl <
2717 BasicJsonType, ConstructibleArrayType,
2718 enable_if_t<std::is_same<ConstructibleArrayType,
2719 typename BasicJsonType::value_type>::value >>
2720 : std::true_type {};
2722 template <typename BasicJsonType, typename ConstructibleArrayType>
2723 struct is_constructible_array_type_impl <
2724 BasicJsonType, ConstructibleArrayType,
2725 enable_if_t<not std::is_same<ConstructibleArrayType,
2726 typename BasicJsonType::value_type>::value and
2727 std::is_default_constructible<ConstructibleArrayType>::value and
2728 (std::is_move_assignable<ConstructibleArrayType>::value or
2729 std::is_copy_assignable<ConstructibleArrayType>::value) and
2730 is_detected<value_type_t, ConstructibleArrayType>::value and
2731 is_detected<iterator_t, ConstructibleArrayType>::value and
2733 detected_t<value_type_t, ConstructibleArrayType>>::value >>
2735 static constexpr bool value =
2736 // This is needed because json_reverse_iterator has a ::iterator type,
2737 // furthermore, std::back_insert_iterator (and other iterators) have a
2738 // base class `iterator`... Therefore it is detected as a
2739 // ConstructibleArrayType. The real fix would be to have an Iterable
2741 not is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value and
2743 (std::is_same<typename ConstructibleArrayType::value_type,
2744 typename BasicJsonType::array_t::value_type>::value or
2745 has_from_json<BasicJsonType,
2746 typename ConstructibleArrayType::value_type>::value or
2747 has_non_default_from_json <
2748 BasicJsonType, typename ConstructibleArrayType::value_type >::value);
2751 template <typename BasicJsonType, typename ConstructibleArrayType>
2752 struct is_constructible_array_type
2753 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
2755 template <typename RealIntegerType, typename CompatibleNumberIntegerType,
2757 struct is_compatible_integer_type_impl : std::false_type {};
2759 template <typename RealIntegerType, typename CompatibleNumberIntegerType>
2760 struct is_compatible_integer_type_impl <
2761 RealIntegerType, CompatibleNumberIntegerType,
2762 enable_if_t<std::is_integral<RealIntegerType>::value and
2763 std::is_integral<CompatibleNumberIntegerType>::value and
2764 not std::is_same<bool, CompatibleNumberIntegerType>::value >>
2766 // is there an assert somewhere on overflows?
2767 using RealLimits = std::numeric_limits<RealIntegerType>;
2768 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
2770 static constexpr auto value =
2771 std::is_constructible<RealIntegerType,
2772 CompatibleNumberIntegerType>::value and
2773 CompatibleLimits::is_integer and
2774 RealLimits::is_signed == CompatibleLimits::is_signed;
2777 template <typename RealIntegerType, typename CompatibleNumberIntegerType>
2778 struct is_compatible_integer_type
2779 : is_compatible_integer_type_impl<RealIntegerType,
2780 CompatibleNumberIntegerType> {};
2782 template <typename BasicJsonType, typename CompatibleType, typename = void>
2783 struct is_compatible_type_impl: std::false_type {};
2785 template <typename BasicJsonType, typename CompatibleType>
2786 struct is_compatible_type_impl <
2787 BasicJsonType, CompatibleType,
2788 enable_if_t<is_complete_type<CompatibleType>::value >>
2790 static constexpr bool value =
2791 has_to_json<BasicJsonType, CompatibleType>::value;
2794 template <typename BasicJsonType, typename CompatibleType>
2795 struct is_compatible_type
2796 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
2798 // https://en.cppreference.com/w/cpp/types/conjunction
2799 template<class...> struct conjunction : std::true_type { };
2800 template<class B1> struct conjunction<B1> : B1 { };
2801 template<class B1, class... Bn>
2802 struct conjunction<B1, Bn...>
2803 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
2805 template <typename T1, typename T2>
2806 struct is_constructible_tuple : std::false_type {};
2808 template <typename T1, typename... Args>
2809 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<std::is_constructible<T1, Args>...> {};
2810 } // namespace detail
2811 } // namespace nlohmann
2813 // #include <nlohmann/detail/value_t.hpp>
2816 #include <array> // array
2817 #include <ciso646> // and
2818 #include <cstddef> // size_t
2819 #include <cstdint> // uint8_t
2820 #include <string> // string
2826 ///////////////////////////
2827 // JSON type enumeration //
2828 ///////////////////////////
2831 @brief the JSON type enumeration
2833 This enumeration collects the different JSON types. It is internally used to
2834 distinguish the stored values, and the functions @ref basic_json::is_null(),
2835 @ref basic_json::is_object(), @ref basic_json::is_array(),
2836 @ref basic_json::is_string(), @ref basic_json::is_boolean(),
2837 @ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
2838 @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
2839 @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
2840 @ref basic_json::is_structured() rely on it.
2842 @note There are three enumeration entries (number_integer, number_unsigned, and
2843 number_float), because the library distinguishes these three types for numbers:
2844 @ref basic_json::number_unsigned_t is used for unsigned integers,
2845 @ref basic_json::number_integer_t is used for signed integers, and
2846 @ref basic_json::number_float_t is used for floating-point numbers or to
2847 approximate integers which do not fit in the limits of their respective type.
2849 @sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
2850 value with the default value for a given type
2852 @since version 1.0.0
2854 enum class value_t : std::uint8_t
2856 null, ///< null value
2857 object, ///< object (unordered set of name/value pairs)
2858 array, ///< array (ordered collection of values)
2859 string, ///< string value
2860 boolean, ///< boolean value
2861 number_integer, ///< number value (signed integer)
2862 number_unsigned, ///< number value (unsigned integer)
2863 number_float, ///< number value (floating-point)
2864 discarded ///< discarded by the the parser callback function
2868 @brief comparison operator for JSON types
2870 Returns an ordering that is similar to Python:
2871 - order: null < boolean < number < object < array < string
2872 - furthermore, each type is not smaller than itself
2873 - discarded values are not comparable
2875 @since version 1.0.0
2877 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2879 static constexpr std::array<std::uint8_t, 8> order = {{
2880 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
2881 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */
2885 const auto l_index = static_cast<std::size_t>(lhs);
2886 const auto r_index = static_cast<std::size_t>(rhs);
2887 return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
2889 } // namespace detail
2890 } // namespace nlohmann
2897 template<typename BasicJsonType>
2898 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
2900 if (JSON_HEDLEY_UNLIKELY(not j.is_null()))
2902 JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
2907 // overloads for basic_json template parameters
2908 template<typename BasicJsonType, typename ArithmeticType,
2909 enable_if_t<std::is_arithmetic<ArithmeticType>::value and
2910 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
2912 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
2914 switch (static_cast<value_t>(j))
2916 case value_t::number_unsigned:
2918 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
2921 case value_t::number_integer:
2923 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
2926 case value_t::number_float:
2928 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
2933 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
2937 template<typename BasicJsonType>
2938 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
2940 if (JSON_HEDLEY_UNLIKELY(not j.is_boolean()))
2942 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
2944 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
2947 template<typename BasicJsonType>
2948 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
2950 if (JSON_HEDLEY_UNLIKELY(not j.is_string()))
2952 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
2954 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
2958 typename BasicJsonType, typename ConstructibleStringType,
2960 is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value and
2961 not std::is_same<typename BasicJsonType::string_t,
2962 ConstructibleStringType>::value,
2964 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
2966 if (JSON_HEDLEY_UNLIKELY(not j.is_string()))
2968 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
2971 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
2974 template<typename BasicJsonType>
2975 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
2977 get_arithmetic_value(j, val);
2980 template<typename BasicJsonType>
2981 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
2983 get_arithmetic_value(j, val);
2986 template<typename BasicJsonType>
2987 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
2989 get_arithmetic_value(j, val);
2992 template<typename BasicJsonType, typename EnumType,
2993 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
2994 void from_json(const BasicJsonType& j, EnumType& e)
2996 typename std::underlying_type<EnumType>::type val;
2997 get_arithmetic_value(j, val);
2998 e = static_cast<EnumType>(val);
3001 // forward_list doesn't have an insert method
3002 template<typename BasicJsonType, typename T, typename Allocator,
3003 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
3004 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
3006 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3008 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3011 std::transform(j.rbegin(), j.rend(),
3012 std::front_inserter(l), [](const BasicJsonType & i)
3014 return i.template get<T>();
3018 // valarray doesn't have an insert method
3019 template<typename BasicJsonType, typename T,
3020 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
3021 void from_json(const BasicJsonType& j, std::valarray<T>& l)
3023 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3025 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3028 std::copy(j.begin(), j.end(), std::begin(l));
3031 template <typename BasicJsonType, typename T, std::size_t N>
3032 auto from_json(const BasicJsonType& j, T (&arr)[N])
3033 -> decltype(j.template get<T>(), void())
3035 for (std::size_t i = 0; i < N; ++i)
3037 arr[i] = j.at(i).template get<T>();
3041 template<typename BasicJsonType>
3042 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
3044 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
3047 template <typename BasicJsonType, typename T, std::size_t N>
3048 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
3049 priority_tag<2> /*unused*/)
3050 -> decltype(j.template get<T>(), void())
3052 for (std::size_t i = 0; i < N; ++i)
3054 arr[i] = j.at(i).template get<T>();
3058 template<typename BasicJsonType, typename ConstructibleArrayType>
3059 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
3061 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
3062 j.template get<typename ConstructibleArrayType::value_type>(),
3067 ConstructibleArrayType ret;
3068 ret.reserve(j.size());
3069 std::transform(j.begin(), j.end(),
3070 std::inserter(ret, end(ret)), [](const BasicJsonType & i)
3072 // get<BasicJsonType>() returns *this, this won't call a from_json
3073 // method when value_type is BasicJsonType
3074 return i.template get<typename ConstructibleArrayType::value_type>();
3076 arr = std::move(ret);
3079 template <typename BasicJsonType, typename ConstructibleArrayType>
3080 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
3081 priority_tag<0> /*unused*/)
3085 ConstructibleArrayType ret;
3087 j.begin(), j.end(), std::inserter(ret, end(ret)),
3088 [](const BasicJsonType & i)
3090 // get<BasicJsonType>() returns *this, this won't call a from_json
3091 // method when value_type is BasicJsonType
3092 return i.template get<typename ConstructibleArrayType::value_type>();
3094 arr = std::move(ret);
3097 template <typename BasicJsonType, typename ConstructibleArrayType,
3099 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value and
3100 not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value and
3101 not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value and
3102 not is_basic_json<ConstructibleArrayType>::value,
3105 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
3106 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
3107 j.template get<typename ConstructibleArrayType::value_type>(),
3110 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3112 JSON_THROW(type_error::create(302, "type must be array, but is " +
3113 std::string(j.type_name())));
3116 from_json_array_impl(j, arr, priority_tag<3> {});
3119 template<typename BasicJsonType, typename ConstructibleObjectType,
3120 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
3121 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
3123 if (JSON_HEDLEY_UNLIKELY(not j.is_object()))
3125 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
3128 ConstructibleObjectType ret;
3129 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
3130 using value_type = typename ConstructibleObjectType::value_type;
3132 inner_object->begin(), inner_object->end(),
3133 std::inserter(ret, ret.begin()),
3134 [](typename BasicJsonType::object_t::value_type const & p)
3136 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
3138 obj = std::move(ret);
3141 // overload for arithmetic types, not chosen for basic_json template arguments
3142 // (BooleanType, etc..); note: Is it really necessary to provide explicit
3143 // overloads for boolean_t etc. in case of a custom BooleanType which is not
3144 // an arithmetic type?
3145 template<typename BasicJsonType, typename ArithmeticType,
3147 std::is_arithmetic<ArithmeticType>::value and
3148 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
3149 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
3150 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
3151 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3153 void from_json(const BasicJsonType& j, ArithmeticType& val)
3155 switch (static_cast<value_t>(j))
3157 case value_t::number_unsigned:
3159 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3162 case value_t::number_integer:
3164 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3167 case value_t::number_float:
3169 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3172 case value_t::boolean:
3174 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
3179 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
3183 template<typename BasicJsonType, typename A1, typename A2>
3184 void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
3186 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
3189 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
3190 void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
3192 t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
3195 template<typename BasicJsonType, typename... Args>
3196 void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
3198 from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
3201 template <typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
3202 typename = enable_if_t<not std::is_constructible<
3203 typename BasicJsonType::string_t, Key>::value>>
3204 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
3206 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3208 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3211 for (const auto& p : j)
3213 if (JSON_HEDLEY_UNLIKELY(not p.is_array()))
3215 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3217 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3221 template <typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
3222 typename = enable_if_t<not std::is_constructible<
3223 typename BasicJsonType::string_t, Key>::value>>
3224 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
3226 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3228 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3231 for (const auto& p : j)
3233 if (JSON_HEDLEY_UNLIKELY(not p.is_array()))
3235 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3237 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3243 template<typename BasicJsonType, typename T>
3244 auto operator()(const BasicJsonType& j, T& val) const
3245 noexcept(noexcept(from_json(j, val)))
3246 -> decltype(from_json(j, val), void())
3248 return from_json(j, val);
3251 } // namespace detail
3253 /// namespace to hold default `from_json` function
3254 /// to see why this is required:
3255 /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
3258 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
3260 } // namespace nlohmann
3262 // #include <nlohmann/detail/conversions/to_json.hpp>
3265 #include <algorithm> // copy
3266 #include <ciso646> // or, and, not
3267 #include <iterator> // begin, end
3268 #include <string> // string
3269 #include <tuple> // tuple, get
3270 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
3271 #include <utility> // move, forward, declval, pair
3272 #include <valarray> // valarray
3273 #include <vector> // vector
3275 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
3278 #include <cstddef> // size_t
3279 #include <iterator> // input_iterator_tag
3280 #include <string> // string, to_string
3281 #include <tuple> // tuple_size, get, tuple_element
3283 // #include <nlohmann/detail/meta/type_traits.hpp>
3285 // #include <nlohmann/detail/value_t.hpp>
3292 template<typename string_type>
3293 void int_to_string( string_type& target, std::size_t value )
3295 target = std::to_string(value);
3297 template <typename IteratorType> class iteration_proxy_value
3300 using difference_type = std::ptrdiff_t;
3301 using value_type = iteration_proxy_value;
3302 using pointer = value_type * ;
3303 using reference = value_type & ;
3304 using iterator_category = std::input_iterator_tag;
3305 using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
3309 IteratorType anchor;
3310 /// an index for arrays (used to create key names)
3311 std::size_t array_index = 0;
3312 /// last stringified array index
3313 mutable std::size_t array_index_last = 0;
3314 /// a string representation of the array index
3315 mutable string_type array_index_str = "0";
3316 /// an empty string (to return a reference for primitive values)
3317 const string_type empty_str = "";
3320 explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
3322 /// dereference operator (needed for range-based for)
3323 iteration_proxy_value& operator*()
3328 /// increment operator (needed for range-based for)
3329 iteration_proxy_value& operator++()
3337 /// equality operator (needed for InputIterator)
3338 bool operator==(const iteration_proxy_value& o) const
3340 return anchor == o.anchor;
3343 /// inequality operator (needed for range-based for)
3344 bool operator!=(const iteration_proxy_value& o) const
3346 return anchor != o.anchor;
3349 /// return key of the iterator
3350 const string_type& key() const
3352 assert(anchor.m_object != nullptr);
3354 switch (anchor.m_object->type())
3356 // use integer array index as key
3357 case value_t::array:
3359 if (array_index != array_index_last)
3361 int_to_string( array_index_str, array_index );
3362 array_index_last = array_index;
3364 return array_index_str;
3367 // use key from the object
3368 case value_t::object:
3369 return anchor.key();
3371 // use an empty key for all primitive types
3377 /// return value of the iterator
3378 typename IteratorType::reference value() const
3380 return anchor.value();
3384 /// proxy class for the items() function
3385 template<typename IteratorType> class iteration_proxy
3388 /// the container to iterate
3389 typename IteratorType::reference container;
3392 /// construct iteration proxy from a container
3393 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
3394 : container(cont) {}
3396 /// return iterator begin (needed for range-based for)
3397 iteration_proxy_value<IteratorType> begin() noexcept
3399 return iteration_proxy_value<IteratorType>(container.begin());
3402 /// return iterator end (needed for range-based for)
3403 iteration_proxy_value<IteratorType> end() noexcept
3405 return iteration_proxy_value<IteratorType>(container.end());
3408 // Structured Bindings Support
3409 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3410 // And see https://github.com/nlohmann/json/pull/1391
3411 template <std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
3412 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
3416 // Structured Bindings Support
3417 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3418 // And see https://github.com/nlohmann/json/pull/1391
3419 template <std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
3420 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
3424 } // namespace detail
3425 } // namespace nlohmann
3427 // The Addition to the STD Namespace is required to add
3428 // Structured Bindings Support to the iteration_proxy_value class
3429 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3430 // And see https://github.com/nlohmann/json/pull/1391
3433 #if defined(__clang__)
3434 // Fix: https://github.com/nlohmann/json/issues/1401
3435 #pragma clang diagnostic push
3436 #pragma clang diagnostic ignored "-Wmismatched-tags"
3438 template <typename IteratorType>
3439 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
3440 : public std::integral_constant<std::size_t, 2> {};
3442 template <std::size_t N, typename IteratorType>
3443 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
3446 using type = decltype(
3447 get<N>(std::declval <
3448 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
3450 #if defined(__clang__)
3451 #pragma clang diagnostic pop
3455 // #include <nlohmann/detail/meta/cpp_future.hpp>
3457 // #include <nlohmann/detail/meta/type_traits.hpp>
3459 // #include <nlohmann/detail/value_t.hpp>
3470 template<value_t> struct external_constructor;
3473 struct external_constructor<value_t::boolean>
3475 template<typename BasicJsonType>
3476 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
3478 j.m_type = value_t::boolean;
3480 j.assert_invariant();
3485 struct external_constructor<value_t::string>
3487 template<typename BasicJsonType>
3488 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
3490 j.m_type = value_t::string;
3492 j.assert_invariant();
3495 template<typename BasicJsonType>
3496 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
3498 j.m_type = value_t::string;
3499 j.m_value = std::move(s);
3500 j.assert_invariant();
3503 template<typename BasicJsonType, typename CompatibleStringType,
3504 enable_if_t<not std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
3506 static void construct(BasicJsonType& j, const CompatibleStringType& str)
3508 j.m_type = value_t::string;
3509 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
3510 j.assert_invariant();
3515 struct external_constructor<value_t::number_float>
3517 template<typename BasicJsonType>
3518 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
3520 j.m_type = value_t::number_float;
3522 j.assert_invariant();
3527 struct external_constructor<value_t::number_unsigned>
3529 template<typename BasicJsonType>
3530 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
3532 j.m_type = value_t::number_unsigned;
3534 j.assert_invariant();
3539 struct external_constructor<value_t::number_integer>
3541 template<typename BasicJsonType>
3542 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
3544 j.m_type = value_t::number_integer;
3546 j.assert_invariant();
3551 struct external_constructor<value_t::array>
3553 template<typename BasicJsonType>
3554 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
3556 j.m_type = value_t::array;
3558 j.assert_invariant();
3561 template<typename BasicJsonType>
3562 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
3564 j.m_type = value_t::array;
3565 j.m_value = std::move(arr);
3566 j.assert_invariant();
3569 template<typename BasicJsonType, typename CompatibleArrayType,
3570 enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
3572 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
3576 j.m_type = value_t::array;
3577 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
3578 j.assert_invariant();
3581 template<typename BasicJsonType>
3582 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
3584 j.m_type = value_t::array;
3585 j.m_value = value_t::array;
3586 j.m_value.array->reserve(arr.size());
3587 for (const bool x : arr)
3589 j.m_value.array->push_back(x);
3591 j.assert_invariant();
3594 template<typename BasicJsonType, typename T,
3595 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
3596 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
3598 j.m_type = value_t::array;
3599 j.m_value = value_t::array;
3600 j.m_value.array->resize(arr.size());
3603 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
3605 j.assert_invariant();
3610 struct external_constructor<value_t::object>
3612 template<typename BasicJsonType>
3613 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
3615 j.m_type = value_t::object;
3617 j.assert_invariant();
3620 template<typename BasicJsonType>
3621 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
3623 j.m_type = value_t::object;
3624 j.m_value = std::move(obj);
3625 j.assert_invariant();
3628 template<typename BasicJsonType, typename CompatibleObjectType,
3629 enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0>
3630 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
3635 j.m_type = value_t::object;
3636 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
3637 j.assert_invariant();
3645 template<typename BasicJsonType, typename T,
3646 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
3647 void to_json(BasicJsonType& j, T b) noexcept
3649 external_constructor<value_t::boolean>::construct(j, b);
3652 template<typename BasicJsonType, typename CompatibleString,
3653 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
3654 void to_json(BasicJsonType& j, const CompatibleString& s)
3656 external_constructor<value_t::string>::construct(j, s);
3659 template<typename BasicJsonType>
3660 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
3662 external_constructor<value_t::string>::construct(j, std::move(s));
3665 template<typename BasicJsonType, typename FloatType,
3666 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
3667 void to_json(BasicJsonType& j, FloatType val) noexcept
3669 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
3672 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
3673 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
3674 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
3676 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
3679 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
3680 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
3681 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
3683 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
3686 template<typename BasicJsonType, typename EnumType,
3687 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
3688 void to_json(BasicJsonType& j, EnumType e) noexcept
3690 using underlying_type = typename std::underlying_type<EnumType>::type;
3691 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
3694 template<typename BasicJsonType>
3695 void to_json(BasicJsonType& j, const std::vector<bool>& e)
3697 external_constructor<value_t::array>::construct(j, e);
3700 template <typename BasicJsonType, typename CompatibleArrayType,
3701 enable_if_t<is_compatible_array_type<BasicJsonType,
3702 CompatibleArrayType>::value and
3703 not is_compatible_object_type<
3704 BasicJsonType, CompatibleArrayType>::value and
3705 not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
3706 not is_basic_json<CompatibleArrayType>::value,
3708 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
3710 external_constructor<value_t::array>::construct(j, arr);
3713 template<typename BasicJsonType, typename T,
3714 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
3715 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
3717 external_constructor<value_t::array>::construct(j, std::move(arr));
3720 template<typename BasicJsonType>
3721 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
3723 external_constructor<value_t::array>::construct(j, std::move(arr));
3726 template<typename BasicJsonType, typename CompatibleObjectType,
3727 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value and not is_basic_json<CompatibleObjectType>::value, int> = 0>
3728 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
3730 external_constructor<value_t::object>::construct(j, obj);
3733 template<typename BasicJsonType>
3734 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
3736 external_constructor<value_t::object>::construct(j, std::move(obj));
3740 typename BasicJsonType, typename T, std::size_t N,
3741 enable_if_t<not std::is_constructible<typename BasicJsonType::string_t,
3742 const T(&)[N]>::value,
3744 void to_json(BasicJsonType& j, const T(&arr)[N])
3746 external_constructor<value_t::array>::construct(j, arr);
3749 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
3750 void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
3752 j = { p.first, p.second };
3755 // for https://github.com/nlohmann/json/pull/1134
3756 template < typename BasicJsonType, typename T,
3757 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
3758 void to_json(BasicJsonType& j, const T& b)
3760 j = { {b.key(), b.value()} };
3763 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
3764 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
3766 j = { std::get<Idx>(t)... };
3769 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
3770 void to_json(BasicJsonType& j, const T& t)
3772 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
3777 template<typename BasicJsonType, typename T>
3778 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
3779 -> decltype(to_json(j, std::forward<T>(val)), void())
3781 return to_json(j, std::forward<T>(val));
3784 } // namespace detail
3786 /// namespace to hold default `to_json` function
3789 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
3791 } // namespace nlohmann
3797 template<typename, typename>
3798 struct adl_serializer
3801 @brief convert a JSON value to any value type
3803 This function is usually called by the `get()` function of the
3804 @ref basic_json class (either explicit or via conversion operators).
3806 @param[in] j JSON value to read from
3807 @param[in,out] val value to write to
3809 template<typename BasicJsonType, typename ValueType>
3810 static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
3811 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
3812 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
3814 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
3818 @brief convert any value type to a JSON value
3820 This function is usually called by the constructors of the @ref basic_json
3823 @param[in,out] j JSON value to write to
3824 @param[in] val value to read from
3826 template <typename BasicJsonType, typename ValueType>
3827 static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
3828 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
3829 -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void())
3831 ::nlohmann::to_json(j, std::forward<ValueType>(val));
3835 } // namespace nlohmann
3837 // #include <nlohmann/detail/conversions/from_json.hpp>
3839 // #include <nlohmann/detail/conversions/to_json.hpp>
3841 // #include <nlohmann/detail/exceptions.hpp>
3843 // #include <nlohmann/detail/input/binary_reader.hpp>
3846 #include <algorithm> // generate_n
3847 #include <array> // array
3848 #include <cassert> // assert
3849 #include <cmath> // ldexp
3850 #include <cstddef> // size_t
3851 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
3852 #include <cstdio> // snprintf
3853 #include <cstring> // memcpy
3854 #include <iterator> // back_inserter
3855 #include <limits> // numeric_limits
3856 #include <string> // char_traits, string
3857 #include <utility> // make_pair, move
3859 // #include <nlohmann/detail/exceptions.hpp>
3861 // #include <nlohmann/detail/input/input_adapters.hpp>
3864 #include <array> // array
3865 #include <cassert> // assert
3866 #include <cstddef> // size_t
3867 #include <cstdio> //FILE *
3868 #include <cstring> // strlen
3869 #include <istream> // istream
3870 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
3871 #include <memory> // shared_ptr, make_shared, addressof
3872 #include <numeric> // accumulate
3873 #include <string> // string, char_traits
3874 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
3875 #include <utility> // pair, declval
3877 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
3879 // #include <nlohmann/detail/macro_scope.hpp>
3886 /// the supported input formats
3887 enum class input_format_t { json, cbor, msgpack, ubjson, bson };
3889 ////////////////////
3890 // input adapters //
3891 ////////////////////
3894 @brief abstract input adapter interface
3896 Produces a stream of std::char_traits<char>::int_type characters from a
3897 std::istream, a buffer, or some other input type. Accepts the return of
3898 exactly one non-EOF character for future input. The int_type characters
3899 returned consist of all valid char values as positive values (typically
3900 unsigned char), plus an EOF value outside that range, specified by the value
3901 of the function std::char_traits<char>::eof(). This value is typically -1, but
3902 could be any arbitrary value which is not a valid char value.
3904 struct input_adapter_protocol
3906 /// get a character [0,255] or std::char_traits<char>::eof().
3907 virtual std::char_traits<char>::int_type get_character() = 0;
3908 virtual ~input_adapter_protocol() = default;
3911 /// a type to simplify interfaces
3912 using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
3915 Input adapter for stdio file access. This adapter read only 1 byte and do not use any
3916 buffer. This adapter is a very low level adapter.
3918 class file_input_adapter : public input_adapter_protocol
3921 JSON_HEDLEY_NON_NULL(2)
3922 explicit file_input_adapter(std::FILE* f) noexcept
3926 // make class move-only
3927 file_input_adapter(const file_input_adapter&) = delete;
3928 file_input_adapter(file_input_adapter&&) = default;
3929 file_input_adapter& operator=(const file_input_adapter&) = delete;
3930 file_input_adapter& operator=(file_input_adapter&&) = default;
3931 ~file_input_adapter() override = default;
3933 std::char_traits<char>::int_type get_character() noexcept override
3935 return std::fgetc(m_file);
3939 /// the file pointer to read from
3945 Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
3946 beginning of input. Does not support changing the underlying std::streambuf
3947 in mid-input. Maintains underlying std::istream and std::streambuf to support
3948 subsequent use of standard std::istream operations to process any input
3949 characters following those used in parsing the JSON input. Clears the
3950 std::istream flags; any input errors (e.g., EOF) will be detected by the first
3951 subsequent call for input from the std::istream.
3953 class input_stream_adapter : public input_adapter_protocol
3956 ~input_stream_adapter() override
3958 // clear stream flags; we use underlying streambuf I/O, do not
3959 // maintain ifstream flags, except eof
3960 is.clear(is.rdstate() & std::ios::eofbit);
3963 explicit input_stream_adapter(std::istream& i)
3964 : is(i), sb(*i.rdbuf())
3967 // delete because of pointer members
3968 input_stream_adapter(const input_stream_adapter&) = delete;
3969 input_stream_adapter& operator=(input_stream_adapter&) = delete;
3970 input_stream_adapter(input_stream_adapter&&) = delete;
3971 input_stream_adapter& operator=(input_stream_adapter&&) = delete;
3973 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
3974 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
3975 // end up as the same value, eg. 0xFFFFFFFF.
3976 std::char_traits<char>::int_type get_character() override
3978 auto res = sb.sbumpc();
3979 // set eof manually, as we don't use the istream interface.
3982 is.clear(is.rdstate() | std::ios::eofbit);
3988 /// the associated input stream
3993 /// input adapter for buffer input
3994 class input_buffer_adapter : public input_adapter_protocol
3997 input_buffer_adapter(const char* b, const std::size_t l) noexcept
3998 : cursor(b), limit(b == nullptr ? nullptr : (b + l))
4001 // delete because of pointer members
4002 input_buffer_adapter(const input_buffer_adapter&) = delete;
4003 input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
4004 input_buffer_adapter(input_buffer_adapter&&) = delete;
4005 input_buffer_adapter& operator=(input_buffer_adapter&&) = delete;
4006 ~input_buffer_adapter() override = default;
4008 std::char_traits<char>::int_type get_character() noexcept override
4010 if (JSON_HEDLEY_LIKELY(cursor < limit))
4012 assert(cursor != nullptr and limit != nullptr);
4013 return std::char_traits<char>::to_int_type(*(cursor++));
4016 return std::char_traits<char>::eof();
4020 /// pointer to the current character
4022 /// pointer past the last character
4023 const char* const limit;
4026 template<typename WideStringType, size_t T>
4027 struct wide_string_input_helper
4030 static void fill_buffer(const WideStringType& str,
4031 size_t& current_wchar,
4032 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4033 size_t& utf8_bytes_index,
4034 size_t& utf8_bytes_filled)
4036 utf8_bytes_index = 0;
4038 if (current_wchar == str.size())
4040 utf8_bytes[0] = std::char_traits<char>::eof();
4041 utf8_bytes_filled = 1;
4045 // get the current character
4046 const auto wc = static_cast<unsigned int>(str[current_wchar++]);
4048 // UTF-32 to UTF-8 encoding
4051 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4052 utf8_bytes_filled = 1;
4054 else if (wc <= 0x7FF)
4056 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u) & 0x1Fu));
4057 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
4058 utf8_bytes_filled = 2;
4060 else if (wc <= 0xFFFF)
4062 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u) & 0x0Fu));
4063 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
4064 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
4065 utf8_bytes_filled = 3;
4067 else if (wc <= 0x10FFFF)
4069 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((wc >> 18u) & 0x07u));
4070 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 12u) & 0x3Fu));
4071 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
4072 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
4073 utf8_bytes_filled = 4;
4077 // unknown character
4078 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4079 utf8_bytes_filled = 1;
4085 template<typename WideStringType>
4086 struct wide_string_input_helper<WideStringType, 2>
4089 static void fill_buffer(const WideStringType& str,
4090 size_t& current_wchar,
4091 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4092 size_t& utf8_bytes_index,
4093 size_t& utf8_bytes_filled)
4095 utf8_bytes_index = 0;
4097 if (current_wchar == str.size())
4099 utf8_bytes[0] = std::char_traits<char>::eof();
4100 utf8_bytes_filled = 1;
4104 // get the current character
4105 const auto wc = static_cast<unsigned int>(str[current_wchar++]);
4107 // UTF-16 to UTF-8 encoding
4110 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4111 utf8_bytes_filled = 1;
4113 else if (wc <= 0x7FF)
4115 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u)));
4116 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
4117 utf8_bytes_filled = 2;
4119 else if (0xD800 > wc or wc >= 0xE000)
4121 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u)));
4122 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
4123 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
4124 utf8_bytes_filled = 3;
4128 if (current_wchar < str.size())
4130 const auto wc2 = static_cast<unsigned int>(str[current_wchar++]);
4131 const auto charcode = 0x10000u + (((wc & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
4132 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
4133 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
4134 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
4135 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
4136 utf8_bytes_filled = 4;
4140 // unknown character
4142 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4143 utf8_bytes_filled = 1;
4150 template<typename WideStringType>
4151 class wide_string_input_adapter : public input_adapter_protocol
4154 explicit wide_string_input_adapter(const WideStringType& w) noexcept
4158 std::char_traits<char>::int_type get_character() noexcept override
4160 // check if buffer needs to be filled
4161 if (utf8_bytes_index == utf8_bytes_filled)
4163 fill_buffer<sizeof(typename WideStringType::value_type)>();
4165 assert(utf8_bytes_filled > 0);
4166 assert(utf8_bytes_index == 0);
4170 assert(utf8_bytes_filled > 0);
4171 assert(utf8_bytes_index < utf8_bytes_filled);
4172 return utf8_bytes[utf8_bytes_index++];
4179 wide_string_input_helper<WideStringType, T>::fill_buffer(str, current_wchar, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
4182 /// the wstring to process
4183 const WideStringType& str;
4185 /// index of the current wchar in str
4186 std::size_t current_wchar = 0;
4188 /// a buffer for UTF-8 bytes
4189 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
4191 /// index to the utf8_codes array for the next valid byte
4192 std::size_t utf8_bytes_index = 0;
4193 /// number of valid bytes in the utf8_codes array
4194 std::size_t utf8_bytes_filled = 0;
4201 JSON_HEDLEY_NON_NULL(2)
4202 input_adapter(std::FILE* file)
4203 : ia(std::make_shared<file_input_adapter>(file)) {}
4204 /// input adapter for input stream
4205 input_adapter(std::istream& i)
4206 : ia(std::make_shared<input_stream_adapter>(i)) {}
4208 /// input adapter for input stream
4209 input_adapter(std::istream&& i)
4210 : ia(std::make_shared<input_stream_adapter>(i)) {}
4212 input_adapter(const std::wstring& ws)
4213 : ia(std::make_shared<wide_string_input_adapter<std::wstring>>(ws)) {}
4215 input_adapter(const std::u16string& ws)
4216 : ia(std::make_shared<wide_string_input_adapter<std::u16string>>(ws)) {}
4218 input_adapter(const std::u32string& ws)
4219 : ia(std::make_shared<wide_string_input_adapter<std::u32string>>(ws)) {}
4221 /// input adapter for buffer
4222 template<typename CharT,
4223 typename std::enable_if<
4224 std::is_pointer<CharT>::value and
4225 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
4226 sizeof(typename std::remove_pointer<CharT>::type) == 1,
4228 input_adapter(CharT b, std::size_t l)
4229 : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
4233 /// input adapter for string literal
4234 template<typename CharT,
4235 typename std::enable_if<
4236 std::is_pointer<CharT>::value and
4237 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
4238 sizeof(typename std::remove_pointer<CharT>::type) == 1,
4240 input_adapter(CharT b)
4241 : input_adapter(reinterpret_cast<const char*>(b),
4242 std::strlen(reinterpret_cast<const char*>(b))) {}
4244 /// input adapter for iterator range with contiguous storage
4245 template<class IteratorType,
4246 typename std::enable_if<
4247 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
4249 input_adapter(IteratorType first, IteratorType last)
4252 // assertion to check that the iterator range is indeed contiguous,
4253 // see http://stackoverflow.com/a/35008842/266378 for more discussion
4254 const auto is_contiguous = std::accumulate(
4255 first, last, std::pair<bool, int>(true, 0),
4256 [&first](std::pair<bool, int> res, decltype(*first) val)
4258 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
4261 assert(is_contiguous);
4264 // assertion to check that each element is 1 byte long
4266 sizeof(typename iterator_traits<IteratorType>::value_type) == 1,
4267 "each element in the iterator range must have the size of 1 byte");
4269 const auto len = static_cast<size_t>(std::distance(first, last));
4270 if (JSON_HEDLEY_LIKELY(len > 0))
4272 // there is at least one element: use the address of first
4273 ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
4277 // the address of first cannot be used: use nullptr
4278 ia = std::make_shared<input_buffer_adapter>(nullptr, len);
4282 /// input adapter for array
4283 template<class T, std::size_t N>
4284 input_adapter(T (&array)[N])
4285 : input_adapter(std::begin(array), std::end(array)) {}
4287 /// input adapter for contiguous container
4288 template<class ContiguousContainer, typename
4289 std::enable_if<not std::is_pointer<ContiguousContainer>::value and
4290 std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
4292 input_adapter(const ContiguousContainer& c)
4293 : input_adapter(std::begin(c), std::end(c)) {}
4295 operator input_adapter_t()
4301 /// the actual adapter
4302 input_adapter_t ia = nullptr;
4304 } // namespace detail
4305 } // namespace nlohmann
4307 // #include <nlohmann/detail/input/json_sax.hpp>
4310 #include <cassert> // assert
4312 #include <string> // string
4313 #include <utility> // move
4314 #include <vector> // vector
4316 // #include <nlohmann/detail/exceptions.hpp>
4318 // #include <nlohmann/detail/macro_scope.hpp>
4325 @brief SAX interface
4327 This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
4328 Each function is called in different situations while the input is parsed. The
4329 boolean return value informs the parser whether to continue processing the
4332 template<typename BasicJsonType>
4335 /// type for (signed) integers
4336 using number_integer_t = typename BasicJsonType::number_integer_t;
4337 /// type for unsigned integers
4338 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4339 /// type for floating-point numbers
4340 using number_float_t = typename BasicJsonType::number_float_t;
4341 /// type for strings
4342 using string_t = typename BasicJsonType::string_t;
4345 @brief a null value was read
4346 @return whether parsing should proceed
4348 virtual bool null() = 0;
4351 @brief a boolean value was read
4352 @param[in] val boolean value
4353 @return whether parsing should proceed
4355 virtual bool boolean(bool val) = 0;
4358 @brief an integer number was read
4359 @param[in] val integer value
4360 @return whether parsing should proceed
4362 virtual bool number_integer(number_integer_t val) = 0;
4365 @brief an unsigned integer number was read
4366 @param[in] val unsigned integer value
4367 @return whether parsing should proceed
4369 virtual bool number_unsigned(number_unsigned_t val) = 0;
4372 @brief an floating-point number was read
4373 @param[in] val floating-point value
4374 @param[in] s raw token value
4375 @return whether parsing should proceed
4377 virtual bool number_float(number_float_t val, const string_t& s) = 0;
4380 @brief a string was read
4381 @param[in] val string value
4382 @return whether parsing should proceed
4383 @note It is safe to move the passed string.
4385 virtual bool string(string_t& val) = 0;
4388 @brief the beginning of an object was read
4389 @param[in] elements number of object elements or -1 if unknown
4390 @return whether parsing should proceed
4391 @note binary formats may report the number of elements
4393 virtual bool start_object(std::size_t elements) = 0;
4396 @brief an object key was read
4397 @param[in] val object key
4398 @return whether parsing should proceed
4399 @note It is safe to move the passed string.
4401 virtual bool key(string_t& val) = 0;
4404 @brief the end of an object was read
4405 @return whether parsing should proceed
4407 virtual bool end_object() = 0;
4410 @brief the beginning of an array was read
4411 @param[in] elements number of array elements or -1 if unknown
4412 @return whether parsing should proceed
4413 @note binary formats may report the number of elements
4415 virtual bool start_array(std::size_t elements) = 0;
4418 @brief the end of an array was read
4419 @return whether parsing should proceed
4421 virtual bool end_array() = 0;
4424 @brief a parse error occurred
4425 @param[in] position the position in the input where the error occurs
4426 @param[in] last_token the last read token
4427 @param[in] ex an exception object describing the error
4428 @return whether parsing should proceed (must return false)
4430 virtual bool parse_error(std::size_t position,
4431 const std::string& last_token,
4432 const detail::exception& ex) = 0;
4434 virtual ~json_sax() = default;
4441 @brief SAX implementation to create a JSON value from SAX events
4443 This class implements the @ref json_sax interface and processes the SAX events
4444 to create a JSON value which makes it basically a DOM parser. The structure or
4445 hierarchy of the JSON value is managed by the stack `ref_stack` which contains
4446 a pointer to the respective array or object for each recursion depth.
4448 After successful parsing, the value that is passed by reference to the
4449 constructor contains the parsed value.
4451 @tparam BasicJsonType the JSON type
4453 template<typename BasicJsonType>
4454 class json_sax_dom_parser
4457 using number_integer_t = typename BasicJsonType::number_integer_t;
4458 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4459 using number_float_t = typename BasicJsonType::number_float_t;
4460 using string_t = typename BasicJsonType::string_t;
4463 @param[in, out] r reference to a JSON value that is manipulated while
4465 @param[in] allow_exceptions_ whether parse errors yield exceptions
4467 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
4468 : root(r), allow_exceptions(allow_exceptions_)
4471 // make class move-only
4472 json_sax_dom_parser(const json_sax_dom_parser&) = delete;
4473 json_sax_dom_parser(json_sax_dom_parser&&) = default;
4474 json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
4475 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
4476 ~json_sax_dom_parser() = default;
4480 handle_value(nullptr);
4484 bool boolean(bool val)
4490 bool number_integer(number_integer_t val)
4496 bool number_unsigned(number_unsigned_t val)
4502 bool number_float(number_float_t val, const string_t& /*unused*/)
4508 bool string(string_t& val)
4514 bool start_object(std::size_t len)
4516 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
4518 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4520 JSON_THROW(out_of_range::create(408,
4521 "excessive object size: " + std::to_string(len)));
4527 bool key(string_t& val)
4529 // add null at given key and store the reference for later
4530 object_element = &(ref_stack.back()->m_value.object->operator[](val));
4536 ref_stack.pop_back();
4540 bool start_array(std::size_t len)
4542 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
4544 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4546 JSON_THROW(out_of_range::create(408,
4547 "excessive array size: " + std::to_string(len)));
4555 ref_stack.pop_back();
4559 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
4560 const detail::exception& ex)
4563 if (allow_exceptions)
4565 // determine the proper exception type from the id
4566 switch ((ex.id / 100) % 100)
4569 JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
4571 JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
4574 JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
4576 JSON_THROW(*static_cast<const detail::type_error*>(&ex));
4578 JSON_THROW(*static_cast<const detail::other_error*>(&ex));
4587 constexpr bool is_errored() const
4594 @invariant If the ref stack is empty, then the passed value will be the new
4596 @invariant If the ref stack contains a value, then it is an array or an
4597 object to which we can add elements
4599 template<typename Value>
4600 JSON_HEDLEY_RETURNS_NON_NULL
4601 BasicJsonType* handle_value(Value&& v)
4603 if (ref_stack.empty())
4605 root = BasicJsonType(std::forward<Value>(v));
4609 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
4611 if (ref_stack.back()->is_array())
4613 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
4614 return &(ref_stack.back()->m_value.array->back());
4617 assert(ref_stack.back()->is_object());
4618 assert(object_element);
4619 *object_element = BasicJsonType(std::forward<Value>(v));
4620 return object_element;
4623 /// the parsed JSON value
4624 BasicJsonType& root;
4625 /// stack to model hierarchy of values
4626 std::vector<BasicJsonType*> ref_stack {};
4627 /// helper to hold the reference for the next object element
4628 BasicJsonType* object_element = nullptr;
4629 /// whether a syntax error occurred
4630 bool errored = false;
4631 /// whether to throw exceptions in case of errors
4632 const bool allow_exceptions = true;
4635 template<typename BasicJsonType>
4636 class json_sax_dom_callback_parser
4639 using number_integer_t = typename BasicJsonType::number_integer_t;
4640 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4641 using number_float_t = typename BasicJsonType::number_float_t;
4642 using string_t = typename BasicJsonType::string_t;
4643 using parser_callback_t = typename BasicJsonType::parser_callback_t;
4644 using parse_event_t = typename BasicJsonType::parse_event_t;
4646 json_sax_dom_callback_parser(BasicJsonType& r,
4647 const parser_callback_t cb,
4648 const bool allow_exceptions_ = true)
4649 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
4651 keep_stack.push_back(true);
4654 // make class move-only
4655 json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
4656 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default;
4657 json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
4658 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default;
4659 ~json_sax_dom_callback_parser() = default;
4663 handle_value(nullptr);
4667 bool boolean(bool val)
4673 bool number_integer(number_integer_t val)
4679 bool number_unsigned(number_unsigned_t val)
4685 bool number_float(number_float_t val, const string_t& /*unused*/)
4691 bool string(string_t& val)
4697 bool start_object(std::size_t len)
4699 // check callback for object start
4700 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
4701 keep_stack.push_back(keep);
4703 auto val = handle_value(BasicJsonType::value_t::object, true);
4704 ref_stack.push_back(val.second);
4706 // check object limit
4707 if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4709 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
4715 bool key(string_t& val)
4717 BasicJsonType k = BasicJsonType(val);
4719 // check callback for key
4720 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
4721 key_keep_stack.push_back(keep);
4723 // add discarded value at given key and store the reference for later
4724 if (keep and ref_stack.back())
4726 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
4734 if (ref_stack.back() and not callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
4737 *ref_stack.back() = discarded;
4740 assert(not ref_stack.empty());
4741 assert(not keep_stack.empty());
4742 ref_stack.pop_back();
4743 keep_stack.pop_back();
4745 if (not ref_stack.empty() and ref_stack.back() and ref_stack.back()->is_object())
4747 // remove discarded value
4748 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
4750 if (it->is_discarded())
4752 ref_stack.back()->erase(it);
4761 bool start_array(std::size_t len)
4763 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
4764 keep_stack.push_back(keep);
4766 auto val = handle_value(BasicJsonType::value_t::array, true);
4767 ref_stack.push_back(val.second);
4769 // check array limit
4770 if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4772 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
4782 if (ref_stack.back())
4784 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
4788 *ref_stack.back() = discarded;
4792 assert(not ref_stack.empty());
4793 assert(not keep_stack.empty());
4794 ref_stack.pop_back();
4795 keep_stack.pop_back();
4797 // remove discarded value
4798 if (not keep and not ref_stack.empty() and ref_stack.back()->is_array())
4800 ref_stack.back()->m_value.array->pop_back();
4806 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
4807 const detail::exception& ex)
4810 if (allow_exceptions)
4812 // determine the proper exception type from the id
4813 switch ((ex.id / 100) % 100)
4816 JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
4818 JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
4821 JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
4823 JSON_THROW(*static_cast<const detail::type_error*>(&ex));
4825 JSON_THROW(*static_cast<const detail::other_error*>(&ex));
4834 constexpr bool is_errored() const
4841 @param[in] v value to add to the JSON value we build during parsing
4842 @param[in] skip_callback whether we should skip calling the callback
4843 function; this is required after start_array() and
4844 start_object() SAX events, because otherwise we would call the
4845 callback function with an empty array or object, respectively.
4847 @invariant If the ref stack is empty, then the passed value will be the new
4849 @invariant If the ref stack contains a value, then it is an array or an
4850 object to which we can add elements
4852 @return pair of boolean (whether value should be kept) and pointer (to the
4853 passed value in the ref_stack hierarchy; nullptr if not kept)
4855 template<typename Value>
4856 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
4858 assert(not keep_stack.empty());
4860 // do not handle this value if we know it would be added to a discarded
4862 if (not keep_stack.back())
4864 return {false, nullptr};
4868 auto value = BasicJsonType(std::forward<Value>(v));
4871 const bool keep = skip_callback or callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
4873 // do not handle this value if we just learnt it shall be discarded
4876 return {false, nullptr};
4879 if (ref_stack.empty())
4881 root = std::move(value);
4882 return {true, &root};
4885 // skip this value if we already decided to skip the parent
4886 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
4887 if (not ref_stack.back())
4889 return {false, nullptr};
4892 // we now only expect arrays and objects
4893 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
4896 if (ref_stack.back()->is_array())
4898 ref_stack.back()->m_value.array->push_back(std::move(value));
4899 return {true, &(ref_stack.back()->m_value.array->back())};
4903 assert(ref_stack.back()->is_object());
4904 // check if we should store an element for the current key
4905 assert(not key_keep_stack.empty());
4906 const bool store_element = key_keep_stack.back();
4907 key_keep_stack.pop_back();
4909 if (not store_element)
4911 return {false, nullptr};
4914 assert(object_element);
4915 *object_element = std::move(value);
4916 return {true, object_element};
4919 /// the parsed JSON value
4920 BasicJsonType& root;
4921 /// stack to model hierarchy of values
4922 std::vector<BasicJsonType*> ref_stack {};
4923 /// stack to manage which values to keep
4924 std::vector<bool> keep_stack {};
4925 /// stack to manage which object keys to keep
4926 std::vector<bool> key_keep_stack {};
4927 /// helper to hold the reference for the next object element
4928 BasicJsonType* object_element = nullptr;
4929 /// whether a syntax error occurred
4930 bool errored = false;
4931 /// callback function
4932 const parser_callback_t callback = nullptr;
4933 /// whether to throw exceptions in case of errors
4934 const bool allow_exceptions = true;
4935 /// a discarded value for the callback
4936 BasicJsonType discarded = BasicJsonType::value_t::discarded;
4939 template<typename BasicJsonType>
4940 class json_sax_acceptor
4943 using number_integer_t = typename BasicJsonType::number_integer_t;
4944 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4945 using number_float_t = typename BasicJsonType::number_float_t;
4946 using string_t = typename BasicJsonType::string_t;
4953 bool boolean(bool /*unused*/)
4958 bool number_integer(number_integer_t /*unused*/)
4963 bool number_unsigned(number_unsigned_t /*unused*/)
4968 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
4973 bool string(string_t& /*unused*/)
4978 bool start_object(std::size_t /*unused*/ = std::size_t(-1))
4983 bool key(string_t& /*unused*/)
4993 bool start_array(std::size_t /*unused*/ = std::size_t(-1))
5003 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
5008 } // namespace detail
5010 } // namespace nlohmann
5012 // #include <nlohmann/detail/macro_scope.hpp>
5014 // #include <nlohmann/detail/meta/is_sax.hpp>
5017 #include <cstdint> // size_t
5018 #include <utility> // declval
5019 #include <string> // string
5021 // #include <nlohmann/detail/meta/detected.hpp>
5023 // #include <nlohmann/detail/meta/type_traits.hpp>
5030 template <typename T>
5031 using null_function_t = decltype(std::declval<T&>().null());
5033 template <typename T>
5034 using boolean_function_t =
5035 decltype(std::declval<T&>().boolean(std::declval<bool>()));
5037 template <typename T, typename Integer>
5038 using number_integer_function_t =
5039 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
5041 template <typename T, typename Unsigned>
5042 using number_unsigned_function_t =
5043 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
5045 template <typename T, typename Float, typename String>
5046 using number_float_function_t = decltype(std::declval<T&>().number_float(
5047 std::declval<Float>(), std::declval<const String&>()));
5049 template <typename T, typename String>
5050 using string_function_t =
5051 decltype(std::declval<T&>().string(std::declval<String&>()));
5053 template <typename T>
5054 using start_object_function_t =
5055 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
5057 template <typename T, typename String>
5058 using key_function_t =
5059 decltype(std::declval<T&>().key(std::declval<String&>()));
5061 template <typename T>
5062 using end_object_function_t = decltype(std::declval<T&>().end_object());
5064 template <typename T>
5065 using start_array_function_t =
5066 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
5068 template <typename T>
5069 using end_array_function_t = decltype(std::declval<T&>().end_array());
5071 template <typename T, typename Exception>
5072 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
5073 std::declval<std::size_t>(), std::declval<const std::string&>(),
5074 std::declval<const Exception&>()));
5076 template <typename SAX, typename BasicJsonType>
5080 static_assert(is_basic_json<BasicJsonType>::value,
5081 "BasicJsonType must be of type basic_json<...>");
5083 using number_integer_t = typename BasicJsonType::number_integer_t;
5084 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5085 using number_float_t = typename BasicJsonType::number_float_t;
5086 using string_t = typename BasicJsonType::string_t;
5087 using exception_t = typename BasicJsonType::exception;
5090 static constexpr bool value =
5091 is_detected_exact<bool, null_function_t, SAX>::value &&
5092 is_detected_exact<bool, boolean_function_t, SAX>::value &&
5093 is_detected_exact<bool, number_integer_function_t, SAX,
5094 number_integer_t>::value &&
5095 is_detected_exact<bool, number_unsigned_function_t, SAX,
5096 number_unsigned_t>::value &&
5097 is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
5099 is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
5100 is_detected_exact<bool, start_object_function_t, SAX>::value &&
5101 is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
5102 is_detected_exact<bool, end_object_function_t, SAX>::value &&
5103 is_detected_exact<bool, start_array_function_t, SAX>::value &&
5104 is_detected_exact<bool, end_array_function_t, SAX>::value &&
5105 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
5108 template <typename SAX, typename BasicJsonType>
5109 struct is_sax_static_asserts
5112 static_assert(is_basic_json<BasicJsonType>::value,
5113 "BasicJsonType must be of type basic_json<...>");
5115 using number_integer_t = typename BasicJsonType::number_integer_t;
5116 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5117 using number_float_t = typename BasicJsonType::number_float_t;
5118 using string_t = typename BasicJsonType::string_t;
5119 using exception_t = typename BasicJsonType::exception;
5122 static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
5123 "Missing/invalid function: bool null()");
5124 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
5125 "Missing/invalid function: bool boolean(bool)");
5126 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
5127 "Missing/invalid function: bool boolean(bool)");
5129 is_detected_exact<bool, number_integer_function_t, SAX,
5130 number_integer_t>::value,
5131 "Missing/invalid function: bool number_integer(number_integer_t)");
5133 is_detected_exact<bool, number_unsigned_function_t, SAX,
5134 number_unsigned_t>::value,
5135 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
5136 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
5137 number_float_t, string_t>::value,
5138 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
5140 is_detected_exact<bool, string_function_t, SAX, string_t>::value,
5141 "Missing/invalid function: bool string(string_t&)");
5142 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
5143 "Missing/invalid function: bool start_object(std::size_t)");
5144 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
5145 "Missing/invalid function: bool key(string_t&)");
5146 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
5147 "Missing/invalid function: bool end_object()");
5148 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
5149 "Missing/invalid function: bool start_array(std::size_t)");
5150 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
5151 "Missing/invalid function: bool end_array()");
5153 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
5154 "Missing/invalid function: bool parse_error(std::size_t, const "
5155 "std::string&, const exception&)");
5157 } // namespace detail
5158 } // namespace nlohmann
5160 // #include <nlohmann/detail/value_t.hpp>
5172 @brief deserialization of CBOR, MessagePack, and UBJSON values
5174 template<typename BasicJsonType, typename SAX = json_sax_dom_parser<BasicJsonType>>
5177 using number_integer_t = typename BasicJsonType::number_integer_t;
5178 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5179 using number_float_t = typename BasicJsonType::number_float_t;
5180 using string_t = typename BasicJsonType::string_t;
5181 using json_sax_t = SAX;
5185 @brief create a binary reader
5187 @param[in] adapter input adapter to read from
5189 explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
5191 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
5195 // make class move-only
5196 binary_reader(const binary_reader&) = delete;
5197 binary_reader(binary_reader&&) = default;
5198 binary_reader& operator=(const binary_reader&) = delete;
5199 binary_reader& operator=(binary_reader&&) = default;
5200 ~binary_reader() = default;
5203 @param[in] format the binary format to parse
5204 @param[in] sax_ a SAX event processor
5205 @param[in] strict whether to expect the input to be consumed completed
5209 JSON_HEDLEY_NON_NULL(3)
5210 bool sax_parse(const input_format_t format,
5212 const bool strict = true)
5215 bool result = false;
5219 case input_format_t::bson:
5220 result = parse_bson_internal();
5223 case input_format_t::cbor:
5224 result = parse_cbor_internal();
5227 case input_format_t::msgpack:
5228 result = parse_msgpack_internal();
5231 case input_format_t::ubjson:
5232 result = parse_ubjson_internal();
5235 default: // LCOV_EXCL_LINE
5236 assert(false); // LCOV_EXCL_LINE
5239 // strict mode: next byte must be EOF
5240 if (result and strict)
5242 if (format == input_format_t::ubjson)
5251 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char>::eof()))
5253 return sax->parse_error(chars_read, get_token_string(),
5254 parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
5262 @brief determine system byte order
5264 @return true if and only if system's byte order is little endian
5266 @note from http://stackoverflow.com/a/1001328/266378
5268 static constexpr bool little_endianess(int num = 1) noexcept
5270 return *reinterpret_cast<char*>(&num) == 1;
5279 @brief Reads in a BSON-object and passes it to the SAX-parser.
5280 @return whether a valid BSON-value was passed to the SAX parser
5282 bool parse_bson_internal()
5284 std::int32_t document_size;
5285 get_number<std::int32_t, true>(input_format_t::bson, document_size);
5287 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
5292 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(/*is_array*/false)))
5297 return sax->end_object();
5301 @brief Parses a C-style string from the BSON input.
5302 @param[in, out] result A reference to the string variable where the read
5303 string is to be stored.
5304 @return `true` if the \x00-byte indicating the end of the string was
5305 encountered before the EOF; false` indicates an unexpected EOF.
5307 bool get_bson_cstr(string_t& result)
5309 auto out = std::back_inserter(result);
5313 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "cstring")))
5317 if (current == 0x00)
5321 *out++ = static_cast<char>(current);
5328 @brief Parses a zero-terminated string of length @a len from the BSON
5330 @param[in] len The length (including the zero-byte at the end) of the
5332 @param[in, out] result A reference to the string variable where the read
5333 string is to be stored.
5334 @tparam NumberType The type of the length @a len
5336 @return `true` if the string was successfully parsed
5338 template<typename NumberType>
5339 bool get_bson_string(const NumberType len, string_t& result)
5341 if (JSON_HEDLEY_UNLIKELY(len < 1))
5343 auto last_token = get_token_string();
5344 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string")));
5347 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) and get() != std::char_traits<char>::eof();
5351 @brief Read a BSON document element of the given @a element_type.
5352 @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html
5353 @param[in] element_type_parse_position The position in the input stream,
5354 where the `element_type` was read.
5355 @warning Not all BSON element types are supported yet. An unsupported
5356 @a element_type will give rise to a parse_error.114:
5357 Unsupported BSON record type 0x...
5358 @return whether a valid BSON-object/array was passed to the SAX parser
5360 bool parse_bson_element_internal(const int element_type,
5361 const std::size_t element_type_parse_position)
5363 switch (element_type)
5365 case 0x01: // double
5368 return get_number<double, true>(input_format_t::bson, number) and sax->number_float(static_cast<number_float_t>(number), "");
5371 case 0x02: // string
5375 return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_string(len, value) and sax->string(value);
5378 case 0x03: // object
5380 return parse_bson_internal();
5385 return parse_bson_array();
5388 case 0x08: // boolean
5390 return sax->boolean(get() != 0);
5401 return get_number<std::int32_t, true>(input_format_t::bson, value) and sax->number_integer(value);
5407 return get_number<std::int64_t, true>(input_format_t::bson, value) and sax->number_integer(value);
5410 default: // anything else not supported (yet)
5412 std::array<char, 3> cr{{}};
5413 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type));
5414 return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data())));
5420 @brief Read a BSON element list (as specified in the BSON-spec)
5422 The same binary layout is used for objects and arrays, hence it must be
5423 indicated with the argument @a is_array which one is expected
5424 (true --> array, false --> object).
5426 @param[in] is_array Determines if the element list being read is to be
5427 treated as an object (@a is_array == false), or as an
5428 array (@a is_array == true).
5429 @return whether a valid BSON-object/array was passed to the SAX parser
5431 bool parse_bson_element_list(const bool is_array)
5434 while (int element_type = get())
5436 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list")))
5441 const std::size_t element_type_parse_position = chars_read;
5442 if (JSON_HEDLEY_UNLIKELY(not get_bson_cstr(key)))
5447 if (not is_array and not sax->key(key))
5452 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
5457 // get_bson_cstr only appends
5465 @brief Reads an array from the BSON input and passes it to the SAX-parser.
5466 @return whether a valid BSON-array was passed to the SAX parser
5468 bool parse_bson_array()
5470 std::int32_t document_size;
5471 get_number<std::int32_t, true>(input_format_t::bson, document_size);
5473 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
5478 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(/*is_array*/true)))
5483 return sax->end_array();
5491 @param[in] get_char whether a new character should be retrieved from the
5492 input (true, default) or whether the last read
5493 character should be considered instead
5495 @return whether a valid CBOR value was passed to the SAX parser
5497 bool parse_cbor_internal(const bool get_char = true)
5499 switch (get_char ? get() : current)
5502 case std::char_traits<char>::eof():
5503 return unexpect_eof(input_format_t::cbor, "value");
5505 // Integer 0x00..0x17 (0..23)
5530 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
5532 case 0x18: // Unsigned integer (one-byte uint8_t follows)
5534 std::uint8_t number;
5535 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
5538 case 0x19: // Unsigned integer (two-byte uint16_t follows)
5540 std::uint16_t number;
5541 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
5544 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
5546 std::uint32_t number;
5547 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
5550 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
5552 std::uint64_t number;
5553 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
5556 // Negative integer -1-0x00..-1-0x17 (-1..-24)
5581 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
5583 case 0x38: // Negative integer (one-byte uint8_t follows)
5585 std::uint8_t number;
5586 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
5589 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
5591 std::uint16_t number;
5592 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
5595 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
5597 std::uint32_t number;
5598 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
5601 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
5603 std::uint64_t number;
5604 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1)
5605 - static_cast<number_integer_t>(number));
5608 // UTF-8 string (0x00..0x17 bytes follow)
5633 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
5634 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
5635 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
5636 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
5637 case 0x7F: // UTF-8 string (indefinite length)
5640 return get_cbor_string(s) and sax->string(s);
5643 // array (0x00..0x17 data items follow)
5668 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
5670 case 0x98: // array (one-byte uint8_t for n follows)
5673 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
5676 case 0x99: // array (two-byte uint16_t for n follow)
5679 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
5682 case 0x9A: // array (four-byte uint32_t for n follow)
5685 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
5688 case 0x9B: // array (eight-byte uint64_t for n follow)
5691 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
5694 case 0x9F: // array (indefinite length)
5695 return get_cbor_array(std::size_t(-1));
5697 // map (0x00..0x17 pairs of data items follow)
5722 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
5724 case 0xB8: // map (one-byte uint8_t for n follows)
5727 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
5730 case 0xB9: // map (two-byte uint16_t for n follow)
5733 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
5736 case 0xBA: // map (four-byte uint32_t for n follow)
5739 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
5742 case 0xBB: // map (eight-byte uint64_t for n follow)
5745 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
5748 case 0xBF: // map (indefinite length)
5749 return get_cbor_object(std::size_t(-1));
5752 return sax->boolean(false);
5755 return sax->boolean(true);
5760 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
5762 const int byte1_raw = get();
5763 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
5767 const int byte2_raw = get();
5768 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
5773 const auto byte1 = static_cast<unsigned char>(byte1_raw);
5774 const auto byte2 = static_cast<unsigned char>(byte2_raw);
5776 // code from RFC 7049, Appendix D, Figure 3:
5777 // As half-precision floating-point numbers were only added
5778 // to IEEE 754 in 2008, today's programming platforms often
5779 // still only have limited support for them. It is very
5780 // easy to include at least decoding support for them even
5781 // without such support. An example of a small decoder for
5782 // half-precision floating-point numbers in the C language
5783 // is shown in Fig. 3.
5784 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
5785 const double val = [&half]
5787 const int exp = (half >> 10u) & 0x1Fu;
5788 const unsigned int mant = half & 0x3FFu;
5789 assert(0 <= exp and exp <= 32);
5790 assert(mant <= 1024);
5794 return std::ldexp(mant, -24);
5797 ? std::numeric_limits<double>::infinity()
5798 : std::numeric_limits<double>::quiet_NaN();
5800 return std::ldexp(mant + 1024, exp - 25);
5803 return sax->number_float((half & 0x8000u) != 0
5804 ? static_cast<number_float_t>(-val)
5805 : static_cast<number_float_t>(val), "");
5808 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
5811 return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
5814 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
5817 return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
5820 default: // anything else (0xFF is handled inside the other types)
5822 auto last_token = get_token_string();
5823 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));
5829 @brief reads a CBOR string
5831 This function first reads starting bytes to determine the expected
5832 string length and then copies this number of bytes into a string.
5833 Additionally, CBOR's strings with indefinite lengths are supported.
5835 @param[out] result created string
5837 @return whether string creation completed
5839 bool get_cbor_string(string_t& result)
5841 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "string")))
5848 // UTF-8 string (0x00..0x17 bytes follow)
5874 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
5877 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
5880 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
5883 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
5886 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
5889 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
5892 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
5895 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
5898 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
5901 case 0x7F: // UTF-8 string (indefinite length)
5903 while (get() != 0xFF)
5906 if (not get_cbor_string(chunk))
5910 result.append(chunk);
5917 auto last_token = get_token_string();
5918 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string")));
5924 @param[in] len the length of the array or std::size_t(-1) for an
5925 array of indefinite size
5926 @return whether array creation completed
5928 bool get_cbor_array(const std::size_t len)
5930 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len)))
5935 if (len != std::size_t(-1))
5937 for (std::size_t i = 0; i < len; ++i)
5939 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
5947 while (get() != 0xFF)
5949 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal(false)))
5956 return sax->end_array();
5960 @param[in] len the length of the object or std::size_t(-1) for an
5961 object of indefinite size
5962 @return whether object creation completed
5964 bool get_cbor_object(const std::size_t len)
5966 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len)))
5972 if (len != std::size_t(-1))
5974 for (std::size_t i = 0; i < len; ++i)
5977 if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
5982 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
5991 while (get() != 0xFF)
5993 if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
5998 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
6006 return sax->end_object();
6014 @return whether a valid MessagePack value was passed to the SAX parser
6016 bool parse_msgpack_internal()
6021 case std::char_traits<char>::eof():
6022 return unexpect_eof(input_format_t::msgpack, "value");
6153 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
6172 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
6191 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
6227 case 0xDA: // str 16
6228 case 0xDB: // str 32
6231 return get_msgpack_string(s) and sax->string(s);
6238 return sax->boolean(false);
6241 return sax->boolean(true);
6243 case 0xCA: // float 32
6246 return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
6249 case 0xCB: // float 64
6252 return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
6255 case 0xCC: // uint 8
6257 std::uint8_t number;
6258 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
6261 case 0xCD: // uint 16
6263 std::uint16_t number;
6264 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
6267 case 0xCE: // uint 32
6269 std::uint32_t number;
6270 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
6273 case 0xCF: // uint 64
6275 std::uint64_t number;
6276 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
6282 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
6285 case 0xD1: // int 16
6287 std::int16_t number;
6288 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
6291 case 0xD2: // int 32
6293 std::int32_t number;
6294 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
6297 case 0xD3: // int 64
6299 std::int64_t number;
6300 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
6303 case 0xDC: // array 16
6306 return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
6309 case 0xDD: // array 32
6312 return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
6315 case 0xDE: // map 16
6318 return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
6321 case 0xDF: // map 32
6324 return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
6360 return sax->number_integer(static_cast<std::int8_t>(current));
6362 default: // anything else
6364 auto last_token = get_token_string();
6365 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value")));
6371 @brief reads a MessagePack string
6373 This function first reads starting bytes to determine the expected
6374 string length and then copies this number of bytes into a string.
6376 @param[out] result created string
6378 @return whether string creation completed
6380 bool get_msgpack_string(string_t& result)
6382 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string")))
6423 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
6429 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
6432 case 0xDA: // str 16
6435 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
6438 case 0xDB: // str 32
6441 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
6446 auto last_token = get_token_string();
6447 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string")));
6453 @param[in] len the length of the array
6454 @return whether array creation completed
6456 bool get_msgpack_array(const std::size_t len)
6458 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len)))
6463 for (std::size_t i = 0; i < len; ++i)
6465 if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal()))
6471 return sax->end_array();
6475 @param[in] len the length of the object
6476 @return whether object creation completed
6478 bool get_msgpack_object(const std::size_t len)
6480 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len)))
6486 for (std::size_t i = 0; i < len; ++i)
6489 if (JSON_HEDLEY_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
6494 if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal()))
6501 return sax->end_object();
6509 @param[in] get_char whether a new character should be retrieved from the
6510 input (true, default) or whether the last read
6511 character should be considered instead
6513 @return whether a valid UBJSON value was passed to the SAX parser
6515 bool parse_ubjson_internal(const bool get_char = true)
6517 return get_ubjson_value(get_char ? get_ignore_noop() : current);
6521 @brief reads a UBJSON string
6523 This function is either called after reading the 'S' byte explicitly
6524 indicating a string, or in case of an object key where the 'S' byte can be
6527 @param[out] result created string
6528 @param[in] get_char whether a new character should be retrieved from the
6529 input (true, default) or whether the last read
6530 character should be considered instead
6532 @return whether string creation completed
6534 bool get_ubjson_string(string_t& result, const bool get_char = true)
6538 get(); // TODO(niels): may we ignore N here?
6541 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
6551 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
6557 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
6563 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
6569 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
6575 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
6579 auto last_token = get_token_string();
6580 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string")));
6585 @param[out] result determined size
6586 @return whether size determination completed
6588 bool get_ubjson_size_value(std::size_t& result)
6590 switch (get_ignore_noop())
6594 std::uint8_t number;
6595 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
6599 result = static_cast<std::size_t>(number);
6606 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
6610 result = static_cast<std::size_t>(number);
6616 std::int16_t number;
6617 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
6621 result = static_cast<std::size_t>(number);
6627 std::int32_t number;
6628 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
6632 result = static_cast<std::size_t>(number);
6638 std::int64_t number;
6639 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
6643 result = static_cast<std::size_t>(number);
6649 auto last_token = get_token_string();
6650 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size")));
6656 @brief determine the type and size for a container
6658 In the optimized UBJSON format, a type and a size can be provided to allow
6659 for a more compact representation.
6661 @param[out] result pair of the size and the type
6663 @return whether pair creation completed
6665 bool get_ubjson_size_type(std::pair<std::size_t, int>& result)
6667 result.first = string_t::npos; // size
6668 result.second = 0; // type
6674 result.second = get(); // must not ignore 'N', because 'N' maybe the type
6675 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "type")))
6681 if (JSON_HEDLEY_UNLIKELY(current != '#'))
6683 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
6687 auto last_token = get_token_string();
6688 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size")));
6691 return get_ubjson_size_value(result.first);
6696 return get_ubjson_size_value(result.first);
6703 @param prefix the previously read or set type prefix
6704 @return whether value creation completed
6706 bool get_ubjson_value(const int prefix)
6710 case std::char_traits<char>::eof(): // EOF
6711 return unexpect_eof(input_format_t::ubjson, "value");
6714 return sax->boolean(true);
6716 return sax->boolean(false);
6723 std::uint8_t number;
6724 return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number);
6730 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
6735 std::int16_t number;
6736 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
6741 std::int32_t number;
6742 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
6747 std::int64_t number;
6748 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
6754 return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
6760 return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
6766 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char")))
6770 if (JSON_HEDLEY_UNLIKELY(current > 127))
6772 auto last_token = get_token_string();
6773 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char")));
6775 string_t s(1, static_cast<char>(current));
6776 return sax->string(s);
6782 return get_ubjson_string(s) and sax->string(s);
6786 return get_ubjson_array();
6789 return get_ubjson_object();
6791 default: // anything else
6793 auto last_token = get_token_string();
6794 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value")));
6800 @return whether array creation completed
6802 bool get_ubjson_array()
6804 std::pair<std::size_t, int> size_and_type;
6805 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
6810 if (size_and_type.first != string_t::npos)
6812 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(size_and_type.first)))
6817 if (size_and_type.second != 0)
6819 if (size_and_type.second != 'N')
6821 for (std::size_t i = 0; i < size_and_type.first; ++i)
6823 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second)))
6832 for (std::size_t i = 0; i < size_and_type.first; ++i)
6834 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
6843 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
6848 while (current != ']')
6850 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal(false)))
6858 return sax->end_array();
6862 @return whether object creation completed
6864 bool get_ubjson_object()
6866 std::pair<std::size_t, int> size_and_type;
6867 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
6873 if (size_and_type.first != string_t::npos)
6875 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(size_and_type.first)))
6880 if (size_and_type.second != 0)
6882 for (std::size_t i = 0; i < size_and_type.first; ++i)
6884 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
6888 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second)))
6897 for (std::size_t i = 0; i < size_and_type.first; ++i)
6899 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
6903 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
6913 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
6918 while (current != '}')
6920 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key, false) or not sax->key(key)))
6924 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
6933 return sax->end_object();
6936 ///////////////////////
6937 // Utility functions //
6938 ///////////////////////
6941 @brief get next character from the input
6943 This function provides the interface to the used input adapter. It does
6944 not throw in case the input reached EOF, but returns a -'ve valued
6945 `std::char_traits<char>::eof()` in that case.
6947 @return character read from the input
6952 return current = ia->get_character();
6956 @return character read from the input after ignoring all 'N' entries
6958 int get_ignore_noop()
6964 while (current == 'N');
6970 @brief read a number from the input
6972 @tparam NumberType the type of the number
6973 @param[in] format the current format (for diagnostics)
6974 @param[out] result number of type @a NumberType
6976 @return whether conversion completed
6978 @note This function needs to respect the system's endianess, because
6979 bytes in CBOR, MessagePack, and UBJSON are stored in network order
6980 (big endian) and therefore need reordering on little endian systems.
6982 template<typename NumberType, bool InputIsLittleEndian = false>
6983 bool get_number(const input_format_t format, NumberType& result)
6985 // step 1: read input into array with system's byte order
6986 std::array<std::uint8_t, sizeof(NumberType)> vec;
6987 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
6990 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format, "number")))
6995 // reverse byte order prior to conversion if necessary
6996 if (is_little_endian != InputIsLittleEndian)
6998 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
7002 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
7006 // step 2: convert array into number of type T and return
7007 std::memcpy(&result, vec.data(), sizeof(NumberType));
7012 @brief create a string by reading characters from the input
7014 @tparam NumberType the type of the number
7015 @param[in] format the current format (for diagnostics)
7016 @param[in] len number of characters to read
7017 @param[out] result string created by reading @a len bytes
7019 @return whether string creation completed
7021 @note We can not reserve @a len bytes for the result, because @a len
7022 may be too large. Usually, @ref unexpect_eof() detects the end of
7023 the input before we run out of string memory.
7025 template<typename NumberType>
7026 bool get_string(const input_format_t format,
7027 const NumberType len,
7030 bool success = true;
7031 std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
7034 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format, "string")))
7038 return static_cast<char>(current);
7044 @param[in] format the current format (for diagnostics)
7045 @param[in] context further context information (for diagnostics)
7046 @return whether the last read character is not EOF
7048 JSON_HEDLEY_NON_NULL(3)
7049 bool unexpect_eof(const input_format_t format, const char* context) const
7051 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char>::eof()))
7053 return sax->parse_error(chars_read, "<end of file>",
7054 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
7060 @return a string representation of the last read byte
7062 std::string get_token_string() const
7064 std::array<char, 3> cr{{}};
7065 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current));
7066 return std::string{cr.data()};
7070 @param[in] format the current format
7071 @param[in] detail a detailed error message
7072 @param[in] context further context information
7073 @return a message string to use in the parse_error exceptions
7075 std::string exception_message(const input_format_t format,
7076 const std::string& detail,
7077 const std::string& context) const
7079 std::string error_msg = "syntax error while parsing ";
7083 case input_format_t::cbor:
7084 error_msg += "CBOR";
7087 case input_format_t::msgpack:
7088 error_msg += "MessagePack";
7091 case input_format_t::ubjson:
7092 error_msg += "UBJSON";
7095 case input_format_t::bson:
7096 error_msg += "BSON";
7099 default: // LCOV_EXCL_LINE
7100 assert(false); // LCOV_EXCL_LINE
7103 return error_msg + " " + context + ": " + detail;
7108 input_adapter_t ia = nullptr;
7110 /// the current character
7111 int current = std::char_traits<char>::eof();
7113 /// the number of characters read
7114 std::size_t chars_read = 0;
7116 /// whether we can assume little endianess
7117 const bool is_little_endian = little_endianess();
7120 json_sax_t* sax = nullptr;
7122 } // namespace detail
7123 } // namespace nlohmann
7125 // #include <nlohmann/detail/input/input_adapters.hpp>
7127 // #include <nlohmann/detail/input/lexer.hpp>
7130 #include <array> // array
7131 #include <clocale> // localeconv
7132 #include <cstddef> // size_t
7133 #include <cstdio> // snprintf
7134 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
7135 #include <initializer_list> // initializer_list
7136 #include <string> // char_traits, string
7137 #include <utility> // move
7138 #include <vector> // vector
7140 // #include <nlohmann/detail/input/input_adapters.hpp>
7142 // #include <nlohmann/detail/input/position_t.hpp>
7144 // #include <nlohmann/detail/macro_scope.hpp>
7156 @brief lexical analysis
7158 This class organizes the lexical analysis during JSON deserialization.
7160 template<typename BasicJsonType>
7163 using number_integer_t = typename BasicJsonType::number_integer_t;
7164 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7165 using number_float_t = typename BasicJsonType::number_float_t;
7166 using string_t = typename BasicJsonType::string_t;
7169 /// token types for the parser
7170 enum class token_type
7172 uninitialized, ///< indicating the scanner is uninitialized
7173 literal_true, ///< the `true` literal
7174 literal_false, ///< the `false` literal
7175 literal_null, ///< the `null` literal
7176 value_string, ///< a string -- use get_string() for actual value
7177 value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value
7178 value_integer, ///< a signed integer -- use get_number_integer() for actual value
7179 value_float, ///< an floating point number -- use get_number_float() for actual value
7180 begin_array, ///< the character for array begin `[`
7181 begin_object, ///< the character for object begin `{`
7182 end_array, ///< the character for array end `]`
7183 end_object, ///< the character for object end `}`
7184 name_separator, ///< the name separator `:`
7185 value_separator, ///< the value separator `,`
7186 parse_error, ///< indicating a parse error
7187 end_of_input, ///< indicating the end of the input buffer
7188 literal_or_value ///< a literal or the begin of a value (only for diagnostics)
7191 /// return name of values of type token_type (only used for errors)
7192 JSON_HEDLEY_RETURNS_NON_NULL
7194 static const char* token_type_name(const token_type t) noexcept
7198 case token_type::uninitialized:
7199 return "<uninitialized>";
7200 case token_type::literal_true:
7201 return "true literal";
7202 case token_type::literal_false:
7203 return "false literal";
7204 case token_type::literal_null:
7205 return "null literal";
7206 case token_type::value_string:
7207 return "string literal";
7208 case lexer::token_type::value_unsigned:
7209 case lexer::token_type::value_integer:
7210 case lexer::token_type::value_float:
7211 return "number literal";
7212 case token_type::begin_array:
7214 case token_type::begin_object:
7216 case token_type::end_array:
7218 case token_type::end_object:
7220 case token_type::name_separator:
7222 case token_type::value_separator:
7224 case token_type::parse_error:
7225 return "<parse error>";
7226 case token_type::end_of_input:
7227 return "end of input";
7228 case token_type::literal_or_value:
7229 return "'[', '{', or a literal";
7231 default: // catch non-enum values
7232 return "unknown token";
7237 explicit lexer(detail::input_adapter_t&& adapter)
7238 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
7240 // delete because of pointer members
7241 lexer(const lexer&) = delete;
7242 lexer(lexer&&) = delete;
7243 lexer& operator=(lexer&) = delete;
7244 lexer& operator=(lexer&&) = delete;
7248 /////////////////////
7250 /////////////////////
7252 /// return the locale-dependent decimal point
7254 static char get_decimal_point() noexcept
7256 const auto loc = localeconv();
7257 assert(loc != nullptr);
7258 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
7261 /////////////////////
7263 /////////////////////
7266 @brief get codepoint from 4 hex characters following `\u`
7268 For input "\u c1 c2 c3 c4" the codepoint is:
7269 (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
7270 = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
7272 Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
7273 must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
7274 conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
7275 between the ASCII value of the character and the desired integer value.
7277 @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
7282 // this function only makes sense after reading `\u`
7283 assert(current == 'u');
7286 const auto factors = { 12u, 8u, 4u, 0u };
7287 for (const auto factor : factors)
7291 if (current >= '0' and current <= '9')
7293 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
7295 else if (current >= 'A' and current <= 'F')
7297 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
7299 else if (current >= 'a' and current <= 'f')
7301 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
7309 assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
7314 @brief check if the next byte(s) are inside a given range
7316 Adds the current byte and, for each passed range, reads a new byte and
7317 checks if it is inside the range. If a violation was detected, set up an
7318 error message and return false. Otherwise, return true.
7320 @param[in] ranges list of integers; interpreted as list of pairs of
7321 inclusive lower and upper bound, respectively
7323 @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
7324 1, 2, or 3 pairs. This precondition is enforced by an assertion.
7326 @return true if and only if no range violation was detected
7328 bool next_byte_in_range(std::initializer_list<int> ranges)
7330 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
7333 for (auto range = ranges.begin(); range != ranges.end(); ++range)
7336 if (JSON_HEDLEY_LIKELY(*range <= current and current <= *(++range)))
7342 error_message = "invalid string: ill-formed UTF-8 byte";
7351 @brief scan a string literal
7353 This function scans a string according to Sect. 7 of RFC 7159. While
7354 scanning, bytes are escaped and copied into buffer token_buffer. Then the
7355 function returns successfully, token_buffer is *not* null-terminated (as it
7356 may contain \0 bytes), and token_buffer.size() is the number of bytes in the
7359 @return token_type::value_string if string could be successfully scanned,
7360 token_type::parse_error otherwise
7362 @note In case of errors, variable error_message contains a textual
7365 token_type scan_string()
7367 // reset token_buffer (ignore opening quote)
7370 // we entered the function by reading an open quote
7371 assert(current == '\"');
7375 // get next character
7378 // end of file while parsing string
7379 case std::char_traits<char>::eof():
7381 error_message = "invalid string: missing closing quote";
7382 return token_type::parse_error;
7388 return token_type::value_string;
7432 const int codepoint1 = get_codepoint();
7433 int codepoint = codepoint1; // start with codepoint1
7435 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
7437 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7438 return token_type::parse_error;
7441 // check if code point is a high surrogate
7442 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
7444 // expect next \uxxxx entry
7445 if (JSON_HEDLEY_LIKELY(get() == '\\' and get() == 'u'))
7447 const int codepoint2 = get_codepoint();
7449 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
7451 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7452 return token_type::parse_error;
7455 // check if codepoint2 is a low surrogate
7456 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
7458 // overwrite codepoint
7459 codepoint = static_cast<int>(
7460 // high surrogate occupies the most significant 22 bits
7461 (static_cast<unsigned int>(codepoint1) << 10u)
7462 // low surrogate occupies the least significant 15 bits
7463 + static_cast<unsigned int>(codepoint2)
7464 // there is still the 0xD800, 0xDC00 and 0x10000 noise
7465 // in the result so we have to subtract with:
7466 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
7471 error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
7472 return token_type::parse_error;
7477 error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
7478 return token_type::parse_error;
7483 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
7485 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
7486 return token_type::parse_error;
7490 // result of the above calculation yields a proper codepoint
7491 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
7493 // translate codepoint into bytes
7494 if (codepoint < 0x80)
7496 // 1-byte characters: 0xxxxxxx (ASCII)
7499 else if (codepoint <= 0x7FF)
7501 // 2-byte characters: 110xxxxx 10xxxxxx
7502 add(static_cast<int>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
7503 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7505 else if (codepoint <= 0xFFFF)
7507 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7508 add(static_cast<int>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7509 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7510 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7514 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7515 add(static_cast<int>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7516 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7517 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7518 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7524 // other characters after escape
7526 error_message = "invalid string: forbidden character after backslash";
7527 return token_type::parse_error;
7533 // invalid control characters
7536 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7537 return token_type::parse_error;
7542 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7543 return token_type::parse_error;
7548 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7549 return token_type::parse_error;
7554 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7555 return token_type::parse_error;
7560 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7561 return token_type::parse_error;
7566 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7567 return token_type::parse_error;
7572 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7573 return token_type::parse_error;
7578 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7579 return token_type::parse_error;
7584 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7585 return token_type::parse_error;
7590 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7591 return token_type::parse_error;
7596 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7597 return token_type::parse_error;
7602 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7603 return token_type::parse_error;
7608 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7609 return token_type::parse_error;
7614 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7615 return token_type::parse_error;
7620 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7621 return token_type::parse_error;
7626 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7627 return token_type::parse_error;
7632 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7633 return token_type::parse_error;
7638 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7639 return token_type::parse_error;
7644 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7645 return token_type::parse_error;
7650 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7651 return token_type::parse_error;
7656 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7657 return token_type::parse_error;
7662 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7663 return token_type::parse_error;
7668 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7669 return token_type::parse_error;
7674 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7675 return token_type::parse_error;
7680 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7681 return token_type::parse_error;
7686 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7687 return token_type::parse_error;
7692 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7693 return token_type::parse_error;
7698 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7699 return token_type::parse_error;
7704 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7705 return token_type::parse_error;
7710 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7711 return token_type::parse_error;
7716 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7717 return token_type::parse_error;
7722 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7723 return token_type::parse_error;
7726 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7826 // U+0080..U+07FF: bytes C2..DF 80..BF
7858 if (JSON_HEDLEY_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
7860 return token_type::parse_error;
7865 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7868 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7870 return token_type::parse_error;
7875 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7876 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7892 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
7894 return token_type::parse_error;
7899 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7902 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
7904 return token_type::parse_error;
7909 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7912 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7914 return token_type::parse_error;
7919 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7924 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7926 return token_type::parse_error;
7931 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7934 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
7936 return token_type::parse_error;
7941 // remaining bytes (80..C1 and F5..FF) are ill-formed
7944 error_message = "invalid string: ill-formed UTF-8 byte";
7945 return token_type::parse_error;
7951 JSON_HEDLEY_NON_NULL(2)
7952 static void strtof(float& f, const char* str, char** endptr) noexcept
7954 f = std::strtof(str, endptr);
7957 JSON_HEDLEY_NON_NULL(2)
7958 static void strtof(double& f, const char* str, char** endptr) noexcept
7960 f = std::strtod(str, endptr);
7963 JSON_HEDLEY_NON_NULL(2)
7964 static void strtof(long double& f, const char* str, char** endptr) noexcept
7966 f = std::strtold(str, endptr);
7970 @brief scan a number literal
7972 This function scans a string according to Sect. 6 of RFC 7159.
7974 The function is realized with a deterministic finite state machine derived
7975 from the grammar described in RFC 7159. Starting in state "init", the
7976 input is read and used to determined the next state. Only state "done"
7977 accepts the number. State "error" is a trap state to model errors. In the
7978 table below, "anything" means any character but the ones listed before.
7980 state | 0 | 1-9 | e E | + | - | . | anything
7981 ---------|----------|----------|----------|---------|---------|----------|-----------
7982 init | zero | any1 | [error] | [error] | minus | [error] | [error]
7983 minus | zero | any1 | [error] | [error] | [error] | [error] | [error]
7984 zero | done | done | exponent | done | done | decimal1 | done
7985 any1 | any1 | any1 | exponent | done | done | decimal1 | done
7986 decimal1 | decimal2 | [error] | [error] | [error] | [error] | [error] | [error]
7987 decimal2 | decimal2 | decimal2 | exponent | done | done | done | done
7988 exponent | any2 | any2 | [error] | sign | sign | [error] | [error]
7989 sign | any2 | any2 | [error] | [error] | [error] | [error] | [error]
7990 any2 | any2 | any2 | done | done | done | done | done
7992 The state machine is realized with one label per state (prefixed with
7993 "scan_number_") and `goto` statements between them. The state machine
7994 contains cycles, but any cycle can be left when EOF is read. Therefore,
7995 the function is guaranteed to terminate.
7997 During scanning, the read bytes are stored in token_buffer. This string is
7998 then converted to a signed integer, an unsigned integer, or a
7999 floating-point number.
8001 @return token_type::value_unsigned, token_type::value_integer, or
8002 token_type::value_float if number could be successfully scanned,
8003 token_type::parse_error otherwise
8005 @note The scanner is independent of the current locale. Internally, the
8006 locale's decimal point is used instead of `.` to work with the
8007 locale-dependent converters.
8009 token_type scan_number() // lgtm [cpp/use-of-goto]
8011 // reset token_buffer to store the number's bytes
8014 // the type of the parsed number; initially set to unsigned; will be
8015 // changed if minus sign, decimal point or exponent is read
8016 token_type number_type = token_type::value_unsigned;
8018 // state (init): we just found out we need to scan a number
8024 goto scan_number_minus;
8030 goto scan_number_zero;
8044 goto scan_number_any1;
8047 // all other characters are rejected outside scan_number()
8048 default: // LCOV_EXCL_LINE
8049 assert(false); // LCOV_EXCL_LINE
8053 // state: we just parsed a leading minus sign
8054 number_type = token_type::value_integer;
8060 goto scan_number_zero;
8074 goto scan_number_any1;
8079 error_message = "invalid number; expected digit after '-'";
8080 return token_type::parse_error;
8085 // state: we just parse a zero (maybe with a leading minus sign)
8090 add(decimal_point_char);
8091 goto scan_number_decimal1;
8098 goto scan_number_exponent;
8102 goto scan_number_done;
8106 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
8121 goto scan_number_any1;
8126 add(decimal_point_char);
8127 goto scan_number_decimal1;
8134 goto scan_number_exponent;
8138 goto scan_number_done;
8141 scan_number_decimal1:
8142 // state: we just parsed a decimal point
8143 number_type = token_type::value_float;
8158 goto scan_number_decimal2;
8163 error_message = "invalid number; expected digit after '.'";
8164 return token_type::parse_error;
8168 scan_number_decimal2:
8169 // we just parsed at least one number after a decimal point
8184 goto scan_number_decimal2;
8191 goto scan_number_exponent;
8195 goto scan_number_done;
8198 scan_number_exponent:
8199 // we just parsed an exponent
8200 number_type = token_type::value_float;
8207 goto scan_number_sign;
8222 goto scan_number_any2;
8228 "invalid number; expected '+', '-', or digit after exponent";
8229 return token_type::parse_error;
8234 // we just parsed an exponent sign
8249 goto scan_number_any2;
8254 error_message = "invalid number; expected digit after exponent sign";
8255 return token_type::parse_error;
8260 // we just parsed a number after the exponent or exponent sign
8275 goto scan_number_any2;
8279 goto scan_number_done;
8283 // unget the character after the number (we only read it to know that
8284 // we are done scanning a number)
8287 char* endptr = nullptr;
8290 // try to parse integers first and fall back to floats
8291 if (number_type == token_type::value_unsigned)
8293 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
8295 // we checked the number format before
8296 assert(endptr == token_buffer.data() + token_buffer.size());
8300 value_unsigned = static_cast<number_unsigned_t>(x);
8301 if (value_unsigned == x)
8303 return token_type::value_unsigned;
8307 else if (number_type == token_type::value_integer)
8309 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
8311 // we checked the number format before
8312 assert(endptr == token_buffer.data() + token_buffer.size());
8316 value_integer = static_cast<number_integer_t>(x);
8317 if (value_integer == x)
8319 return token_type::value_integer;
8324 // this code is reached if we parse a floating-point number or if an
8325 // integer conversion above failed
8326 strtof(value_float, token_buffer.data(), &endptr);
8328 // we checked the number format before
8329 assert(endptr == token_buffer.data() + token_buffer.size());
8331 return token_type::value_float;
8335 @param[in] literal_text the literal text to expect
8336 @param[in] length the length of the passed literal text
8337 @param[in] return_type the token type to return on success
8339 JSON_HEDLEY_NON_NULL(2)
8340 token_type scan_literal(const char* literal_text, const std::size_t length,
8341 token_type return_type)
8343 assert(current == literal_text[0]);
8344 for (std::size_t i = 1; i < length; ++i)
8346 if (JSON_HEDLEY_UNLIKELY(get() != literal_text[i]))
8348 error_message = "invalid literal";
8349 return token_type::parse_error;
8355 /////////////////////
8357 /////////////////////
8359 /// reset token_buffer; current character is beginning of token
8360 void reset() noexcept
8362 token_buffer.clear();
8363 token_string.clear();
8364 token_string.push_back(std::char_traits<char>::to_char_type(current));
8368 @brief get next character from the input
8370 This function provides the interface to the used input adapter. It does
8371 not throw in case the input reached EOF, but returns a
8372 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
8373 for use in error messages.
8375 @return character read from the input
8377 std::char_traits<char>::int_type get()
8379 ++position.chars_read_total;
8380 ++position.chars_read_current_line;
8384 // just reset the next_unget variable and work with current
8389 current = ia->get_character();
8392 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char>::eof()))
8394 token_string.push_back(std::char_traits<char>::to_char_type(current));
8397 if (current == '\n')
8399 ++position.lines_read;
8400 position.chars_read_current_line = 0;
8407 @brief unget current character (read it again on next get)
8409 We implement unget by setting variable next_unget to true. The input is not
8410 changed - we just simulate ungetting by modifying chars_read_total,
8411 chars_read_current_line, and token_string. The next call to get() will
8412 behave as if the unget character is read again.
8418 --position.chars_read_total;
8420 // in case we "unget" a newline, we have to also decrement the lines_read
8421 if (position.chars_read_current_line == 0)
8423 if (position.lines_read > 0)
8425 --position.lines_read;
8430 --position.chars_read_current_line;
8433 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char>::eof()))
8435 assert(not token_string.empty());
8436 token_string.pop_back();
8440 /// add a character to token_buffer
8443 token_buffer.push_back(std::char_traits<char>::to_char_type(c));
8447 /////////////////////
8449 /////////////////////
8451 /// return integer value
8452 constexpr number_integer_t get_number_integer() const noexcept
8454 return value_integer;
8457 /// return unsigned integer value
8458 constexpr number_unsigned_t get_number_unsigned() const noexcept
8460 return value_unsigned;
8463 /// return floating-point value
8464 constexpr number_float_t get_number_float() const noexcept
8469 /// return current string value (implicitly resets the token; useful only once)
8470 string_t& get_string()
8472 return token_buffer;
8475 /////////////////////
8477 /////////////////////
8479 /// return position of last read token
8480 constexpr position_t get_position() const noexcept
8485 /// return the last read token (for errors only). Will never contain EOF
8486 /// (an arbitrary value that is not a valid char value, often -1), because
8487 /// 255 may legitimately occur. May contain NUL, which should be escaped.
8488 std::string get_token_string() const
8490 // escape control characters
8492 for (const auto c : token_string)
8494 if ('\x00' <= c and c <= '\x1F')
8496 // escape control characters
8497 std::array<char, 9> cs{{}};
8498 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c));
8499 result += cs.data();
8503 // add character as is
8504 result.push_back(c);
8511 /// return syntax error message
8512 JSON_HEDLEY_RETURNS_NON_NULL
8513 constexpr const char* get_error_message() const noexcept
8515 return error_message;
8518 /////////////////////
8520 /////////////////////
8523 @brief skip the UTF-8 byte order mark
8524 @return true iff there is no BOM or the correct BOM has been skipped
8530 // check if we completely parse the BOM
8531 return get() == 0xBB and get() == 0xBF;
8534 // the first character is not the beginning of the BOM; unget it to
8542 // initially, skip the BOM
8543 if (position.chars_read_total == 0 and not skip_bom())
8545 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8546 return token_type::parse_error;
8549 // read next character and ignore whitespace
8554 while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
8558 // structural characters
8560 return token_type::begin_array;
8562 return token_type::end_array;
8564 return token_type::begin_object;
8566 return token_type::end_object;
8568 return token_type::name_separator;
8570 return token_type::value_separator;
8574 return scan_literal("true", 4, token_type::literal_true);
8576 return scan_literal("false", 5, token_type::literal_false);
8578 return scan_literal("null", 4, token_type::literal_null);
8582 return scan_string();
8596 return scan_number();
8598 // end of input (the null byte is needed when parsing from
8601 case std::char_traits<char>::eof():
8602 return token_type::end_of_input;
8606 error_message = "invalid literal";
8607 return token_type::parse_error;
8613 detail::input_adapter_t ia = nullptr;
8615 /// the current character
8616 std::char_traits<char>::int_type current = std::char_traits<char>::eof();
8618 /// whether the next get() call should just return current
8619 bool next_unget = false;
8621 /// the start position of the current token
8622 position_t position {};
8624 /// raw input token string (for error messages)
8625 std::vector<char> token_string {};
8627 /// buffer for variable-length tokens (numbers, strings)
8628 string_t token_buffer {};
8630 /// a description of occurred lexer errors
8631 const char* error_message = "";
8634 number_integer_t value_integer = 0;
8635 number_unsigned_t value_unsigned = 0;
8636 number_float_t value_float = 0;
8638 /// the decimal point
8639 const char decimal_point_char = '.';
8641 } // namespace detail
8642 } // namespace nlohmann
8644 // #include <nlohmann/detail/input/parser.hpp>
8647 #include <cassert> // assert
8648 #include <cmath> // isfinite
8649 #include <cstdint> // uint8_t
8650 #include <functional> // function
8651 #include <string> // string
8652 #include <utility> // move
8653 #include <vector> // vector
8655 // #include <nlohmann/detail/exceptions.hpp>
8657 // #include <nlohmann/detail/input/input_adapters.hpp>
8659 // #include <nlohmann/detail/input/json_sax.hpp>
8661 // #include <nlohmann/detail/input/lexer.hpp>
8663 // #include <nlohmann/detail/macro_scope.hpp>
8665 // #include <nlohmann/detail/meta/is_sax.hpp>
8667 // #include <nlohmann/detail/value_t.hpp>
8679 @brief syntax analysis
8681 This class implements a recursive decent parser.
8683 template<typename BasicJsonType>
8686 using number_integer_t = typename BasicJsonType::number_integer_t;
8687 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8688 using number_float_t = typename BasicJsonType::number_float_t;
8689 using string_t = typename BasicJsonType::string_t;
8690 using lexer_t = lexer<BasicJsonType>;
8691 using token_type = typename lexer_t::token_type;
8694 enum class parse_event_t : uint8_t
8696 /// the parser read `{` and started to process a JSON object
8698 /// the parser read `}` and finished processing a JSON object
8700 /// the parser read `[` and started to process a JSON array
8702 /// the parser read `]` and finished processing a JSON array
8704 /// the parser read a key of a value in an object
8706 /// the parser finished reading a JSON value
8710 using parser_callback_t =
8711 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
8713 /// a parser reading from an input adapter
8714 explicit parser(detail::input_adapter_t&& adapter,
8715 const parser_callback_t cb = nullptr,
8716 const bool allow_exceptions_ = true)
8717 : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
8724 @brief public parser interface
8726 @param[in] strict whether to expect the last token to be EOF
8727 @param[in,out] result parsed JSON value
8729 @throw parse_error.101 in case of an unexpected token
8730 @throw parse_error.102 if to_unicode fails or surrogate error
8731 @throw parse_error.103 if to_unicode fails
8733 void parse(const bool strict, BasicJsonType& result)
8737 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
8738 sax_parse_internal(&sdp);
8739 result.assert_invariant();
8741 // in strict mode, input must be completely read
8742 if (strict and (get_token() != token_type::end_of_input))
8744 sdp.parse_error(m_lexer.get_position(),
8745 m_lexer.get_token_string(),
8746 parse_error::create(101, m_lexer.get_position(),
8747 exception_message(token_type::end_of_input, "value")));
8750 // in case of an error, return discarded value
8751 if (sdp.is_errored())
8753 result = value_t::discarded;
8757 // set top-level value to null if it was discarded by the callback
8759 if (result.is_discarded())
8766 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
8767 sax_parse_internal(&sdp);
8768 result.assert_invariant();
8770 // in strict mode, input must be completely read
8771 if (strict and (get_token() != token_type::end_of_input))
8773 sdp.parse_error(m_lexer.get_position(),
8774 m_lexer.get_token_string(),
8775 parse_error::create(101, m_lexer.get_position(),
8776 exception_message(token_type::end_of_input, "value")));
8779 // in case of an error, return discarded value
8780 if (sdp.is_errored())
8782 result = value_t::discarded;
8789 @brief public accept interface
8791 @param[in] strict whether to expect the last token to be EOF
8792 @return whether the input is a proper JSON text
8794 bool accept(const bool strict = true)
8796 json_sax_acceptor<BasicJsonType> sax_acceptor;
8797 return sax_parse(&sax_acceptor, strict);
8800 template <typename SAX>
8801 JSON_HEDLEY_NON_NULL(2)
8802 bool sax_parse(SAX* sax, const bool strict = true)
8804 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
8805 const bool result = sax_parse_internal(sax);
8807 // strict mode: next byte must be EOF
8808 if (result and strict and (get_token() != token_type::end_of_input))
8810 return sax->parse_error(m_lexer.get_position(),
8811 m_lexer.get_token_string(),
8812 parse_error::create(101, m_lexer.get_position(),
8813 exception_message(token_type::end_of_input, "value")));
8820 template <typename SAX>
8821 JSON_HEDLEY_NON_NULL(2)
8822 bool sax_parse_internal(SAX* sax)
8824 // stack to remember the hierarchy of structured values we are parsing
8825 // true = array; false = object
8826 std::vector<bool> states;
8827 // value to avoid a goto (see comment where set to true)
8828 bool skip_to_state_evaluation = false;
8832 if (not skip_to_state_evaluation)
8834 // invariant: get_token() was called before each iteration
8837 case token_type::begin_object:
8839 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
8844 // closing } -> we are done
8845 if (get_token() == token_type::end_object)
8847 if (JSON_HEDLEY_UNLIKELY(not sax->end_object()))
8855 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
8857 return sax->parse_error(m_lexer.get_position(),
8858 m_lexer.get_token_string(),
8859 parse_error::create(101, m_lexer.get_position(),
8860 exception_message(token_type::value_string, "object key")));
8862 if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
8867 // parse separator (:)
8868 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
8870 return sax->parse_error(m_lexer.get_position(),
8871 m_lexer.get_token_string(),
8872 parse_error::create(101, m_lexer.get_position(),
8873 exception_message(token_type::name_separator, "object separator")));
8876 // remember we are now inside an object
8877 states.push_back(false);
8884 case token_type::begin_array:
8886 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
8891 // closing ] -> we are done
8892 if (get_token() == token_type::end_array)
8894 if (JSON_HEDLEY_UNLIKELY(not sax->end_array()))
8901 // remember we are now inside an array
8902 states.push_back(true);
8904 // parse values (no need to call get_token)
8908 case token_type::value_float:
8910 const auto res = m_lexer.get_number_float();
8912 if (JSON_HEDLEY_UNLIKELY(not std::isfinite(res)))
8914 return sax->parse_error(m_lexer.get_position(),
8915 m_lexer.get_token_string(),
8916 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
8919 if (JSON_HEDLEY_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
8927 case token_type::literal_false:
8929 if (JSON_HEDLEY_UNLIKELY(not sax->boolean(false)))
8936 case token_type::literal_null:
8938 if (JSON_HEDLEY_UNLIKELY(not sax->null()))
8945 case token_type::literal_true:
8947 if (JSON_HEDLEY_UNLIKELY(not sax->boolean(true)))
8954 case token_type::value_integer:
8956 if (JSON_HEDLEY_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
8963 case token_type::value_string:
8965 if (JSON_HEDLEY_UNLIKELY(not sax->string(m_lexer.get_string())))
8972 case token_type::value_unsigned:
8974 if (JSON_HEDLEY_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
8981 case token_type::parse_error:
8983 // using "uninitialized" to avoid "expected" message
8984 return sax->parse_error(m_lexer.get_position(),
8985 m_lexer.get_token_string(),
8986 parse_error::create(101, m_lexer.get_position(),
8987 exception_message(token_type::uninitialized, "value")));
8990 default: // the last token was unexpected
8992 return sax->parse_error(m_lexer.get_position(),
8993 m_lexer.get_token_string(),
8994 parse_error::create(101, m_lexer.get_position(),
8995 exception_message(token_type::literal_or_value, "value")));
9001 skip_to_state_evaluation = false;
9004 // we reached this line after we successfully parsed a value
9007 // empty stack: we reached the end of the hierarchy: done
9011 if (states.back()) // array
9013 // comma -> next value
9014 if (get_token() == token_type::value_separator)
9016 // parse a new value
9022 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
9024 if (JSON_HEDLEY_UNLIKELY(not sax->end_array()))
9029 // We are done with this array. Before we can parse a
9030 // new value, we need to evaluate the new state first.
9031 // By setting skip_to_state_evaluation to false, we
9032 // are effectively jumping to the beginning of this if.
9033 assert(not states.empty());
9035 skip_to_state_evaluation = true;
9039 return sax->parse_error(m_lexer.get_position(),
9040 m_lexer.get_token_string(),
9041 parse_error::create(101, m_lexer.get_position(),
9042 exception_message(token_type::end_array, "array")));
9046 // comma -> next value
9047 if (get_token() == token_type::value_separator)
9050 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
9052 return sax->parse_error(m_lexer.get_position(),
9053 m_lexer.get_token_string(),
9054 parse_error::create(101, m_lexer.get_position(),
9055 exception_message(token_type::value_string, "object key")));
9058 if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
9063 // parse separator (:)
9064 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
9066 return sax->parse_error(m_lexer.get_position(),
9067 m_lexer.get_token_string(),
9068 parse_error::create(101, m_lexer.get_position(),
9069 exception_message(token_type::name_separator, "object separator")));
9078 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
9080 if (JSON_HEDLEY_UNLIKELY(not sax->end_object()))
9085 // We are done with this object. Before we can parse a
9086 // new value, we need to evaluate the new state first.
9087 // By setting skip_to_state_evaluation to false, we
9088 // are effectively jumping to the beginning of this if.
9089 assert(not states.empty());
9091 skip_to_state_evaluation = true;
9095 return sax->parse_error(m_lexer.get_position(),
9096 m_lexer.get_token_string(),
9097 parse_error::create(101, m_lexer.get_position(),
9098 exception_message(token_type::end_object, "object")));
9103 /// get next token from lexer
9104 token_type get_token()
9106 return last_token = m_lexer.scan();
9109 std::string exception_message(const token_type expected, const std::string& context)
9111 std::string error_msg = "syntax error ";
9113 if (not context.empty())
9115 error_msg += "while parsing " + context + " ";
9120 if (last_token == token_type::parse_error)
9122 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
9123 m_lexer.get_token_string() + "'";
9127 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
9130 if (expected != token_type::uninitialized)
9132 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
9139 /// callback function
9140 const parser_callback_t callback = nullptr;
9141 /// the type of the last read token
9142 token_type last_token = token_type::uninitialized;
9145 /// whether to throw exceptions in case of errors
9146 const bool allow_exceptions = true;
9148 } // namespace detail
9149 } // namespace nlohmann
9151 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
9154 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
9157 #include <cstddef> // ptrdiff_t
9158 #include <limits> // numeric_limits
9165 @brief an iterator for primitive JSON types
9167 This class models an iterator for primitive JSON types (boolean, number,
9168 string). It's only purpose is to allow the iterator/const_iterator classes
9169 to "iterate" over primitive values. Internally, the iterator is modeled by
9170 a `difference_type` variable. Value begin_value (`0`) models the begin,
9171 end_value (`1`) models past the end.
9173 class primitive_iterator_t
9176 using difference_type = std::ptrdiff_t;
9177 static constexpr difference_type begin_value = 0;
9178 static constexpr difference_type end_value = begin_value + 1;
9180 /// iterator as signed integer type
9181 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
9184 constexpr difference_type get_value() const noexcept
9189 /// set iterator to a defined beginning
9190 void set_begin() noexcept
9195 /// set iterator to a defined past the end
9196 void set_end() noexcept
9201 /// return whether the iterator can be dereferenced
9202 constexpr bool is_begin() const noexcept
9204 return m_it == begin_value;
9207 /// return whether the iterator is at end
9208 constexpr bool is_end() const noexcept
9210 return m_it == end_value;
9213 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
9215 return lhs.m_it == rhs.m_it;
9218 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
9220 return lhs.m_it < rhs.m_it;
9223 primitive_iterator_t operator+(difference_type n) noexcept
9225 auto result = *this;
9230 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
9232 return lhs.m_it - rhs.m_it;
9235 primitive_iterator_t& operator++() noexcept
9241 primitive_iterator_t const operator++(int) noexcept
9243 auto result = *this;
9248 primitive_iterator_t& operator--() noexcept
9254 primitive_iterator_t const operator--(int) noexcept
9256 auto result = *this;
9261 primitive_iterator_t& operator+=(difference_type n) noexcept
9267 primitive_iterator_t& operator-=(difference_type n) noexcept
9273 } // namespace detail
9274 } // namespace nlohmann
9282 @brief an iterator value
9284 @note This structure could easily be a union, but MSVC currently does not allow
9285 unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
9287 template<typename BasicJsonType> struct internal_iterator
9289 /// iterator for JSON objects
9290 typename BasicJsonType::object_t::iterator object_iterator {};
9291 /// iterator for JSON arrays
9292 typename BasicJsonType::array_t::iterator array_iterator {};
9293 /// generic iterator for all other types
9294 primitive_iterator_t primitive_iterator {};
9296 } // namespace detail
9297 } // namespace nlohmann
9299 // #include <nlohmann/detail/iterators/iter_impl.hpp>
9302 #include <ciso646> // not
9303 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
9304 #include <type_traits> // conditional, is_const, remove_const
9306 // #include <nlohmann/detail/exceptions.hpp>
9308 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
9310 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
9312 // #include <nlohmann/detail/macro_scope.hpp>
9314 // #include <nlohmann/detail/meta/cpp_future.hpp>
9316 // #include <nlohmann/detail/meta/type_traits.hpp>
9318 // #include <nlohmann/detail/value_t.hpp>
9325 // forward declare, to be able to friend it later on
9326 template<typename IteratorType> class iteration_proxy;
9327 template<typename IteratorType> class iteration_proxy_value;
9330 @brief a template for a bidirectional iterator for the @ref basic_json class
9331 This class implements a both iterators (iterator and const_iterator) for the
9332 @ref basic_json class.
9333 @note An iterator is called *initialized* when a pointer to a JSON value has
9334 been set (e.g., by a constructor or a copy assignment). If the iterator is
9335 default-constructed, it is *uninitialized* and most methods are undefined.
9336 **The library uses assertions to detect calls on uninitialized iterators.**
9337 @requirement The class satisfies the following concept requirements:
9339 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
9340 The iterator that can be moved can be moved in both directions (i.e.
9341 incremented and decremented).
9342 @since version 1.0.0, simplified in version 2.0.9, change to bidirectional
9343 iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
9345 template<typename BasicJsonType>
9348 /// allow basic_json to access private members
9349 friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
9350 friend BasicJsonType;
9351 friend iteration_proxy<iter_impl>;
9352 friend iteration_proxy_value<iter_impl>;
9354 using object_t = typename BasicJsonType::object_t;
9355 using array_t = typename BasicJsonType::array_t;
9356 // make sure BasicJsonType is basic_json or const basic_json
9357 static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
9358 "iter_impl only accepts (const) basic_json");
9362 /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
9363 /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
9364 /// A user-defined iterator should provide publicly accessible typedefs named
9365 /// iterator_category, value_type, difference_type, pointer, and reference.
9366 /// Note that value_type is required to be non-const, even for constant iterators.
9367 using iterator_category = std::bidirectional_iterator_tag;
9369 /// the type of the values when the iterator is dereferenced
9370 using value_type = typename BasicJsonType::value_type;
9371 /// a type to represent differences between iterators
9372 using difference_type = typename BasicJsonType::difference_type;
9373 /// defines a pointer to the type iterated over (value_type)
9374 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
9375 typename BasicJsonType::const_pointer,
9376 typename BasicJsonType::pointer>::type;
9377 /// defines a reference to the type iterated over (value_type)
9379 typename std::conditional<std::is_const<BasicJsonType>::value,
9380 typename BasicJsonType::const_reference,
9381 typename BasicJsonType::reference>::type;
9383 /// default constructor
9384 iter_impl() = default;
9387 @brief constructor for a given JSON instance
9388 @param[in] object pointer to a JSON object for this iterator
9389 @pre object != nullptr
9390 @post The iterator is initialized; i.e. `m_object != nullptr`.
9392 explicit iter_impl(pointer object) noexcept : m_object(object)
9394 assert(m_object != nullptr);
9396 switch (m_object->m_type)
9398 case value_t::object:
9400 m_it.object_iterator = typename object_t::iterator();
9404 case value_t::array:
9406 m_it.array_iterator = typename array_t::iterator();
9412 m_it.primitive_iterator = primitive_iterator_t();
9419 @note The conventional copy constructor and copy assignment are implicitly
9420 defined. Combined with the following converting constructor and
9421 assignment, they support: (1) copy from iterator to iterator, (2)
9422 copy from const iterator to const iterator, and (3) conversion from
9423 iterator to const iterator. However conversion from const iterator
9424 to iterator is not defined.
9428 @brief const copy constructor
9429 @param[in] other const iterator to copy from
9430 @note This copy constructor had to be defined explicitly to circumvent a bug
9431 occurring on msvc v19.0 compiler (VS 2015) debug build. For more
9432 information refer to: https://github.com/nlohmann/json/issues/1608
9434 iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
9435 : m_object(other.m_object), m_it(other.m_it)
9439 @brief converting assignment
9440 @param[in] other const iterator to copy from
9441 @return const/non-const iterator
9442 @note It is not checked whether @a other is initialized.
9444 iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
9446 m_object = other.m_object;
9452 @brief converting constructor
9453 @param[in] other non-const iterator to copy from
9454 @note It is not checked whether @a other is initialized.
9456 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
9457 : m_object(other.m_object), m_it(other.m_it)
9461 @brief converting assignment
9462 @param[in] other non-const iterator to copy from
9463 @return const/non-const iterator
9464 @note It is not checked whether @a other is initialized.
9466 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
9468 m_object = other.m_object;
9475 @brief set the iterator to the first value
9476 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9478 void set_begin() noexcept
9480 assert(m_object != nullptr);
9482 switch (m_object->m_type)
9484 case value_t::object:
9486 m_it.object_iterator = m_object->m_value.object->begin();
9490 case value_t::array:
9492 m_it.array_iterator = m_object->m_value.array->begin();
9498 // set to end so begin()==end() is true: null is empty
9499 m_it.primitive_iterator.set_end();
9505 m_it.primitive_iterator.set_begin();
9512 @brief set the iterator past the last value
9513 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9515 void set_end() noexcept
9517 assert(m_object != nullptr);
9519 switch (m_object->m_type)
9521 case value_t::object:
9523 m_it.object_iterator = m_object->m_value.object->end();
9527 case value_t::array:
9529 m_it.array_iterator = m_object->m_value.array->end();
9535 m_it.primitive_iterator.set_end();
9543 @brief return a reference to the value pointed to by the iterator
9544 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9546 reference operator*() const
9548 assert(m_object != nullptr);
9550 switch (m_object->m_type)
9552 case value_t::object:
9554 assert(m_it.object_iterator != m_object->m_value.object->end());
9555 return m_it.object_iterator->second;
9558 case value_t::array:
9560 assert(m_it.array_iterator != m_object->m_value.array->end());
9561 return *m_it.array_iterator;
9565 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
9569 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
9574 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
9580 @brief dereference the iterator
9581 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9583 pointer operator->() const
9585 assert(m_object != nullptr);
9587 switch (m_object->m_type)
9589 case value_t::object:
9591 assert(m_it.object_iterator != m_object->m_value.object->end());
9592 return &(m_it.object_iterator->second);
9595 case value_t::array:
9597 assert(m_it.array_iterator != m_object->m_value.array->end());
9598 return &*m_it.array_iterator;
9603 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
9608 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
9614 @brief post-increment (it++)
9615 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9617 iter_impl const operator++(int)
9619 auto result = *this;
9625 @brief pre-increment (++it)
9626 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9628 iter_impl& operator++()
9630 assert(m_object != nullptr);
9632 switch (m_object->m_type)
9634 case value_t::object:
9636 std::advance(m_it.object_iterator, 1);
9640 case value_t::array:
9642 std::advance(m_it.array_iterator, 1);
9648 ++m_it.primitive_iterator;
9657 @brief post-decrement (it--)
9658 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9660 iter_impl const operator--(int)
9662 auto result = *this;
9668 @brief pre-decrement (--it)
9669 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9671 iter_impl& operator--()
9673 assert(m_object != nullptr);
9675 switch (m_object->m_type)
9677 case value_t::object:
9679 std::advance(m_it.object_iterator, -1);
9683 case value_t::array:
9685 std::advance(m_it.array_iterator, -1);
9691 --m_it.primitive_iterator;
9700 @brief comparison: equal
9701 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9703 bool operator==(const iter_impl& other) const
9705 // if objects are not the same, the comparison is undefined
9706 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
9708 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
9711 assert(m_object != nullptr);
9713 switch (m_object->m_type)
9715 case value_t::object:
9716 return (m_it.object_iterator == other.m_it.object_iterator);
9718 case value_t::array:
9719 return (m_it.array_iterator == other.m_it.array_iterator);
9722 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
9727 @brief comparison: not equal
9728 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9730 bool operator!=(const iter_impl& other) const
9732 return not operator==(other);
9736 @brief comparison: smaller
9737 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9739 bool operator<(const iter_impl& other) const
9741 // if objects are not the same, the comparison is undefined
9742 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
9744 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
9747 assert(m_object != nullptr);
9749 switch (m_object->m_type)
9751 case value_t::object:
9752 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
9754 case value_t::array:
9755 return (m_it.array_iterator < other.m_it.array_iterator);
9758 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
9763 @brief comparison: less than or equal
9764 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9766 bool operator<=(const iter_impl& other) const
9768 return not other.operator < (*this);
9772 @brief comparison: greater than
9773 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9775 bool operator>(const iter_impl& other) const
9777 return not operator<=(other);
9781 @brief comparison: greater than or equal
9782 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9784 bool operator>=(const iter_impl& other) const
9786 return not operator<(other);
9790 @brief add to iterator
9791 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9793 iter_impl& operator+=(difference_type i)
9795 assert(m_object != nullptr);
9797 switch (m_object->m_type)
9799 case value_t::object:
9800 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
9802 case value_t::array:
9804 std::advance(m_it.array_iterator, i);
9810 m_it.primitive_iterator += i;
9819 @brief subtract from iterator
9820 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9822 iter_impl& operator-=(difference_type i)
9824 return operator+=(-i);
9828 @brief add to iterator
9829 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9831 iter_impl operator+(difference_type i) const
9833 auto result = *this;
9839 @brief addition of distance and iterator
9840 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9842 friend iter_impl operator+(difference_type i, const iter_impl& it)
9850 @brief subtract from iterator
9851 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9853 iter_impl operator-(difference_type i) const
9855 auto result = *this;
9861 @brief return difference
9862 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9864 difference_type operator-(const iter_impl& other) const
9866 assert(m_object != nullptr);
9868 switch (m_object->m_type)
9870 case value_t::object:
9871 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
9873 case value_t::array:
9874 return m_it.array_iterator - other.m_it.array_iterator;
9877 return m_it.primitive_iterator - other.m_it.primitive_iterator;
9882 @brief access to successor
9883 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9885 reference operator[](difference_type n) const
9887 assert(m_object != nullptr);
9889 switch (m_object->m_type)
9891 case value_t::object:
9892 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
9894 case value_t::array:
9895 return *std::next(m_it.array_iterator, n);
9898 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
9902 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
9907 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
9913 @brief return the key of an object iterator
9914 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9916 const typename object_t::key_type& key() const
9918 assert(m_object != nullptr);
9920 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
9922 return m_it.object_iterator->first;
9925 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
9929 @brief return the value of an iterator
9930 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9932 reference value() const
9938 /// associated JSON instance
9939 pointer m_object = nullptr;
9940 /// the actual iterator of the associated instance
9941 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
9943 } // namespace detail
9944 } // namespace nlohmann
9946 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
9948 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
9951 #include <cstddef> // ptrdiff_t
9952 #include <iterator> // reverse_iterator
9953 #include <utility> // declval
9959 //////////////////////
9960 // reverse_iterator //
9961 //////////////////////
9964 @brief a template for a reverse iterator class
9966 @tparam Base the base iterator type to reverse. Valid types are @ref
9967 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
9968 create @ref const_reverse_iterator).
9970 @requirement The class satisfies the following concept requirements:
9972 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
9973 The iterator that can be moved can be moved in both directions (i.e.
9974 incremented and decremented).
9975 - [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
9976 It is possible to write to the pointed-to element (only if @a Base is
9979 @since version 1.0.0
9981 template<typename Base>
9982 class json_reverse_iterator : public std::reverse_iterator<Base>
9985 using difference_type = std::ptrdiff_t;
9986 /// shortcut to the reverse iterator adapter
9987 using base_iterator = std::reverse_iterator<Base>;
9988 /// the reference type for the pointed-to element
9989 using reference = typename Base::reference;
9991 /// create reverse iterator from iterator
9992 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
9993 : base_iterator(it) {}
9995 /// create reverse iterator from base class
9996 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
9998 /// post-increment (it++)
9999 json_reverse_iterator const operator++(int)
10001 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
10004 /// pre-increment (++it)
10005 json_reverse_iterator& operator++()
10007 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
10010 /// post-decrement (it--)
10011 json_reverse_iterator const operator--(int)
10013 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
10016 /// pre-decrement (--it)
10017 json_reverse_iterator& operator--()
10019 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
10022 /// add to iterator
10023 json_reverse_iterator& operator+=(difference_type i)
10025 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
10028 /// add to iterator
10029 json_reverse_iterator operator+(difference_type i) const
10031 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
10034 /// subtract from iterator
10035 json_reverse_iterator operator-(difference_type i) const
10037 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
10040 /// return difference
10041 difference_type operator-(const json_reverse_iterator& other) const
10043 return base_iterator(*this) - base_iterator(other);
10046 /// access to successor
10047 reference operator[](difference_type n) const
10049 return *(this->operator+(n));
10052 /// return the key of an object iterator
10053 auto key() const -> decltype(std::declval<Base>().key())
10055 auto it = --this->base();
10059 /// return the value of an iterator
10060 reference value() const
10062 auto it = --this->base();
10063 return it.operator * ();
10066 } // namespace detail
10067 } // namespace nlohmann
10069 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10071 // #include <nlohmann/detail/json_pointer.hpp>
10074 #include <algorithm> // all_of
10075 #include <cassert> // assert
10076 #include <cctype> // isdigit
10077 #include <numeric> // accumulate
10078 #include <string> // string
10079 #include <utility> // move
10080 #include <vector> // vector
10082 // #include <nlohmann/detail/exceptions.hpp>
10084 // #include <nlohmann/detail/macro_scope.hpp>
10086 // #include <nlohmann/detail/value_t.hpp>
10091 template<typename BasicJsonType>
10094 // allow basic_json to access private members
10095 NLOHMANN_BASIC_JSON_TPL_DECLARATION
10096 friend class basic_json;
10100 @brief create JSON pointer
10102 Create a JSON pointer according to the syntax described in
10103 [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
10105 @param[in] s string representing the JSON pointer; if omitted, the empty
10106 string is assumed which references the whole JSON value
10108 @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
10109 not begin with a slash (`/`); see example below
10111 @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
10112 not followed by `0` (representing `~`) or `1` (representing `/`); see
10115 @liveexample{The example shows the construction several valid JSON pointers
10116 as well as the exceptional behavior.,json_pointer}
10118 @since version 2.0.0
10120 explicit json_pointer(const std::string& s = "")
10121 : reference_tokens(split(s))
10125 @brief return a string representation of the JSON pointer
10127 @invariant For each JSON pointer `ptr`, it holds:
10129 ptr == json_pointer(ptr.to_string());
10132 @return a string representation of the JSON pointer
10134 @liveexample{The example shows the result of `to_string`.,json_pointer__to_string}
10136 @since version 2.0.0
10138 std::string to_string() const
10140 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
10142 [](const std::string & a, const std::string & b)
10144 return a + "/" + escape(b);
10148 /// @copydoc to_string()
10149 operator std::string() const
10151 return to_string();
10155 @brief append another JSON pointer at the end of this JSON pointer
10157 @param[in] ptr JSON pointer to append
10158 @return JSON pointer with @a ptr appended
10160 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
10162 @complexity Linear in the length of @a ptr.
10164 @sa @ref operator/=(std::string) to append a reference token
10165 @sa @ref operator/=(std::size_t) to append an array index
10166 @sa @ref operator/(const json_pointer&, const json_pointer&) for a binary operator
10168 @since version 3.6.0
10170 json_pointer& operator/=(const json_pointer& ptr)
10172 reference_tokens.insert(reference_tokens.end(),
10173 ptr.reference_tokens.begin(),
10174 ptr.reference_tokens.end());
10179 @brief append an unescaped reference token at the end of this JSON pointer
10181 @param[in] token reference token to append
10182 @return JSON pointer with @a token appended without escaping @a token
10184 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
10186 @complexity Amortized constant.
10188 @sa @ref operator/=(const json_pointer&) to append a JSON pointer
10189 @sa @ref operator/=(std::size_t) to append an array index
10190 @sa @ref operator/(const json_pointer&, std::size_t) for a binary operator
10192 @since version 3.6.0
10194 json_pointer& operator/=(std::string token)
10196 push_back(std::move(token));
10201 @brief append an array index at the end of this JSON pointer
10203 @param[in] array_index array index to append
10204 @return JSON pointer with @a array_index appended
10206 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
10208 @complexity Amortized constant.
10210 @sa @ref operator/=(const json_pointer&) to append a JSON pointer
10211 @sa @ref operator/=(std::string) to append a reference token
10212 @sa @ref operator/(const json_pointer&, std::string) for a binary operator
10214 @since version 3.6.0
10216 json_pointer& operator/=(std::size_t array_index)
10218 return *this /= std::to_string(array_index);
10222 @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
10224 @param[in] lhs JSON pointer
10225 @param[in] rhs JSON pointer
10226 @return a new JSON pointer with @a rhs appended to @a lhs
10228 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
10230 @complexity Linear in the length of @a lhs and @a rhs.
10232 @sa @ref operator/=(const json_pointer&) to append a JSON pointer
10234 @since version 3.6.0
10236 friend json_pointer operator/(const json_pointer& lhs,
10237 const json_pointer& rhs)
10239 return json_pointer(lhs) /= rhs;
10243 @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
10245 @param[in] ptr JSON pointer
10246 @param[in] token reference token
10247 @return a new JSON pointer with unescaped @a token appended to @a ptr
10249 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
10251 @complexity Linear in the length of @a ptr.
10253 @sa @ref operator/=(std::string) to append a reference token
10255 @since version 3.6.0
10257 friend json_pointer operator/(const json_pointer& ptr, std::string token)
10259 return json_pointer(ptr) /= std::move(token);
10263 @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
10265 @param[in] ptr JSON pointer
10266 @param[in] array_index array index
10267 @return a new JSON pointer with @a array_index appended to @a ptr
10269 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
10271 @complexity Linear in the length of @a ptr.
10273 @sa @ref operator/=(std::size_t) to append an array index
10275 @since version 3.6.0
10277 friend json_pointer operator/(const json_pointer& ptr, std::size_t array_index)
10279 return json_pointer(ptr) /= array_index;
10283 @brief returns the parent of this JSON pointer
10285 @return parent of this JSON pointer; in case this JSON pointer is the root,
10286 the root itself is returned
10288 @complexity Linear in the length of the JSON pointer.
10290 @liveexample{The example shows the result of `parent_pointer` for different
10291 JSON Pointers.,json_pointer__parent_pointer}
10293 @since version 3.6.0
10295 json_pointer parent_pointer() const
10302 json_pointer res = *this;
10308 @brief remove last reference token
10312 @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back}
10314 @complexity Constant.
10316 @throw out_of_range.405 if JSON pointer has no parent
10318 @since version 3.6.0
10322 if (JSON_HEDLEY_UNLIKELY(empty()))
10324 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
10327 reference_tokens.pop_back();
10331 @brief return last reference token
10334 @return last reference token
10336 @liveexample{The example shows the usage of `back`.,json_pointer__back}
10338 @complexity Constant.
10340 @throw out_of_range.405 if JSON pointer has no parent
10342 @since version 3.6.0
10344 const std::string& back() const
10346 if (JSON_HEDLEY_UNLIKELY(empty()))
10348 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
10351 return reference_tokens.back();
10355 @brief append an unescaped token at the end of the reference pointer
10357 @param[in] token token to add
10359 @complexity Amortized constant.
10361 @liveexample{The example shows the result of `push_back` for different
10362 JSON Pointers.,json_pointer__push_back}
10364 @since version 3.6.0
10366 void push_back(const std::string& token)
10368 reference_tokens.push_back(token);
10371 /// @copydoc push_back(const std::string&)
10372 void push_back(std::string&& token)
10374 reference_tokens.push_back(std::move(token));
10378 @brief return whether pointer points to the root document
10380 @return true iff the JSON pointer points to the root document
10382 @complexity Constant.
10384 @exceptionsafety No-throw guarantee: this function never throws exceptions.
10386 @liveexample{The example shows the result of `empty` for different JSON
10387 Pointers.,json_pointer__empty}
10389 @since version 3.6.0
10391 bool empty() const noexcept
10393 return reference_tokens.empty();
10398 @param[in] s reference token to be converted into an array index
10400 @return integer representation of @a s
10402 @throw out_of_range.404 if string @a s could not be converted to an integer
10404 static int array_index(const std::string& s)
10406 std::size_t processed_chars = 0;
10407 const int res = std::stoi(s, &processed_chars);
10409 // check if the string was completely read
10410 if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
10412 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
10418 json_pointer top() const
10420 if (JSON_HEDLEY_UNLIKELY(empty()))
10422 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
10425 json_pointer result = *this;
10426 result.reference_tokens = {reference_tokens[0]};
10431 @brief create and return a reference to the pointed to value
10433 @complexity Linear in the number of reference tokens.
10435 @throw parse_error.109 if array index is not a number
10436 @throw type_error.313 if value cannot be unflattened
10438 BasicJsonType& get_and_create(BasicJsonType& j) const
10440 using size_type = typename BasicJsonType::size_type;
10443 // in case no reference tokens exist, return a reference to the JSON value
10444 // j which will be overwritten by a primitive value
10445 for (const auto& reference_token : reference_tokens)
10447 switch (result->type())
10449 case detail::value_t::null:
10451 if (reference_token == "0")
10453 // start a new array if reference token is 0
10454 result = &result->operator[](0);
10458 // start a new object otherwise
10459 result = &result->operator[](reference_token);
10464 case detail::value_t::object:
10466 // create an entry in the object
10467 result = &result->operator[](reference_token);
10471 case detail::value_t::array:
10473 // create an entry in the array
10476 result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
10478 JSON_CATCH(std::invalid_argument&)
10480 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10486 The following code is only reached if there exists a reference
10487 token _and_ the current value is primitive. In this case, we have
10488 an error situation, because primitive values may only occur as
10489 single value; that is, with an empty list of reference tokens.
10492 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
10500 @brief return a reference to the pointed to value
10502 @note This version does not throw if a value is not present, but tries to
10503 create nested values instead. For instance, calling this function
10504 with pointer `"/this/that"` on a null value is equivalent to calling
10505 `operator[]("this").operator[]("that")` on that value, effectively
10506 changing the null value to an object.
10508 @param[in] ptr a JSON value
10510 @return reference to the JSON value pointed to by the JSON pointer
10512 @complexity Linear in the length of the JSON pointer.
10514 @throw parse_error.106 if an array index begins with '0'
10515 @throw parse_error.109 if an array index was not a number
10516 @throw out_of_range.404 if the JSON pointer can not be resolved
10518 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
10520 using size_type = typename BasicJsonType::size_type;
10521 for (const auto& reference_token : reference_tokens)
10523 // convert null values to arrays or objects before continuing
10524 if (ptr->is_null())
10526 // check if reference token is a number
10528 std::all_of(reference_token.begin(), reference_token.end(),
10529 [](const unsigned char x)
10531 return std::isdigit(x);
10534 // change value to array for numbers or "-" or to object otherwise
10535 *ptr = (nums or reference_token == "-")
10536 ? detail::value_t::array
10537 : detail::value_t::object;
10540 switch (ptr->type())
10542 case detail::value_t::object:
10544 // use unchecked object access
10545 ptr = &ptr->operator[](reference_token);
10549 case detail::value_t::array:
10551 // error condition (cf. RFC 6901, Sect. 4)
10552 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10554 JSON_THROW(detail::parse_error::create(106, 0,
10555 "array index '" + reference_token +
10556 "' must not begin with '0'"));
10559 if (reference_token == "-")
10561 // explicitly treat "-" as index beyond the end
10562 ptr = &ptr->operator[](ptr->m_value.array->size());
10566 // convert array index to number; unchecked access
10569 ptr = &ptr->operator[](
10570 static_cast<size_type>(array_index(reference_token)));
10572 JSON_CATCH(std::invalid_argument&)
10574 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10581 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
10589 @throw parse_error.106 if an array index begins with '0'
10590 @throw parse_error.109 if an array index was not a number
10591 @throw out_of_range.402 if the array index '-' is used
10592 @throw out_of_range.404 if the JSON pointer can not be resolved
10594 BasicJsonType& get_checked(BasicJsonType* ptr) const
10596 using size_type = typename BasicJsonType::size_type;
10597 for (const auto& reference_token : reference_tokens)
10599 switch (ptr->type())
10601 case detail::value_t::object:
10603 // note: at performs range check
10604 ptr = &ptr->at(reference_token);
10608 case detail::value_t::array:
10610 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
10612 // "-" always fails the range check
10613 JSON_THROW(detail::out_of_range::create(402,
10614 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
10615 ") is out of range"));
10618 // error condition (cf. RFC 6901, Sect. 4)
10619 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10621 JSON_THROW(detail::parse_error::create(106, 0,
10622 "array index '" + reference_token +
10623 "' must not begin with '0'"));
10626 // note: at performs range check
10629 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
10631 JSON_CATCH(std::invalid_argument&)
10633 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10639 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
10647 @brief return a const reference to the pointed to value
10649 @param[in] ptr a JSON value
10651 @return const reference to the JSON value pointed to by the JSON
10654 @throw parse_error.106 if an array index begins with '0'
10655 @throw parse_error.109 if an array index was not a number
10656 @throw out_of_range.402 if the array index '-' is used
10657 @throw out_of_range.404 if the JSON pointer can not be resolved
10659 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
10661 using size_type = typename BasicJsonType::size_type;
10662 for (const auto& reference_token : reference_tokens)
10664 switch (ptr->type())
10666 case detail::value_t::object:
10668 // use unchecked object access
10669 ptr = &ptr->operator[](reference_token);
10673 case detail::value_t::array:
10675 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
10677 // "-" cannot be used for const access
10678 JSON_THROW(detail::out_of_range::create(402,
10679 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
10680 ") is out of range"));
10683 // error condition (cf. RFC 6901, Sect. 4)
10684 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10686 JSON_THROW(detail::parse_error::create(106, 0,
10687 "array index '" + reference_token +
10688 "' must not begin with '0'"));
10691 // use unchecked array access
10694 ptr = &ptr->operator[](
10695 static_cast<size_type>(array_index(reference_token)));
10697 JSON_CATCH(std::invalid_argument&)
10699 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10705 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
10713 @throw parse_error.106 if an array index begins with '0'
10714 @throw parse_error.109 if an array index was not a number
10715 @throw out_of_range.402 if the array index '-' is used
10716 @throw out_of_range.404 if the JSON pointer can not be resolved
10718 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
10720 using size_type = typename BasicJsonType::size_type;
10721 for (const auto& reference_token : reference_tokens)
10723 switch (ptr->type())
10725 case detail::value_t::object:
10727 // note: at performs range check
10728 ptr = &ptr->at(reference_token);
10732 case detail::value_t::array:
10734 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
10736 // "-" always fails the range check
10737 JSON_THROW(detail::out_of_range::create(402,
10738 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
10739 ") is out of range"));
10742 // error condition (cf. RFC 6901, Sect. 4)
10743 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10745 JSON_THROW(detail::parse_error::create(106, 0,
10746 "array index '" + reference_token +
10747 "' must not begin with '0'"));
10750 // note: at performs range check
10753 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
10755 JSON_CATCH(std::invalid_argument&)
10757 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10763 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
10771 @throw parse_error.106 if an array index begins with '0'
10772 @throw parse_error.109 if an array index was not a number
10774 bool contains(const BasicJsonType* ptr) const
10776 using size_type = typename BasicJsonType::size_type;
10777 for (const auto& reference_token : reference_tokens)
10779 switch (ptr->type())
10781 case detail::value_t::object:
10783 if (not ptr->contains(reference_token))
10785 // we did not find the key in the object
10789 ptr = &ptr->operator[](reference_token);
10793 case detail::value_t::array:
10795 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
10797 // "-" always fails the range check
10801 // error condition (cf. RFC 6901, Sect. 4)
10802 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10804 JSON_THROW(detail::parse_error::create(106, 0,
10805 "array index '" + reference_token +
10806 "' must not begin with '0'"));
10811 const auto idx = static_cast<size_type>(array_index(reference_token));
10812 if (idx >= ptr->size())
10814 // index out of range
10818 ptr = &ptr->operator[](idx);
10821 JSON_CATCH(std::invalid_argument&)
10823 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10830 // we do not expect primitive values if there is still a
10831 // reference token to process
10837 // no reference token left means we found a primitive value
10842 @brief split the string input to reference tokens
10844 @note This function is only called by the json_pointer constructor.
10845 All exceptions below are documented there.
10847 @throw parse_error.107 if the pointer is not empty or begins with '/'
10848 @throw parse_error.108 if character '~' is not followed by '0' or '1'
10850 static std::vector<std::string> split(const std::string& reference_string)
10852 std::vector<std::string> result;
10854 // special case: empty reference string -> no reference tokens
10855 if (reference_string.empty())
10860 // check if nonempty reference string begins with slash
10861 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
10863 JSON_THROW(detail::parse_error::create(107, 1,
10864 "JSON pointer must be empty or begin with '/' - was: '" +
10865 reference_string + "'"));
10868 // extract the reference tokens:
10869 // - slash: position of the last read slash (or end of string)
10870 // - start: position after the previous slash
10872 // search for the first slash after the first character
10873 std::size_t slash = reference_string.find_first_of('/', 1),
10874 // set the beginning of the first reference token
10876 // we can stop if start == 0 (if slash == std::string::npos)
10878 // set the beginning of the next reference token
10879 // (will eventually be 0 if slash == std::string::npos)
10880 start = (slash == std::string::npos) ? 0 : slash + 1,
10882 slash = reference_string.find_first_of('/', start))
10884 // use the text between the beginning of the reference token
10885 // (start) and the last slash (slash).
10886 auto reference_token = reference_string.substr(start, slash - start);
10888 // check reference tokens are properly escaped
10889 for (std::size_t pos = reference_token.find_first_of('~');
10890 pos != std::string::npos;
10891 pos = reference_token.find_first_of('~', pos + 1))
10893 assert(reference_token[pos] == '~');
10895 // ~ must be followed by 0 or 1
10896 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 or
10897 (reference_token[pos + 1] != '0' and
10898 reference_token[pos + 1] != '1')))
10900 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
10904 // finally, store the reference token
10905 unescape(reference_token);
10906 result.push_back(reference_token);
10913 @brief replace all occurrences of a substring by another string
10915 @param[in,out] s the string to manipulate; changed so that all
10916 occurrences of @a f are replaced with @a t
10917 @param[in] f the substring to replace with @a t
10918 @param[in] t the string to replace @a f
10920 @pre The search string @a f must not be empty. **This precondition is
10921 enforced with an assertion.**
10923 @since version 2.0.0
10925 static void replace_substring(std::string& s, const std::string& f,
10926 const std::string& t)
10928 assert(not f.empty());
10929 for (auto pos = s.find(f); // find first occurrence of f
10930 pos != std::string::npos; // make sure f was found
10931 s.replace(pos, f.size(), t), // replace with t, and
10932 pos = s.find(f, pos + t.size())) // find next occurrence of f
10936 /// escape "~" to "~0" and "/" to "~1"
10937 static std::string escape(std::string s)
10939 replace_substring(s, "~", "~0");
10940 replace_substring(s, "/", "~1");
10944 /// unescape "~1" to tilde and "~0" to slash (order is important!)
10945 static void unescape(std::string& s)
10947 replace_substring(s, "~1", "/");
10948 replace_substring(s, "~0", "~");
10952 @param[in] reference_string the reference string to the current value
10953 @param[in] value the value to consider
10954 @param[in,out] result the result object to insert values to
10956 @note Empty objects or arrays are flattened to `null`.
10958 static void flatten(const std::string& reference_string,
10959 const BasicJsonType& value,
10960 BasicJsonType& result)
10962 switch (value.type())
10964 case detail::value_t::array:
10966 if (value.m_value.array->empty())
10968 // flatten empty array as null
10969 result[reference_string] = nullptr;
10973 // iterate array and use index as reference string
10974 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
10976 flatten(reference_string + "/" + std::to_string(i),
10977 value.m_value.array->operator[](i), result);
10983 case detail::value_t::object:
10985 if (value.m_value.object->empty())
10987 // flatten empty object as null
10988 result[reference_string] = nullptr;
10992 // iterate object and use keys as reference string
10993 for (const auto& element : *value.m_value.object)
10995 flatten(reference_string + "/" + escape(element.first), element.second, result);
11003 // add primitive value with its reference string
11004 result[reference_string] = value;
11011 @param[in] value flattened JSON
11013 @return unflattened JSON
11015 @throw parse_error.109 if array index is not a number
11016 @throw type_error.314 if value is not an object
11017 @throw type_error.315 if object values are not primitive
11018 @throw type_error.313 if value cannot be unflattened
11020 static BasicJsonType
11021 unflatten(const BasicJsonType& value)
11023 if (JSON_HEDLEY_UNLIKELY(not value.is_object()))
11025 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
11028 BasicJsonType result;
11030 // iterate the JSON object values
11031 for (const auto& element : *value.m_value.object)
11033 if (JSON_HEDLEY_UNLIKELY(not element.second.is_primitive()))
11035 JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
11038 // assign value to reference pointed to by JSON pointer; Note that if
11039 // the JSON pointer is "" (i.e., points to the whole value), function
11040 // get_and_create returns a reference to result itself. An assignment
11041 // will then create a primitive value.
11042 json_pointer(element.first).get_and_create(result) = element.second;
11049 @brief compares two JSON pointers for equality
11051 @param[in] lhs JSON pointer to compare
11052 @param[in] rhs JSON pointer to compare
11053 @return whether @a lhs is equal to @a rhs
11055 @complexity Linear in the length of the JSON pointer
11057 @exceptionsafety No-throw guarantee: this function never throws exceptions.
11059 friend bool operator==(json_pointer const& lhs,
11060 json_pointer const& rhs) noexcept
11062 return lhs.reference_tokens == rhs.reference_tokens;
11066 @brief compares two JSON pointers for inequality
11068 @param[in] lhs JSON pointer to compare
11069 @param[in] rhs JSON pointer to compare
11070 @return whether @a lhs is not equal @a rhs
11072 @complexity Linear in the length of the JSON pointer
11074 @exceptionsafety No-throw guarantee: this function never throws exceptions.
11076 friend bool operator!=(json_pointer const& lhs,
11077 json_pointer const& rhs) noexcept
11079 return not (lhs == rhs);
11082 /// the reference tokens
11083 std::vector<std::string> reference_tokens;
11085 } // namespace nlohmann
11087 // #include <nlohmann/detail/json_ref.hpp>
11090 #include <initializer_list>
11093 // #include <nlohmann/detail/meta/type_traits.hpp>
11100 template<typename BasicJsonType>
11104 using value_type = BasicJsonType;
11106 json_ref(value_type&& value)
11107 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
11110 json_ref(const value_type& value)
11111 : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
11114 json_ref(std::initializer_list<json_ref> init)
11115 : owned_value(init), value_ref(&owned_value), is_rvalue(true)
11120 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
11121 json_ref(Args && ... args)
11122 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value),
11125 // class should be movable only
11126 json_ref(json_ref&&) = default;
11127 json_ref(const json_ref&) = delete;
11128 json_ref& operator=(const json_ref&) = delete;
11129 json_ref& operator=(json_ref&&) = delete;
11130 ~json_ref() = default;
11132 value_type moved_or_copied() const
11136 return std::move(*value_ref);
11141 value_type const& operator*() const
11143 return *static_cast<value_type const*>(value_ref);
11146 value_type const* operator->() const
11148 return static_cast<value_type const*>(value_ref);
11152 mutable value_type owned_value = nullptr;
11153 value_type* value_ref = nullptr;
11154 const bool is_rvalue;
11156 } // namespace detail
11157 } // namespace nlohmann
11159 // #include <nlohmann/detail/macro_scope.hpp>
11161 // #include <nlohmann/detail/meta/cpp_future.hpp>
11163 // #include <nlohmann/detail/meta/type_traits.hpp>
11165 // #include <nlohmann/detail/output/binary_writer.hpp>
11168 #include <algorithm> // reverse
11169 #include <array> // array
11170 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
11171 #include <cstring> // memcpy
11172 #include <limits> // numeric_limits
11173 #include <string> // string
11175 // #include <nlohmann/detail/input/binary_reader.hpp>
11177 // #include <nlohmann/detail/macro_scope.hpp>
11179 // #include <nlohmann/detail/output/output_adapters.hpp>
11182 #include <algorithm> // copy
11183 #include <cstddef> // size_t
11184 #include <ios> // streamsize
11185 #include <iterator> // back_inserter
11186 #include <memory> // shared_ptr, make_shared
11187 #include <ostream> // basic_ostream
11188 #include <string> // basic_string
11189 #include <vector> // vector
11190 // #include <nlohmann/detail/macro_scope.hpp>
11197 /// abstract output adapter interface
11198 template<typename CharType> struct output_adapter_protocol
11200 virtual void write_character(CharType c) = 0;
11201 virtual void write_characters(const CharType* s, std::size_t length) = 0;
11202 virtual ~output_adapter_protocol() = default;
11205 /// a type to simplify interfaces
11206 template<typename CharType>
11207 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
11209 /// output adapter for byte vectors
11210 template<typename CharType>
11211 class output_vector_adapter : public output_adapter_protocol<CharType>
11214 explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
11218 void write_character(CharType c) override
11223 JSON_HEDLEY_NON_NULL(2)
11224 void write_characters(const CharType* s, std::size_t length) override
11226 std::copy(s, s + length, std::back_inserter(v));
11230 std::vector<CharType>& v;
11233 /// output adapter for output streams
11234 template<typename CharType>
11235 class output_stream_adapter : public output_adapter_protocol<CharType>
11238 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
11242 void write_character(CharType c) override
11247 JSON_HEDLEY_NON_NULL(2)
11248 void write_characters(const CharType* s, std::size_t length) override
11250 stream.write(s, static_cast<std::streamsize>(length));
11254 std::basic_ostream<CharType>& stream;
11257 /// output adapter for basic_string
11258 template<typename CharType, typename StringType = std::basic_string<CharType>>
11259 class output_string_adapter : public output_adapter_protocol<CharType>
11262 explicit output_string_adapter(StringType& s) noexcept
11266 void write_character(CharType c) override
11271 JSON_HEDLEY_NON_NULL(2)
11272 void write_characters(const CharType* s, std::size_t length) override
11274 str.append(s, length);
11281 template<typename CharType, typename StringType = std::basic_string<CharType>>
11282 class output_adapter
11285 output_adapter(std::vector<CharType>& vec)
11286 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
11288 output_adapter(std::basic_ostream<CharType>& s)
11289 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
11291 output_adapter(StringType& s)
11292 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
11294 operator output_adapter_t<CharType>()
11300 output_adapter_t<CharType> oa = nullptr;
11302 } // namespace detail
11303 } // namespace nlohmann
11310 ///////////////////
11311 // binary writer //
11312 ///////////////////
11315 @brief serialization to CBOR and MessagePack values
11317 template<typename BasicJsonType, typename CharType>
11318 class binary_writer
11320 using string_t = typename BasicJsonType::string_t;
11324 @brief create a binary writer
11326 @param[in] adapter output adapter to write to
11328 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
11334 @param[in] j JSON value to serialize
11335 @pre j.type() == value_t::object
11337 void write_bson(const BasicJsonType& j)
11341 case value_t::object:
11343 write_bson_object(*j.m_value.object);
11349 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
11355 @param[in] j JSON value to serialize
11357 void write_cbor(const BasicJsonType& j)
11361 case value_t::null:
11363 oa->write_character(to_char_type(0xF6));
11367 case value_t::boolean:
11369 oa->write_character(j.m_value.boolean
11370 ? to_char_type(0xF5)
11371 : to_char_type(0xF4));
11375 case value_t::number_integer:
11377 if (j.m_value.number_integer >= 0)
11379 // CBOR does not differentiate between positive signed
11380 // integers and unsigned integers. Therefore, we used the
11381 // code from the value_t::number_unsigned case here.
11382 if (j.m_value.number_integer <= 0x17)
11384 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
11386 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
11388 oa->write_character(to_char_type(0x18));
11389 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
11391 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
11393 oa->write_character(to_char_type(0x19));
11394 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
11396 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
11398 oa->write_character(to_char_type(0x1A));
11399 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
11403 oa->write_character(to_char_type(0x1B));
11404 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
11409 // The conversions below encode the sign in the first
11410 // byte, and the value is converted to a positive number.
11411 const auto positive_number = -1 - j.m_value.number_integer;
11412 if (j.m_value.number_integer >= -24)
11414 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
11416 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
11418 oa->write_character(to_char_type(0x38));
11419 write_number(static_cast<std::uint8_t>(positive_number));
11421 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
11423 oa->write_character(to_char_type(0x39));
11424 write_number(static_cast<std::uint16_t>(positive_number));
11426 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
11428 oa->write_character(to_char_type(0x3A));
11429 write_number(static_cast<std::uint32_t>(positive_number));
11433 oa->write_character(to_char_type(0x3B));
11434 write_number(static_cast<std::uint64_t>(positive_number));
11440 case value_t::number_unsigned:
11442 if (j.m_value.number_unsigned <= 0x17)
11444 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
11446 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
11448 oa->write_character(to_char_type(0x18));
11449 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
11451 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
11453 oa->write_character(to_char_type(0x19));
11454 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
11456 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
11458 oa->write_character(to_char_type(0x1A));
11459 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
11463 oa->write_character(to_char_type(0x1B));
11464 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
11469 case value_t::number_float:
11471 oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
11472 write_number(j.m_value.number_float);
11476 case value_t::string:
11478 // step 1: write control byte and the string length
11479 const auto N = j.m_value.string->size();
11482 write_number(static_cast<std::uint8_t>(0x60 + N));
11484 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
11486 oa->write_character(to_char_type(0x78));
11487 write_number(static_cast<std::uint8_t>(N));
11489 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
11491 oa->write_character(to_char_type(0x79));
11492 write_number(static_cast<std::uint16_t>(N));
11494 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
11496 oa->write_character(to_char_type(0x7A));
11497 write_number(static_cast<std::uint32_t>(N));
11500 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
11502 oa->write_character(to_char_type(0x7B));
11503 write_number(static_cast<std::uint64_t>(N));
11507 // step 2: write the string
11508 oa->write_characters(
11509 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
11510 j.m_value.string->size());
11514 case value_t::array:
11516 // step 1: write control byte and the array size
11517 const auto N = j.m_value.array->size();
11520 write_number(static_cast<std::uint8_t>(0x80 + N));
11522 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
11524 oa->write_character(to_char_type(0x98));
11525 write_number(static_cast<std::uint8_t>(N));
11527 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
11529 oa->write_character(to_char_type(0x99));
11530 write_number(static_cast<std::uint16_t>(N));
11532 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
11534 oa->write_character(to_char_type(0x9A));
11535 write_number(static_cast<std::uint32_t>(N));
11538 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
11540 oa->write_character(to_char_type(0x9B));
11541 write_number(static_cast<std::uint64_t>(N));
11545 // step 2: write each element
11546 for (const auto& el : *j.m_value.array)
11553 case value_t::object:
11555 // step 1: write control byte and the object size
11556 const auto N = j.m_value.object->size();
11559 write_number(static_cast<std::uint8_t>(0xA0 + N));
11561 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
11563 oa->write_character(to_char_type(0xB8));
11564 write_number(static_cast<std::uint8_t>(N));
11566 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
11568 oa->write_character(to_char_type(0xB9));
11569 write_number(static_cast<std::uint16_t>(N));
11571 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
11573 oa->write_character(to_char_type(0xBA));
11574 write_number(static_cast<std::uint32_t>(N));
11577 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
11579 oa->write_character(to_char_type(0xBB));
11580 write_number(static_cast<std::uint64_t>(N));
11584 // step 2: write each element
11585 for (const auto& el : *j.m_value.object)
11587 write_cbor(el.first);
11588 write_cbor(el.second);
11599 @param[in] j JSON value to serialize
11601 void write_msgpack(const BasicJsonType& j)
11605 case value_t::null: // nil
11607 oa->write_character(to_char_type(0xC0));
11611 case value_t::boolean: // true and false
11613 oa->write_character(j.m_value.boolean
11614 ? to_char_type(0xC3)
11615 : to_char_type(0xC2));
11619 case value_t::number_integer:
11621 if (j.m_value.number_integer >= 0)
11623 // MessagePack does not differentiate between positive
11624 // signed integers and unsigned integers. Therefore, we used
11625 // the code from the value_t::number_unsigned case here.
11626 if (j.m_value.number_unsigned < 128)
11629 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
11631 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
11634 oa->write_character(to_char_type(0xCC));
11635 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
11637 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
11640 oa->write_character(to_char_type(0xCD));
11641 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
11643 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
11646 oa->write_character(to_char_type(0xCE));
11647 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
11649 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
11652 oa->write_character(to_char_type(0xCF));
11653 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
11658 if (j.m_value.number_integer >= -32)
11661 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
11663 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() and
11664 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
11667 oa->write_character(to_char_type(0xD0));
11668 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
11670 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() and
11671 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
11674 oa->write_character(to_char_type(0xD1));
11675 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
11677 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() and
11678 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
11681 oa->write_character(to_char_type(0xD2));
11682 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
11684 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() and
11685 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
11688 oa->write_character(to_char_type(0xD3));
11689 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
11695 case value_t::number_unsigned:
11697 if (j.m_value.number_unsigned < 128)
11700 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
11702 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
11705 oa->write_character(to_char_type(0xCC));
11706 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
11708 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
11711 oa->write_character(to_char_type(0xCD));
11712 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
11714 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
11717 oa->write_character(to_char_type(0xCE));
11718 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
11720 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
11723 oa->write_character(to_char_type(0xCF));
11724 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
11729 case value_t::number_float:
11731 oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
11732 write_number(j.m_value.number_float);
11736 case value_t::string:
11738 // step 1: write control byte and the string length
11739 const auto N = j.m_value.string->size();
11743 write_number(static_cast<std::uint8_t>(0xA0 | N));
11745 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
11748 oa->write_character(to_char_type(0xD9));
11749 write_number(static_cast<std::uint8_t>(N));
11751 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
11754 oa->write_character(to_char_type(0xDA));
11755 write_number(static_cast<std::uint16_t>(N));
11757 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
11760 oa->write_character(to_char_type(0xDB));
11761 write_number(static_cast<std::uint32_t>(N));
11764 // step 2: write the string
11765 oa->write_characters(
11766 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
11767 j.m_value.string->size());
11771 case value_t::array:
11773 // step 1: write control byte and the array size
11774 const auto N = j.m_value.array->size();
11778 write_number(static_cast<std::uint8_t>(0x90 | N));
11780 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
11783 oa->write_character(to_char_type(0xDC));
11784 write_number(static_cast<std::uint16_t>(N));
11786 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
11789 oa->write_character(to_char_type(0xDD));
11790 write_number(static_cast<std::uint32_t>(N));
11793 // step 2: write each element
11794 for (const auto& el : *j.m_value.array)
11801 case value_t::object:
11803 // step 1: write control byte and the object size
11804 const auto N = j.m_value.object->size();
11808 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
11810 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
11813 oa->write_character(to_char_type(0xDE));
11814 write_number(static_cast<std::uint16_t>(N));
11816 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
11819 oa->write_character(to_char_type(0xDF));
11820 write_number(static_cast<std::uint32_t>(N));
11823 // step 2: write each element
11824 for (const auto& el : *j.m_value.object)
11826 write_msgpack(el.first);
11827 write_msgpack(el.second);
11838 @param[in] j JSON value to serialize
11839 @param[in] use_count whether to use '#' prefixes (optimized format)
11840 @param[in] use_type whether to use '$' prefixes (optimized format)
11841 @param[in] add_prefix whether prefixes need to be used for this value
11843 void write_ubjson(const BasicJsonType& j, const bool use_count,
11844 const bool use_type, const bool add_prefix = true)
11848 case value_t::null:
11852 oa->write_character(to_char_type('Z'));
11857 case value_t::boolean:
11861 oa->write_character(j.m_value.boolean
11862 ? to_char_type('T')
11863 : to_char_type('F'));
11868 case value_t::number_integer:
11870 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
11874 case value_t::number_unsigned:
11876 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
11880 case value_t::number_float:
11882 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
11886 case value_t::string:
11890 oa->write_character(to_char_type('S'));
11892 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
11893 oa->write_characters(
11894 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
11895 j.m_value.string->size());
11899 case value_t::array:
11903 oa->write_character(to_char_type('['));
11906 bool prefix_required = true;
11907 if (use_type and not j.m_value.array->empty())
11910 const CharType first_prefix = ubjson_prefix(j.front());
11911 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
11912 [this, first_prefix](const BasicJsonType & v)
11914 return ubjson_prefix(v) == first_prefix;
11919 prefix_required = false;
11920 oa->write_character(to_char_type('$'));
11921 oa->write_character(first_prefix);
11927 oa->write_character(to_char_type('#'));
11928 write_number_with_ubjson_prefix(j.m_value.array->size(), true);
11931 for (const auto& el : *j.m_value.array)
11933 write_ubjson(el, use_count, use_type, prefix_required);
11938 oa->write_character(to_char_type(']'));
11944 case value_t::object:
11948 oa->write_character(to_char_type('{'));
11951 bool prefix_required = true;
11952 if (use_type and not j.m_value.object->empty())
11955 const CharType first_prefix = ubjson_prefix(j.front());
11956 const bool same_prefix = std::all_of(j.begin(), j.end(),
11957 [this, first_prefix](const BasicJsonType & v)
11959 return ubjson_prefix(v) == first_prefix;
11964 prefix_required = false;
11965 oa->write_character(to_char_type('$'));
11966 oa->write_character(first_prefix);
11972 oa->write_character(to_char_type('#'));
11973 write_number_with_ubjson_prefix(j.m_value.object->size(), true);
11976 for (const auto& el : *j.m_value.object)
11978 write_number_with_ubjson_prefix(el.first.size(), true);
11979 oa->write_characters(
11980 reinterpret_cast<const CharType*>(el.first.c_str()),
11982 write_ubjson(el.second, use_count, use_type, prefix_required);
11987 oa->write_character(to_char_type('}'));
12004 @return The size of a BSON document entry header, including the id marker
12005 and the entry name size (and its null-terminator).
12007 static std::size_t calc_bson_entry_header_size(const string_t& name)
12009 const auto it = name.find(static_cast<typename string_t::value_type>(0));
12010 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
12012 JSON_THROW(out_of_range::create(409,
12013 "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
12016 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
12020 @brief Writes the given @a element_type and @a name to the output adapter
12022 void write_bson_entry_header(const string_t& name,
12023 const std::uint8_t element_type)
12025 oa->write_character(to_char_type(element_type)); // boolean
12026 oa->write_characters(
12027 reinterpret_cast<const CharType*>(name.c_str()),
12032 @brief Writes a BSON element with key @a name and boolean value @a value
12034 void write_bson_boolean(const string_t& name,
12037 write_bson_entry_header(name, 0x08);
12038 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
12042 @brief Writes a BSON element with key @a name and double value @a value
12044 void write_bson_double(const string_t& name,
12045 const double value)
12047 write_bson_entry_header(name, 0x01);
12048 write_number<double, true>(value);
12052 @return The size of the BSON-encoded string in @a value
12054 static std::size_t calc_bson_string_size(const string_t& value)
12056 return sizeof(std::int32_t) + value.size() + 1ul;
12060 @brief Writes a BSON element with key @a name and string value @a value
12062 void write_bson_string(const string_t& name,
12063 const string_t& value)
12065 write_bson_entry_header(name, 0x02);
12067 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
12068 oa->write_characters(
12069 reinterpret_cast<const CharType*>(value.c_str()),
12074 @brief Writes a BSON element with key @a name and null value
12076 void write_bson_null(const string_t& name)
12078 write_bson_entry_header(name, 0x0A);
12082 @return The size of the BSON-encoded integer @a value
12084 static std::size_t calc_bson_integer_size(const std::int64_t value)
12086 return (std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)()
12087 ? sizeof(std::int32_t)
12088 : sizeof(std::int64_t);
12092 @brief Writes a BSON element with key @a name and integer @a value
12094 void write_bson_integer(const string_t& name,
12095 const std::int64_t value)
12097 if ((std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)())
12099 write_bson_entry_header(name, 0x10); // int32
12100 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
12104 write_bson_entry_header(name, 0x12); // int64
12105 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
12110 @return The size of the BSON-encoded unsigned integer in @a j
12112 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
12114 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
12115 ? sizeof(std::int32_t)
12116 : sizeof(std::int64_t);
12120 @brief Writes a BSON element with key @a name and unsigned @a value
12122 void write_bson_unsigned(const string_t& name,
12123 const std::uint64_t value)
12125 if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
12127 write_bson_entry_header(name, 0x10 /* int32 */);
12128 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
12130 else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
12132 write_bson_entry_header(name, 0x12 /* int64 */);
12133 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
12137 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
12142 @brief Writes a BSON element with key @a name and object @a value
12144 void write_bson_object_entry(const string_t& name,
12145 const typename BasicJsonType::object_t& value)
12147 write_bson_entry_header(name, 0x03); // object
12148 write_bson_object(value);
12152 @return The size of the BSON-encoded array @a value
12154 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
12156 std::size_t array_index = 0ul;
12158 const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), 0ul, [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
12160 return result + calc_bson_element_size(std::to_string(array_index++), el);
12163 return sizeof(std::int32_t) + embedded_document_size + 1ul;
12167 @brief Writes a BSON element with key @a name and array @a value
12169 void write_bson_array(const string_t& name,
12170 const typename BasicJsonType::array_t& value)
12172 write_bson_entry_header(name, 0x04); // array
12173 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
12175 std::size_t array_index = 0ul;
12177 for (const auto& el : value)
12179 write_bson_element(std::to_string(array_index++), el);
12182 oa->write_character(to_char_type(0x00));
12186 @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
12187 @return The calculated size for the BSON document entry for @a j with the given @a name.
12189 static std::size_t calc_bson_element_size(const string_t& name,
12190 const BasicJsonType& j)
12192 const auto header_size = calc_bson_entry_header_size(name);
12195 case value_t::object:
12196 return header_size + calc_bson_object_size(*j.m_value.object);
12198 case value_t::array:
12199 return header_size + calc_bson_array_size(*j.m_value.array);
12201 case value_t::boolean:
12202 return header_size + 1ul;
12204 case value_t::number_float:
12205 return header_size + 8ul;
12207 case value_t::number_integer:
12208 return header_size + calc_bson_integer_size(j.m_value.number_integer);
12210 case value_t::number_unsigned:
12211 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
12213 case value_t::string:
12214 return header_size + calc_bson_string_size(*j.m_value.string);
12216 case value_t::null:
12217 return header_size + 0ul;
12228 @brief Serializes the JSON value @a j to BSON and associates it with the
12230 @param name The name to associate with the JSON entity @a j within the
12231 current BSON document
12232 @return The size of the BSON entry
12234 void write_bson_element(const string_t& name,
12235 const BasicJsonType& j)
12239 case value_t::object:
12240 return write_bson_object_entry(name, *j.m_value.object);
12242 case value_t::array:
12243 return write_bson_array(name, *j.m_value.array);
12245 case value_t::boolean:
12246 return write_bson_boolean(name, j.m_value.boolean);
12248 case value_t::number_float:
12249 return write_bson_double(name, j.m_value.number_float);
12251 case value_t::number_integer:
12252 return write_bson_integer(name, j.m_value.number_integer);
12254 case value_t::number_unsigned:
12255 return write_bson_unsigned(name, j.m_value.number_unsigned);
12257 case value_t::string:
12258 return write_bson_string(name, *j.m_value.string);
12260 case value_t::null:
12261 return write_bson_null(name);
12272 @brief Calculates the size of the BSON serialization of the given
12274 @param[in] j JSON value to serialize
12275 @pre j.type() == value_t::object
12277 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
12279 std::size_t document_size = std::accumulate(value.begin(), value.end(), 0ul,
12280 [](size_t result, const typename BasicJsonType::object_t::value_type & el)
12282 return result += calc_bson_element_size(el.first, el.second);
12285 return sizeof(std::int32_t) + document_size + 1ul;
12289 @param[in] j JSON value to serialize
12290 @pre j.type() == value_t::object
12292 void write_bson_object(const typename BasicJsonType::object_t& value)
12294 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
12296 for (const auto& el : value)
12298 write_bson_element(el.first, el.second);
12301 oa->write_character(to_char_type(0x00));
12308 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
12310 return to_char_type(0xFA); // Single-Precision Float
12313 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
12315 return to_char_type(0xFB); // Double-Precision Float
12322 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
12324 return to_char_type(0xCA); // float 32
12327 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
12329 return to_char_type(0xCB); // float 64
12336 // UBJSON: write number (floating point)
12337 template<typename NumberType, typename std::enable_if<
12338 std::is_floating_point<NumberType>::value, int>::type = 0>
12339 void write_number_with_ubjson_prefix(const NumberType n,
12340 const bool add_prefix)
12344 oa->write_character(get_ubjson_float_prefix(n));
12349 // UBJSON: write number (unsigned integer)
12350 template<typename NumberType, typename std::enable_if<
12351 std::is_unsigned<NumberType>::value, int>::type = 0>
12352 void write_number_with_ubjson_prefix(const NumberType n,
12353 const bool add_prefix)
12355 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
12359 oa->write_character(to_char_type('i')); // int8
12361 write_number(static_cast<std::uint8_t>(n));
12363 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
12367 oa->write_character(to_char_type('U')); // uint8
12369 write_number(static_cast<std::uint8_t>(n));
12371 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
12375 oa->write_character(to_char_type('I')); // int16
12377 write_number(static_cast<std::int16_t>(n));
12379 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
12383 oa->write_character(to_char_type('l')); // int32
12385 write_number(static_cast<std::int32_t>(n));
12387 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
12391 oa->write_character(to_char_type('L')); // int64
12393 write_number(static_cast<std::int64_t>(n));
12397 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
12401 // UBJSON: write number (signed integer)
12402 template<typename NumberType, typename std::enable_if<
12403 std::is_signed<NumberType>::value and
12404 not std::is_floating_point<NumberType>::value, int>::type = 0>
12405 void write_number_with_ubjson_prefix(const NumberType n,
12406 const bool add_prefix)
12408 if ((std::numeric_limits<std::int8_t>::min)() <= n and n <= (std::numeric_limits<std::int8_t>::max)())
12412 oa->write_character(to_char_type('i')); // int8
12414 write_number(static_cast<std::int8_t>(n));
12416 else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n and n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
12420 oa->write_character(to_char_type('U')); // uint8
12422 write_number(static_cast<std::uint8_t>(n));
12424 else if ((std::numeric_limits<std::int16_t>::min)() <= n and n <= (std::numeric_limits<std::int16_t>::max)())
12428 oa->write_character(to_char_type('I')); // int16
12430 write_number(static_cast<std::int16_t>(n));
12432 else if ((std::numeric_limits<std::int32_t>::min)() <= n and n <= (std::numeric_limits<std::int32_t>::max)())
12436 oa->write_character(to_char_type('l')); // int32
12438 write_number(static_cast<std::int32_t>(n));
12440 else if ((std::numeric_limits<std::int64_t>::min)() <= n and n <= (std::numeric_limits<std::int64_t>::max)())
12444 oa->write_character(to_char_type('L')); // int64
12446 write_number(static_cast<std::int64_t>(n));
12451 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
12457 @brief determine the type prefix of container values
12459 @note This function does not need to be 100% accurate when it comes to
12460 integer limits. In case a number exceeds the limits of int64_t,
12461 this will be detected by a later call to function
12462 write_number_with_ubjson_prefix. Therefore, we return 'L' for any
12463 value that does not fit the previous limits.
12465 CharType ubjson_prefix(const BasicJsonType& j) const noexcept
12469 case value_t::null:
12472 case value_t::boolean:
12473 return j.m_value.boolean ? 'T' : 'F';
12475 case value_t::number_integer:
12477 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
12481 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
12485 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
12489 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
12493 // no check and assume int64_t (see note above)
12497 case value_t::number_unsigned:
12499 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
12503 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
12507 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
12511 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
12515 // no check and assume int64_t (see note above)
12519 case value_t::number_float:
12520 return get_ubjson_float_prefix(j.m_value.number_float);
12522 case value_t::string:
12525 case value_t::array:
12528 case value_t::object:
12531 default: // discarded values
12536 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
12538 return 'd'; // float 32
12541 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
12543 return 'D'; // float 64
12546 ///////////////////////
12547 // Utility functions //
12548 ///////////////////////
12551 @brief write a number to output input
12552 @param[in] n number of type @a NumberType
12553 @tparam NumberType the type of the number
12554 @tparam OutputIsLittleEndian Set to true if output data is
12555 required to be little endian
12557 @note This function needs to respect the system's endianess, because bytes
12558 in CBOR, MessagePack, and UBJSON are stored in network order (big
12559 endian) and therefore need reordering on little endian systems.
12561 template<typename NumberType, bool OutputIsLittleEndian = false>
12562 void write_number(const NumberType n)
12564 // step 1: write number to array of length NumberType
12565 std::array<CharType, sizeof(NumberType)> vec;
12566 std::memcpy(vec.data(), &n, sizeof(NumberType));
12568 // step 2: write array to output (with possible reordering)
12569 if (is_little_endian != OutputIsLittleEndian)
12571 // reverse byte order prior to conversion if necessary
12572 std::reverse(vec.begin(), vec.end());
12575 oa->write_characters(vec.data(), sizeof(NumberType));
12579 // The following to_char_type functions are implement the conversion
12580 // between uint8_t and CharType. In case CharType is not unsigned,
12581 // such a conversion is required to allow values greater than 128.
12582 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
12583 template < typename C = CharType,
12584 enable_if_t < std::is_signed<C>::value and std::is_signed<char>::value > * = nullptr >
12585 static constexpr CharType to_char_type(std::uint8_t x) noexcept
12587 return *reinterpret_cast<char*>(&x);
12590 template < typename C = CharType,
12591 enable_if_t < std::is_signed<C>::value and std::is_unsigned<char>::value > * = nullptr >
12592 static CharType to_char_type(std::uint8_t x) noexcept
12594 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
12595 static_assert(std::is_pod<CharType>::value, "CharType must be POD");
12597 std::memcpy(&result, &x, sizeof(x));
12601 template<typename C = CharType,
12602 enable_if_t<std::is_unsigned<C>::value>* = nullptr>
12603 static constexpr CharType to_char_type(std::uint8_t x) noexcept
12608 template < typename InputCharType, typename C = CharType,
12610 std::is_signed<C>::value and
12611 std::is_signed<char>::value and
12612 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
12614 static constexpr CharType to_char_type(InputCharType x) noexcept
12620 /// whether we can assume little endianess
12621 const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
12624 output_adapter_t<CharType> oa = nullptr;
12626 } // namespace detail
12627 } // namespace nlohmann
12629 // #include <nlohmann/detail/output/output_adapters.hpp>
12631 // #include <nlohmann/detail/output/serializer.hpp>
12634 #include <algorithm> // reverse, remove, fill, find, none_of
12635 #include <array> // array
12636 #include <cassert> // assert
12637 #include <ciso646> // and, or
12638 #include <clocale> // localeconv, lconv
12639 #include <cmath> // labs, isfinite, isnan, signbit
12640 #include <cstddef> // size_t, ptrdiff_t
12641 #include <cstdint> // uint8_t
12642 #include <cstdio> // snprintf
12643 #include <limits> // numeric_limits
12644 #include <string> // string
12645 #include <type_traits> // is_same
12646 #include <utility> // move
12648 // #include <nlohmann/detail/conversions/to_chars.hpp>
12651 #include <array> // array
12652 #include <cassert> // assert
12653 #include <ciso646> // or, and, not
12654 #include <cmath> // signbit, isfinite
12655 #include <cstdint> // intN_t, uintN_t
12656 #include <cstring> // memcpy, memmove
12657 #include <limits> // numeric_limits
12658 #include <type_traits> // conditional
12659 // #include <nlohmann/detail/macro_scope.hpp>
12668 @brief implements the Grisu2 algorithm for binary to decimal floating-point
12671 This implementation is a slightly modified version of the reference
12672 implementation which may be obtained from
12673 http://florian.loitsch.com/publications (bench.tar.gz).
12675 The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
12677 For a detailed description of the algorithm see:
12679 [1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
12680 Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
12681 Language Design and Implementation, PLDI 2010
12682 [2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
12683 Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
12684 Design and Implementation, PLDI 1996
12686 namespace dtoa_impl
12689 template <typename Target, typename Source>
12690 Target reinterpret_bits(const Source source)
12692 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
12695 std::memcpy(&target, &source, sizeof(Source));
12699 struct diyfp // f * 2^e
12701 static constexpr int kPrecision = 64; // = q
12703 std::uint64_t f = 0;
12706 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
12709 @brief returns x - y
12710 @pre x.e == y.e and x.f >= y.f
12712 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
12714 assert(x.e == y.e);
12715 assert(x.f >= y.f);
12717 return {x.f - y.f, x.e};
12721 @brief returns x * y
12722 @note The result is rounded. (Only the upper q bits are returned.)
12724 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
12726 static_assert(kPrecision == 64, "internal error");
12729 // f = round((x.f * y.f) / 2^q)
12730 // e = x.e + y.e + q
12732 // Emulate the 64-bit * 64-bit multiplication:
12735 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
12736 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
12737 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
12738 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
12739 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
12740 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
12741 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
12743 // (Since Q might be larger than 2^32 - 1)
12745 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
12747 // (Q_hi + H does not overflow a 64-bit int)
12749 // = p_lo + 2^64 p_hi
12751 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
12752 const std::uint64_t u_hi = x.f >> 32u;
12753 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
12754 const std::uint64_t v_hi = y.f >> 32u;
12756 const std::uint64_t p0 = u_lo * v_lo;
12757 const std::uint64_t p1 = u_lo * v_hi;
12758 const std::uint64_t p2 = u_hi * v_lo;
12759 const std::uint64_t p3 = u_hi * v_hi;
12761 const std::uint64_t p0_hi = p0 >> 32u;
12762 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
12763 const std::uint64_t p1_hi = p1 >> 32u;
12764 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
12765 const std::uint64_t p2_hi = p2 >> 32u;
12767 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
12769 // The full product might now be computed as
12771 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
12772 // p_lo = p0_lo + (Q << 32)
12774 // But in this particular case here, the full p_lo is not required.
12775 // Effectively we only need to add the highest bit in p_lo to p_hi (and
12776 // Q_hi + 1 does not overflow).
12778 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
12780 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
12782 return {h, x.e + y.e + 64};
12786 @brief normalize x such that the significand is >= 2^(q-1)
12789 static diyfp normalize(diyfp x) noexcept
12793 while ((x.f >> 63u) == 0)
12803 @brief normalize x such that the result has the exponent E
12804 @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
12806 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
12808 const int delta = x.e - target_exponent;
12810 assert(delta >= 0);
12811 assert(((x.f << delta) >> delta) == x.f);
12813 return {x.f << delta, target_exponent};
12825 Compute the (normalized) diyfp representing the input number 'value' and its
12828 @pre value must be finite and positive
12830 template <typename FloatType>
12831 boundaries compute_boundaries(FloatType value)
12833 assert(std::isfinite(value));
12836 // Convert the IEEE representation into a diyfp.
12838 // If v is denormal:
12839 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
12840 // If v is normalized:
12841 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
12843 static_assert(std::numeric_limits<FloatType>::is_iec559,
12844 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
12846 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
12847 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
12848 constexpr int kMinExp = 1 - kBias;
12849 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
12851 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
12853 const std::uint64_t bits = reinterpret_bits<bits_type>(value);
12854 const std::uint64_t E = bits >> (kPrecision - 1);
12855 const std::uint64_t F = bits & (kHiddenBit - 1);
12857 const bool is_denormal = E == 0;
12858 const diyfp v = is_denormal
12859 ? diyfp(F, kMinExp)
12860 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
12862 // Compute the boundaries m- and m+ of the floating-point value
12865 // Determine v- and v+, the floating-point predecessor and successor if v,
12868 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
12869 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
12873 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
12874 // between m- and m+ round to v, regardless of how the input rounding
12875 // algorithm breaks ties.
12877 // ---+-------------+-------------+-------------+-------------+--- (A)
12880 // -----------------+------+------+-------------+-------------+--- (B)
12883 const bool lower_boundary_is_closer = F == 0 and E > 1;
12884 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
12885 const diyfp m_minus = lower_boundary_is_closer
12886 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
12887 : diyfp(2 * v.f - 1, v.e - 1); // (A)
12889 // Determine the normalized w+ = m+.
12890 const diyfp w_plus = diyfp::normalize(m_plus);
12892 // Determine w- = m- such that e_(w-) = e_(w+).
12893 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
12895 return {diyfp::normalize(v), w_minus, w_plus};
12898 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
12899 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
12900 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
12902 // alpha <= e = e_c + e_w + q <= gamma
12906 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
12907 // <= f_c * f_w * 2^gamma
12909 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
12911 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
12915 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
12917 // The choice of (alpha,gamma) determines the size of the table and the form of
12918 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
12921 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
12922 // processed independently: An integral part p1, and a fractional part p2:
12924 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
12925 // = (f div 2^-e) + (f mod 2^-e) * 2^e
12928 // The conversion of p1 into decimal form requires a series of divisions and
12929 // modulos by (a power of) 10. These operations are faster for 32-bit than for
12930 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
12931 // achieved by choosing
12933 // -e >= 32 or e <= -32 := gamma
12935 // In order to convert the fractional part
12937 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
12939 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
12940 // d[-i] are extracted in order:
12942 // (10 * p2) div 2^-e = d[-1]
12943 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
12945 // The multiplication by 10 must not overflow. It is sufficient to choose
12947 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
12949 // Since p2 = f mod 2^-e < 2^-e,
12951 // -e <= 60 or e >= -60 := alpha
12953 constexpr int kAlpha = -60;
12954 constexpr int kGamma = -32;
12956 struct cached_power // c = f * 2^e ~= 10^k
12964 For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
12965 power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
12966 satisfies (Definition 3.2 from [1])
12968 alpha <= e_c + e + q <= gamma.
12970 inline cached_power get_cached_power_for_binary_exponent(int e)
12974 // alpha <= e_c + e + q <= gamma (1)
12975 // ==> f_c * 2^alpha <= c * 2^e * 2^q
12977 // and since the c's are normalized, 2^(q-1) <= f_c,
12979 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
12980 // ==> 2^(alpha - e - 1) <= c
12982 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
12984 // k = ceil( log_10( 2^(alpha - e - 1) ) )
12985 // = ceil( (alpha - e - 1) * log_10(2) )
12988 // "In theory the result of the procedure could be wrong since c is rounded,
12989 // and the computation itself is approximated [...]. In practice, however,
12990 // this simple function is sufficient."
12992 // For IEEE double precision floating-point numbers converted into
12993 // normalized diyfp's w = f * 2^e, with q = 64,
12995 // e >= -1022 (min IEEE exponent)
12997 // -52 (p - 1, possibly normalize denormal IEEE numbers)
12998 // -11 (normalize the diyfp)
13003 // e <= +1023 (max IEEE exponent)
13005 // -11 (normalize the diyfp)
13008 // This binary exponent range [-1137,960] results in a decimal exponent
13009 // range [-307,324]. One does not need to store a cached power for each
13010 // k in this range. For each such k it suffices to find a cached power
13011 // such that the exponent of the product lies in [alpha,gamma].
13012 // This implies that the difference of the decimal exponents of adjacent
13013 // table entries must be less than or equal to
13015 // floor( (gamma - alpha) * log_10(2) ) = 8.
13017 // (A smaller distance gamma-alpha would require a larger table.)
13020 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
13022 constexpr int kCachedPowersMinDecExp = -300;
13023 constexpr int kCachedPowersDecStep = 8;
13025 static constexpr std::array<cached_power, 79> kCachedPowers =
13028 { 0xAB70FE17C79AC6CA, -1060, -300 },
13029 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
13030 { 0xBE5691EF416BD60C, -1007, -284 },
13031 { 0x8DD01FAD907FFC3C, -980, -276 },
13032 { 0xD3515C2831559A83, -954, -268 },
13033 { 0x9D71AC8FADA6C9B5, -927, -260 },
13034 { 0xEA9C227723EE8BCB, -901, -252 },
13035 { 0xAECC49914078536D, -874, -244 },
13036 { 0x823C12795DB6CE57, -847, -236 },
13037 { 0xC21094364DFB5637, -821, -228 },
13038 { 0x9096EA6F3848984F, -794, -220 },
13039 { 0xD77485CB25823AC7, -768, -212 },
13040 { 0xA086CFCD97BF97F4, -741, -204 },
13041 { 0xEF340A98172AACE5, -715, -196 },
13042 { 0xB23867FB2A35B28E, -688, -188 },
13043 { 0x84C8D4DFD2C63F3B, -661, -180 },
13044 { 0xC5DD44271AD3CDBA, -635, -172 },
13045 { 0x936B9FCEBB25C996, -608, -164 },
13046 { 0xDBAC6C247D62A584, -582, -156 },
13047 { 0xA3AB66580D5FDAF6, -555, -148 },
13048 { 0xF3E2F893DEC3F126, -529, -140 },
13049 { 0xB5B5ADA8AAFF80B8, -502, -132 },
13050 { 0x87625F056C7C4A8B, -475, -124 },
13051 { 0xC9BCFF6034C13053, -449, -116 },
13052 { 0x964E858C91BA2655, -422, -108 },
13053 { 0xDFF9772470297EBD, -396, -100 },
13054 { 0xA6DFBD9FB8E5B88F, -369, -92 },
13055 { 0xF8A95FCF88747D94, -343, -84 },
13056 { 0xB94470938FA89BCF, -316, -76 },
13057 { 0x8A08F0F8BF0F156B, -289, -68 },
13058 { 0xCDB02555653131B6, -263, -60 },
13059 { 0x993FE2C6D07B7FAC, -236, -52 },
13060 { 0xE45C10C42A2B3B06, -210, -44 },
13061 { 0xAA242499697392D3, -183, -36 },
13062 { 0xFD87B5F28300CA0E, -157, -28 },
13063 { 0xBCE5086492111AEB, -130, -20 },
13064 { 0x8CBCCC096F5088CC, -103, -12 },
13065 { 0xD1B71758E219652C, -77, -4 },
13066 { 0x9C40000000000000, -50, 4 },
13067 { 0xE8D4A51000000000, -24, 12 },
13068 { 0xAD78EBC5AC620000, 3, 20 },
13069 { 0x813F3978F8940984, 30, 28 },
13070 { 0xC097CE7BC90715B3, 56, 36 },
13071 { 0x8F7E32CE7BEA5C70, 83, 44 },
13072 { 0xD5D238A4ABE98068, 109, 52 },
13073 { 0x9F4F2726179A2245, 136, 60 },
13074 { 0xED63A231D4C4FB27, 162, 68 },
13075 { 0xB0DE65388CC8ADA8, 189, 76 },
13076 { 0x83C7088E1AAB65DB, 216, 84 },
13077 { 0xC45D1DF942711D9A, 242, 92 },
13078 { 0x924D692CA61BE758, 269, 100 },
13079 { 0xDA01EE641A708DEA, 295, 108 },
13080 { 0xA26DA3999AEF774A, 322, 116 },
13081 { 0xF209787BB47D6B85, 348, 124 },
13082 { 0xB454E4A179DD1877, 375, 132 },
13083 { 0x865B86925B9BC5C2, 402, 140 },
13084 { 0xC83553C5C8965D3D, 428, 148 },
13085 { 0x952AB45CFA97A0B3, 455, 156 },
13086 { 0xDE469FBD99A05FE3, 481, 164 },
13087 { 0xA59BC234DB398C25, 508, 172 },
13088 { 0xF6C69A72A3989F5C, 534, 180 },
13089 { 0xB7DCBF5354E9BECE, 561, 188 },
13090 { 0x88FCF317F22241E2, 588, 196 },
13091 { 0xCC20CE9BD35C78A5, 614, 204 },
13092 { 0x98165AF37B2153DF, 641, 212 },
13093 { 0xE2A0B5DC971F303A, 667, 220 },
13094 { 0xA8D9D1535CE3B396, 694, 228 },
13095 { 0xFB9B7CD9A4A7443C, 720, 236 },
13096 { 0xBB764C4CA7A44410, 747, 244 },
13097 { 0x8BAB8EEFB6409C1A, 774, 252 },
13098 { 0xD01FEF10A657842C, 800, 260 },
13099 { 0x9B10A4E5E9913129, 827, 268 },
13100 { 0xE7109BFBA19C0C9D, 853, 276 },
13101 { 0xAC2820D9623BF429, 880, 284 },
13102 { 0x80444B5E7AA7CF85, 907, 292 },
13103 { 0xBF21E44003ACDD2D, 933, 300 },
13104 { 0x8E679C2F5E44FF8F, 960, 308 },
13105 { 0xD433179D9C8CB841, 986, 316 },
13106 { 0x9E19DB92B4E31BA9, 1013, 324 },
13110 // This computation gives exactly the same results for k as
13111 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
13112 // for |e| <= 1500, but doesn't require floating-point operations.
13113 // NB: log_10(2) ~= 78913 / 2^18
13114 assert(e >= -1500);
13116 const int f = kAlpha - e - 1;
13117 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
13119 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
13120 assert(index >= 0);
13121 assert(static_cast<std::size_t>(index) < kCachedPowers.size());
13123 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
13124 assert(kAlpha <= cached.e + e + 64);
13125 assert(kGamma >= cached.e + e + 64);
13131 For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
13132 For n == 0, returns 1 and sets pow10 := 1.
13134 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
13137 if (n >= 1000000000)
13139 pow10 = 1000000000;
13143 else if (n >= 100000000)
13148 else if (n >= 10000000)
13153 else if (n >= 1000000)
13158 else if (n >= 100000)
13163 else if (n >= 10000)
13168 else if (n >= 1000)
13190 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
13191 std::uint64_t rest, std::uint64_t ten_k)
13194 assert(dist <= delta);
13195 assert(rest <= delta);
13198 // <--------------------------- delta ---->
13199 // <---- dist --------->
13200 // --------------[------------------+-------------------]--------------
13205 // <---- rest ---->
13206 // --------------[------------------+----+--------------]--------------
13210 // ten_k represents a unit-in-the-last-place in the decimal representation
13212 // Decrement buf by ten_k while this takes buf closer to w.
13214 // The tests are written in this order to avoid overflow in unsigned
13215 // integer arithmetic.
13218 and delta - rest >= ten_k
13219 and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
13221 assert(buf[len - 1] != '0');
13228 Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
13229 M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
13231 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
13232 diyfp M_minus, diyfp w, diyfp M_plus)
13234 static_assert(kAlpha >= -60, "internal error");
13235 static_assert(kGamma <= -32, "internal error");
13237 // Generates the digits (and the exponent) of a decimal floating-point
13238 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
13239 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
13241 // <--------------------------- delta ---->
13242 // <---- dist --------->
13243 // --------------[------------------+-------------------]--------------
13246 // Grisu2 generates the digits of M+ from left to right and stops as soon as
13247 // V is in [M-,M+].
13249 assert(M_plus.e >= kAlpha);
13250 assert(M_plus.e <= kGamma);
13252 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
13253 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
13255 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
13258 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
13259 // = ((p1 ) * 2^-e + (p2 )) * 2^e
13262 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
13264 auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
13265 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
13269 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
13273 std::uint32_t pow10;
13274 const int k = find_largest_pow10(p1, pow10);
13276 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
13278 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
13279 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
13281 // M+ = p1 + p2 * 2^e
13282 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
13283 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
13284 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
13286 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
13288 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
13290 // but stop as soon as
13292 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
13298 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
13299 // pow10 = 10^(n-1) <= p1 < 10^n
13301 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
13302 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
13304 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
13305 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
13308 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
13310 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
13315 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
13319 // Now check if enough digits have been generated.
13322 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
13325 // Since rest and delta share the same exponent e, it suffices to
13326 // compare the significands.
13327 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
13330 // V = buffer * 10^n, with M- <= V <= M+.
13332 decimal_exponent += n;
13334 // We may now just stop. But instead look if the buffer could be
13335 // decremented to bring V closer to w.
13337 // pow10 = 10^n is now 1 ulp in the decimal representation V.
13338 // The rounding procedure works with diyfp's with an implicit
13341 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
13343 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
13344 grisu2_round(buffer, length, dist, delta, rest, ten_n);
13351 // pow10 = 10^(n-1) <= p1 < 10^n
13352 // Invariants restored.
13357 // The digits of the integral part have been generated:
13359 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
13360 // = buffer + p2 * 2^e
13362 // Now generate the digits of the fractional part p2 * 2^e.
13365 // No decimal point is generated: the exponent is adjusted instead.
13367 // p2 actually represents the fraction
13371 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
13373 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
13375 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
13376 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
13380 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
13381 // = ( d) * 2^-e + ( r)
13384 // 10^m * p2 * 2^e = d + r * 2^e
13388 // M+ = buffer + p2 * 2^e
13389 // = buffer + 10^-m * (d + r * 2^e)
13390 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
13392 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
13394 assert(p2 > delta);
13400 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
13401 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
13402 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
13403 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
13405 assert(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
13407 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
13408 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
13410 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
13411 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
13412 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
13415 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
13417 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
13422 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
13423 // Invariant restored.
13425 // Check if enough digits have been generated.
13427 // 10^-m * p2 * 2^e <= delta * 2^e
13428 // p2 * 2^e <= 10^m * delta * 2^e
13429 // p2 <= 10^m * delta
13438 // V = buffer * 10^-m, with M- <= V <= M+.
13440 decimal_exponent -= m;
13442 // 1 ulp in the decimal representation is now 10^-m.
13443 // Since delta and dist are now scaled by 10^m, we need to do the
13444 // same with ulp in order to keep the units in sync.
13446 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
13448 const std::uint64_t ten_m = one.f;
13449 grisu2_round(buffer, length, dist, delta, p2, ten_m);
13451 // By construction this algorithm generates the shortest possible decimal
13452 // number (Loitsch, Theorem 6.2) which rounds back to w.
13453 // For an input number of precision p, at least
13455 // N = 1 + ceil(p * log_10(2))
13457 // decimal digits are sufficient to identify all binary floating-point
13458 // numbers (Matula, "In-and-Out conversions").
13459 // This implies that the algorithm does not produce more than N decimal
13462 // N = 17 for p = 53 (IEEE double precision)
13463 // N = 9 for p = 24 (IEEE single precision)
13467 v = buf * 10^decimal_exponent
13468 len is the length of the buffer (number of decimal digits)
13469 The buffer must be large enough, i.e. >= max_digits10.
13471 JSON_HEDLEY_NON_NULL(1)
13472 inline void grisu2(char* buf, int& len, int& decimal_exponent,
13473 diyfp m_minus, diyfp v, diyfp m_plus)
13475 assert(m_plus.e == m_minus.e);
13476 assert(m_plus.e == v.e);
13478 // --------(-----------------------+-----------------------)-------- (A)
13481 // --------------------(-----------+-----------------------)-------- (B)
13484 // First scale v (and m- and m+) such that the exponent is in the range
13487 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
13489 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
13491 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
13492 const diyfp w = diyfp::mul(v, c_minus_k);
13493 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
13494 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
13496 // ----(---+---)---------------(---+---)---------------(---+---)----
13498 // = c*m- = c*v = c*m+
13500 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
13501 // w+ are now off by a small amount.
13504 // w - v * 10^k < 1 ulp
13506 // To account for this inaccuracy, add resp. subtract 1 ulp.
13508 // --------+---[---------------(---+---)---------------]---+--------
13511 // Now any number in [M-, M+] (bounds included) will round to w when input,
13512 // regardless of how the input rounding algorithm breaks ties.
13514 // And digit_gen generates the shortest possible such number in [M-, M+].
13515 // Note that this does not mean that Grisu2 always generates the shortest
13516 // possible number in the interval (m-, m+).
13517 const diyfp M_minus(w_minus.f + 1, w_minus.e);
13518 const diyfp M_plus (w_plus.f - 1, w_plus.e );
13520 decimal_exponent = -cached.k; // = -(-k) = k
13522 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
13526 v = buf * 10^decimal_exponent
13527 len is the length of the buffer (number of decimal digits)
13528 The buffer must be large enough, i.e. >= max_digits10.
13530 template <typename FloatType>
13531 JSON_HEDLEY_NON_NULL(1)
13532 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
13534 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
13535 "internal error: not enough precision");
13537 assert(std::isfinite(value));
13540 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
13541 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
13542 // decimal representations are not exactly "short".
13544 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
13545 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
13546 // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
13548 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
13549 // representation using the corresponding std::from_chars function recovers value exactly". That
13550 // indicates that single precision floating-point numbers should be recovered using
13553 // NB: If the neighbors are computed for single-precision numbers, there is a single float
13554 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
13555 // value is off by 1 ulp.
13557 const boundaries w = compute_boundaries(static_cast<double>(value));
13559 const boundaries w = compute_boundaries(value);
13562 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
13566 @brief appends a decimal representation of e to buf
13567 @return a pointer to the element following the exponent.
13568 @pre -1000 < e < 1000
13570 JSON_HEDLEY_NON_NULL(1)
13571 JSON_HEDLEY_RETURNS_NON_NULL
13572 inline char* append_exponent(char* buf, int e)
13587 auto k = static_cast<std::uint32_t>(e);
13590 // Always print at least two digits in the exponent.
13591 // This is for compatibility with printf("%g").
13593 *buf++ = static_cast<char>('0' + k);
13597 *buf++ = static_cast<char>('0' + k / 10);
13599 *buf++ = static_cast<char>('0' + k);
13603 *buf++ = static_cast<char>('0' + k / 100);
13605 *buf++ = static_cast<char>('0' + k / 10);
13607 *buf++ = static_cast<char>('0' + k);
13614 @brief prettify v = buf * 10^decimal_exponent
13616 If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
13617 notation. Otherwise it will be printed in exponential notation.
13622 JSON_HEDLEY_NON_NULL(1)
13623 JSON_HEDLEY_RETURNS_NON_NULL
13624 inline char* format_buffer(char* buf, int len, int decimal_exponent,
13625 int min_exp, int max_exp)
13627 assert(min_exp < 0);
13628 assert(max_exp > 0);
13631 const int n = len + decimal_exponent;
13633 // v = buf * 10^(n-k)
13634 // k is the length of the buffer (number of decimal digits)
13635 // n is the position of the decimal point relative to the start of the buffer.
13637 if (k <= n and n <= max_exp)
13640 // len <= max_exp + 2
13642 std::memset(buf + k, '0', static_cast<size_t>(n - k));
13643 // Make it look like a floating-point number (#362, #378)
13646 return buf + (n + 2);
13649 if (0 < n and n <= max_exp)
13652 // len <= max_digits10 + 1
13656 std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
13658 return buf + (k + 1);
13661 if (min_exp < n and n <= 0)
13664 // len <= 2 + (-min_exp - 1) + max_digits10
13666 std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
13669 std::memset(buf + 2, '0', static_cast<size_t>(-n));
13670 return buf + (2 + (-n) + k);
13683 // len <= max_digits10 + 1 + 5
13685 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
13691 return append_exponent(buf, n - 1);
13694 } // namespace dtoa_impl
13697 @brief generates a decimal representation of the floating-point number value in [first, last).
13699 The format of the resulting decimal representation is similar to printf's %g
13700 format. Returns an iterator pointing past-the-end of the decimal representation.
13702 @note The input number must be finite, i.e. NaN's and Inf's are not supported.
13703 @note The buffer must be large enough.
13704 @note The result is NOT null-terminated.
13706 template <typename FloatType>
13707 JSON_HEDLEY_NON_NULL(1, 2)
13708 JSON_HEDLEY_RETURNS_NON_NULL
13709 char* to_chars(char* first, const char* last, FloatType value)
13711 static_cast<void>(last); // maybe unused - fix warning
13712 assert(std::isfinite(value));
13714 // Use signbit(value) instead of (value < 0) since signbit works for -0.
13715 if (std::signbit(value))
13721 if (value == 0) // +-0
13724 // Make it look like a floating-point number (#362, #378)
13730 assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
13732 // Compute v = buffer * 10^decimal_exponent.
13733 // The decimal digits are stored in the buffer, which needs to be interpreted
13734 // as an unsigned decimal integer.
13735 // len is the length of the buffer, i.e. the number of decimal digits.
13737 int decimal_exponent = 0;
13738 dtoa_impl::grisu2(first, len, decimal_exponent, value);
13740 assert(len <= std::numeric_limits<FloatType>::max_digits10);
13742 // Format the buffer like printf("%.*g", prec, value)
13743 constexpr int kMinExp = -4;
13744 // Use digits10 here to increase compatibility with version 2.
13745 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
13747 assert(last - first >= kMaxExp + 2);
13748 assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
13749 assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
13751 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
13754 } // namespace detail
13755 } // namespace nlohmann
13757 // #include <nlohmann/detail/exceptions.hpp>
13759 // #include <nlohmann/detail/macro_scope.hpp>
13761 // #include <nlohmann/detail/meta/cpp_future.hpp>
13763 // #include <nlohmann/detail/output/binary_writer.hpp>
13765 // #include <nlohmann/detail/output/output_adapters.hpp>
13767 // #include <nlohmann/detail/value_t.hpp>
13774 ///////////////////
13775 // serialization //
13776 ///////////////////
13778 /// how to treat decoding errors
13779 enum class error_handler_t
13781 strict, ///< throw a type_error exception in case of invalid UTF-8
13782 replace, ///< replace invalid UTF-8 sequences with U+FFFD
13783 ignore ///< ignore invalid UTF-8 sequences
13786 template<typename BasicJsonType>
13789 using string_t = typename BasicJsonType::string_t;
13790 using number_float_t = typename BasicJsonType::number_float_t;
13791 using number_integer_t = typename BasicJsonType::number_integer_t;
13792 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
13793 static constexpr std::uint8_t UTF8_ACCEPT = 0;
13794 static constexpr std::uint8_t UTF8_REJECT = 1;
13798 @param[in] s output stream to serialize to
13799 @param[in] ichar indentation character to use
13800 @param[in] error_handler_ how to react on decoding errors
13802 serializer(output_adapter_t<char> s, const char ichar,
13803 error_handler_t error_handler_ = error_handler_t::strict)
13805 , loc(std::localeconv())
13806 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : * (loc->thousands_sep))
13807 , decimal_point(loc->decimal_point == nullptr ? '\0' : * (loc->decimal_point))
13808 , indent_char(ichar)
13809 , indent_string(512, indent_char)
13810 , error_handler(error_handler_)
13813 // delete because of pointer members
13814 serializer(const serializer&) = delete;
13815 serializer& operator=(const serializer&) = delete;
13816 serializer(serializer&&) = delete;
13817 serializer& operator=(serializer&&) = delete;
13818 ~serializer() = default;
13821 @brief internal implementation of the serialization function
13823 This function is called by the public member function dump and organizes
13824 the serialization internally. The indentation level is propagated as
13825 additional parameter. In case of arrays and objects, the function is
13826 called recursively.
13828 - strings and object keys are escaped using `escape_string()`
13829 - integer numbers are converted implicitly via `operator<<`
13830 - floating-point numbers are converted to a string using `"%g"` format
13832 @param[in] val value to serialize
13833 @param[in] pretty_print whether the output shall be pretty-printed
13834 @param[in] indent_step the indent level
13835 @param[in] current_indent the current indent level (only used internally)
13837 void dump(const BasicJsonType& val, const bool pretty_print,
13838 const bool ensure_ascii,
13839 const unsigned int indent_step,
13840 const unsigned int current_indent = 0)
13842 switch (val.m_type)
13844 case value_t::object:
13846 if (val.m_value.object->empty())
13848 o->write_characters("{}", 2);
13854 o->write_characters("{\n", 2);
13856 // variable to hold indentation for recursive calls
13857 const auto new_indent = current_indent + indent_step;
13858 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
13860 indent_string.resize(indent_string.size() * 2, ' ');
13863 // first n-1 elements
13864 auto i = val.m_value.object->cbegin();
13865 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
13867 o->write_characters(indent_string.c_str(), new_indent);
13868 o->write_character('\"');
13869 dump_escaped(i->first, ensure_ascii);
13870 o->write_characters("\": ", 3);
13871 dump(i->second, true, ensure_ascii, indent_step, new_indent);
13872 o->write_characters(",\n", 2);
13876 assert(i != val.m_value.object->cend());
13877 assert(std::next(i) == val.m_value.object->cend());
13878 o->write_characters(indent_string.c_str(), new_indent);
13879 o->write_character('\"');
13880 dump_escaped(i->first, ensure_ascii);
13881 o->write_characters("\": ", 3);
13882 dump(i->second, true, ensure_ascii, indent_step, new_indent);
13884 o->write_character('\n');
13885 o->write_characters(indent_string.c_str(), current_indent);
13886 o->write_character('}');
13890 o->write_character('{');
13892 // first n-1 elements
13893 auto i = val.m_value.object->cbegin();
13894 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
13896 o->write_character('\"');
13897 dump_escaped(i->first, ensure_ascii);
13898 o->write_characters("\":", 2);
13899 dump(i->second, false, ensure_ascii, indent_step, current_indent);
13900 o->write_character(',');
13904 assert(i != val.m_value.object->cend());
13905 assert(std::next(i) == val.m_value.object->cend());
13906 o->write_character('\"');
13907 dump_escaped(i->first, ensure_ascii);
13908 o->write_characters("\":", 2);
13909 dump(i->second, false, ensure_ascii, indent_step, current_indent);
13911 o->write_character('}');
13917 case value_t::array:
13919 if (val.m_value.array->empty())
13921 o->write_characters("[]", 2);
13927 o->write_characters("[\n", 2);
13929 // variable to hold indentation for recursive calls
13930 const auto new_indent = current_indent + indent_step;
13931 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
13933 indent_string.resize(indent_string.size() * 2, ' ');
13936 // first n-1 elements
13937 for (auto i = val.m_value.array->cbegin();
13938 i != val.m_value.array->cend() - 1; ++i)
13940 o->write_characters(indent_string.c_str(), new_indent);
13941 dump(*i, true, ensure_ascii, indent_step, new_indent);
13942 o->write_characters(",\n", 2);
13946 assert(not val.m_value.array->empty());
13947 o->write_characters(indent_string.c_str(), new_indent);
13948 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
13950 o->write_character('\n');
13951 o->write_characters(indent_string.c_str(), current_indent);
13952 o->write_character(']');
13956 o->write_character('[');
13958 // first n-1 elements
13959 for (auto i = val.m_value.array->cbegin();
13960 i != val.m_value.array->cend() - 1; ++i)
13962 dump(*i, false, ensure_ascii, indent_step, current_indent);
13963 o->write_character(',');
13967 assert(not val.m_value.array->empty());
13968 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
13970 o->write_character(']');
13976 case value_t::string:
13978 o->write_character('\"');
13979 dump_escaped(*val.m_value.string, ensure_ascii);
13980 o->write_character('\"');
13984 case value_t::boolean:
13986 if (val.m_value.boolean)
13988 o->write_characters("true", 4);
13992 o->write_characters("false", 5);
13997 case value_t::number_integer:
13999 dump_integer(val.m_value.number_integer);
14003 case value_t::number_unsigned:
14005 dump_integer(val.m_value.number_unsigned);
14009 case value_t::number_float:
14011 dump_float(val.m_value.number_float);
14015 case value_t::discarded:
14017 o->write_characters("<discarded>", 11);
14021 case value_t::null:
14023 o->write_characters("null", 4);
14027 default: // LCOV_EXCL_LINE
14028 assert(false); // LCOV_EXCL_LINE
14034 @brief dump escaped string
14036 Escape a string by replacing certain special characters by a sequence of an
14037 escape character (backslash) and another character and other control
14038 characters by a sequence of "\u" followed by a four-digit hex
14039 representation. The escaped string is written to output stream @a o.
14041 @param[in] s the string to escape
14042 @param[in] ensure_ascii whether to escape non-ASCII characters with
14045 @complexity Linear in the length of string @a s.
14047 void dump_escaped(const string_t& s, const bool ensure_ascii)
14049 std::uint32_t codepoint;
14050 std::uint8_t state = UTF8_ACCEPT;
14051 std::size_t bytes = 0; // number of bytes written to string_buffer
14053 // number of bytes written at the point of the last valid byte
14054 std::size_t bytes_after_last_accept = 0;
14055 std::size_t undumped_chars = 0;
14057 for (std::size_t i = 0; i < s.size(); ++i)
14059 const auto byte = static_cast<uint8_t>(s[i]);
14061 switch (decode(state, codepoint, byte))
14063 case UTF8_ACCEPT: // decode found a new code point
14067 case 0x08: // backspace
14069 string_buffer[bytes++] = '\\';
14070 string_buffer[bytes++] = 'b';
14074 case 0x09: // horizontal tab
14076 string_buffer[bytes++] = '\\';
14077 string_buffer[bytes++] = 't';
14081 case 0x0A: // newline
14083 string_buffer[bytes++] = '\\';
14084 string_buffer[bytes++] = 'n';
14088 case 0x0C: // formfeed
14090 string_buffer[bytes++] = '\\';
14091 string_buffer[bytes++] = 'f';
14095 case 0x0D: // carriage return
14097 string_buffer[bytes++] = '\\';
14098 string_buffer[bytes++] = 'r';
14102 case 0x22: // quotation mark
14104 string_buffer[bytes++] = '\\';
14105 string_buffer[bytes++] = '\"';
14109 case 0x5C: // reverse solidus
14111 string_buffer[bytes++] = '\\';
14112 string_buffer[bytes++] = '\\';
14118 // escape control characters (0x00..0x1F) or, if
14119 // ensure_ascii parameter is used, non-ASCII characters
14120 if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
14122 if (codepoint <= 0xFFFF)
14124 (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
14125 static_cast<std::uint16_t>(codepoint));
14130 (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
14131 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
14132 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
14138 // copy byte to buffer (all previous bytes
14139 // been copied have in default case above)
14140 string_buffer[bytes++] = s[i];
14146 // write buffer and reset index; there must be 13 bytes
14147 // left, as this is the maximal number of bytes to be
14148 // written ("\uxxxx\uxxxx\0") for one code point
14149 if (string_buffer.size() - bytes < 13)
14151 o->write_characters(string_buffer.data(), bytes);
14155 // remember the byte position of this accept
14156 bytes_after_last_accept = bytes;
14157 undumped_chars = 0;
14161 case UTF8_REJECT: // decode found invalid UTF-8 byte
14163 switch (error_handler)
14165 case error_handler_t::strict:
14167 std::string sn(3, '\0');
14168 (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
14169 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
14172 case error_handler_t::ignore:
14173 case error_handler_t::replace:
14175 // in case we saw this character the first time, we
14176 // would like to read it again, because the byte
14177 // may be OK for itself, but just not OK for the
14178 // previous sequence
14179 if (undumped_chars > 0)
14184 // reset length buffer to the last accepted index;
14185 // thus removing/ignoring the invalid characters
14186 bytes = bytes_after_last_accept;
14188 if (error_handler == error_handler_t::replace)
14190 // add a replacement character
14193 string_buffer[bytes++] = '\\';
14194 string_buffer[bytes++] = 'u';
14195 string_buffer[bytes++] = 'f';
14196 string_buffer[bytes++] = 'f';
14197 string_buffer[bytes++] = 'f';
14198 string_buffer[bytes++] = 'd';
14202 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
14203 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
14204 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
14207 // write buffer and reset index; there must be 13 bytes
14208 // left, as this is the maximal number of bytes to be
14209 // written ("\uxxxx\uxxxx\0") for one code point
14210 if (string_buffer.size() - bytes < 13)
14212 o->write_characters(string_buffer.data(), bytes);
14216 bytes_after_last_accept = bytes;
14219 undumped_chars = 0;
14221 // continue processing the string
14222 state = UTF8_ACCEPT;
14226 default: // LCOV_EXCL_LINE
14227 assert(false); // LCOV_EXCL_LINE
14232 default: // decode found yet incomplete multi-byte code point
14234 if (not ensure_ascii)
14236 // code point will not be escaped - copy byte to buffer
14237 string_buffer[bytes++] = s[i];
14245 // we finished processing the string
14246 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
14251 o->write_characters(string_buffer.data(), bytes);
14256 // we finish reading, but do not accept: string was incomplete
14257 switch (error_handler)
14259 case error_handler_t::strict:
14261 std::string sn(3, '\0');
14262 (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
14263 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
14266 case error_handler_t::ignore:
14268 // write all accepted bytes
14269 o->write_characters(string_buffer.data(), bytes_after_last_accept);
14273 case error_handler_t::replace:
14275 // write all accepted bytes
14276 o->write_characters(string_buffer.data(), bytes_after_last_accept);
14277 // add a replacement character
14280 o->write_characters("\\ufffd", 6);
14284 o->write_characters("\xEF\xBF\xBD", 3);
14289 default: // LCOV_EXCL_LINE
14290 assert(false); // LCOV_EXCL_LINE
14296 @brief count digits
14298 Count the number of decimal (base 10) digits for an input unsigned integer.
14300 @param[in] x unsigned integer number to count its digits
14301 @return number of decimal digits
14303 inline unsigned int count_digits(number_unsigned_t x) noexcept
14305 unsigned int n_digits = 1;
14314 return n_digits + 1;
14318 return n_digits + 2;
14322 return n_digits + 3;
14330 @brief dump an integer
14332 Dump a given integer to output stream @a o. Works internally with
14335 @param[in] x integer number (signed or unsigned) to dump
14336 @tparam NumberType either @a number_integer_t or @a number_unsigned_t
14338 template<typename NumberType, detail::enable_if_t<
14339 std::is_same<NumberType, number_unsigned_t>::value or
14340 std::is_same<NumberType, number_integer_t>::value,
14342 void dump_integer(NumberType x)
14344 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
14347 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
14348 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
14349 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
14350 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
14351 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
14352 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
14353 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
14354 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
14355 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
14356 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
14360 // special case for "0"
14363 o->write_character('0');
14367 // use a pointer to fill the buffer
14368 auto buffer_ptr = number_buffer.begin();
14370 const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not(x >= 0); // see issue #755
14371 number_unsigned_t abs_value;
14373 unsigned int n_chars;
14378 abs_value = remove_sign(x);
14380 // account one more byte for the minus sign
14381 n_chars = 1 + count_digits(abs_value);
14385 abs_value = static_cast<number_unsigned_t>(x);
14386 n_chars = count_digits(abs_value);
14389 // spare 1 byte for '\0'
14390 assert(n_chars < number_buffer.size() - 1);
14392 // jump to the end to generate the string from backward
14393 // so we later avoid reversing the result
14394 buffer_ptr += n_chars;
14396 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
14397 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
14398 while (abs_value >= 100)
14400 const auto digits_index = static_cast<unsigned>((abs_value % 100));
14402 *(--buffer_ptr) = digits_to_99[digits_index][1];
14403 *(--buffer_ptr) = digits_to_99[digits_index][0];
14406 if (abs_value >= 10)
14408 const auto digits_index = static_cast<unsigned>(abs_value);
14409 *(--buffer_ptr) = digits_to_99[digits_index][1];
14410 *(--buffer_ptr) = digits_to_99[digits_index][0];
14414 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
14417 o->write_characters(number_buffer.data(), n_chars);
14421 @brief dump a floating-point number
14423 Dump a given floating-point number to output stream @a o. Works internally
14424 with @a number_buffer.
14426 @param[in] x floating-point number to dump
14428 void dump_float(number_float_t x)
14431 if (not std::isfinite(x))
14433 o->write_characters("null", 4);
14437 // If number_float_t is an IEEE-754 single or double precision number,
14438 // use the Grisu2 algorithm to produce short numbers which are
14439 // guaranteed to round-trip, using strtof and strtod, resp.
14441 // NB: The test below works if <long double> == <double>.
14442 static constexpr bool is_ieee_single_or_double
14443 = (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 24 and std::numeric_limits<number_float_t>::max_exponent == 128) or
14444 (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 53 and std::numeric_limits<number_float_t>::max_exponent == 1024);
14446 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
14449 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
14451 char* begin = number_buffer.data();
14452 char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
14454 o->write_characters(begin, static_cast<size_t>(end - begin));
14457 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
14459 // get number of digits for a float -> text -> float round-trip
14460 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
14462 // the actual conversion
14463 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
14465 // negative value indicates an error
14467 // check if buffer was large enough
14468 assert(static_cast<std::size_t>(len) < number_buffer.size());
14470 // erase thousands separator
14471 if (thousands_sep != '\0')
14473 const auto end = std::remove(number_buffer.begin(),
14474 number_buffer.begin() + len, thousands_sep);
14475 std::fill(end, number_buffer.end(), '\0');
14476 assert((end - number_buffer.begin()) <= len);
14477 len = (end - number_buffer.begin());
14480 // convert decimal point to '.'
14481 if (decimal_point != '\0' and decimal_point != '.')
14483 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
14484 if (dec_pos != number_buffer.end())
14490 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
14492 // determine if need to append ".0"
14493 const bool value_is_int_like =
14494 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
14497 return c == '.' or c == 'e';
14500 if (value_is_int_like)
14502 o->write_characters(".0", 2);
14507 @brief check whether a string is UTF-8 encoded
14509 The function checks each byte of a string whether it is UTF-8 encoded. The
14510 result of the check is stored in the @a state parameter. The function must
14511 be called initially with state 0 (accept). State 1 means the string must
14512 be rejected, because the current byte is not allowed. If the string is
14513 completely processed, but the state is non-zero, the string ended
14514 prematurely; that is, the last byte indicated more bytes should have
14517 @param[in,out] state the state of the decoding
14518 @param[in,out] codep codepoint (valid only if resulting state is UTF8_ACCEPT)
14519 @param[in] byte next byte to decode
14522 @note The function has been edited: a std::array is used.
14524 @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
14525 @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
14527 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
14529 static const std::array<std::uint8_t, 400> utf8d =
14532 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
14533 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
14534 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
14535 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
14536 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
14537 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
14538 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
14539 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
14540 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
14541 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
14542 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
14543 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
14544 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
14545 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
14549 const std::uint8_t type = utf8d[byte];
14551 codep = (state != UTF8_ACCEPT)
14552 ? (byte & 0x3fu) | (codep << 6u)
14553 : (0xFFu >> type) & (byte);
14555 state = utf8d[256u + state * 16u + type];
14560 * Overload to make the compiler happy while it is instantiating
14561 * dump_integer for number_unsigned_t.
14562 * Must never be called.
14564 number_unsigned_t remove_sign(number_unsigned_t x)
14566 assert(false); // LCOV_EXCL_LINE
14567 return x; // LCOV_EXCL_LINE
14571 * Helper function for dump_integer
14573 * This function takes a negative signed integer and returns its absolute
14574 * value as unsigned integer. The plus/minus shuffling is necessary as we can
14575 * not directly remove the sign of an arbitrary signed integer as the
14576 * absolute values of INT_MIN and INT_MAX are usually not the same. See
14577 * #1708 for details.
14579 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
14581 assert(x < 0 and x < (std::numeric_limits<number_integer_t>::max)());
14582 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
14586 /// the output of the serializer
14587 output_adapter_t<char> o = nullptr;
14589 /// a (hopefully) large enough character buffer
14590 std::array<char, 64> number_buffer{{}};
14593 const std::lconv* loc = nullptr;
14594 /// the locale's thousand separator character
14595 const char thousands_sep = '\0';
14596 /// the locale's decimal point character
14597 const char decimal_point = '\0';
14600 std::array<char, 512> string_buffer{{}};
14602 /// the indentation character
14603 const char indent_char;
14604 /// the indentation string
14605 string_t indent_string;
14607 /// error_handler how to react on decoding errors
14608 const error_handler_t error_handler;
14610 } // namespace detail
14611 } // namespace nlohmann
14613 // #include <nlohmann/detail/value_t.hpp>
14615 // #include <nlohmann/json_fwd.hpp>
14619 @brief namespace for Niels Lohmann
14620 @see https://github.com/nlohmann
14621 @since version 1.0.0
14627 @brief a class to store JSON values
14629 @tparam ObjectType type for JSON objects (`std::map` by default; will be used
14631 @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
14633 @tparam StringType type for JSON strings and object keys (`std::string` by
14634 default; will be used in @ref string_t)
14635 @tparam BooleanType type for JSON booleans (`bool` by default; will be used
14637 @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
14638 default; will be used in @ref number_integer_t)
14639 @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
14640 `uint64_t` by default; will be used in @ref number_unsigned_t)
14641 @tparam NumberFloatType type for JSON floating-point numbers (`double` by
14642 default; will be used in @ref number_float_t)
14643 @tparam AllocatorType type of the allocator to use (`std::allocator` by
14645 @tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
14646 and `from_json()` (@ref adl_serializer by default)
14648 @requirement The class satisfies the following concept requirements:
14650 - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
14651 JSON values can be default constructed. The result will be a JSON null
14653 - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
14654 A JSON value can be constructed from an rvalue argument.
14655 - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
14656 A JSON value can be copy-constructed from an lvalue expression.
14657 - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
14658 A JSON value van be assigned from an rvalue argument.
14659 - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
14660 A JSON value can be copy-assigned from an lvalue expression.
14661 - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
14662 JSON values can be destructed.
14664 - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
14666 [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
14667 All non-static data members are private and standard layout types, the
14668 class has no virtual functions or (virtual) base classes.
14670 - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
14671 JSON values can be compared with `==`, see @ref
14672 operator==(const_reference,const_reference).
14673 - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
14674 JSON values can be compared with `<`, see @ref
14675 operator<(const_reference,const_reference).
14676 - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
14677 Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
14678 other compatible types, using unqualified function call @ref swap().
14679 - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
14680 JSON values can be compared against `std::nullptr_t` objects which are used
14681 to model the `null` value.
14683 - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
14684 JSON values can be used like STL containers and provide iterator access.
14685 - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
14686 JSON values can be used like STL containers and provide reverse iterator
14689 @invariant The member variables @a m_value and @a m_type have the following
14691 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
14692 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
14693 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
14694 The invariants are checked by member function assert_invariant().
14697 @note ObjectType trick from http://stackoverflow.com/a/9860911
14700 @see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
14701 Format](http://rfc7159.net/rfc7159)
14703 @since version 1.0.0
14707 NLOHMANN_BASIC_JSON_TPL_DECLARATION
14711 template<detail::value_t> friend struct detail::external_constructor;
14712 friend ::nlohmann::json_pointer<basic_json>;
14713 friend ::nlohmann::detail::parser<basic_json>;
14714 friend ::nlohmann::detail::serializer<basic_json>;
14715 template<typename BasicJsonType>
14716 friend class ::nlohmann::detail::iter_impl;
14717 template<typename BasicJsonType, typename CharType>
14718 friend class ::nlohmann::detail::binary_writer;
14719 template<typename BasicJsonType, typename SAX>
14720 friend class ::nlohmann::detail::binary_reader;
14721 template<typename BasicJsonType>
14722 friend class ::nlohmann::detail::json_sax_dom_parser;
14723 template<typename BasicJsonType>
14724 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
14726 /// workaround type for MSVC
14727 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
14729 // convenience aliases for types residing in namespace detail;
14730 using lexer = ::nlohmann::detail::lexer<basic_json>;
14731 using parser = ::nlohmann::detail::parser<basic_json>;
14733 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
14734 template<typename BasicJsonType>
14735 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
14736 template<typename BasicJsonType>
14737 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
14738 template<typename Iterator>
14739 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
14740 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
14742 template<typename CharType>
14743 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
14745 using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
14746 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
14748 using serializer = ::nlohmann::detail::serializer<basic_json>;
14751 using value_t = detail::value_t;
14752 /// JSON Pointer, see @ref nlohmann::json_pointer
14753 using json_pointer = ::nlohmann::json_pointer<basic_json>;
14754 template<typename T, typename SFINAE>
14755 using json_serializer = JSONSerializer<T, SFINAE>;
14756 /// how to treat decoding errors
14757 using error_handler_t = detail::error_handler_t;
14758 /// helper type for initializer lists of basic_json values
14759 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
14761 using input_format_t = detail::input_format_t;
14762 /// SAX interface type, see @ref nlohmann::json_sax
14763 using json_sax_t = json_sax<basic_json>;
14769 /// @name exceptions
14770 /// Classes to implement user-defined exceptions.
14773 /// @copydoc detail::exception
14774 using exception = detail::exception;
14775 /// @copydoc detail::parse_error
14776 using parse_error = detail::parse_error;
14777 /// @copydoc detail::invalid_iterator
14778 using invalid_iterator = detail::invalid_iterator;
14779 /// @copydoc detail::type_error
14780 using type_error = detail::type_error;
14781 /// @copydoc detail::out_of_range
14782 using out_of_range = detail::out_of_range;
14783 /// @copydoc detail::other_error
14784 using other_error = detail::other_error;
14789 /////////////////////
14790 // container types //
14791 /////////////////////
14793 /// @name container types
14794 /// The canonic container types to use @ref basic_json like any other STL
14798 /// the type of elements in a basic_json container
14799 using value_type = basic_json;
14801 /// the type of an element reference
14802 using reference = value_type&;
14803 /// the type of an element const reference
14804 using const_reference = const value_type&;
14806 /// a type to represent differences between iterators
14807 using difference_type = std::ptrdiff_t;
14808 /// a type to represent container sizes
14809 using size_type = std::size_t;
14811 /// the allocator type
14812 using allocator_type = AllocatorType<basic_json>;
14814 /// the type of an element pointer
14815 using pointer = typename std::allocator_traits<allocator_type>::pointer;
14816 /// the type of an element const pointer
14817 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
14819 /// an iterator for a basic_json container
14820 using iterator = iter_impl<basic_json>;
14821 /// a const iterator for a basic_json container
14822 using const_iterator = iter_impl<const basic_json>;
14823 /// a reverse iterator for a basic_json container
14824 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
14825 /// a const reverse iterator for a basic_json container
14826 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
14832 @brief returns the allocator associated with the container
14834 static allocator_type get_allocator()
14836 return allocator_type();
14840 @brief returns version information on the library
14842 This function returns a JSON object with information about the library,
14843 including the version number and information on the platform and compiler.
14845 @return JSON object holding version information
14847 ----------- | ---------------
14848 `compiler` | Information on the used compiler. It is an object with the following keys: `c++` (the used C++ standard), `family` (the compiler family; possible values are `clang`, `icc`, `gcc`, `ilecpp`, `msvc`, `pgcpp`, `sunpro`, and `unknown`), and `version` (the compiler version).
14849 `copyright` | The copyright line for the library as string.
14850 `name` | The name of the library as string.
14851 `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
14852 `url` | The URL of the project as string.
14853 `version` | The version of the library. It is an object with the following keys: `major`, `minor`, and `patch` as defined by [Semantic Versioning](http://semver.org), and `string` (the version string).
14855 @liveexample{The following code shows an example output of the `meta()`
14858 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14859 changes to any JSON value.
14861 @complexity Constant.
14865 JSON_HEDLEY_WARN_UNUSED_RESULT
14866 static basic_json meta()
14870 result["copyright"] = "(C) 2013-2017 Niels Lohmann";
14871 result["name"] = "JSON for Modern C++";
14872 result["url"] = "https://github.com/nlohmann/json";
14873 result["version"]["string"] =
14874 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
14875 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
14876 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
14877 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
14878 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
14879 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
14882 result["platform"] = "win32";
14883 #elif defined __linux__
14884 result["platform"] = "linux";
14885 #elif defined __APPLE__
14886 result["platform"] = "apple";
14887 #elif defined __unix__
14888 result["platform"] = "unix";
14890 result["platform"] = "unknown";
14893 #if defined(__ICC) || defined(__INTEL_COMPILER)
14894 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
14895 #elif defined(__clang__)
14896 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
14897 #elif defined(__GNUC__) || defined(__GNUG__)
14898 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
14899 #elif defined(__HP_cc) || defined(__HP_aCC)
14900 result["compiler"] = "hp"
14901 #elif defined(__IBMCPP__)
14902 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
14903 #elif defined(_MSC_VER)
14904 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
14905 #elif defined(__PGI)
14906 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
14907 #elif defined(__SUNPRO_CC)
14908 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
14910 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
14914 result["compiler"]["c++"] = std::to_string(__cplusplus);
14916 result["compiler"]["c++"] = "unknown";
14922 ///////////////////////////
14923 // JSON value data types //
14924 ///////////////////////////
14926 /// @name JSON value data types
14927 /// The data types to store a JSON value. These types are derived from
14928 /// the template arguments passed to class @ref basic_json.
14931 #if defined(JSON_HAS_CPP_14)
14932 // Use transparent comparator if possible, combined with perfect forwarding
14933 // on find() and count() calls prevents unnecessary string construction.
14934 using object_comparator_t = std::less<>;
14936 using object_comparator_t = std::less<StringType>;
14940 @brief a type for an object
14942 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
14943 > An object is an unordered collection of zero or more name/value pairs,
14944 > where a name is a string and a value is a string, number, boolean, null,
14945 > object, or array.
14947 To store objects in C++, a type is defined by the template parameters
14950 @tparam ObjectType the container to store objects (e.g., `std::map` or
14951 `std::unordered_map`)
14952 @tparam StringType the type of the keys or names (e.g., `std::string`).
14953 The comparison function `std::less<StringType>` is used to order elements
14954 inside the container.
14955 @tparam AllocatorType the allocator to use for objects (e.g.,
14960 With the default values for @a ObjectType (`std::map`), @a StringType
14961 (`std::string`), and @a AllocatorType (`std::allocator`), the default
14962 value for @a object_t is:
14966 std::string, // key_type
14967 basic_json, // value_type
14968 std::less<std::string>, // key_compare
14969 std::allocator<std::pair<const std::string, basic_json>> // allocator_type
14975 The choice of @a object_t influences the behavior of the JSON class. With
14976 the default type, objects have the following behavior:
14978 - When all names are unique, objects will be interoperable in the sense
14979 that all software implementations receiving that object will agree on
14980 the name-value mappings.
14981 - When the names within an object are not unique, it is unspecified which
14982 one of the values for a given key will be chosen. For instance,
14983 `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
14985 - Internally, name/value pairs are stored in lexicographical order of the
14986 names. Objects will also be serialized (see @ref dump) in this order.
14987 For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
14988 and serialized as `{"a": 2, "b": 1}`.
14989 - When comparing objects, the order of the name/value pairs is irrelevant.
14990 This makes objects interoperable in the sense that they will not be
14991 affected by these differences. For instance, `{"b": 1, "a": 2}` and
14992 `{"a": 2, "b": 1}` will be treated as equal.
14996 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
14997 > An implementation may set limits on the maximum depth of nesting.
14999 In this class, the object's limit of nesting is not explicitly constrained.
15000 However, a maximum depth of nesting may be introduced by the compiler or
15001 runtime environment. A theoretical limit can be queried by calling the
15002 @ref max_size function of a JSON object.
15006 Objects are stored as pointers in a @ref basic_json type. That is, for any
15007 access to object values, a pointer of type `object_t*` must be
15010 @sa @ref array_t -- type for an array value
15012 @since version 1.0.0
15014 @note The order name/value pairs are added to the object is *not*
15015 preserved by the library. Therefore, iterating an object may return
15016 name/value pairs in a different order than they were originally stored. In
15017 fact, keys will be traversed in alphabetical order as `std::map` with
15018 `std::less` is used by default. Please note this behavior conforms to [RFC
15019 7159](http://rfc7159.net/rfc7159), because any order implements the
15020 specified "unordered" nature of JSON objects.
15022 using object_t = ObjectType<StringType,
15024 object_comparator_t,
15025 AllocatorType<std::pair<const StringType,
15029 @brief a type for an array
15031 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
15032 > An array is an ordered sequence of zero or more values.
15034 To store objects in C++, a type is defined by the template parameters
15037 @tparam ArrayType container type to store arrays (e.g., `std::vector` or
15039 @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
15043 With the default values for @a ArrayType (`std::vector`) and @a
15044 AllocatorType (`std::allocator`), the default value for @a array_t is:
15048 basic_json, // value_type
15049 std::allocator<basic_json> // allocator_type
15055 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
15056 > An implementation may set limits on the maximum depth of nesting.
15058 In this class, the array's limit of nesting is not explicitly constrained.
15059 However, a maximum depth of nesting may be introduced by the compiler or
15060 runtime environment. A theoretical limit can be queried by calling the
15061 @ref max_size function of a JSON array.
15065 Arrays are stored as pointers in a @ref basic_json type. That is, for any
15066 access to array values, a pointer of type `array_t*` must be dereferenced.
15068 @sa @ref object_t -- type for an object value
15070 @since version 1.0.0
15072 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
15075 @brief a type for a string
15077 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
15078 > A string is a sequence of zero or more Unicode characters.
15080 To store objects in C++, a type is defined by the template parameter
15081 described below. Unicode values are split by the JSON class into
15082 byte-sized characters during deserialization.
15084 @tparam StringType the container to store strings (e.g., `std::string`).
15085 Note this container is used for keys/names in objects, see @ref object_t.
15089 With the default values for @a StringType (`std::string`), the default
15090 value for @a string_t is:
15098 Strings are stored in UTF-8 encoding. Therefore, functions like
15099 `std::string::size()` or `std::string::length()` return the number of
15100 bytes in the string rather than the number of characters or glyphs.
15102 #### String comparison
15104 [RFC 7159](http://rfc7159.net/rfc7159) states:
15105 > Software implementations are typically required to test names of object
15106 > members for equality. Implementations that transform the textual
15107 > representation into sequences of Unicode code units and then perform the
15108 > comparison numerically, code unit by code unit, are interoperable in the
15109 > sense that implementations will agree in all cases on equality or
15110 > inequality of two strings. For example, implementations that compare
15111 > strings with escaped characters unconverted may incorrectly find that
15112 > `"a\\b"` and `"a\u005Cb"` are not equal.
15114 This implementation is interoperable as it does compare strings code unit
15119 String values are stored as pointers in a @ref basic_json type. That is,
15120 for any access to string values, a pointer of type `string_t*` must be
15123 @since version 1.0.0
15125 using string_t = StringType;
15128 @brief a type for a boolean
15130 [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
15131 type which differentiates the two literals `true` and `false`.
15133 To store objects in C++, a type is defined by the template parameter @a
15134 BooleanType which chooses the type to use.
15138 With the default values for @a BooleanType (`bool`), the default value for
15147 Boolean values are stored directly inside a @ref basic_json type.
15149 @since version 1.0.0
15151 using boolean_t = BooleanType;
15154 @brief a type for a number (integer)
15156 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
15157 > The representation of numbers is similar to that used in most
15158 > programming languages. A number is represented in base 10 using decimal
15159 > digits. It contains an integer component that may be prefixed with an
15160 > optional minus sign, which may be followed by a fraction part and/or an
15161 > exponent part. Leading zeros are not allowed. (...) Numeric values that
15162 > cannot be represented in the grammar below (such as Infinity and NaN)
15163 > are not permitted.
15165 This description includes both integer and floating-point numbers.
15166 However, C++ allows more precise storage if it is known whether the number
15167 is a signed integer, an unsigned integer or a floating-point number.
15168 Therefore, three different types, @ref number_integer_t, @ref
15169 number_unsigned_t and @ref number_float_t are used.
15171 To store integer numbers in C++, a type is defined by the template
15172 parameter @a NumberIntegerType which chooses the type to use.
15176 With the default values for @a NumberIntegerType (`int64_t`), the default
15177 value for @a number_integer_t is:
15183 #### Default behavior
15185 - The restrictions about leading zeros is not enforced in C++. Instead,
15186 leading zeros in integer literals lead to an interpretation as octal
15187 number. Internally, the value will be stored as decimal number. For
15188 instance, the C++ integer literal `010` will be serialized to `8`.
15189 During deserialization, leading zeros yield an error.
15190 - Not-a-number (NaN) values will be serialized to `null`.
15194 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
15195 > An implementation may set limits on the range and precision of numbers.
15197 When the default type is used, the maximal integer number that can be
15198 stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
15199 that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
15200 that are out of range will yield over/underflow when used in a
15201 constructor. During deserialization, too large or small integer numbers
15202 will be automatically be stored as @ref number_unsigned_t or @ref
15205 [RFC 7159](http://rfc7159.net/rfc7159) further states:
15206 > Note that when such software is used, numbers that are integers and are
15207 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
15208 > that implementations will agree exactly on their numeric values.
15210 As this range is a subrange of the exactly supported range [INT64_MIN,
15211 INT64_MAX], this class's integer type is interoperable.
15215 Integer number values are stored directly inside a @ref basic_json type.
15217 @sa @ref number_float_t -- type for number values (floating-point)
15219 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
15221 @since version 1.0.0
15223 using number_integer_t = NumberIntegerType;
15226 @brief a type for a number (unsigned)
15228 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
15229 > The representation of numbers is similar to that used in most
15230 > programming languages. A number is represented in base 10 using decimal
15231 > digits. It contains an integer component that may be prefixed with an
15232 > optional minus sign, which may be followed by a fraction part and/or an
15233 > exponent part. Leading zeros are not allowed. (...) Numeric values that
15234 > cannot be represented in the grammar below (such as Infinity and NaN)
15235 > are not permitted.
15237 This description includes both integer and floating-point numbers.
15238 However, C++ allows more precise storage if it is known whether the number
15239 is a signed integer, an unsigned integer or a floating-point number.
15240 Therefore, three different types, @ref number_integer_t, @ref
15241 number_unsigned_t and @ref number_float_t are used.
15243 To store unsigned integer numbers in C++, a type is defined by the
15244 template parameter @a NumberUnsignedType which chooses the type to use.
15248 With the default values for @a NumberUnsignedType (`uint64_t`), the
15249 default value for @a number_unsigned_t is:
15255 #### Default behavior
15257 - The restrictions about leading zeros is not enforced in C++. Instead,
15258 leading zeros in integer literals lead to an interpretation as octal
15259 number. Internally, the value will be stored as decimal number. For
15260 instance, the C++ integer literal `010` will be serialized to `8`.
15261 During deserialization, leading zeros yield an error.
15262 - Not-a-number (NaN) values will be serialized to `null`.
15266 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
15267 > An implementation may set limits on the range and precision of numbers.
15269 When the default type is used, the maximal integer number that can be
15270 stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
15271 number that can be stored is `0`. Integer numbers that are out of range
15272 will yield over/underflow when used in a constructor. During
15273 deserialization, too large or small integer numbers will be automatically
15274 be stored as @ref number_integer_t or @ref number_float_t.
15276 [RFC 7159](http://rfc7159.net/rfc7159) further states:
15277 > Note that when such software is used, numbers that are integers and are
15278 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
15279 > that implementations will agree exactly on their numeric values.
15281 As this range is a subrange (when considered in conjunction with the
15282 number_integer_t type) of the exactly supported range [0, UINT64_MAX],
15283 this class's integer type is interoperable.
15287 Integer number values are stored directly inside a @ref basic_json type.
15289 @sa @ref number_float_t -- type for number values (floating-point)
15290 @sa @ref number_integer_t -- type for number values (integer)
15292 @since version 2.0.0
15294 using number_unsigned_t = NumberUnsignedType;
15297 @brief a type for a number (floating-point)
15299 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
15300 > The representation of numbers is similar to that used in most
15301 > programming languages. A number is represented in base 10 using decimal
15302 > digits. It contains an integer component that may be prefixed with an
15303 > optional minus sign, which may be followed by a fraction part and/or an
15304 > exponent part. Leading zeros are not allowed. (...) Numeric values that
15305 > cannot be represented in the grammar below (such as Infinity and NaN)
15306 > are not permitted.
15308 This description includes both integer and floating-point numbers.
15309 However, C++ allows more precise storage if it is known whether the number
15310 is a signed integer, an unsigned integer or a floating-point number.
15311 Therefore, three different types, @ref number_integer_t, @ref
15312 number_unsigned_t and @ref number_float_t are used.
15314 To store floating-point numbers in C++, a type is defined by the template
15315 parameter @a NumberFloatType which chooses the type to use.
15319 With the default values for @a NumberFloatType (`double`), the default
15320 value for @a number_float_t is:
15326 #### Default behavior
15328 - The restrictions about leading zeros is not enforced in C++. Instead,
15329 leading zeros in floating-point literals will be ignored. Internally,
15330 the value will be stored as decimal number. For instance, the C++
15331 floating-point literal `01.2` will be serialized to `1.2`. During
15332 deserialization, leading zeros yield an error.
15333 - Not-a-number (NaN) values will be serialized to `null`.
15337 [RFC 7159](http://rfc7159.net/rfc7159) states:
15338 > This specification allows implementations to set limits on the range and
15339 > precision of numbers accepted. Since software that implements IEEE
15340 > 754-2008 binary64 (double precision) numbers is generally available and
15341 > widely used, good interoperability can be achieved by implementations
15342 > that expect no more precision or range than these provide, in the sense
15343 > that implementations will approximate JSON numbers within the expected
15346 This implementation does exactly follow this approach, as it uses double
15347 precision floating-point numbers. Note values smaller than
15348 `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
15349 will be stored as NaN internally and be serialized to `null`.
15353 Floating-point number values are stored directly inside a @ref basic_json
15356 @sa @ref number_integer_t -- type for number values (integer)
15358 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
15360 @since version 1.0.0
15362 using number_float_t = NumberFloatType;
15368 /// helper for exception-safe object creation
15369 template<typename T, typename... Args>
15370 JSON_HEDLEY_RETURNS_NON_NULL
15371 static T* create(Args&& ... args)
15373 AllocatorType<T> alloc;
15374 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
15376 auto deleter = [&](T * object)
15378 AllocatorTraits::deallocate(alloc, object, 1);
15380 std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
15381 AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
15382 assert(object != nullptr);
15383 return object.release();
15386 ////////////////////////
15387 // JSON value storage //
15388 ////////////////////////
15391 @brief a JSON value
15393 The actual storage for a JSON value of the @ref basic_json class. This
15394 union combines the different storage types for the JSON value types
15395 defined in @ref value_t.
15397 JSON type | value_t type | used type
15398 --------- | --------------- | ------------------------
15399 object | object | pointer to @ref object_t
15400 array | array | pointer to @ref array_t
15401 string | string | pointer to @ref string_t
15402 boolean | boolean | @ref boolean_t
15403 number | number_integer | @ref number_integer_t
15404 number | number_unsigned | @ref number_unsigned_t
15405 number | number_float | @ref number_float_t
15406 null | null | *no value is stored*
15408 @note Variable-length types (objects, arrays, and strings) are stored as
15409 pointers. The size of the union should not exceed 64 bits if the default
15410 value types are used.
15412 @since version 1.0.0
15416 /// object (stored with pointer to save storage)
15418 /// array (stored with pointer to save storage)
15420 /// string (stored with pointer to save storage)
15424 /// number (integer)
15425 number_integer_t number_integer;
15426 /// number (unsigned integer)
15427 number_unsigned_t number_unsigned;
15428 /// number (floating-point)
15429 number_float_t number_float;
15431 /// default constructor (for null values)
15432 json_value() = default;
15433 /// constructor for booleans
15434 json_value(boolean_t v) noexcept : boolean(v) {}
15435 /// constructor for numbers (integer)
15436 json_value(number_integer_t v) noexcept : number_integer(v) {}
15437 /// constructor for numbers (unsigned)
15438 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
15439 /// constructor for numbers (floating-point)
15440 json_value(number_float_t v) noexcept : number_float(v) {}
15441 /// constructor for empty values of a given type
15442 json_value(value_t t)
15446 case value_t::object:
15448 object = create<object_t>();
15452 case value_t::array:
15454 array = create<array_t>();
15458 case value_t::string:
15460 string = create<string_t>("");
15464 case value_t::boolean:
15466 boolean = boolean_t(false);
15470 case value_t::number_integer:
15472 number_integer = number_integer_t(0);
15476 case value_t::number_unsigned:
15478 number_unsigned = number_unsigned_t(0);
15482 case value_t::number_float:
15484 number_float = number_float_t(0.0);
15488 case value_t::null:
15490 object = nullptr; // silence warning, see #821
15496 object = nullptr; // silence warning, see #821
15497 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
15499 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.7.3")); // LCOV_EXCL_LINE
15506 /// constructor for strings
15507 json_value(const string_t& value)
15509 string = create<string_t>(value);
15512 /// constructor for rvalue strings
15513 json_value(string_t&& value)
15515 string = create<string_t>(std::move(value));
15518 /// constructor for objects
15519 json_value(const object_t& value)
15521 object = create<object_t>(value);
15524 /// constructor for rvalue objects
15525 json_value(object_t&& value)
15527 object = create<object_t>(std::move(value));
15530 /// constructor for arrays
15531 json_value(const array_t& value)
15533 array = create<array_t>(value);
15536 /// constructor for rvalue arrays
15537 json_value(array_t&& value)
15539 array = create<array_t>(std::move(value));
15542 void destroy(value_t t) noexcept
15544 // flatten the current json_value to a heap-allocated stack
15545 std::vector<basic_json> stack;
15547 // move the top-level items to stack
15548 if (t == value_t::array)
15550 stack.reserve(array->size());
15551 std::move(array->begin(), array->end(), std::back_inserter(stack));
15553 else if (t == value_t::object)
15555 stack.reserve(object->size());
15556 for (auto&& it : *object)
15558 stack.push_back(std::move(it.second));
15562 while (not stack.empty())
15564 // move the last item to local variable to be processed
15565 basic_json current_item(std::move(stack.back()));
15568 // if current_item is array/object, move
15569 // its children to the stack to be processed later
15570 if (current_item.is_array())
15572 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
15573 std::back_inserter(stack));
15575 current_item.m_value.array->clear();
15577 else if (current_item.is_object())
15579 for (auto&& it : *current_item.m_value.object)
15581 stack.push_back(std::move(it.second));
15584 current_item.m_value.object->clear();
15587 // it's now safe that current_item get destructed
15588 // since it doesn't have any children
15593 case value_t::object:
15595 AllocatorType<object_t> alloc;
15596 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
15597 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
15601 case value_t::array:
15603 AllocatorType<array_t> alloc;
15604 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
15605 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
15609 case value_t::string:
15611 AllocatorType<string_t> alloc;
15612 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
15613 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
15626 @brief checks the class invariants
15628 This function asserts the class invariants. It needs to be called at the
15629 end of every constructor to make sure that created objects respect the
15630 invariant. Furthermore, it has to be called each time the type of a JSON
15631 value is changed, because the invariant expresses a relationship between
15632 @a m_type and @a m_value.
15634 void assert_invariant() const noexcept
15636 assert(m_type != value_t::object or m_value.object != nullptr);
15637 assert(m_type != value_t::array or m_value.array != nullptr);
15638 assert(m_type != value_t::string or m_value.string != nullptr);
15642 //////////////////////////
15643 // JSON parser callback //
15644 //////////////////////////
15647 @brief parser event types
15649 The parser callback distinguishes the following events:
15650 - `object_start`: the parser read `{` and started to process a JSON object
15651 - `key`: the parser read a key of a value in an object
15652 - `object_end`: the parser read `}` and finished processing a JSON object
15653 - `array_start`: the parser read `[` and started to process a JSON array
15654 - `array_end`: the parser read `]` and finished processing a JSON array
15655 - `value`: the parser finished reading a JSON value
15657 @image html callback_events.png "Example when certain parse events are triggered"
15659 @sa @ref parser_callback_t for more information and examples
15661 using parse_event_t = typename parser::parse_event_t;
15664 @brief per-element parser callback type
15666 With a parser callback function, the result of parsing a JSON text can be
15667 influenced. When passed to @ref parse, it is called on certain events
15668 (passed as @ref parse_event_t via parameter @a event) with a set recursion
15669 depth @a depth and context JSON value @a parsed. The return value of the
15670 callback function is a boolean indicating whether the element that emitted
15671 the callback shall be kept or not.
15673 We distinguish six scenarios (determined by the event type) in which the
15674 callback function can be called. The following table describes the values
15675 of the parameters @a depth, @a event, and @a parsed.
15677 parameter @a event | description | parameter @a depth | parameter @a parsed
15678 ------------------ | ----------- | ------------------ | -------------------
15679 parse_event_t::object_start | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded
15680 parse_event_t::key | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key
15681 parse_event_t::object_end | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object
15682 parse_event_t::array_start | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded
15683 parse_event_t::array_end | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array
15684 parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
15686 @image html callback_events.png "Example when certain parse events are triggered"
15688 Discarding a value (i.e., returning `false`) has different effects
15689 depending on the context in which function was called:
15691 - Discarded values in structured types are skipped. That is, the parser
15692 will behave as if the discarded value was never read.
15693 - In case a value outside a structured type is skipped, it is replaced
15694 with `null`. This case happens if the top-level element is skipped.
15696 @param[in] depth the depth of the recursion during parsing
15698 @param[in] event an event of type parse_event_t indicating the context in
15699 the callback function has been called
15701 @param[in,out] parsed the current intermediate parse result; note that
15702 writing to this value has no effect for parse_event_t::key events
15704 @return Whether the JSON value which called the function during parsing
15705 should be kept (`true`) or not (`false`). In the latter case, it is either
15706 skipped completely or replaced by an empty discarded object.
15708 @sa @ref parse for examples
15710 @since version 1.0.0
15712 using parser_callback_t = typename parser::parser_callback_t;
15718 /// @name constructors and destructors
15719 /// Constructors of class @ref basic_json, copy/move constructor, copy
15720 /// assignment, static functions creating objects, and the destructor.
15724 @brief create an empty value with a given type
15726 Create an empty JSON value with a given type. The value will be default
15727 initialized with an empty value which depends on the type:
15729 Value type | initial value
15730 ----------- | -------------
15738 @param[in] v the type of the value to create
15740 @complexity Constant.
15742 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15743 changes to any JSON value.
15745 @liveexample{The following code shows the constructor for different @ref
15746 value_t values,basic_json__value_t}
15748 @sa @ref clear() -- restores the postcondition of this constructor
15750 @since version 1.0.0
15752 basic_json(const value_t v)
15753 : m_type(v), m_value(v)
15755 assert_invariant();
15759 @brief create a null object
15761 Create a `null` JSON value. It either takes a null pointer as parameter
15762 (explicitly creating `null`) or no parameter (implicitly creating `null`).
15763 The passed null pointer itself is not read -- it is only used to choose
15764 the right constructor.
15766 @complexity Constant.
15768 @exceptionsafety No-throw guarantee: this constructor never throws
15771 @liveexample{The following code shows the constructor with and without a
15772 null pointer parameter.,basic_json__nullptr_t}
15774 @since version 1.0.0
15776 basic_json(std::nullptr_t = nullptr) noexcept
15777 : basic_json(value_t::null)
15779 assert_invariant();
15783 @brief create a JSON value
15785 This is a "catch all" constructor for all compatible JSON types; that is,
15786 types for which a `to_json()` method exists. The constructor forwards the
15787 parameter @a val to that method (to `json_serializer<U>::to_json` method
15788 with `U = uncvref_t<CompatibleType>`, to be exact).
15790 Template type @a CompatibleType includes, but is not limited to, the
15792 - **arrays**: @ref array_t and all kinds of compatible containers such as
15793 `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
15794 `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
15795 `std::multiset`, and `std::unordered_multiset` with a `value_type` from
15796 which a @ref basic_json value can be constructed.
15797 - **objects**: @ref object_t and all kinds of compatible associative
15798 containers such as `std::map`, `std::unordered_map`, `std::multimap`,
15799 and `std::unordered_multimap` with a `key_type` compatible to
15800 @ref string_t and a `value_type` from which a @ref basic_json value can
15802 - **strings**: @ref string_t, string literals, and all compatible string
15803 containers can be used.
15804 - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
15805 @ref number_float_t, and all convertible number types such as `int`,
15806 `size_t`, `int64_t`, `float` or `double` can be used.
15807 - **boolean**: @ref boolean_t / `bool` can be used.
15809 See the examples below.
15811 @tparam CompatibleType a type such that:
15812 - @a CompatibleType is not derived from `std::istream`,
15813 - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
15815 - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
15816 - @a CompatibleType is not a @ref basic_json nested type (e.g.,
15817 @ref json_pointer, @ref iterator, etc ...)
15818 - @ref @ref json_serializer<U> has a
15819 `to_json(basic_json_t&, CompatibleType&&)` method
15821 @tparam U = `uncvref_t<CompatibleType>`
15823 @param[in] val the value to be forwarded to the respective constructor
15825 @complexity Usually linear in the size of the passed @a val, also
15826 depending on the implementation of the called `to_json()`
15829 @exceptionsafety Depends on the called constructor. For types directly
15830 supported by the library (i.e., all types for which no `to_json()` function
15831 was provided), strong guarantee holds: if an exception is thrown, there are
15832 no changes to any JSON value.
15834 @liveexample{The following code shows the constructor with several
15835 compatible types.,basic_json__CompatibleType}
15837 @since version 2.1.0
15839 template <typename CompatibleType,
15840 typename U = detail::uncvref_t<CompatibleType>,
15841 detail::enable_if_t<
15842 not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
15843 basic_json(CompatibleType && val) noexcept(noexcept(
15844 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
15845 std::forward<CompatibleType>(val))))
15847 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
15848 assert_invariant();
15852 @brief create a JSON value from an existing one
15854 This is a constructor for existing @ref basic_json types.
15855 It does not hijack copy/move constructors, since the parameter has different
15856 template arguments than the current ones.
15858 The constructor tries to convert the internal @ref m_value of the parameter.
15860 @tparam BasicJsonType a type such that:
15861 - @a BasicJsonType is a @ref basic_json type.
15862 - @a BasicJsonType has different template arguments than @ref basic_json_t.
15864 @param[in] val the @ref basic_json value to be converted.
15866 @complexity Usually linear in the size of the passed @a val, also
15867 depending on the implementation of the called `to_json()`
15870 @exceptionsafety Depends on the called constructor. For types directly
15871 supported by the library (i.e., all types for which no `to_json()` function
15872 was provided), strong guarantee holds: if an exception is thrown, there are
15873 no changes to any JSON value.
15875 @since version 3.2.0
15877 template <typename BasicJsonType,
15878 detail::enable_if_t<
15879 detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
15880 basic_json(const BasicJsonType& val)
15882 using other_boolean_t = typename BasicJsonType::boolean_t;
15883 using other_number_float_t = typename BasicJsonType::number_float_t;
15884 using other_number_integer_t = typename BasicJsonType::number_integer_t;
15885 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
15886 using other_string_t = typename BasicJsonType::string_t;
15887 using other_object_t = typename BasicJsonType::object_t;
15888 using other_array_t = typename BasicJsonType::array_t;
15890 switch (val.type())
15892 case value_t::boolean:
15893 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
15895 case value_t::number_float:
15896 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
15898 case value_t::number_integer:
15899 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
15901 case value_t::number_unsigned:
15902 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
15904 case value_t::string:
15905 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
15907 case value_t::object:
15908 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
15910 case value_t::array:
15911 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
15913 case value_t::null:
15916 case value_t::discarded:
15917 m_type = value_t::discarded;
15919 default: // LCOV_EXCL_LINE
15920 assert(false); // LCOV_EXCL_LINE
15922 assert_invariant();
15926 @brief create a container (array or object) from an initializer list
15928 Creates a JSON value of type array or object from the passed initializer
15929 list @a init. In case @a type_deduction is `true` (default), the type of
15930 the JSON value to be created is deducted from the initializer list @a init
15931 according to the following rules:
15933 1. If the list is empty, an empty JSON object value `{}` is created.
15934 2. If the list consists of pairs whose first element is a string, a JSON
15935 object value is created where the first elements of the pairs are
15936 treated as keys and the second elements are as values.
15937 3. In all other cases, an array is created.
15939 The rules aim to create the best fit between a C++ initializer list and
15940 JSON values. The rationale is as follows:
15942 1. The empty initializer list is written as `{}` which is exactly an empty
15944 2. C++ has no way of describing mapped types other than to list a list of
15945 pairs. As JSON requires that keys must be of type string, rule 2 is the
15946 weakest constraint one can pose on initializer lists to interpret them
15948 3. In all other cases, the initializer list could not be interpreted as
15949 JSON object type, so interpreting it as JSON array type is safe.
15951 With the rules described above, the following JSON values cannot be
15952 expressed by an initializer list:
15954 - the empty array (`[]`): use @ref array(initializer_list_t)
15955 with an empty initializer list in this case
15956 - arrays whose elements satisfy rule 2: use @ref
15957 array(initializer_list_t) with the same initializer list
15960 @note When used without parentheses around an empty initializer list, @ref
15961 basic_json() is called instead of this function, yielding the JSON null
15964 @param[in] init initializer list with JSON values
15966 @param[in] type_deduction internal parameter; when set to `true`, the type
15967 of the JSON value is deducted from the initializer list @a init; when set
15968 to `false`, the type provided via @a manual_type is forced. This mode is
15969 used by the functions @ref array(initializer_list_t) and
15970 @ref object(initializer_list_t).
15972 @param[in] manual_type internal parameter; when @a type_deduction is set
15973 to `false`, the created JSON value will use the provided type (only @ref
15974 value_t::array and @ref value_t::object are valid); when @a type_deduction
15975 is set to `true`, this parameter has no effect
15977 @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
15978 `value_t::object`, but @a init contains an element which is not a pair
15979 whose first element is a string. In this case, the constructor could not
15980 create an object. If @a type_deduction would have be `true`, an array
15981 would have been created. See @ref object(initializer_list_t)
15984 @complexity Linear in the size of the initializer list @a init.
15986 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15987 changes to any JSON value.
15989 @liveexample{The example below shows how JSON values are created from
15990 initializer lists.,basic_json__list_init_t}
15992 @sa @ref array(initializer_list_t) -- create a JSON array
15993 value from an initializer list
15994 @sa @ref object(initializer_list_t) -- create a JSON object
15995 value from an initializer list
15997 @since version 1.0.0
15999 basic_json(initializer_list_t init,
16000 bool type_deduction = true,
16001 value_t manual_type = value_t::array)
16003 // check if each element is an array with two elements whose first
16004 // element is a string
16005 bool is_an_object = std::all_of(init.begin(), init.end(),
16006 [](const detail::json_ref<basic_json>& element_ref)
16008 return element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string();
16011 // adjust type if type deduction is not wanted
16012 if (not type_deduction)
16014 // if array is wanted, do not create an object though possible
16015 if (manual_type == value_t::array)
16017 is_an_object = false;
16020 // if object is wanted but impossible, throw an exception
16021 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object and not is_an_object))
16023 JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
16029 // the initializer list is a list of pairs -> create object
16030 m_type = value_t::object;
16031 m_value = value_t::object;
16033 std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
16035 auto element = element_ref.moved_or_copied();
16036 m_value.object->emplace(
16037 std::move(*((*element.m_value.array)[0].m_value.string)),
16038 std::move((*element.m_value.array)[1]));
16043 // the initializer list describes an array -> create array
16044 m_type = value_t::array;
16045 m_value.array = create<array_t>(init.begin(), init.end());
16048 assert_invariant();
16052 @brief explicitly create an array from an initializer list
16054 Creates a JSON array value from a given initializer list. That is, given a
16055 list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
16056 initializer list is empty, the empty array `[]` is created.
16058 @note This function is only needed to express two edge cases that cannot
16059 be realized with the initializer list constructor (@ref
16060 basic_json(initializer_list_t, bool, value_t)). These cases
16062 1. creating an array whose elements are all pairs whose first element is a
16063 string -- in this case, the initializer list constructor would create an
16064 object, taking the first elements as keys
16065 2. creating an empty array -- passing the empty initializer list to the
16066 initializer list constructor yields an empty object
16068 @param[in] init initializer list with JSON values to create an array from
16071 @return JSON array value
16073 @complexity Linear in the size of @a init.
16075 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
16076 changes to any JSON value.
16078 @liveexample{The following code shows an example for the `array`
16081 @sa @ref basic_json(initializer_list_t, bool, value_t) --
16082 create a JSON value from an initializer list
16083 @sa @ref object(initializer_list_t) -- create a JSON object
16084 value from an initializer list
16086 @since version 1.0.0
16088 JSON_HEDLEY_WARN_UNUSED_RESULT
16089 static basic_json array(initializer_list_t init = {})
16091 return basic_json(init, false, value_t::array);
16095 @brief explicitly create an object from an initializer list
16097 Creates a JSON object value from a given initializer list. The initializer
16098 lists elements must be pairs, and their first elements must be strings. If
16099 the initializer list is empty, the empty object `{}` is created.
16101 @note This function is only added for symmetry reasons. In contrast to the
16102 related function @ref array(initializer_list_t), there are
16103 no cases which can only be expressed by this function. That is, any
16104 initializer list @a init can also be passed to the initializer list
16105 constructor @ref basic_json(initializer_list_t, bool, value_t).
16107 @param[in] init initializer list to create an object from (optional)
16109 @return JSON object value
16111 @throw type_error.301 if @a init is not a list of pairs whose first
16112 elements are strings. In this case, no object can be created. When such a
16113 value is passed to @ref basic_json(initializer_list_t, bool, value_t),
16114 an array would have been created from the passed initializer list @a init.
16117 @complexity Linear in the size of @a init.
16119 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
16120 changes to any JSON value.
16122 @liveexample{The following code shows an example for the `object`
16125 @sa @ref basic_json(initializer_list_t, bool, value_t) --
16126 create a JSON value from an initializer list
16127 @sa @ref array(initializer_list_t) -- create a JSON array
16128 value from an initializer list
16130 @since version 1.0.0
16132 JSON_HEDLEY_WARN_UNUSED_RESULT
16133 static basic_json object(initializer_list_t init = {})
16135 return basic_json(init, false, value_t::object);
16139 @brief construct an array with count copies of given value
16141 Constructs a JSON array value by creating @a cnt copies of a passed value.
16142 In case @a cnt is `0`, an empty array is created.
16144 @param[in] cnt the number of JSON copies of @a val to create
16145 @param[in] val the JSON value to copy
16147 @post `std::distance(begin(),end()) == cnt` holds.
16149 @complexity Linear in @a cnt.
16151 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
16152 changes to any JSON value.
16154 @liveexample{The following code shows examples for the @ref
16155 basic_json(size_type\, const basic_json&)
16156 constructor.,basic_json__size_type_basic_json}
16158 @since version 1.0.0
16160 basic_json(size_type cnt, const basic_json& val)
16161 : m_type(value_t::array)
16163 m_value.array = create<array_t>(cnt, val);
16164 assert_invariant();
16168 @brief construct a JSON container given an iterator range
16170 Constructs the JSON value with the contents of the range `[first, last)`.
16171 The semantics depends on the different types a JSON value can have:
16172 - In case of a null type, invalid_iterator.206 is thrown.
16173 - In case of other primitive types (number, boolean, or string), @a first
16174 must be `begin()` and @a last must be `end()`. In this case, the value is
16175 copied. Otherwise, invalid_iterator.204 is thrown.
16176 - In case of structured types (array, object), the constructor behaves as
16177 similar versions for `std::vector` or `std::map`; that is, a JSON array
16178 or object is constructed from the values in the range.
16180 @tparam InputIT an input iterator type (@ref iterator or @ref
16183 @param[in] first begin of the range to copy from (included)
16184 @param[in] last end of the range to copy from (excluded)
16186 @pre Iterators @a first and @a last must be initialized. **This
16187 precondition is enforced with an assertion (see warning).** If
16188 assertions are switched off, a violation of this precondition yields
16189 undefined behavior.
16191 @pre Range `[first, last)` is valid. Usually, this precondition cannot be
16192 checked efficiently. Only certain edge cases are detected; see the
16193 description of the exceptions below. A violation of this precondition
16194 yields undefined behavior.
16196 @warning A precondition is enforced with a runtime assertion that will
16197 result in calling `std::abort` if this precondition is not met.
16198 Assertions can be disabled by defining `NDEBUG` at compile time.
16199 See https://en.cppreference.com/w/cpp/error/assert for more
16202 @throw invalid_iterator.201 if iterators @a first and @a last are not
16203 compatible (i.e., do not belong to the same JSON value). In this case,
16204 the range `[first, last)` is undefined.
16205 @throw invalid_iterator.204 if iterators @a first and @a last belong to a
16206 primitive type (number, boolean, or string), but @a first does not point
16207 to the first element any more. In this case, the range `[first, last)` is
16208 undefined. See example code below.
16209 @throw invalid_iterator.206 if iterators @a first and @a last belong to a
16210 null value. In this case, the range `[first, last)` is undefined.
16212 @complexity Linear in distance between @a first and @a last.
16214 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
16215 changes to any JSON value.
16217 @liveexample{The example below shows several ways to create JSON values by
16218 specifying a subrange with iterators.,basic_json__InputIt_InputIt}
16220 @since version 1.0.0
16222 template<class InputIT, typename std::enable_if<
16223 std::is_same<InputIT, typename basic_json_t::iterator>::value or
16224 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
16225 basic_json(InputIT first, InputIT last)
16227 assert(first.m_object != nullptr);
16228 assert(last.m_object != nullptr);
16230 // make sure iterator fits the current value
16231 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
16233 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
16236 // copy type from first iterator
16237 m_type = first.m_object->m_type;
16239 // check if iterator range is complete for primitive values
16242 case value_t::boolean:
16243 case value_t::number_float:
16244 case value_t::number_integer:
16245 case value_t::number_unsigned:
16246 case value_t::string:
16248 if (JSON_HEDLEY_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
16249 or not last.m_it.primitive_iterator.is_end()))
16251 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
16262 case value_t::number_integer:
16264 m_value.number_integer = first.m_object->m_value.number_integer;
16268 case value_t::number_unsigned:
16270 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
16274 case value_t::number_float:
16276 m_value.number_float = first.m_object->m_value.number_float;
16280 case value_t::boolean:
16282 m_value.boolean = first.m_object->m_value.boolean;
16286 case value_t::string:
16288 m_value = *first.m_object->m_value.string;
16292 case value_t::object:
16294 m_value.object = create<object_t>(first.m_it.object_iterator,
16295 last.m_it.object_iterator);
16299 case value_t::array:
16301 m_value.array = create<array_t>(first.m_it.array_iterator,
16302 last.m_it.array_iterator);
16307 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
16308 std::string(first.m_object->type_name())));
16311 assert_invariant();
16315 ///////////////////////////////////////
16316 // other constructors and destructor //
16317 ///////////////////////////////////////
16320 basic_json(const detail::json_ref<basic_json>& ref)
16321 : basic_json(ref.moved_or_copied())
16325 @brief copy constructor
16327 Creates a copy of a given JSON value.
16329 @param[in] other the JSON value to copy
16331 @post `*this == other`
16333 @complexity Linear in the size of @a other.
16335 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
16336 changes to any JSON value.
16338 @requirement This function helps `basic_json` satisfying the
16339 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
16341 - The complexity is linear.
16342 - As postcondition, it holds: `other == basic_json(other)`.
16344 @liveexample{The following code shows an example for the copy
16345 constructor.,basic_json__basic_json}
16347 @since version 1.0.0
16349 basic_json(const basic_json& other)
16350 : m_type(other.m_type)
16352 // check of passed value is valid
16353 other.assert_invariant();
16357 case value_t::object:
16359 m_value = *other.m_value.object;
16363 case value_t::array:
16365 m_value = *other.m_value.array;
16369 case value_t::string:
16371 m_value = *other.m_value.string;
16375 case value_t::boolean:
16377 m_value = other.m_value.boolean;
16381 case value_t::number_integer:
16383 m_value = other.m_value.number_integer;
16387 case value_t::number_unsigned:
16389 m_value = other.m_value.number_unsigned;
16393 case value_t::number_float:
16395 m_value = other.m_value.number_float;
16403 assert_invariant();
16407 @brief move constructor
16409 Move constructor. Constructs a JSON value with the contents of the given
16410 value @a other using move semantics. It "steals" the resources from @a
16411 other and leaves it as JSON null value.
16413 @param[in,out] other value to move to this object
16415 @post `*this` has the same value as @a other before the call.
16416 @post @a other is a JSON null value.
16418 @complexity Constant.
16420 @exceptionsafety No-throw guarantee: this constructor never throws
16423 @requirement This function helps `basic_json` satisfying the
16424 [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
16427 @liveexample{The code below shows the move constructor explicitly called
16428 via std::move.,basic_json__moveconstructor}
16430 @since version 1.0.0
16432 basic_json(basic_json&& other) noexcept
16433 : m_type(std::move(other.m_type)),
16434 m_value(std::move(other.m_value))
16436 // check that passed value is valid
16437 other.assert_invariant();
16439 // invalidate payload
16440 other.m_type = value_t::null;
16441 other.m_value = {};
16443 assert_invariant();
16447 @brief copy assignment
16449 Copy assignment operator. Copies a JSON value via the "copy and swap"
16450 strategy: It is expressed in terms of the copy constructor, destructor,
16451 and the `swap()` member function.
16453 @param[in] other value to copy from
16455 @complexity Linear.
16457 @requirement This function helps `basic_json` satisfying the
16458 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
16460 - The complexity is linear.
16462 @liveexample{The code below shows and example for the copy assignment. It
16463 creates a copy of value `a` which is then swapped with `b`. Finally\, the
16464 copy of `a` (which is the null value after the swap) is
16465 destroyed.,basic_json__copyassignment}
16467 @since version 1.0.0
16469 basic_json& operator=(basic_json other) noexcept (
16470 std::is_nothrow_move_constructible<value_t>::value and
16471 std::is_nothrow_move_assignable<value_t>::value and
16472 std::is_nothrow_move_constructible<json_value>::value and
16473 std::is_nothrow_move_assignable<json_value>::value
16476 // check that passed value is valid
16477 other.assert_invariant();
16480 swap(m_type, other.m_type);
16481 swap(m_value, other.m_value);
16483 assert_invariant();
16490 Destroys the JSON value and frees all allocated memory.
16492 @complexity Linear.
16494 @requirement This function helps `basic_json` satisfying the
16495 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
16497 - The complexity is linear.
16498 - All stored elements are destroyed and all memory is freed.
16500 @since version 1.0.0
16502 ~basic_json() noexcept
16504 assert_invariant();
16505 m_value.destroy(m_type);
16511 ///////////////////////
16512 // object inspection //
16513 ///////////////////////
16515 /// @name object inspection
16516 /// Functions to inspect the type of a JSON value.
16520 @brief serialization
16522 Serialization function for JSON values. The function tries to mimic
16523 Python's `json.dumps()` function, and currently supports its @a indent
16524 and @a ensure_ascii parameters.
16526 @param[in] indent If indent is nonnegative, then array elements and object
16527 members will be pretty-printed with that indent level. An indent level of
16528 `0` will only insert newlines. `-1` (the default) selects the most compact
16530 @param[in] indent_char The character to use for indentation if @a indent is
16531 greater than `0`. The default is ` ` (space).
16532 @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
16533 in the output are escaped with `\uXXXX` sequences, and the result consists
16534 of ASCII characters only.
16535 @param[in] error_handler how to react on decoding errors; there are three
16536 possible values: `strict` (throws and exception in case a decoding error
16537 occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
16538 and `ignore` (ignore invalid UTF-8 sequences during serialization).
16540 @return string containing the serialization of the JSON value
16542 @throw type_error.316 if a string stored inside the JSON value is not
16545 @complexity Linear.
16547 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
16548 changes in the JSON value.
16550 @liveexample{The following example shows the effect of different @a indent\,
16551 @a indent_char\, and @a ensure_ascii parameters to the result of the
16552 serialization.,dump}
16554 @see https://docs.python.org/2/library/json.html#json.dump
16556 @since version 1.0.0; indentation character @a indent_char, option
16557 @a ensure_ascii and exceptions added in version 3.0.0; error
16558 handlers added in version 3.4.0.
16560 string_t dump(const int indent = -1,
16561 const char indent_char = ' ',
16562 const bool ensure_ascii = false,
16563 const error_handler_t error_handler = error_handler_t::strict) const
16566 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
16570 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
16574 s.dump(*this, false, ensure_ascii, 0);
16581 @brief return the type of the JSON value (explicit)
16583 Return the type of the JSON value as a value from the @ref value_t
16586 @return the type of the JSON value
16587 Value type | return value
16588 ------------------------- | -------------------------
16589 null | value_t::null
16590 boolean | value_t::boolean
16591 string | value_t::string
16592 number (integer) | value_t::number_integer
16593 number (unsigned integer) | value_t::number_unsigned
16594 number (floating-point) | value_t::number_float
16595 object | value_t::object
16596 array | value_t::array
16597 discarded | value_t::discarded
16599 @complexity Constant.
16601 @exceptionsafety No-throw guarantee: this member function never throws
16604 @liveexample{The following code exemplifies `type()` for all JSON
16607 @sa @ref operator value_t() -- return the type of the JSON value (implicit)
16608 @sa @ref type_name() -- return the type as string
16610 @since version 1.0.0
16612 constexpr value_t type() const noexcept
16618 @brief return whether type is primitive
16620 This function returns true if and only if the JSON type is primitive
16621 (string, number, boolean, or null).
16623 @return `true` if type is primitive (string, number, boolean, or null),
16626 @complexity Constant.
16628 @exceptionsafety No-throw guarantee: this member function never throws
16631 @liveexample{The following code exemplifies `is_primitive()` for all JSON
16632 types.,is_primitive}
16634 @sa @ref is_structured() -- returns whether JSON value is structured
16635 @sa @ref is_null() -- returns whether JSON value is `null`
16636 @sa @ref is_string() -- returns whether JSON value is a string
16637 @sa @ref is_boolean() -- returns whether JSON value is a boolean
16638 @sa @ref is_number() -- returns whether JSON value is a number
16640 @since version 1.0.0
16642 constexpr bool is_primitive() const noexcept
16644 return is_null() or is_string() or is_boolean() or is_number();
16648 @brief return whether type is structured
16650 This function returns true if and only if the JSON type is structured
16653 @return `true` if type is structured (array or object), `false` otherwise.
16655 @complexity Constant.
16657 @exceptionsafety No-throw guarantee: this member function never throws
16660 @liveexample{The following code exemplifies `is_structured()` for all JSON
16661 types.,is_structured}
16663 @sa @ref is_primitive() -- returns whether value is primitive
16664 @sa @ref is_array() -- returns whether value is an array
16665 @sa @ref is_object() -- returns whether value is an object
16667 @since version 1.0.0
16669 constexpr bool is_structured() const noexcept
16671 return is_array() or is_object();
16675 @brief return whether value is null
16677 This function returns true if and only if the JSON value is null.
16679 @return `true` if type is null, `false` otherwise.
16681 @complexity Constant.
16683 @exceptionsafety No-throw guarantee: this member function never throws
16686 @liveexample{The following code exemplifies `is_null()` for all JSON
16689 @since version 1.0.0
16691 constexpr bool is_null() const noexcept
16693 return m_type == value_t::null;
16697 @brief return whether value is a boolean
16699 This function returns true if and only if the JSON value is a boolean.
16701 @return `true` if type is boolean, `false` otherwise.
16703 @complexity Constant.
16705 @exceptionsafety No-throw guarantee: this member function never throws
16708 @liveexample{The following code exemplifies `is_boolean()` for all JSON
16711 @since version 1.0.0
16713 constexpr bool is_boolean() const noexcept
16715 return m_type == value_t::boolean;
16719 @brief return whether value is a number
16721 This function returns true if and only if the JSON value is a number. This
16722 includes both integer (signed and unsigned) and floating-point values.
16724 @return `true` if type is number (regardless whether integer, unsigned
16725 integer or floating-type), `false` otherwise.
16727 @complexity Constant.
16729 @exceptionsafety No-throw guarantee: this member function never throws
16732 @liveexample{The following code exemplifies `is_number()` for all JSON
16735 @sa @ref is_number_integer() -- check if value is an integer or unsigned
16737 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
16739 @sa @ref is_number_float() -- check if value is a floating-point number
16741 @since version 1.0.0
16743 constexpr bool is_number() const noexcept
16745 return is_number_integer() or is_number_float();
16749 @brief return whether value is an integer number
16751 This function returns true if and only if the JSON value is a signed or
16752 unsigned integer number. This excludes floating-point values.
16754 @return `true` if type is an integer or unsigned integer number, `false`
16757 @complexity Constant.
16759 @exceptionsafety No-throw guarantee: this member function never throws
16762 @liveexample{The following code exemplifies `is_number_integer()` for all
16763 JSON types.,is_number_integer}
16765 @sa @ref is_number() -- check if value is a number
16766 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
16768 @sa @ref is_number_float() -- check if value is a floating-point number
16770 @since version 1.0.0
16772 constexpr bool is_number_integer() const noexcept
16774 return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
16778 @brief return whether value is an unsigned integer number
16780 This function returns true if and only if the JSON value is an unsigned
16781 integer number. This excludes floating-point and signed integer values.
16783 @return `true` if type is an unsigned integer number, `false` otherwise.
16785 @complexity Constant.
16787 @exceptionsafety No-throw guarantee: this member function never throws
16790 @liveexample{The following code exemplifies `is_number_unsigned()` for all
16791 JSON types.,is_number_unsigned}
16793 @sa @ref is_number() -- check if value is a number
16794 @sa @ref is_number_integer() -- check if value is an integer or unsigned
16796 @sa @ref is_number_float() -- check if value is a floating-point number
16798 @since version 2.0.0
16800 constexpr bool is_number_unsigned() const noexcept
16802 return m_type == value_t::number_unsigned;
16806 @brief return whether value is a floating-point number
16808 This function returns true if and only if the JSON value is a
16809 floating-point number. This excludes signed and unsigned integer values.
16811 @return `true` if type is a floating-point number, `false` otherwise.
16813 @complexity Constant.
16815 @exceptionsafety No-throw guarantee: this member function never throws
16818 @liveexample{The following code exemplifies `is_number_float()` for all
16819 JSON types.,is_number_float}
16821 @sa @ref is_number() -- check if value is number
16822 @sa @ref is_number_integer() -- check if value is an integer number
16823 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
16826 @since version 1.0.0
16828 constexpr bool is_number_float() const noexcept
16830 return m_type == value_t::number_float;
16834 @brief return whether value is an object
16836 This function returns true if and only if the JSON value is an object.
16838 @return `true` if type is object, `false` otherwise.
16840 @complexity Constant.
16842 @exceptionsafety No-throw guarantee: this member function never throws
16845 @liveexample{The following code exemplifies `is_object()` for all JSON
16848 @since version 1.0.0
16850 constexpr bool is_object() const noexcept
16852 return m_type == value_t::object;
16856 @brief return whether value is an array
16858 This function returns true if and only if the JSON value is an array.
16860 @return `true` if type is array, `false` otherwise.
16862 @complexity Constant.
16864 @exceptionsafety No-throw guarantee: this member function never throws
16867 @liveexample{The following code exemplifies `is_array()` for all JSON
16870 @since version 1.0.0
16872 constexpr bool is_array() const noexcept
16874 return m_type == value_t::array;
16878 @brief return whether value is a string
16880 This function returns true if and only if the JSON value is a string.
16882 @return `true` if type is string, `false` otherwise.
16884 @complexity Constant.
16886 @exceptionsafety No-throw guarantee: this member function never throws
16889 @liveexample{The following code exemplifies `is_string()` for all JSON
16892 @since version 1.0.0
16894 constexpr bool is_string() const noexcept
16896 return m_type == value_t::string;
16900 @brief return whether value is discarded
16902 This function returns true if and only if the JSON value was discarded
16903 during parsing with a callback function (see @ref parser_callback_t).
16905 @note This function will always be `false` for JSON values after parsing.
16906 That is, discarded values can only occur during parsing, but will be
16907 removed when inside a structured value or replaced by null in other cases.
16909 @return `true` if type is discarded, `false` otherwise.
16911 @complexity Constant.
16913 @exceptionsafety No-throw guarantee: this member function never throws
16916 @liveexample{The following code exemplifies `is_discarded()` for all JSON
16917 types.,is_discarded}
16919 @since version 1.0.0
16921 constexpr bool is_discarded() const noexcept
16923 return m_type == value_t::discarded;
16927 @brief return the type of the JSON value (implicit)
16929 Implicitly return the type of the JSON value as a value from the @ref
16930 value_t enumeration.
16932 @return the type of the JSON value
16934 @complexity Constant.
16936 @exceptionsafety No-throw guarantee: this member function never throws
16939 @liveexample{The following code exemplifies the @ref value_t operator for
16940 all JSON types.,operator__value_t}
16942 @sa @ref type() -- return the type of the JSON value (explicit)
16943 @sa @ref type_name() -- return the type as string
16945 @since version 1.0.0
16947 constexpr operator value_t() const noexcept
16959 /// get a boolean (explicit)
16960 boolean_t get_impl(boolean_t* /*unused*/) const
16962 if (JSON_HEDLEY_LIKELY(is_boolean()))
16964 return m_value.boolean;
16967 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
16970 /// get a pointer to the value (object)
16971 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
16973 return is_object() ? m_value.object : nullptr;
16976 /// get a pointer to the value (object)
16977 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
16979 return is_object() ? m_value.object : nullptr;
16982 /// get a pointer to the value (array)
16983 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
16985 return is_array() ? m_value.array : nullptr;
16988 /// get a pointer to the value (array)
16989 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
16991 return is_array() ? m_value.array : nullptr;
16994 /// get a pointer to the value (string)
16995 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
16997 return is_string() ? m_value.string : nullptr;
17000 /// get a pointer to the value (string)
17001 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
17003 return is_string() ? m_value.string : nullptr;
17006 /// get a pointer to the value (boolean)
17007 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
17009 return is_boolean() ? &m_value.boolean : nullptr;
17012 /// get a pointer to the value (boolean)
17013 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
17015 return is_boolean() ? &m_value.boolean : nullptr;
17018 /// get a pointer to the value (integer number)
17019 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
17021 return is_number_integer() ? &m_value.number_integer : nullptr;
17024 /// get a pointer to the value (integer number)
17025 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
17027 return is_number_integer() ? &m_value.number_integer : nullptr;
17030 /// get a pointer to the value (unsigned number)
17031 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
17033 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
17036 /// get a pointer to the value (unsigned number)
17037 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
17039 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
17042 /// get a pointer to the value (floating-point number)
17043 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
17045 return is_number_float() ? &m_value.number_float : nullptr;
17048 /// get a pointer to the value (floating-point number)
17049 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
17051 return is_number_float() ? &m_value.number_float : nullptr;
17055 @brief helper function to implement get_ref()
17057 This function helps to implement get_ref() without code duplication for
17058 const and non-const overloads
17060 @tparam ThisType will be deduced as `basic_json` or `const basic_json`
17062 @throw type_error.303 if ReferenceType does not match underlying value
17063 type of the current JSON
17065 template<typename ReferenceType, typename ThisType>
17066 static ReferenceType get_ref_impl(ThisType& obj)
17068 // delegate the call to get_ptr<>()
17069 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
17071 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
17076 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
17080 /// @name value access
17081 /// Direct access to the stored value of a JSON value.
17085 @brief get special-case overload
17087 This overloads avoids a lot of template boilerplate, it can be seen as the
17090 @tparam BasicJsonType == @ref basic_json
17092 @return a copy of *this
17094 @complexity Constant.
17096 @since version 2.1.0
17098 template<typename BasicJsonType, detail::enable_if_t<
17099 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
17101 basic_json get() const
17107 @brief get special-case overload
17109 This overloads converts the current @ref basic_json in a different
17110 @ref basic_json type
17112 @tparam BasicJsonType == @ref basic_json
17114 @return a copy of *this, converted into @tparam BasicJsonType
17116 @complexity Depending on the implementation of the called `from_json()`
17119 @since version 3.2.0
17121 template<typename BasicJsonType, detail::enable_if_t<
17122 not std::is_same<BasicJsonType, basic_json>::value and
17123 detail::is_basic_json<BasicJsonType>::value, int> = 0>
17124 BasicJsonType get() const
17130 @brief get a value (explicit)
17132 Explicit type conversion between the JSON value and a compatible value
17133 which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
17134 and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
17135 The value is converted by calling the @ref json_serializer<ValueType>
17136 `from_json()` method.
17138 The function is equivalent to executing
17141 JSONSerializer<ValueType>::from_json(*this, ret);
17145 This overloads is chosen if:
17146 - @a ValueType is not @ref basic_json,
17147 - @ref json_serializer<ValueType> has a `from_json()` method of the form
17148 `void from_json(const basic_json&, ValueType&)`, and
17149 - @ref json_serializer<ValueType> does not have a `from_json()` method of
17150 the form `ValueType from_json(const basic_json&)`
17152 @tparam ValueTypeCV the provided value type
17153 @tparam ValueType the returned value type
17155 @return copy of the JSON value, converted to @a ValueType
17157 @throw what @ref json_serializer<ValueType> `from_json()` method throws
17159 @liveexample{The example below shows several conversions from JSON values
17160 to other types. There a few things to note: (1) Floating-point numbers can
17161 be converted to integers\, (2) A JSON array can be converted to a standard
17162 `std::vector<short>`\, (3) A JSON object can be converted to C++
17163 associative containers such as `std::unordered_map<std::string\,
17164 json>`.,get__ValueType_const}
17166 @since version 2.1.0
17168 template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
17169 detail::enable_if_t <
17170 not detail::is_basic_json<ValueType>::value and
17171 detail::has_from_json<basic_json_t, ValueType>::value and
17172 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
17174 ValueType get() const noexcept(noexcept(
17175 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
17177 // we cannot static_assert on ValueTypeCV being non-const, because
17178 // there is support for get<const basic_json_t>(), which is why we
17179 // still need the uncvref
17180 static_assert(not std::is_reference<ValueTypeCV>::value,
17181 "get() cannot be used with reference types, you might want to use get_ref()");
17182 static_assert(std::is_default_constructible<ValueType>::value,
17183 "types must be DefaultConstructible when used with get()");
17186 JSONSerializer<ValueType>::from_json(*this, ret);
17191 @brief get a value (explicit); special case
17193 Explicit type conversion between the JSON value and a compatible value
17194 which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
17195 and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
17196 The value is converted by calling the @ref json_serializer<ValueType>
17197 `from_json()` method.
17199 The function is equivalent to executing
17201 return JSONSerializer<ValueTypeCV>::from_json(*this);
17204 This overloads is chosen if:
17205 - @a ValueType is not @ref basic_json and
17206 - @ref json_serializer<ValueType> has a `from_json()` method of the form
17207 `ValueType from_json(const basic_json&)`
17209 @note If @ref json_serializer<ValueType> has both overloads of
17210 `from_json()`, this one is chosen.
17212 @tparam ValueTypeCV the provided value type
17213 @tparam ValueType the returned value type
17215 @return copy of the JSON value, converted to @a ValueType
17217 @throw what @ref json_serializer<ValueType> `from_json()` method throws
17219 @since version 2.1.0
17221 template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
17222 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
17223 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
17225 ValueType get() const noexcept(noexcept(
17226 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
17228 static_assert(not std::is_reference<ValueTypeCV>::value,
17229 "get() cannot be used with reference types, you might want to use get_ref()");
17230 return JSONSerializer<ValueType>::from_json(*this);
17234 @brief get a value (explicit)
17236 Explicit type conversion between the JSON value and a compatible value.
17237 The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
17238 `from_json()` method.
17240 The function is equivalent to executing
17243 JSONSerializer<ValueType>::from_json(*this, v);
17246 This overloads is chosen if:
17247 - @a ValueType is not @ref basic_json,
17248 - @ref json_serializer<ValueType> has a `from_json()` method of the form
17249 `void from_json(const basic_json&, ValueType&)`, and
17251 @tparam ValueType the input parameter type.
17253 @return the input parameter, allowing chaining calls.
17255 @throw what @ref json_serializer<ValueType> `from_json()` method throws
17257 @liveexample{The example below shows several conversions from JSON values
17258 to other types. There a few things to note: (1) Floating-point numbers can
17259 be converted to integers\, (2) A JSON array can be converted to a standard
17260 `std::vector<short>`\, (3) A JSON object can be converted to C++
17261 associative containers such as `std::unordered_map<std::string\,
17264 @since version 3.3.0
17266 template<typename ValueType,
17267 detail::enable_if_t <
17268 not detail::is_basic_json<ValueType>::value and
17269 detail::has_from_json<basic_json_t, ValueType>::value,
17271 ValueType & get_to(ValueType& v) const noexcept(noexcept(
17272 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
17274 JSONSerializer<ValueType>::from_json(*this, v);
17279 typename T, std::size_t N,
17280 typename Array = T (&)[N],
17281 detail::enable_if_t <
17282 detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
17283 Array get_to(T (&v)[N]) const
17284 noexcept(noexcept(JSONSerializer<Array>::from_json(
17285 std::declval<const basic_json_t&>(), v)))
17287 JSONSerializer<Array>::from_json(*this, v);
17293 @brief get a pointer value (implicit)
17295 Implicit pointer access to the internally stored JSON value. No copies are
17298 @warning Writing data to the pointee of the result yields an undefined
17301 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
17302 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
17303 @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
17306 @return pointer to the internally stored JSON value if the requested
17307 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
17309 @complexity Constant.
17311 @liveexample{The example below shows how pointers to internal values of a
17312 JSON value can be requested. Note that no type conversions are made and a
17313 `nullptr` is returned if the value and the requested pointer type does not
17316 @since version 1.0.0
17318 template<typename PointerType, typename std::enable_if<
17319 std::is_pointer<PointerType>::value, int>::type = 0>
17320 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
17322 // delegate the call to get_impl_ptr<>()
17323 return get_impl_ptr(static_cast<PointerType>(nullptr));
17327 @brief get a pointer value (implicit)
17330 template<typename PointerType, typename std::enable_if<
17331 std::is_pointer<PointerType>::value and
17332 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
17333 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
17335 // delegate the call to get_impl_ptr<>() const
17336 return get_impl_ptr(static_cast<PointerType>(nullptr));
17340 @brief get a pointer value (explicit)
17342 Explicit pointer access to the internally stored JSON value. No copies are
17345 @warning The pointer becomes invalid if the underlying JSON object
17348 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
17349 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
17350 @ref number_unsigned_t, or @ref number_float_t.
17352 @return pointer to the internally stored JSON value if the requested
17353 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
17355 @complexity Constant.
17357 @liveexample{The example below shows how pointers to internal values of a
17358 JSON value can be requested. Note that no type conversions are made and a
17359 `nullptr` is returned if the value and the requested pointer type does not
17360 match.,get__PointerType}
17362 @sa @ref get_ptr() for explicit pointer-member access
17364 @since version 1.0.0
17366 template<typename PointerType, typename std::enable_if<
17367 std::is_pointer<PointerType>::value, int>::type = 0>
17368 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
17370 // delegate the call to get_ptr
17371 return get_ptr<PointerType>();
17375 @brief get a pointer value (explicit)
17378 template<typename PointerType, typename std::enable_if<
17379 std::is_pointer<PointerType>::value, int>::type = 0>
17380 constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
17382 // delegate the call to get_ptr
17383 return get_ptr<PointerType>();
17387 @brief get a reference value (implicit)
17389 Implicit reference access to the internally stored JSON value. No copies
17392 @warning Writing data to the referee of the result yields an undefined
17395 @tparam ReferenceType reference type; must be a reference to @ref array_t,
17396 @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
17397 @ref number_float_t. Enforced by static assertion.
17399 @return reference to the internally stored JSON value if the requested
17400 reference type @a ReferenceType fits to the JSON value; throws
17401 type_error.303 otherwise
17403 @throw type_error.303 in case passed type @a ReferenceType is incompatible
17404 with the stored JSON value; see example below
17406 @complexity Constant.
17408 @liveexample{The example shows several calls to `get_ref()`.,get_ref}
17410 @since version 1.1.0
17412 template<typename ReferenceType, typename std::enable_if<
17413 std::is_reference<ReferenceType>::value, int>::type = 0>
17414 ReferenceType get_ref()
17416 // delegate call to get_ref_impl
17417 return get_ref_impl<ReferenceType>(*this);
17421 @brief get a reference value (implicit)
17424 template<typename ReferenceType, typename std::enable_if<
17425 std::is_reference<ReferenceType>::value and
17426 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
17427 ReferenceType get_ref() const
17429 // delegate call to get_ref_impl
17430 return get_ref_impl<ReferenceType>(*this);
17434 @brief get a value (implicit)
17436 Implicit type conversion between the JSON value and a compatible value.
17437 The call is realized by calling @ref get() const.
17439 @tparam ValueType non-pointer type compatible to the JSON value, for
17440 instance `int` for JSON integer numbers, `bool` for JSON booleans, or
17441 `std::vector` types for JSON arrays. The character type of @ref string_t
17442 as well as an initializer list of this type is excluded to avoid
17443 ambiguities as these types implicitly convert to `std::string`.
17445 @return copy of the JSON value, converted to type @a ValueType
17447 @throw type_error.302 in case passed type @a ValueType is incompatible
17448 to the JSON value type (e.g., the JSON value is of type boolean, but a
17449 string is requested); see example below
17451 @complexity Linear in the size of the JSON value.
17453 @liveexample{The example below shows several conversions from JSON values
17454 to other types. There a few things to note: (1) Floating-point numbers can
17455 be converted to integers\, (2) A JSON array can be converted to a standard
17456 `std::vector<short>`\, (3) A JSON object can be converted to C++
17457 associative containers such as `std::unordered_map<std::string\,
17458 json>`.,operator__ValueType}
17460 @since version 1.0.0
17462 template < typename ValueType, typename std::enable_if <
17463 not std::is_pointer<ValueType>::value and
17464 not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
17465 not std::is_same<ValueType, typename string_t::value_type>::value and
17466 not detail::is_basic_json<ValueType>::value
17468 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
17469 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
17470 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) and _MSC_VER <= 1914))
17471 and not std::is_same<ValueType, typename std::string_view>::value
17474 and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
17475 , int >::type = 0 >
17476 operator ValueType() const
17478 // delegate the call to get<>() const
17479 return get<ValueType>();
17485 ////////////////////
17486 // element access //
17487 ////////////////////
17489 /// @name element access
17490 /// Access to the JSON value.
17494 @brief access specified array element with bounds checking
17496 Returns a reference to the element at specified location @a idx, with
17499 @param[in] idx index of the element to access
17501 @return reference to the element at index @a idx
17503 @throw type_error.304 if the JSON value is not an array; in this case,
17504 calling `at` with an index makes no sense. See example below.
17505 @throw out_of_range.401 if the index @a idx is out of range of the array;
17506 that is, `idx >= size()`. See example below.
17508 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17509 changes in the JSON value.
17511 @complexity Constant.
17513 @since version 1.0.0
17515 @liveexample{The example below shows how array elements can be read and
17516 written using `at()`. It also demonstrates the different exceptions that
17517 can be thrown.,at__size_type}
17519 reference at(size_type idx)
17521 // at only works for arrays
17522 if (JSON_HEDLEY_LIKELY(is_array()))
17526 return m_value.array->at(idx);
17528 JSON_CATCH (std::out_of_range&)
17530 // create better exception explanation
17531 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
17536 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
17541 @brief access specified array element with bounds checking
17543 Returns a const reference to the element at specified location @a idx,
17544 with bounds checking.
17546 @param[in] idx index of the element to access
17548 @return const reference to the element at index @a idx
17550 @throw type_error.304 if the JSON value is not an array; in this case,
17551 calling `at` with an index makes no sense. See example below.
17552 @throw out_of_range.401 if the index @a idx is out of range of the array;
17553 that is, `idx >= size()`. See example below.
17555 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17556 changes in the JSON value.
17558 @complexity Constant.
17560 @since version 1.0.0
17562 @liveexample{The example below shows how array elements can be read using
17563 `at()`. It also demonstrates the different exceptions that can be thrown.,
17564 at__size_type_const}
17566 const_reference at(size_type idx) const
17568 // at only works for arrays
17569 if (JSON_HEDLEY_LIKELY(is_array()))
17573 return m_value.array->at(idx);
17575 JSON_CATCH (std::out_of_range&)
17577 // create better exception explanation
17578 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
17583 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
17588 @brief access specified object element with bounds checking
17590 Returns a reference to the element at with specified key @a key, with
17593 @param[in] key key of the element to access
17595 @return reference to the element at key @a key
17597 @throw type_error.304 if the JSON value is not an object; in this case,
17598 calling `at` with a key makes no sense. See example below.
17599 @throw out_of_range.403 if the key @a key is is not stored in the object;
17600 that is, `find(key) == end()`. See example below.
17602 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17603 changes in the JSON value.
17605 @complexity Logarithmic in the size of the container.
17607 @sa @ref operator[](const typename object_t::key_type&) for unchecked
17608 access by reference
17609 @sa @ref value() for access by value with a default value
17611 @since version 1.0.0
17613 @liveexample{The example below shows how object elements can be read and
17614 written using `at()`. It also demonstrates the different exceptions that
17615 can be thrown.,at__object_t_key_type}
17617 reference at(const typename object_t::key_type& key)
17619 // at only works for objects
17620 if (JSON_HEDLEY_LIKELY(is_object()))
17624 return m_value.object->at(key);
17626 JSON_CATCH (std::out_of_range&)
17628 // create better exception explanation
17629 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
17634 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
17639 @brief access specified object element with bounds checking
17641 Returns a const reference to the element at with specified key @a key,
17642 with bounds checking.
17644 @param[in] key key of the element to access
17646 @return const reference to the element at key @a key
17648 @throw type_error.304 if the JSON value is not an object; in this case,
17649 calling `at` with a key makes no sense. See example below.
17650 @throw out_of_range.403 if the key @a key is is not stored in the object;
17651 that is, `find(key) == end()`. See example below.
17653 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17654 changes in the JSON value.
17656 @complexity Logarithmic in the size of the container.
17658 @sa @ref operator[](const typename object_t::key_type&) for unchecked
17659 access by reference
17660 @sa @ref value() for access by value with a default value
17662 @since version 1.0.0
17664 @liveexample{The example below shows how object elements can be read using
17665 `at()`. It also demonstrates the different exceptions that can be thrown.,
17666 at__object_t_key_type_const}
17668 const_reference at(const typename object_t::key_type& key) const
17670 // at only works for objects
17671 if (JSON_HEDLEY_LIKELY(is_object()))
17675 return m_value.object->at(key);
17677 JSON_CATCH (std::out_of_range&)
17679 // create better exception explanation
17680 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
17685 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
17690 @brief access specified array element
17692 Returns a reference to the element at specified location @a idx.
17694 @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
17695 then the array is silently filled up with `null` values to make `idx` a
17696 valid reference to the last stored element.
17698 @param[in] idx index of the element to access
17700 @return reference to the element at index @a idx
17702 @throw type_error.305 if the JSON value is not an array or null; in that
17703 cases, using the [] operator with an index makes no sense.
17705 @complexity Constant if @a idx is in the range of the array. Otherwise
17706 linear in `idx - size()`.
17708 @liveexample{The example below shows how array elements can be read and
17709 written using `[]` operator. Note the addition of `null`
17710 values.,operatorarray__size_type}
17712 @since version 1.0.0
17714 reference operator[](size_type idx)
17716 // implicitly convert null value to an empty array
17719 m_type = value_t::array;
17720 m_value.array = create<array_t>();
17721 assert_invariant();
17724 // operator[] only works for arrays
17725 if (JSON_HEDLEY_LIKELY(is_array()))
17727 // fill up array with null values if given idx is outside range
17728 if (idx >= m_value.array->size())
17730 m_value.array->insert(m_value.array->end(),
17731 idx - m_value.array->size() + 1,
17735 return m_value.array->operator[](idx);
17738 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
17742 @brief access specified array element
17744 Returns a const reference to the element at specified location @a idx.
17746 @param[in] idx index of the element to access
17748 @return const reference to the element at index @a idx
17750 @throw type_error.305 if the JSON value is not an array; in that case,
17751 using the [] operator with an index makes no sense.
17753 @complexity Constant.
17755 @liveexample{The example below shows how array elements can be read using
17756 the `[]` operator.,operatorarray__size_type_const}
17758 @since version 1.0.0
17760 const_reference operator[](size_type idx) const
17762 // const operator[] only works for arrays
17763 if (JSON_HEDLEY_LIKELY(is_array()))
17765 return m_value.array->operator[](idx);
17768 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
17772 @brief access specified object element
17774 Returns a reference to the element at with specified key @a key.
17776 @note If @a key is not found in the object, then it is silently added to
17777 the object and filled with a `null` value to make `key` a valid reference.
17778 In case the value was `null` before, it is converted to an object.
17780 @param[in] key key of the element to access
17782 @return reference to the element at key @a key
17784 @throw type_error.305 if the JSON value is not an object or null; in that
17785 cases, using the [] operator with a key makes no sense.
17787 @complexity Logarithmic in the size of the container.
17789 @liveexample{The example below shows how object elements can be read and
17790 written using the `[]` operator.,operatorarray__key_type}
17792 @sa @ref at(const typename object_t::key_type&) for access by reference
17793 with range checking
17794 @sa @ref value() for access by value with a default value
17796 @since version 1.0.0
17798 reference operator[](const typename object_t::key_type& key)
17800 // implicitly convert null value to an empty object
17803 m_type = value_t::object;
17804 m_value.object = create<object_t>();
17805 assert_invariant();
17808 // operator[] only works for objects
17809 if (JSON_HEDLEY_LIKELY(is_object()))
17811 return m_value.object->operator[](key);
17814 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
17818 @brief read-only access specified object element
17820 Returns a const reference to the element at with specified key @a key. No
17821 bounds checking is performed.
17823 @warning If the element with key @a key does not exist, the behavior is
17826 @param[in] key key of the element to access
17828 @return const reference to the element at key @a key
17830 @pre The element with key @a key must exist. **This precondition is
17831 enforced with an assertion.**
17833 @throw type_error.305 if the JSON value is not an object; in that case,
17834 using the [] operator with a key makes no sense.
17836 @complexity Logarithmic in the size of the container.
17838 @liveexample{The example below shows how object elements can be read using
17839 the `[]` operator.,operatorarray__key_type_const}
17841 @sa @ref at(const typename object_t::key_type&) for access by reference
17842 with range checking
17843 @sa @ref value() for access by value with a default value
17845 @since version 1.0.0
17847 const_reference operator[](const typename object_t::key_type& key) const
17849 // const operator[] only works for objects
17850 if (JSON_HEDLEY_LIKELY(is_object()))
17852 assert(m_value.object->find(key) != m_value.object->end());
17853 return m_value.object->find(key)->second;
17856 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
17860 @brief access specified object element
17862 Returns a reference to the element at with specified key @a key.
17864 @note If @a key is not found in the object, then it is silently added to
17865 the object and filled with a `null` value to make `key` a valid reference.
17866 In case the value was `null` before, it is converted to an object.
17868 @param[in] key key of the element to access
17870 @return reference to the element at key @a key
17872 @throw type_error.305 if the JSON value is not an object or null; in that
17873 cases, using the [] operator with a key makes no sense.
17875 @complexity Logarithmic in the size of the container.
17877 @liveexample{The example below shows how object elements can be read and
17878 written using the `[]` operator.,operatorarray__key_type}
17880 @sa @ref at(const typename object_t::key_type&) for access by reference
17881 with range checking
17882 @sa @ref value() for access by value with a default value
17884 @since version 1.1.0
17886 template<typename T>
17887 JSON_HEDLEY_NON_NULL(2)
17888 reference operator[](T* key)
17890 // implicitly convert null to object
17893 m_type = value_t::object;
17894 m_value = value_t::object;
17895 assert_invariant();
17898 // at only works for objects
17899 if (JSON_HEDLEY_LIKELY(is_object()))
17901 return m_value.object->operator[](key);
17904 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
17908 @brief read-only access specified object element
17910 Returns a const reference to the element at with specified key @a key. No
17911 bounds checking is performed.
17913 @warning If the element with key @a key does not exist, the behavior is
17916 @param[in] key key of the element to access
17918 @return const reference to the element at key @a key
17920 @pre The element with key @a key must exist. **This precondition is
17921 enforced with an assertion.**
17923 @throw type_error.305 if the JSON value is not an object; in that case,
17924 using the [] operator with a key makes no sense.
17926 @complexity Logarithmic in the size of the container.
17928 @liveexample{The example below shows how object elements can be read using
17929 the `[]` operator.,operatorarray__key_type_const}
17931 @sa @ref at(const typename object_t::key_type&) for access by reference
17932 with range checking
17933 @sa @ref value() for access by value with a default value
17935 @since version 1.1.0
17937 template<typename T>
17938 JSON_HEDLEY_NON_NULL(2)
17939 const_reference operator[](T* key) const
17941 // at only works for objects
17942 if (JSON_HEDLEY_LIKELY(is_object()))
17944 assert(m_value.object->find(key) != m_value.object->end());
17945 return m_value.object->find(key)->second;
17948 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
17952 @brief access specified object element with default value
17954 Returns either a copy of an object's element at the specified key @a key
17955 or a given default value if no element with key @a key exists.
17957 The function is basically equivalent to executing
17961 } catch(out_of_range) {
17962 return default_value;
17966 @note Unlike @ref at(const typename object_t::key_type&), this function
17967 does not throw if the given key @a key was not found.
17969 @note Unlike @ref operator[](const typename object_t::key_type& key), this
17970 function does not implicitly add an element to the position defined by @a
17971 key. This function is furthermore also applicable to const objects.
17973 @param[in] key key of the element to access
17974 @param[in] default_value the value to return if @a key is not found
17976 @tparam ValueType type compatible to JSON values, for instance `int` for
17977 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
17978 JSON arrays. Note the type of the expected value at @a key and the default
17979 value @a default_value must be compatible.
17981 @return copy of the element at key @a key or @a default_value if @a key
17984 @throw type_error.302 if @a default_value does not match the type of the
17986 @throw type_error.306 if the JSON value is not an object; in that case,
17987 using `value()` with a key makes no sense.
17989 @complexity Logarithmic in the size of the container.
17991 @liveexample{The example below shows how object elements can be queried
17992 with a default value.,basic_json__value}
17994 @sa @ref at(const typename object_t::key_type&) for access by reference
17995 with range checking
17996 @sa @ref operator[](const typename object_t::key_type&) for unchecked
17997 access by reference
17999 @since version 1.0.0
18001 template<class ValueType, typename std::enable_if<
18002 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
18003 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
18005 // at only works for objects
18006 if (JSON_HEDLEY_LIKELY(is_object()))
18008 // if key is found, return value and given default value otherwise
18009 const auto it = find(key);
18015 return default_value;
18018 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
18022 @brief overload for a default value of type const char*
18023 @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const
18025 string_t value(const typename object_t::key_type& key, const char* default_value) const
18027 return value(key, string_t(default_value));
18031 @brief access specified object element via JSON Pointer with default value
18033 Returns either a copy of an object's element at the specified key @a key
18034 or a given default value if no element with key @a key exists.
18036 The function is basically equivalent to executing
18040 } catch(out_of_range) {
18041 return default_value;
18045 @note Unlike @ref at(const json_pointer&), this function does not throw
18046 if the given key @a key was not found.
18048 @param[in] ptr a JSON pointer to the element to access
18049 @param[in] default_value the value to return if @a ptr found no value
18051 @tparam ValueType type compatible to JSON values, for instance `int` for
18052 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
18053 JSON arrays. Note the type of the expected value at @a key and the default
18054 value @a default_value must be compatible.
18056 @return copy of the element at key @a key or @a default_value if @a key
18059 @throw type_error.302 if @a default_value does not match the type of the
18061 @throw type_error.306 if the JSON value is not an object; in that case,
18062 using `value()` with a key makes no sense.
18064 @complexity Logarithmic in the size of the container.
18066 @liveexample{The example below shows how object elements can be queried
18067 with a default value.,basic_json__value_ptr}
18069 @sa @ref operator[](const json_pointer&) for unchecked access by reference
18071 @since version 2.0.2
18073 template<class ValueType, typename std::enable_if<
18074 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
18075 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
18077 // at only works for objects
18078 if (JSON_HEDLEY_LIKELY(is_object()))
18080 // if pointer resolves a value, return it or use default value
18083 return ptr.get_checked(this);
18085 JSON_INTERNAL_CATCH (out_of_range&)
18087 return default_value;
18091 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
18095 @brief overload for a default value of type const char*
18096 @copydoc basic_json::value(const json_pointer&, ValueType) const
18098 JSON_HEDLEY_NON_NULL(3)
18099 string_t value(const json_pointer& ptr, const char* default_value) const
18101 return value(ptr, string_t(default_value));
18105 @brief access the first element
18107 Returns a reference to the first element in the container. For a JSON
18108 container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
18110 @return In case of a structured type (array or object), a reference to the
18111 first element is returned. In case of number, string, or boolean values, a
18112 reference to the value is returned.
18114 @complexity Constant.
18116 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
18117 or an empty array or object (undefined behavior, **guarded by
18119 @post The JSON value remains unchanged.
18121 @throw invalid_iterator.214 when called on `null` value
18123 @liveexample{The following code shows an example for `front()`.,front}
18125 @sa @ref back() -- access the last element
18127 @since version 1.0.0
18135 @copydoc basic_json::front()
18137 const_reference front() const
18143 @brief access the last element
18145 Returns a reference to the last element in the container. For a JSON
18146 container `c`, the expression `c.back()` is equivalent to
18148 auto tmp = c.end();
18153 @return In case of a structured type (array or object), a reference to the
18154 last element is returned. In case of number, string, or boolean values, a
18155 reference to the value is returned.
18157 @complexity Constant.
18159 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
18160 or an empty array or object (undefined behavior, **guarded by
18162 @post The JSON value remains unchanged.
18164 @throw invalid_iterator.214 when called on a `null` value. See example
18167 @liveexample{The following code shows an example for `back()`.,back}
18169 @sa @ref front() -- access the first element
18171 @since version 1.0.0
18181 @copydoc basic_json::back()
18183 const_reference back() const
18191 @brief remove element given an iterator
18193 Removes the element specified by iterator @a pos. The iterator @a pos must
18194 be valid and dereferenceable. Thus the `end()` iterator (which is valid,
18195 but is not dereferenceable) cannot be used as a value for @a pos.
18197 If called on a primitive type other than `null`, the resulting JSON value
18200 @param[in] pos iterator to the element to remove
18201 @return Iterator following the last removed element. If the iterator @a
18202 pos refers to the last element, the `end()` iterator is returned.
18204 @tparam IteratorType an @ref iterator or @ref const_iterator
18206 @post Invalidates iterators and references at or after the point of the
18207 erase, including the `end()` iterator.
18209 @throw type_error.307 if called on a `null` value; example: `"cannot use
18210 erase() with null"`
18211 @throw invalid_iterator.202 if called on an iterator which does not belong
18212 to the current JSON value; example: `"iterator does not fit current
18214 @throw invalid_iterator.205 if called on a primitive type with invalid
18215 iterator (i.e., any iterator which is not `begin()`); example: `"iterator
18218 @complexity The complexity depends on the type:
18219 - objects: amortized constant
18220 - arrays: linear in distance between @a pos and the end of the container
18221 - strings: linear in the length of the string
18222 - other types: constant
18224 @liveexample{The example shows the result of `erase()` for different JSON
18225 types.,erase__IteratorType}
18227 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
18229 @sa @ref erase(const typename object_t::key_type&) -- removes the element
18230 from an object at the given key
18231 @sa @ref erase(const size_type) -- removes the element from an array at
18234 @since version 1.0.0
18236 template<class IteratorType, typename std::enable_if<
18237 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
18238 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
18240 IteratorType erase(IteratorType pos)
18242 // make sure iterator fits the current value
18243 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
18245 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
18248 IteratorType result = end();
18252 case value_t::boolean:
18253 case value_t::number_float:
18254 case value_t::number_integer:
18255 case value_t::number_unsigned:
18256 case value_t::string:
18258 if (JSON_HEDLEY_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
18260 JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
18265 AllocatorType<string_t> alloc;
18266 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
18267 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
18268 m_value.string = nullptr;
18271 m_type = value_t::null;
18272 assert_invariant();
18276 case value_t::object:
18278 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
18282 case value_t::array:
18284 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
18289 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
18296 @brief remove elements given an iterator range
18298 Removes the element specified by the range `[first; last)`. The iterator
18299 @a first does not need to be dereferenceable if `first == last`: erasing
18300 an empty range is a no-op.
18302 If called on a primitive type other than `null`, the resulting JSON value
18305 @param[in] first iterator to the beginning of the range to remove
18306 @param[in] last iterator past the end of the range to remove
18307 @return Iterator following the last removed element. If the iterator @a
18308 second refers to the last element, the `end()` iterator is returned.
18310 @tparam IteratorType an @ref iterator or @ref const_iterator
18312 @post Invalidates iterators and references at or after the point of the
18313 erase, including the `end()` iterator.
18315 @throw type_error.307 if called on a `null` value; example: `"cannot use
18316 erase() with null"`
18317 @throw invalid_iterator.203 if called on iterators which does not belong
18318 to the current JSON value; example: `"iterators do not fit current value"`
18319 @throw invalid_iterator.204 if called on a primitive type with invalid
18320 iterators (i.e., if `first != begin()` and `last != end()`); example:
18321 `"iterators out of range"`
18323 @complexity The complexity depends on the type:
18324 - objects: `log(size()) + std::distance(first, last)`
18325 - arrays: linear in the distance between @a first and @a last, plus linear
18326 in the distance between @a last and end of the container
18327 - strings: linear in the length of the string
18328 - other types: constant
18330 @liveexample{The example shows the result of `erase()` for different JSON
18331 types.,erase__IteratorType_IteratorType}
18333 @sa @ref erase(IteratorType) -- removes the element at a given position
18334 @sa @ref erase(const typename object_t::key_type&) -- removes the element
18335 from an object at the given key
18336 @sa @ref erase(const size_type) -- removes the element from an array at
18339 @since version 1.0.0
18341 template<class IteratorType, typename std::enable_if<
18342 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
18343 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
18345 IteratorType erase(IteratorType first, IteratorType last)
18347 // make sure iterator fits the current value
18348 if (JSON_HEDLEY_UNLIKELY(this != first.m_object or this != last.m_object))
18350 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
18353 IteratorType result = end();
18357 case value_t::boolean:
18358 case value_t::number_float:
18359 case value_t::number_integer:
18360 case value_t::number_unsigned:
18361 case value_t::string:
18363 if (JSON_HEDLEY_LIKELY(not first.m_it.primitive_iterator.is_begin()
18364 or not last.m_it.primitive_iterator.is_end()))
18366 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
18371 AllocatorType<string_t> alloc;
18372 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
18373 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
18374 m_value.string = nullptr;
18377 m_type = value_t::null;
18378 assert_invariant();
18382 case value_t::object:
18384 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
18385 last.m_it.object_iterator);
18389 case value_t::array:
18391 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
18392 last.m_it.array_iterator);
18397 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
18404 @brief remove element from a JSON object given a key
18406 Removes elements from a JSON object with the key value @a key.
18408 @param[in] key value of the elements to remove
18410 @return Number of elements removed. If @a ObjectType is the default
18411 `std::map` type, the return value will always be `0` (@a key was not
18412 found) or `1` (@a key was found).
18414 @post References and iterators to the erased elements are invalidated.
18415 Other references and iterators are not affected.
18417 @throw type_error.307 when called on a type other than JSON object;
18418 example: `"cannot use erase() with null"`
18420 @complexity `log(size()) + count(key)`
18422 @liveexample{The example shows the effect of `erase()`.,erase__key_type}
18424 @sa @ref erase(IteratorType) -- removes the element at a given position
18425 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
18427 @sa @ref erase(const size_type) -- removes the element from an array at
18430 @since version 1.0.0
18432 size_type erase(const typename object_t::key_type& key)
18434 // this erase only works for objects
18435 if (JSON_HEDLEY_LIKELY(is_object()))
18437 return m_value.object->erase(key);
18440 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
18444 @brief remove element from a JSON array given an index
18446 Removes element from a JSON array at the index @a idx.
18448 @param[in] idx index of the element to remove
18450 @throw type_error.307 when called on a type other than JSON object;
18451 example: `"cannot use erase() with null"`
18452 @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
18455 @complexity Linear in distance between @a idx and the end of the container.
18457 @liveexample{The example shows the effect of `erase()`.,erase__size_type}
18459 @sa @ref erase(IteratorType) -- removes the element at a given position
18460 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
18462 @sa @ref erase(const typename object_t::key_type&) -- removes the element
18463 from an object at the given key
18465 @since version 1.0.0
18467 void erase(const size_type idx)
18469 // this erase only works for arrays
18470 if (JSON_HEDLEY_LIKELY(is_array()))
18472 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
18474 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
18477 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
18481 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
18496 @brief find an element in a JSON object
18498 Finds an element in a JSON object with key equivalent to @a key. If the
18499 element is not found or the JSON value is not an object, end() is
18502 @note This method always returns @ref end() when executed on a JSON type
18503 that is not an object.
18505 @param[in] key key value of the element to search for.
18507 @return Iterator to an element with key equivalent to @a key. If no such
18508 element is found or the JSON value is not an object, past-the-end (see
18509 @ref end()) iterator is returned.
18511 @complexity Logarithmic in the size of the JSON object.
18513 @liveexample{The example shows how `find()` is used.,find__key_type}
18515 @sa @ref contains(KeyT&&) const -- checks whether a key exists
18517 @since version 1.0.0
18519 template<typename KeyT>
18520 iterator find(KeyT&& key)
18522 auto result = end();
18526 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
18533 @brief find an element in a JSON object
18534 @copydoc find(KeyT&&)
18536 template<typename KeyT>
18537 const_iterator find(KeyT&& key) const
18539 auto result = cend();
18543 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
18550 @brief returns the number of occurrences of a key in a JSON object
18552 Returns the number of elements with key @a key. If ObjectType is the
18553 default `std::map` type, the return value will always be `0` (@a key was
18554 not found) or `1` (@a key was found).
18556 @note This method always returns `0` when executed on a JSON type that is
18559 @param[in] key key value of the element to count
18561 @return Number of elements with key @a key. If the JSON value is not an
18562 object, the return value will be `0`.
18564 @complexity Logarithmic in the size of the JSON object.
18566 @liveexample{The example shows how `count()` is used.,count}
18568 @since version 1.0.0
18570 template<typename KeyT>
18571 size_type count(KeyT&& key) const
18573 // return 0 for all nonobject types
18574 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
18578 @brief check the existence of an element in a JSON object
18580 Check whether an element exists in a JSON object with key equivalent to
18581 @a key. If the element is not found or the JSON value is not an object,
18584 @note This method always returns false when executed on a JSON type
18585 that is not an object.
18587 @param[in] key key value to check its existence.
18589 @return true if an element with specified @a key exists. If no such
18590 element with such key is found or the JSON value is not an object,
18593 @complexity Logarithmic in the size of the JSON object.
18595 @liveexample{The following code shows an example for `contains()`.,contains}
18597 @sa @ref find(KeyT&&) -- returns an iterator to an object element
18598 @sa @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer
18600 @since version 3.6.0
18602 template<typename KeyT, typename std::enable_if<
18603 not std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int>::type = 0>
18604 bool contains(KeyT && key) const
18606 return is_object() and m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
18610 @brief check the existence of an element in a JSON object given a JSON pointer
18612 Check whether the given JSON pointer @a ptr can be resolved in the current
18615 @note This method can be executed on any JSON value type.
18617 @param[in] ptr JSON pointer to check its existence.
18619 @return true if the JSON pointer can be resolved to a stored value, false
18622 @post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`.
18624 @throw parse_error.106 if an array index begins with '0'
18625 @throw parse_error.109 if an array index was not a number
18627 @complexity Logarithmic in the size of the JSON object.
18629 @liveexample{The following code shows an example for `contains()`.,contains_json_pointer}
18631 @sa @ref contains(KeyT &&) const -- checks the existence of a key
18633 @since version 3.7.0
18635 bool contains(const json_pointer& ptr) const
18637 return ptr.contains(this);
18647 /// @name iterators
18651 @brief returns an iterator to the first element
18653 Returns an iterator to the first element.
18655 @image html range-begin-end.svg "Illustration from cppreference.com"
18657 @return iterator to the first element
18659 @complexity Constant.
18661 @requirement This function helps `basic_json` satisfying the
18662 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18664 - The complexity is constant.
18666 @liveexample{The following code shows an example for `begin()`.,begin}
18668 @sa @ref cbegin() -- returns a const iterator to the beginning
18669 @sa @ref end() -- returns an iterator to the end
18670 @sa @ref cend() -- returns a const iterator to the end
18672 @since version 1.0.0
18674 iterator begin() noexcept
18676 iterator result(this);
18677 result.set_begin();
18682 @copydoc basic_json::cbegin()
18684 const_iterator begin() const noexcept
18690 @brief returns a const iterator to the first element
18692 Returns a const iterator to the first element.
18694 @image html range-begin-end.svg "Illustration from cppreference.com"
18696 @return const iterator to the first element
18698 @complexity Constant.
18700 @requirement This function helps `basic_json` satisfying the
18701 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18703 - The complexity is constant.
18704 - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
18706 @liveexample{The following code shows an example for `cbegin()`.,cbegin}
18708 @sa @ref begin() -- returns an iterator to the beginning
18709 @sa @ref end() -- returns an iterator to the end
18710 @sa @ref cend() -- returns a const iterator to the end
18712 @since version 1.0.0
18714 const_iterator cbegin() const noexcept
18716 const_iterator result(this);
18717 result.set_begin();
18722 @brief returns an iterator to one past the last element
18724 Returns an iterator to one past the last element.
18726 @image html range-begin-end.svg "Illustration from cppreference.com"
18728 @return iterator one past the last element
18730 @complexity Constant.
18732 @requirement This function helps `basic_json` satisfying the
18733 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18735 - The complexity is constant.
18737 @liveexample{The following code shows an example for `end()`.,end}
18739 @sa @ref cend() -- returns a const iterator to the end
18740 @sa @ref begin() -- returns an iterator to the beginning
18741 @sa @ref cbegin() -- returns a const iterator to the beginning
18743 @since version 1.0.0
18745 iterator end() noexcept
18747 iterator result(this);
18753 @copydoc basic_json::cend()
18755 const_iterator end() const noexcept
18761 @brief returns a const iterator to one past the last element
18763 Returns a const iterator to one past the last element.
18765 @image html range-begin-end.svg "Illustration from cppreference.com"
18767 @return const iterator one past the last element
18769 @complexity Constant.
18771 @requirement This function helps `basic_json` satisfying the
18772 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18774 - The complexity is constant.
18775 - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
18777 @liveexample{The following code shows an example for `cend()`.,cend}
18779 @sa @ref end() -- returns an iterator to the end
18780 @sa @ref begin() -- returns an iterator to the beginning
18781 @sa @ref cbegin() -- returns a const iterator to the beginning
18783 @since version 1.0.0
18785 const_iterator cend() const noexcept
18787 const_iterator result(this);
18793 @brief returns an iterator to the reverse-beginning
18795 Returns an iterator to the reverse-beginning; that is, the last element.
18797 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
18799 @complexity Constant.
18801 @requirement This function helps `basic_json` satisfying the
18802 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
18804 - The complexity is constant.
18805 - Has the semantics of `reverse_iterator(end())`.
18807 @liveexample{The following code shows an example for `rbegin()`.,rbegin}
18809 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
18810 @sa @ref rend() -- returns a reverse iterator to the end
18811 @sa @ref crend() -- returns a const reverse iterator to the end
18813 @since version 1.0.0
18815 reverse_iterator rbegin() noexcept
18817 return reverse_iterator(end());
18821 @copydoc basic_json::crbegin()
18823 const_reverse_iterator rbegin() const noexcept
18829 @brief returns an iterator to the reverse-end
18831 Returns an iterator to the reverse-end; that is, one before the first
18834 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
18836 @complexity Constant.
18838 @requirement This function helps `basic_json` satisfying the
18839 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
18841 - The complexity is constant.
18842 - Has the semantics of `reverse_iterator(begin())`.
18844 @liveexample{The following code shows an example for `rend()`.,rend}
18846 @sa @ref crend() -- returns a const reverse iterator to the end
18847 @sa @ref rbegin() -- returns a reverse iterator to the beginning
18848 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
18850 @since version 1.0.0
18852 reverse_iterator rend() noexcept
18854 return reverse_iterator(begin());
18858 @copydoc basic_json::crend()
18860 const_reverse_iterator rend() const noexcept
18866 @brief returns a const reverse iterator to the last element
18868 Returns a const iterator to the reverse-beginning; that is, the last
18871 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
18873 @complexity Constant.
18875 @requirement This function helps `basic_json` satisfying the
18876 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
18878 - The complexity is constant.
18879 - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
18881 @liveexample{The following code shows an example for `crbegin()`.,crbegin}
18883 @sa @ref rbegin() -- returns a reverse iterator to the beginning
18884 @sa @ref rend() -- returns a reverse iterator to the end
18885 @sa @ref crend() -- returns a const reverse iterator to the end
18887 @since version 1.0.0
18889 const_reverse_iterator crbegin() const noexcept
18891 return const_reverse_iterator(cend());
18895 @brief returns a const reverse iterator to one before the first
18897 Returns a const reverse iterator to the reverse-end; that is, one before
18900 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
18902 @complexity Constant.
18904 @requirement This function helps `basic_json` satisfying the
18905 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
18907 - The complexity is constant.
18908 - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
18910 @liveexample{The following code shows an example for `crend()`.,crend}
18912 @sa @ref rend() -- returns a reverse iterator to the end
18913 @sa @ref rbegin() -- returns a reverse iterator to the beginning
18914 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
18916 @since version 1.0.0
18918 const_reverse_iterator crend() const noexcept
18920 return const_reverse_iterator(cbegin());
18925 @brief wrapper to access iterator member functions in range-based for
18927 This function allows to access @ref iterator::key() and @ref
18928 iterator::value() during range-based for loops. In these loops, a
18929 reference to the JSON values is returned, so there is no access to the
18930 underlying iterator.
18932 For loop without iterator_wrapper:
18935 for (auto it = j_object.begin(); it != j_object.end(); ++it)
18937 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
18941 Range-based for loop without iterator proxy:
18944 for (auto it : j_object)
18946 // "it" is of type json::reference and has no key() member
18947 std::cout << "value: " << it << '\n';
18951 Range-based for loop with iterator proxy:
18954 for (auto it : json::iterator_wrapper(j_object))
18956 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
18960 @note When iterating over an array, `key()` will return the index of the
18961 element as string (see example).
18963 @param[in] ref reference to a JSON value
18964 @return iteration proxy object wrapping @a ref with an interface to use in
18965 range-based for loops
18967 @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
18969 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18970 changes in the JSON value.
18972 @complexity Constant.
18974 @note The name of this function is not yet final and may change in the
18977 @deprecated This stream operator is deprecated and will be removed in
18978 future 4.0.0 of the library. Please use @ref items() instead;
18979 that is, replace `json::iterator_wrapper(j)` with `j.items()`.
18981 JSON_HEDLEY_DEPRECATED(3.1.0)
18982 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
18984 return ref.items();
18988 @copydoc iterator_wrapper(reference)
18990 JSON_HEDLEY_DEPRECATED(3.1.0)
18991 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
18993 return ref.items();
18997 @brief helper to access iterator member functions in range-based for
18999 This function allows to access @ref iterator::key() and @ref
19000 iterator::value() during range-based for loops. In these loops, a
19001 reference to the JSON values is returned, so there is no access to the
19002 underlying iterator.
19004 For loop without `items()` function:
19007 for (auto it = j_object.begin(); it != j_object.end(); ++it)
19009 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
19013 Range-based for loop without `items()` function:
19016 for (auto it : j_object)
19018 // "it" is of type json::reference and has no key() member
19019 std::cout << "value: " << it << '\n';
19023 Range-based for loop with `items()` function:
19026 for (auto& el : j_object.items())
19028 std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
19032 The `items()` function also allows to use
19033 [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
19037 for (auto& [key, val] : j_object.items())
19039 std::cout << "key: " << key << ", value:" << val << '\n';
19043 @note When iterating over an array, `key()` will return the index of the
19044 element as string (see example). For primitive types (e.g., numbers),
19045 `key()` returns an empty string.
19047 @return iteration proxy object wrapping @a ref with an interface to use in
19048 range-based for loops
19050 @liveexample{The following code shows how the function is used.,items}
19052 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19053 changes in the JSON value.
19055 @complexity Constant.
19057 @since version 3.1.0, structured bindings support since 3.5.0.
19059 iteration_proxy<iterator> items() noexcept
19061 return iteration_proxy<iterator>(*this);
19067 iteration_proxy<const_iterator> items() const noexcept
19069 return iteration_proxy<const_iterator>(*this);
19083 @brief checks whether the container is empty.
19085 Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
19087 @return The return value depends on the different types and is
19088 defined as follows:
19089 Value type | return value
19090 ----------- | -------------
19095 object | result of function `object_t::empty()`
19096 array | result of function `array_t::empty()`
19098 @liveexample{The following code uses `empty()` to check if a JSON
19099 object contains any elements.,empty}
19101 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
19102 the Container concept; that is, their `empty()` functions have constant
19105 @iterators No changes.
19107 @exceptionsafety No-throw guarantee: this function never throws exceptions.
19109 @note This function does not return whether a string stored as JSON value
19110 is empty - it returns whether the JSON container itself is empty which is
19111 false in the case of a string.
19113 @requirement This function helps `basic_json` satisfying the
19114 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
19116 - The complexity is constant.
19117 - Has the semantics of `begin() == end()`.
19119 @sa @ref size() -- returns the number of elements
19121 @since version 1.0.0
19123 bool empty() const noexcept
19127 case value_t::null:
19129 // null values are empty
19133 case value_t::array:
19135 // delegate call to array_t::empty()
19136 return m_value.array->empty();
19139 case value_t::object:
19141 // delegate call to object_t::empty()
19142 return m_value.object->empty();
19147 // all other types are nonempty
19154 @brief returns the number of elements
19156 Returns the number of elements in a JSON value.
19158 @return The return value depends on the different types and is
19159 defined as follows:
19160 Value type | return value
19161 ----------- | -------------
19166 object | result of function object_t::size()
19167 array | result of function array_t::size()
19169 @liveexample{The following code calls `size()` on the different value
19172 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
19173 the Container concept; that is, their size() functions have constant
19176 @iterators No changes.
19178 @exceptionsafety No-throw guarantee: this function never throws exceptions.
19180 @note This function does not return the length of a string stored as JSON
19181 value - it returns the number of elements in the JSON value which is 1 in
19182 the case of a string.
19184 @requirement This function helps `basic_json` satisfying the
19185 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
19187 - The complexity is constant.
19188 - Has the semantics of `std::distance(begin(), end())`.
19190 @sa @ref empty() -- checks whether the container is empty
19191 @sa @ref max_size() -- returns the maximal number of elements
19193 @since version 1.0.0
19195 size_type size() const noexcept
19199 case value_t::null:
19201 // null values are empty
19205 case value_t::array:
19207 // delegate call to array_t::size()
19208 return m_value.array->size();
19211 case value_t::object:
19213 // delegate call to object_t::size()
19214 return m_value.object->size();
19219 // all other types have size 1
19226 @brief returns the maximum possible number of elements
19228 Returns the maximum number of elements a JSON value is able to hold due to
19229 system or library implementation limitations, i.e. `std::distance(begin(),
19230 end())` for the JSON value.
19232 @return The return value depends on the different types and is
19233 defined as follows:
19234 Value type | return value
19235 ----------- | -------------
19236 null | `0` (same as `size()`)
19237 boolean | `1` (same as `size()`)
19238 string | `1` (same as `size()`)
19239 number | `1` (same as `size()`)
19240 object | result of function `object_t::max_size()`
19241 array | result of function `array_t::max_size()`
19243 @liveexample{The following code calls `max_size()` on the different value
19244 types. Note the output is implementation specific.,max_size}
19246 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
19247 the Container concept; that is, their `max_size()` functions have constant
19250 @iterators No changes.
19252 @exceptionsafety No-throw guarantee: this function never throws exceptions.
19254 @requirement This function helps `basic_json` satisfying the
19255 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
19257 - The complexity is constant.
19258 - Has the semantics of returning `b.size()` where `b` is the largest
19259 possible JSON value.
19261 @sa @ref size() -- returns the number of elements
19263 @since version 1.0.0
19265 size_type max_size() const noexcept
19269 case value_t::array:
19271 // delegate call to array_t::max_size()
19272 return m_value.array->max_size();
19275 case value_t::object:
19277 // delegate call to object_t::max_size()
19278 return m_value.object->max_size();
19283 // all other types have max_size() == size()
19296 /// @name modifiers
19300 @brief clears the contents
19302 Clears the content of a JSON value and resets it to the default value as
19303 if @ref basic_json(value_t) would have been called with the current value
19304 type from @ref type():
19306 Value type | initial value
19307 ----------- | -------------
19315 @post Has the same effect as calling
19317 *this = basic_json(type());
19320 @liveexample{The example below shows the effect of `clear()` to different
19323 @complexity Linear in the size of the JSON value.
19325 @iterators All iterators, pointers and references related to this container
19328 @exceptionsafety No-throw guarantee: this function never throws exceptions.
19330 @sa @ref basic_json(value_t) -- constructor that creates an object with the
19331 same value than calling `clear()`
19333 @since version 1.0.0
19335 void clear() noexcept
19339 case value_t::number_integer:
19341 m_value.number_integer = 0;
19345 case value_t::number_unsigned:
19347 m_value.number_unsigned = 0;
19351 case value_t::number_float:
19353 m_value.number_float = 0.0;
19357 case value_t::boolean:
19359 m_value.boolean = false;
19363 case value_t::string:
19365 m_value.string->clear();
19369 case value_t::array:
19371 m_value.array->clear();
19375 case value_t::object:
19377 m_value.object->clear();
19387 @brief add an object to an array
19389 Appends the given element @a val to the end of the JSON value. If the
19390 function is called on a JSON null value, an empty array is created before
19393 @param[in] val the value to add to the JSON array
19395 @throw type_error.308 when called on a type other than JSON array or
19396 null; example: `"cannot use push_back() with number"`
19398 @complexity Amortized constant.
19400 @liveexample{The example shows how `push_back()` and `+=` can be used to
19401 add elements to a JSON array. Note how the `null` value was silently
19402 converted to a JSON array.,push_back}
19404 @since version 1.0.0
19406 void push_back(basic_json&& val)
19408 // push_back only works for null objects or arrays
19409 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
19411 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
19414 // transform null object into an array
19417 m_type = value_t::array;
19418 m_value = value_t::array;
19419 assert_invariant();
19422 // add element to array (move semantics)
19423 m_value.array->push_back(std::move(val));
19424 // invalidate object: mark it null so we do not call the destructor
19425 // cppcheck-suppress accessMoved
19426 val.m_type = value_t::null;
19430 @brief add an object to an array
19431 @copydoc push_back(basic_json&&)
19433 reference operator+=(basic_json&& val)
19435 push_back(std::move(val));
19440 @brief add an object to an array
19441 @copydoc push_back(basic_json&&)
19443 void push_back(const basic_json& val)
19445 // push_back only works for null objects or arrays
19446 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
19448 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
19451 // transform null object into an array
19454 m_type = value_t::array;
19455 m_value = value_t::array;
19456 assert_invariant();
19459 // add element to array
19460 m_value.array->push_back(val);
19464 @brief add an object to an array
19465 @copydoc push_back(basic_json&&)
19467 reference operator+=(const basic_json& val)
19474 @brief add an object to an object
19476 Inserts the given element @a val to the JSON object. If the function is
19477 called on a JSON null value, an empty object is created before inserting
19480 @param[in] val the value to add to the JSON object
19482 @throw type_error.308 when called on a type other than JSON object or
19483 null; example: `"cannot use push_back() with number"`
19485 @complexity Logarithmic in the size of the container, O(log(`size()`)).
19487 @liveexample{The example shows how `push_back()` and `+=` can be used to
19488 add elements to a JSON object. Note how the `null` value was silently
19489 converted to a JSON object.,push_back__object_t__value}
19491 @since version 1.0.0
19493 void push_back(const typename object_t::value_type& val)
19495 // push_back only works for null objects or objects
19496 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_object())))
19498 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
19501 // transform null object into an object
19504 m_type = value_t::object;
19505 m_value = value_t::object;
19506 assert_invariant();
19509 // add element to array
19510 m_value.object->insert(val);
19514 @brief add an object to an object
19515 @copydoc push_back(const typename object_t::value_type&)
19517 reference operator+=(const typename object_t::value_type& val)
19524 @brief add an object to an object
19526 This function allows to use `push_back` with an initializer list. In case
19528 1. the current value is an object,
19529 2. the initializer list @a init contains only two elements, and
19530 3. the first element of @a init is a string,
19532 @a init is converted into an object element and added using
19533 @ref push_back(const typename object_t::value_type&). Otherwise, @a init
19534 is converted to a JSON value and added using @ref push_back(basic_json&&).
19536 @param[in] init an initializer list
19538 @complexity Linear in the size of the initializer list @a init.
19540 @note This function is required to resolve an ambiguous overload error,
19541 because pairs like `{"key", "value"}` can be both interpreted as
19542 `object_t::value_type` or `std::initializer_list<basic_json>`, see
19543 https://github.com/nlohmann/json/issues/235 for more information.
19545 @liveexample{The example shows how initializer lists are treated as
19546 objects when possible.,push_back__initializer_list}
19548 void push_back(initializer_list_t init)
19550 if (is_object() and init.size() == 2 and (*init.begin())->is_string())
19552 basic_json&& key = init.begin()->moved_or_copied();
19553 push_back(typename object_t::value_type(
19554 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
19558 push_back(basic_json(init));
19563 @brief add an object to an object
19564 @copydoc push_back(initializer_list_t)
19566 reference operator+=(initializer_list_t init)
19573 @brief add an object to an array
19575 Creates a JSON value from the passed parameters @a args to the end of the
19576 JSON value. If the function is called on a JSON null value, an empty array
19577 is created before appending the value created from @a args.
19579 @param[in] args arguments to forward to a constructor of @ref basic_json
19580 @tparam Args compatible types to create a @ref basic_json object
19582 @return reference to the inserted element
19584 @throw type_error.311 when called on a type other than JSON array or
19585 null; example: `"cannot use emplace_back() with number"`
19587 @complexity Amortized constant.
19589 @liveexample{The example shows how `push_back()` can be used to add
19590 elements to a JSON array. Note how the `null` value was silently converted
19591 to a JSON array.,emplace_back}
19593 @since version 2.0.8, returns reference since 3.7.0
19595 template<class... Args>
19596 reference emplace_back(Args&& ... args)
19598 // emplace_back only works for null objects or arrays
19599 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
19601 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
19604 // transform null object into an array
19607 m_type = value_t::array;
19608 m_value = value_t::array;
19609 assert_invariant();
19612 // add element to array (perfect forwarding)
19613 #ifdef JSON_HAS_CPP_17
19614 return m_value.array->emplace_back(std::forward<Args>(args)...);
19616 m_value.array->emplace_back(std::forward<Args>(args)...);
19617 return m_value.array->back();
19622 @brief add an object to an object if key does not exist
19624 Inserts a new element into a JSON object constructed in-place with the
19625 given @a args if there is no element with the key in the container. If the
19626 function is called on a JSON null value, an empty object is created before
19627 appending the value created from @a args.
19629 @param[in] args arguments to forward to a constructor of @ref basic_json
19630 @tparam Args compatible types to create a @ref basic_json object
19632 @return a pair consisting of an iterator to the inserted element, or the
19633 already-existing element if no insertion happened, and a bool
19634 denoting whether the insertion took place.
19636 @throw type_error.311 when called on a type other than JSON object or
19637 null; example: `"cannot use emplace() with number"`
19639 @complexity Logarithmic in the size of the container, O(log(`size()`)).
19641 @liveexample{The example shows how `emplace()` can be used to add elements
19642 to a JSON object. Note how the `null` value was silently converted to a
19643 JSON object. Further note how no value is added if there was already one
19644 value stored with the same key.,emplace}
19646 @since version 2.0.8
19648 template<class... Args>
19649 std::pair<iterator, bool> emplace(Args&& ... args)
19651 // emplace only works for null objects or arrays
19652 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_object())))
19654 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
19657 // transform null object into an object
19660 m_type = value_t::object;
19661 m_value = value_t::object;
19662 assert_invariant();
19665 // add element to array (perfect forwarding)
19666 auto res = m_value.object->emplace(std::forward<Args>(args)...);
19667 // create result iterator and set iterator to the result of emplace
19669 it.m_it.object_iterator = res.first;
19671 // return pair of iterator and boolean
19672 return {it, res.second};
19675 /// Helper for insertion of an iterator
19676 /// @note: This uses std::distance to support GCC 4.8,
19677 /// see https://github.com/nlohmann/json/pull/1257
19678 template<typename... Args>
19679 iterator insert_iterator(const_iterator pos, Args&& ... args)
19681 iterator result(this);
19682 assert(m_value.array != nullptr);
19684 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
19685 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
19686 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
19688 // This could have been written as:
19689 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
19690 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
19696 @brief inserts element
19698 Inserts element @a val before iterator @a pos.
19700 @param[in] pos iterator before which the content will be inserted; may be
19702 @param[in] val element to insert
19703 @return iterator pointing to the inserted @a val.
19705 @throw type_error.309 if called on JSON values other than arrays;
19706 example: `"cannot use insert() with string"`
19707 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
19708 example: `"iterator does not fit current value"`
19710 @complexity Constant plus linear in the distance between @a pos and end of
19713 @liveexample{The example shows how `insert()` is used.,insert}
19715 @since version 1.0.0
19717 iterator insert(const_iterator pos, const basic_json& val)
19719 // insert only works for arrays
19720 if (JSON_HEDLEY_LIKELY(is_array()))
19722 // check if iterator pos fits to this JSON value
19723 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
19725 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
19728 // insert to array and return iterator
19729 return insert_iterator(pos, val);
19732 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
19736 @brief inserts element
19737 @copydoc insert(const_iterator, const basic_json&)
19739 iterator insert(const_iterator pos, basic_json&& val)
19741 return insert(pos, val);
19745 @brief inserts elements
19747 Inserts @a cnt copies of @a val before iterator @a pos.
19749 @param[in] pos iterator before which the content will be inserted; may be
19751 @param[in] cnt number of copies of @a val to insert
19752 @param[in] val element to insert
19753 @return iterator pointing to the first element inserted, or @a pos if
19756 @throw type_error.309 if called on JSON values other than arrays; example:
19757 `"cannot use insert() with string"`
19758 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
19759 example: `"iterator does not fit current value"`
19761 @complexity Linear in @a cnt plus linear in the distance between @a pos
19762 and end of the container.
19764 @liveexample{The example shows how `insert()` is used.,insert__count}
19766 @since version 1.0.0
19768 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
19770 // insert only works for arrays
19771 if (JSON_HEDLEY_LIKELY(is_array()))
19773 // check if iterator pos fits to this JSON value
19774 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
19776 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
19779 // insert to array and return iterator
19780 return insert_iterator(pos, cnt, val);
19783 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
19787 @brief inserts elements
19789 Inserts elements from range `[first, last)` before iterator @a pos.
19791 @param[in] pos iterator before which the content will be inserted; may be
19793 @param[in] first begin of the range of elements to insert
19794 @param[in] last end of the range of elements to insert
19796 @throw type_error.309 if called on JSON values other than arrays; example:
19797 `"cannot use insert() with string"`
19798 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
19799 example: `"iterator does not fit current value"`
19800 @throw invalid_iterator.210 if @a first and @a last do not belong to the
19801 same JSON value; example: `"iterators do not fit"`
19802 @throw invalid_iterator.211 if @a first or @a last are iterators into
19803 container for which insert is called; example: `"passed iterators may not
19804 belong to container"`
19806 @return iterator pointing to the first element inserted, or @a pos if
19809 @complexity Linear in `std::distance(first, last)` plus linear in the
19810 distance between @a pos and end of the container.
19812 @liveexample{The example shows how `insert()` is used.,insert__range}
19814 @since version 1.0.0
19816 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
19818 // insert only works for arrays
19819 if (JSON_HEDLEY_UNLIKELY(not is_array()))
19821 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
19824 // check if iterator pos fits to this JSON value
19825 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
19827 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
19830 // check if range iterators belong to the same JSON object
19831 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19833 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
19836 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
19838 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
19841 // insert to array and return iterator
19842 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
19846 @brief inserts elements
19848 Inserts elements from initializer list @a ilist before iterator @a pos.
19850 @param[in] pos iterator before which the content will be inserted; may be
19852 @param[in] ilist initializer list to insert the values from
19854 @throw type_error.309 if called on JSON values other than arrays; example:
19855 `"cannot use insert() with string"`
19856 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
19857 example: `"iterator does not fit current value"`
19859 @return iterator pointing to the first element inserted, or @a pos if
19862 @complexity Linear in `ilist.size()` plus linear in the distance between
19863 @a pos and end of the container.
19865 @liveexample{The example shows how `insert()` is used.,insert__ilist}
19867 @since version 1.0.0
19869 iterator insert(const_iterator pos, initializer_list_t ilist)
19871 // insert only works for arrays
19872 if (JSON_HEDLEY_UNLIKELY(not is_array()))
19874 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
19877 // check if iterator pos fits to this JSON value
19878 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
19880 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
19883 // insert to array and return iterator
19884 return insert_iterator(pos, ilist.begin(), ilist.end());
19888 @brief inserts elements
19890 Inserts elements from range `[first, last)`.
19892 @param[in] first begin of the range of elements to insert
19893 @param[in] last end of the range of elements to insert
19895 @throw type_error.309 if called on JSON values other than objects; example:
19896 `"cannot use insert() with string"`
19897 @throw invalid_iterator.202 if iterator @a first or @a last does does not
19898 point to an object; example: `"iterators first and last must point to
19900 @throw invalid_iterator.210 if @a first and @a last do not belong to the
19901 same JSON value; example: `"iterators do not fit"`
19903 @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
19904 of elements to insert.
19906 @liveexample{The example shows how `insert()` is used.,insert__range_object}
19908 @since version 3.0.0
19910 void insert(const_iterator first, const_iterator last)
19912 // insert only works for objects
19913 if (JSON_HEDLEY_UNLIKELY(not is_object()))
19915 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
19918 // check if range iterators belong to the same JSON object
19919 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19921 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
19924 // passed iterators must belong to objects
19925 if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object()))
19927 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
19930 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
19934 @brief updates a JSON object from another object, overwriting existing keys
19936 Inserts all values from JSON object @a j and overwrites existing keys.
19938 @param[in] j JSON object to read values from
19940 @throw type_error.312 if called on JSON values other than objects; example:
19941 `"cannot use update() with string"`
19943 @complexity O(N*log(size() + N)), where N is the number of elements to
19946 @liveexample{The example shows how `update()` is used.,update}
19948 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
19950 @since version 3.0.0
19952 void update(const_reference j)
19954 // implicitly convert null value to an empty object
19957 m_type = value_t::object;
19958 m_value.object = create<object_t>();
19959 assert_invariant();
19962 if (JSON_HEDLEY_UNLIKELY(not is_object()))
19964 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
19966 if (JSON_HEDLEY_UNLIKELY(not j.is_object()))
19968 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
19971 for (auto it = j.cbegin(); it != j.cend(); ++it)
19973 m_value.object->operator[](it.key()) = it.value();
19978 @brief updates a JSON object from another object, overwriting existing keys
19980 Inserts all values from from range `[first, last)` and overwrites existing
19983 @param[in] first begin of the range of elements to insert
19984 @param[in] last end of the range of elements to insert
19986 @throw type_error.312 if called on JSON values other than objects; example:
19987 `"cannot use update() with string"`
19988 @throw invalid_iterator.202 if iterator @a first or @a last does does not
19989 point to an object; example: `"iterators first and last must point to
19991 @throw invalid_iterator.210 if @a first and @a last do not belong to the
19992 same JSON value; example: `"iterators do not fit"`
19994 @complexity O(N*log(size() + N)), where N is the number of elements to
19997 @liveexample{The example shows how `update()` is used__range.,update}
19999 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
20001 @since version 3.0.0
20003 void update(const_iterator first, const_iterator last)
20005 // implicitly convert null value to an empty object
20008 m_type = value_t::object;
20009 m_value.object = create<object_t>();
20010 assert_invariant();
20013 if (JSON_HEDLEY_UNLIKELY(not is_object()))
20015 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
20018 // check if range iterators belong to the same JSON object
20019 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
20021 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
20024 // passed iterators must belong to objects
20025 if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object()
20026 or not last.m_object->is_object()))
20028 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
20031 for (auto it = first; it != last; ++it)
20033 m_value.object->operator[](it.key()) = it.value();
20038 @brief exchanges the values
20040 Exchanges the contents of the JSON value with those of @a other. Does not
20041 invoke any move, copy, or swap operations on individual elements. All
20042 iterators and references remain valid. The past-the-end iterator is
20045 @param[in,out] other JSON value to exchange the contents with
20047 @complexity Constant.
20049 @liveexample{The example below shows how JSON values can be swapped with
20050 `swap()`.,swap__reference}
20052 @since version 1.0.0
20054 void swap(reference other) noexcept (
20055 std::is_nothrow_move_constructible<value_t>::value and
20056 std::is_nothrow_move_assignable<value_t>::value and
20057 std::is_nothrow_move_constructible<json_value>::value and
20058 std::is_nothrow_move_assignable<json_value>::value
20061 std::swap(m_type, other.m_type);
20062 std::swap(m_value, other.m_value);
20063 assert_invariant();
20067 @brief exchanges the values
20069 Exchanges the contents of a JSON array with those of @a other. Does not
20070 invoke any move, copy, or swap operations on individual elements. All
20071 iterators and references remain valid. The past-the-end iterator is
20074 @param[in,out] other array to exchange the contents with
20076 @throw type_error.310 when JSON value is not an array; example: `"cannot
20077 use swap() with string"`
20079 @complexity Constant.
20081 @liveexample{The example below shows how arrays can be swapped with
20082 `swap()`.,swap__array_t}
20084 @since version 1.0.0
20086 void swap(array_t& other)
20088 // swap only works for arrays
20089 if (JSON_HEDLEY_LIKELY(is_array()))
20091 std::swap(*(m_value.array), other);
20095 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
20100 @brief exchanges the values
20102 Exchanges the contents of a JSON object with those of @a other. Does not
20103 invoke any move, copy, or swap operations on individual elements. All
20104 iterators and references remain valid. The past-the-end iterator is
20107 @param[in,out] other object to exchange the contents with
20109 @throw type_error.310 when JSON value is not an object; example:
20110 `"cannot use swap() with string"`
20112 @complexity Constant.
20114 @liveexample{The example below shows how objects can be swapped with
20115 `swap()`.,swap__object_t}
20117 @since version 1.0.0
20119 void swap(object_t& other)
20121 // swap only works for objects
20122 if (JSON_HEDLEY_LIKELY(is_object()))
20124 std::swap(*(m_value.object), other);
20128 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
20133 @brief exchanges the values
20135 Exchanges the contents of a JSON string with those of @a other. Does not
20136 invoke any move, copy, or swap operations on individual elements. All
20137 iterators and references remain valid. The past-the-end iterator is
20140 @param[in,out] other string to exchange the contents with
20142 @throw type_error.310 when JSON value is not a string; example: `"cannot
20143 use swap() with boolean"`
20145 @complexity Constant.
20147 @liveexample{The example below shows how strings can be swapped with
20148 `swap()`.,swap__string_t}
20150 @since version 1.0.0
20152 void swap(string_t& other)
20154 // swap only works for strings
20155 if (JSON_HEDLEY_LIKELY(is_string()))
20157 std::swap(*(m_value.string), other);
20161 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
20168 //////////////////////////////////////////
20169 // lexicographical comparison operators //
20170 //////////////////////////////////////////
20172 /// @name lexicographical comparison operators
20176 @brief comparison: equal
20178 Compares two JSON values for equality according to the following rules:
20179 - Two JSON values are equal if (1) they are from the same type and (2)
20180 their stored values are the same according to their respective
20182 - Integer and floating-point numbers are automatically converted before
20183 comparison. Note than two NaN values are always treated as unequal.
20184 - Two JSON null values are equal.
20186 @note Floating-point inside JSON values numbers are compared with
20187 `json::number_float_t::operator==` which is `double::operator==` by
20188 default. To compare floating-point while respecting an epsilon, an alternative
20189 [comparison function](https://github.com/mariokonrad/marnav/blob/master/src/marnav/math/floatingpoint.hpp#L34-#L39)
20190 could be used, for instance
20192 template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
20193 inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
20195 return std::abs(a - b) <= epsilon;
20199 @note NaN values never compare equal to themselves or to other NaN values.
20201 @param[in] lhs first JSON value to consider
20202 @param[in] rhs second JSON value to consider
20203 @return whether the values @a lhs and @a rhs are equal
20205 @exceptionsafety No-throw guarantee: this function never throws exceptions.
20207 @complexity Linear.
20209 @liveexample{The example demonstrates comparing several JSON
20210 types.,operator__equal}
20212 @since version 1.0.0
20214 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
20216 const auto lhs_type = lhs.type();
20217 const auto rhs_type = rhs.type();
20219 if (lhs_type == rhs_type)
20223 case value_t::array:
20224 return *lhs.m_value.array == *rhs.m_value.array;
20226 case value_t::object:
20227 return *lhs.m_value.object == *rhs.m_value.object;
20229 case value_t::null:
20232 case value_t::string:
20233 return *lhs.m_value.string == *rhs.m_value.string;
20235 case value_t::boolean:
20236 return lhs.m_value.boolean == rhs.m_value.boolean;
20238 case value_t::number_integer:
20239 return lhs.m_value.number_integer == rhs.m_value.number_integer;
20241 case value_t::number_unsigned:
20242 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
20244 case value_t::number_float:
20245 return lhs.m_value.number_float == rhs.m_value.number_float;
20251 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
20253 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
20255 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
20257 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
20259 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
20261 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
20263 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
20265 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
20267 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
20269 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
20271 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
20273 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
20280 @brief comparison: equal
20281 @copydoc operator==(const_reference, const_reference)
20283 template<typename ScalarType, typename std::enable_if<
20284 std::is_scalar<ScalarType>::value, int>::type = 0>
20285 friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
20287 return lhs == basic_json(rhs);
20291 @brief comparison: equal
20292 @copydoc operator==(const_reference, const_reference)
20294 template<typename ScalarType, typename std::enable_if<
20295 std::is_scalar<ScalarType>::value, int>::type = 0>
20296 friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
20298 return basic_json(lhs) == rhs;
20302 @brief comparison: not equal
20304 Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
20306 @param[in] lhs first JSON value to consider
20307 @param[in] rhs second JSON value to consider
20308 @return whether the values @a lhs and @a rhs are not equal
20310 @complexity Linear.
20312 @exceptionsafety No-throw guarantee: this function never throws exceptions.
20314 @liveexample{The example demonstrates comparing several JSON
20315 types.,operator__notequal}
20317 @since version 1.0.0
20319 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
20321 return not (lhs == rhs);
20325 @brief comparison: not equal
20326 @copydoc operator!=(const_reference, const_reference)
20328 template<typename ScalarType, typename std::enable_if<
20329 std::is_scalar<ScalarType>::value, int>::type = 0>
20330 friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
20332 return lhs != basic_json(rhs);
20336 @brief comparison: not equal
20337 @copydoc operator!=(const_reference, const_reference)
20339 template<typename ScalarType, typename std::enable_if<
20340 std::is_scalar<ScalarType>::value, int>::type = 0>
20341 friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
20343 return basic_json(lhs) != rhs;
20347 @brief comparison: less than
20349 Compares whether one JSON value @a lhs is less than another JSON value @a
20350 rhs according to the following rules:
20351 - If @a lhs and @a rhs have the same type, the values are compared using
20352 the default `<` operator.
20353 - Integer and floating-point numbers are automatically converted before
20355 - In case @a lhs and @a rhs have different types, the values are ignored
20356 and the order of the types is considered, see
20357 @ref operator<(const value_t, const value_t).
20359 @param[in] lhs first JSON value to consider
20360 @param[in] rhs second JSON value to consider
20361 @return whether @a lhs is less than @a rhs
20363 @complexity Linear.
20365 @exceptionsafety No-throw guarantee: this function never throws exceptions.
20367 @liveexample{The example demonstrates comparing several JSON
20368 types.,operator__less}
20370 @since version 1.0.0
20372 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
20374 const auto lhs_type = lhs.type();
20375 const auto rhs_type = rhs.type();
20377 if (lhs_type == rhs_type)
20381 case value_t::array:
20382 // note parentheses are necessary, see
20383 // https://github.com/nlohmann/json/issues/1530
20384 return (*lhs.m_value.array) < (*rhs.m_value.array);
20386 case value_t::object:
20387 return (*lhs.m_value.object) < (*rhs.m_value.object);
20389 case value_t::null:
20392 case value_t::string:
20393 return (*lhs.m_value.string) < (*rhs.m_value.string);
20395 case value_t::boolean:
20396 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
20398 case value_t::number_integer:
20399 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
20401 case value_t::number_unsigned:
20402 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
20404 case value_t::number_float:
20405 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
20411 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
20413 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
20415 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
20417 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
20419 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
20421 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
20423 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
20425 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
20427 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
20429 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
20431 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
20433 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
20436 // We only reach this line if we cannot compare values. In that case,
20437 // we compare types. Note we have to call the operator explicitly,
20438 // because MSVC has problems otherwise.
20439 return operator<(lhs_type, rhs_type);
20443 @brief comparison: less than
20444 @copydoc operator<(const_reference, const_reference)
20446 template<typename ScalarType, typename std::enable_if<
20447 std::is_scalar<ScalarType>::value, int>::type = 0>
20448 friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
20450 return lhs < basic_json(rhs);
20454 @brief comparison: less than
20455 @copydoc operator<(const_reference, const_reference)
20457 template<typename ScalarType, typename std::enable_if<
20458 std::is_scalar<ScalarType>::value, int>::type = 0>
20459 friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
20461 return basic_json(lhs) < rhs;
20465 @brief comparison: less than or equal
20467 Compares whether one JSON value @a lhs is less than or equal to another
20468 JSON value by calculating `not (rhs < lhs)`.
20470 @param[in] lhs first JSON value to consider
20471 @param[in] rhs second JSON value to consider
20472 @return whether @a lhs is less than or equal to @a rhs
20474 @complexity Linear.
20476 @exceptionsafety No-throw guarantee: this function never throws exceptions.
20478 @liveexample{The example demonstrates comparing several JSON
20479 types.,operator__greater}
20481 @since version 1.0.0
20483 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
20485 return not (rhs < lhs);
20489 @brief comparison: less than or equal
20490 @copydoc operator<=(const_reference, const_reference)
20492 template<typename ScalarType, typename std::enable_if<
20493 std::is_scalar<ScalarType>::value, int>::type = 0>
20494 friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
20496 return lhs <= basic_json(rhs);
20500 @brief comparison: less than or equal
20501 @copydoc operator<=(const_reference, const_reference)
20503 template<typename ScalarType, typename std::enable_if<
20504 std::is_scalar<ScalarType>::value, int>::type = 0>
20505 friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
20507 return basic_json(lhs) <= rhs;
20511 @brief comparison: greater than
20513 Compares whether one JSON value @a lhs is greater than another
20514 JSON value by calculating `not (lhs <= rhs)`.
20516 @param[in] lhs first JSON value to consider
20517 @param[in] rhs second JSON value to consider
20518 @return whether @a lhs is greater than to @a rhs
20520 @complexity Linear.
20522 @exceptionsafety No-throw guarantee: this function never throws exceptions.
20524 @liveexample{The example demonstrates comparing several JSON
20525 types.,operator__lessequal}
20527 @since version 1.0.0
20529 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
20531 return not (lhs <= rhs);
20535 @brief comparison: greater than
20536 @copydoc operator>(const_reference, const_reference)
20538 template<typename ScalarType, typename std::enable_if<
20539 std::is_scalar<ScalarType>::value, int>::type = 0>
20540 friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
20542 return lhs > basic_json(rhs);
20546 @brief comparison: greater than
20547 @copydoc operator>(const_reference, const_reference)
20549 template<typename ScalarType, typename std::enable_if<
20550 std::is_scalar<ScalarType>::value, int>::type = 0>
20551 friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
20553 return basic_json(lhs) > rhs;
20557 @brief comparison: greater than or equal
20559 Compares whether one JSON value @a lhs is greater than or equal to another
20560 JSON value by calculating `not (lhs < rhs)`.
20562 @param[in] lhs first JSON value to consider
20563 @param[in] rhs second JSON value to consider
20564 @return whether @a lhs is greater than or equal to @a rhs
20566 @complexity Linear.
20568 @exceptionsafety No-throw guarantee: this function never throws exceptions.
20570 @liveexample{The example demonstrates comparing several JSON
20571 types.,operator__greaterequal}
20573 @since version 1.0.0
20575 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
20577 return not (lhs < rhs);
20581 @brief comparison: greater than or equal
20582 @copydoc operator>=(const_reference, const_reference)
20584 template<typename ScalarType, typename std::enable_if<
20585 std::is_scalar<ScalarType>::value, int>::type = 0>
20586 friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
20588 return lhs >= basic_json(rhs);
20592 @brief comparison: greater than or equal
20593 @copydoc operator>=(const_reference, const_reference)
20595 template<typename ScalarType, typename std::enable_if<
20596 std::is_scalar<ScalarType>::value, int>::type = 0>
20597 friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
20599 return basic_json(lhs) >= rhs;
20604 ///////////////////
20605 // serialization //
20606 ///////////////////
20608 /// @name serialization
20612 @brief serialize to stream
20614 Serialize the given JSON value @a j to the output stream @a o. The JSON
20615 value will be serialized using the @ref dump member function.
20617 - The indentation of the output can be controlled with the member variable
20618 `width` of the output stream @a o. For instance, using the manipulator
20619 `std::setw(4)` on @a o sets the indentation level to `4` and the
20620 serialization result is the same as calling `dump(4)`.
20622 - The indentation character can be controlled with the member variable
20623 `fill` of the output stream @a o. For instance, the manipulator
20624 `std::setfill('\\t')` sets indentation to use a tab character rather than
20625 the default space character.
20627 @param[in,out] o stream to serialize to
20628 @param[in] j JSON value to serialize
20630 @return the stream @a o
20632 @throw type_error.316 if a string stored inside the JSON value is not
20635 @complexity Linear.
20637 @liveexample{The example below shows the serialization with different
20638 parameters to `width` to adjust the indentation level.,operator_serialize}
20640 @since version 1.0.0; indentation character added in version 3.0.0
20642 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
20644 // read width member and use it as indentation parameter if nonzero
20645 const bool pretty_print = o.width() > 0;
20646 const auto indentation = pretty_print ? o.width() : 0;
20648 // reset width to 0 for subsequent calls to this stream
20651 // do the actual serialization
20652 serializer s(detail::output_adapter<char>(o), o.fill());
20653 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
20658 @brief serialize to stream
20659 @deprecated This stream operator is deprecated and will be removed in
20660 future 4.0.0 of the library. Please use
20661 @ref operator<<(std::ostream&, const basic_json&)
20662 instead; that is, replace calls like `j >> o;` with `o << j;`.
20663 @since version 1.0.0; deprecated since version 3.0.0
20665 JSON_HEDLEY_DEPRECATED(3.0.0)
20666 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
20674 /////////////////////
20675 // deserialization //
20676 /////////////////////
20678 /// @name deserialization
20682 @brief deserialize from a compatible input
20684 This function reads from a compatible input. Examples are:
20685 - an array of 1-byte values
20686 - strings with character/literal type with size of 1 byte
20688 - container with contiguous storage of 1-byte values. Compatible container
20689 types include `std::vector`, `std::string`, `std::array`,
20690 `std::valarray`, and `std::initializer_list`. Furthermore, C-style
20691 arrays can be used with `std::begin()`/`std::end()`. User-defined
20692 containers can be used as long as they implement random-access iterators
20693 and a contiguous storage.
20695 @pre Each element of the container has a size of 1 byte. Violating this
20696 precondition yields undefined behavior. **This precondition is enforced
20697 with a static assertion.**
20699 @pre The container storage is contiguous. Violating this precondition
20700 yields undefined behavior. **This precondition is enforced with an
20703 @warning There is no way to enforce all preconditions at compile-time. If
20704 the function is called with a noncompliant container and with
20705 assertions switched off, the behavior is undefined and will most
20706 likely yield segmentation violation.
20708 @param[in] i input to read from
20709 @param[in] cb a parser callback function of type @ref parser_callback_t
20710 which is used to control the deserialization by filtering unwanted values
20712 @param[in] allow_exceptions whether to throw exceptions in case of a
20713 parse error (optional, true by default)
20715 @return deserialized JSON value; in case of a parse error and
20716 @a allow_exceptions set to `false`, the return value will be
20717 value_t::discarded.
20719 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
20720 of input; expected string literal""`
20721 @throw parse_error.102 if to_unicode fails or surrogate error
20722 @throw parse_error.103 if to_unicode fails
20724 @complexity Linear in the length of the input. The parser is a predictive
20725 LL(1) parser. The complexity can be higher if the parser callback function
20726 @a cb has a super-linear complexity.
20728 @note A UTF-8 byte order mark is silently ignored.
20730 @liveexample{The example below demonstrates the `parse()` function reading
20731 from an array.,parse__array__parser_callback_t}
20733 @liveexample{The example below demonstrates the `parse()` function with
20734 and without callback function.,parse__string__parser_callback_t}
20736 @liveexample{The example below demonstrates the `parse()` function with
20737 and without callback function.,parse__istream__parser_callback_t}
20739 @liveexample{The example below demonstrates the `parse()` function reading
20740 from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
20742 @since version 2.0.3 (contiguous containers)
20744 JSON_HEDLEY_WARN_UNUSED_RESULT
20745 static basic_json parse(detail::input_adapter&& i,
20746 const parser_callback_t cb = nullptr,
20747 const bool allow_exceptions = true)
20750 parser(i, cb, allow_exceptions).parse(true, result);
20754 static bool accept(detail::input_adapter&& i)
20756 return parser(i).accept(true);
20760 @brief generate SAX events
20762 The SAX event lister must follow the interface of @ref json_sax.
20764 This function reads from a compatible input. Examples are:
20765 - an array of 1-byte values
20766 - strings with character/literal type with size of 1 byte
20768 - container with contiguous storage of 1-byte values. Compatible container
20769 types include `std::vector`, `std::string`, `std::array`,
20770 `std::valarray`, and `std::initializer_list`. Furthermore, C-style
20771 arrays can be used with `std::begin()`/`std::end()`. User-defined
20772 containers can be used as long as they implement random-access iterators
20773 and a contiguous storage.
20775 @pre Each element of the container has a size of 1 byte. Violating this
20776 precondition yields undefined behavior. **This precondition is enforced
20777 with a static assertion.**
20779 @pre The container storage is contiguous. Violating this precondition
20780 yields undefined behavior. **This precondition is enforced with an
20783 @warning There is no way to enforce all preconditions at compile-time. If
20784 the function is called with a noncompliant container and with
20785 assertions switched off, the behavior is undefined and will most
20786 likely yield segmentation violation.
20788 @param[in] i input to read from
20789 @param[in,out] sax SAX event listener
20790 @param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON)
20791 @param[in] strict whether the input has to be consumed completely
20793 @return return value of the last processed SAX event
20795 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
20796 of input; expected string literal""`
20797 @throw parse_error.102 if to_unicode fails or surrogate error
20798 @throw parse_error.103 if to_unicode fails
20800 @complexity Linear in the length of the input. The parser is a predictive
20801 LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
20802 a super-linear complexity.
20804 @note A UTF-8 byte order mark is silently ignored.
20806 @liveexample{The example below demonstrates the `sax_parse()` function
20807 reading from string and processing the events with a user-defined SAX
20808 event consumer.,sax_parse}
20810 @since version 3.2.0
20812 template <typename SAX>
20813 JSON_HEDLEY_NON_NULL(2)
20814 static bool sax_parse(detail::input_adapter&& i, SAX* sax,
20815 input_format_t format = input_format_t::json,
20816 const bool strict = true)
20819 return format == input_format_t::json
20820 ? parser(std::move(i)).sax_parse(sax, strict)
20821 : detail::binary_reader<basic_json, SAX>(std::move(i)).sax_parse(format, sax, strict);
20825 @brief deserialize from an iterator range with contiguous storage
20827 This function reads from an iterator range of a container with contiguous
20828 storage of 1-byte values. Compatible container types include
20829 `std::vector`, `std::string`, `std::array`, `std::valarray`, and
20830 `std::initializer_list`. Furthermore, C-style arrays can be used with
20831 `std::begin()`/`std::end()`. User-defined containers can be used as long
20832 as they implement random-access iterators and a contiguous storage.
20834 @pre The iterator range is contiguous. Violating this precondition yields
20835 undefined behavior. **This precondition is enforced with an assertion.**
20836 @pre Each element in the range has a size of 1 byte. Violating this
20837 precondition yields undefined behavior. **This precondition is enforced
20838 with a static assertion.**
20840 @warning There is no way to enforce all preconditions at compile-time. If
20841 the function is called with noncompliant iterators and with
20842 assertions switched off, the behavior is undefined and will most
20843 likely yield segmentation violation.
20845 @tparam IteratorType iterator of container with contiguous storage
20846 @param[in] first begin of the range to parse (included)
20847 @param[in] last end of the range to parse (excluded)
20848 @param[in] cb a parser callback function of type @ref parser_callback_t
20849 which is used to control the deserialization by filtering unwanted values
20851 @param[in] allow_exceptions whether to throw exceptions in case of a
20852 parse error (optional, true by default)
20854 @return deserialized JSON value; in case of a parse error and
20855 @a allow_exceptions set to `false`, the return value will be
20856 value_t::discarded.
20858 @throw parse_error.101 in case of an unexpected token
20859 @throw parse_error.102 if to_unicode fails or surrogate error
20860 @throw parse_error.103 if to_unicode fails
20862 @complexity Linear in the length of the input. The parser is a predictive
20863 LL(1) parser. The complexity can be higher if the parser callback function
20864 @a cb has a super-linear complexity.
20866 @note A UTF-8 byte order mark is silently ignored.
20868 @liveexample{The example below demonstrates the `parse()` function reading
20869 from an iterator range.,parse__iteratortype__parser_callback_t}
20871 @since version 2.0.3
20873 template<class IteratorType, typename std::enable_if<
20875 std::random_access_iterator_tag,
20876 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
20877 static basic_json parse(IteratorType first, IteratorType last,
20878 const parser_callback_t cb = nullptr,
20879 const bool allow_exceptions = true)
20882 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
20886 template<class IteratorType, typename std::enable_if<
20888 std::random_access_iterator_tag,
20889 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
20890 static bool accept(IteratorType first, IteratorType last)
20892 return parser(detail::input_adapter(first, last)).accept(true);
20895 template<class IteratorType, class SAX, typename std::enable_if<
20897 std::random_access_iterator_tag,
20898 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
20899 JSON_HEDLEY_NON_NULL(3)
20900 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
20902 return parser(detail::input_adapter(first, last)).sax_parse(sax);
20906 @brief deserialize from stream
20907 @deprecated This stream operator is deprecated and will be removed in
20908 version 4.0.0 of the library. Please use
20909 @ref operator>>(std::istream&, basic_json&)
20910 instead; that is, replace calls like `j << i;` with `i >> j;`.
20911 @since version 1.0.0; deprecated since version 3.0.0
20913 JSON_HEDLEY_DEPRECATED(3.0.0)
20914 friend std::istream& operator<<(basic_json& j, std::istream& i)
20916 return operator>>(i, j);
20920 @brief deserialize from stream
20922 Deserializes an input stream to a JSON value.
20924 @param[in,out] i input stream to read a serialized JSON value from
20925 @param[in,out] j JSON value to write the deserialized input to
20927 @throw parse_error.101 in case of an unexpected token
20928 @throw parse_error.102 if to_unicode fails or surrogate error
20929 @throw parse_error.103 if to_unicode fails
20931 @complexity Linear in the length of the input. The parser is a predictive
20934 @note A UTF-8 byte order mark is silently ignored.
20936 @liveexample{The example below shows how a JSON value is constructed by
20937 reading a serialization from a stream.,operator_deserialize}
20939 @sa parse(std::istream&, const parser_callback_t) for a variant with a
20940 parser callback function to filter values while parsing
20942 @since version 1.0.0
20944 friend std::istream& operator>>(std::istream& i, basic_json& j)
20946 parser(detail::input_adapter(i)).parse(false, j);
20952 ///////////////////////////
20953 // convenience functions //
20954 ///////////////////////////
20957 @brief return the type as string
20959 Returns the type name as string to be used in error messages - usually to
20960 indicate that a function was called on a wrong JSON type.
20962 @return a string representation of a the @a m_type member:
20963 Value type | return value
20964 ----------- | -------------
20966 boolean | `"boolean"`
20967 string | `"string"`
20968 number | `"number"` (for all number types)
20969 object | `"object"`
20971 discarded | `"discarded"`
20973 @exceptionsafety No-throw guarantee: this function never throws exceptions.
20975 @complexity Constant.
20977 @liveexample{The following code exemplifies `type_name()` for all JSON
20980 @sa @ref type() -- return the type of the JSON value
20981 @sa @ref operator value_t() -- return the type of the JSON value (implicit)
20983 @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
20986 JSON_HEDLEY_RETURNS_NON_NULL
20987 const char* type_name() const noexcept
20992 case value_t::null:
20994 case value_t::object:
20996 case value_t::array:
20998 case value_t::string:
21000 case value_t::boolean:
21002 case value_t::discarded:
21003 return "discarded";
21012 //////////////////////
21013 // member variables //
21014 //////////////////////
21016 /// the type of the current element
21017 value_t m_type = value_t::null;
21019 /// the value of the current element
21020 json_value m_value = {};
21022 //////////////////////////////////////////
21023 // binary serialization/deserialization //
21024 //////////////////////////////////////////
21026 /// @name binary serialization/deserialization support
21031 @brief create a CBOR serialization of a given JSON value
21033 Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
21034 Binary Object Representation) serialization format. CBOR is a binary
21035 serialization format which aims to be more compact than JSON itself, yet
21036 more efficient to parse.
21038 The library uses the following mapping from JSON values types to
21039 CBOR types according to the CBOR specification (RFC 7049):
21041 JSON value type | value/range | CBOR type | first byte
21042 --------------- | ------------------------------------------ | ---------------------------------- | ---------------
21043 null | `null` | Null | 0xF6
21044 boolean | `true` | True | 0xF5
21045 boolean | `false` | False | 0xF4
21046 number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B
21047 number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A
21048 number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39
21049 number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38
21050 number_integer | -24..-1 | Negative integer | 0x20..0x37
21051 number_integer | 0..23 | Integer | 0x00..0x17
21052 number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18
21053 number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
21054 number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
21055 number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
21056 number_unsigned | 0..23 | Integer | 0x00..0x17
21057 number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18
21058 number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
21059 number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
21060 number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
21061 number_float | *any value* | Double-Precision Float | 0xFB
21062 string | *length*: 0..23 | UTF-8 string | 0x60..0x77
21063 string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78
21064 string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79
21065 string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A
21066 string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B
21067 array | *size*: 0..23 | array | 0x80..0x97
21068 array | *size*: 23..255 | array (1 byte follow) | 0x98
21069 array | *size*: 256..65535 | array (2 bytes follow) | 0x99
21070 array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A
21071 array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B
21072 object | *size*: 0..23 | map | 0xA0..0xB7
21073 object | *size*: 23..255 | map (1 byte follow) | 0xB8
21074 object | *size*: 256..65535 | map (2 bytes follow) | 0xB9
21075 object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA
21076 object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB
21078 @note The mapping is **complete** in the sense that any JSON value type
21079 can be converted to a CBOR value.
21081 @note If NaN or Infinity are stored inside a JSON number, they are
21082 serialized properly. This behavior differs from the @ref dump()
21083 function which serializes NaN or Infinity to `null`.
21085 @note The following CBOR types are not used in the conversion:
21086 - byte strings (0x40..0x5F)
21087 - UTF-8 strings terminated by "break" (0x7F)
21088 - arrays terminated by "break" (0x9F)
21089 - maps terminated by "break" (0xBF)
21090 - date/time (0xC0..0xC1)
21091 - bignum (0xC2..0xC3)
21092 - decimal fraction (0xC4)
21094 - tagged items (0xC6..0xD4, 0xD8..0xDB)
21095 - expected conversions (0xD5..0xD7)
21096 - simple values (0xE0..0xF3, 0xF8)
21098 - half and single-precision floats (0xF9-0xFA)
21101 @param[in] j JSON value to serialize
21102 @return MessagePack serialization as byte vector
21104 @complexity Linear in the size of the JSON value @a j.
21106 @liveexample{The example shows the serialization of a JSON value to a byte
21107 vector in CBOR format.,to_cbor}
21110 @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
21111 analogous deserialization
21112 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
21113 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
21114 related UBJSON format
21116 @since version 2.0.9
21118 static std::vector<uint8_t> to_cbor(const basic_json& j)
21120 std::vector<uint8_t> result;
21121 to_cbor(j, result);
21125 static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
21127 binary_writer<uint8_t>(o).write_cbor(j);
21130 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
21132 binary_writer<char>(o).write_cbor(j);
21136 @brief create a MessagePack serialization of a given JSON value
21138 Serializes a given JSON value @a j to a byte vector using the MessagePack
21139 serialization format. MessagePack is a binary serialization format which
21140 aims to be more compact than JSON itself, yet more efficient to parse.
21142 The library uses the following mapping from JSON values types to
21143 MessagePack types according to the MessagePack specification:
21145 JSON value type | value/range | MessagePack type | first byte
21146 --------------- | --------------------------------- | ---------------- | ----------
21147 null | `null` | nil | 0xC0
21148 boolean | `true` | true | 0xC3
21149 boolean | `false` | false | 0xC2
21150 number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3
21151 number_integer | -2147483648..-32769 | int32 | 0xD2
21152 number_integer | -32768..-129 | int16 | 0xD1
21153 number_integer | -128..-33 | int8 | 0xD0
21154 number_integer | -32..-1 | negative fixint | 0xE0..0xFF
21155 number_integer | 0..127 | positive fixint | 0x00..0x7F
21156 number_integer | 128..255 | uint 8 | 0xCC
21157 number_integer | 256..65535 | uint 16 | 0xCD
21158 number_integer | 65536..4294967295 | uint 32 | 0xCE
21159 number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF
21160 number_unsigned | 0..127 | positive fixint | 0x00..0x7F
21161 number_unsigned | 128..255 | uint 8 | 0xCC
21162 number_unsigned | 256..65535 | uint 16 | 0xCD
21163 number_unsigned | 65536..4294967295 | uint 32 | 0xCE
21164 number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF
21165 number_float | *any value* | float 64 | 0xCB
21166 string | *length*: 0..31 | fixstr | 0xA0..0xBF
21167 string | *length*: 32..255 | str 8 | 0xD9
21168 string | *length*: 256..65535 | str 16 | 0xDA
21169 string | *length*: 65536..4294967295 | str 32 | 0xDB
21170 array | *size*: 0..15 | fixarray | 0x90..0x9F
21171 array | *size*: 16..65535 | array 16 | 0xDC
21172 array | *size*: 65536..4294967295 | array 32 | 0xDD
21173 object | *size*: 0..15 | fix map | 0x80..0x8F
21174 object | *size*: 16..65535 | map 16 | 0xDE
21175 object | *size*: 65536..4294967295 | map 32 | 0xDF
21177 @note The mapping is **complete** in the sense that any JSON value type
21178 can be converted to a MessagePack value.
21180 @note The following values can **not** be converted to a MessagePack value:
21181 - strings with more than 4294967295 bytes
21182 - arrays with more than 4294967295 elements
21183 - objects with more than 4294967295 elements
21185 @note The following MessagePack types are not used in the conversion:
21186 - bin 8 - bin 32 (0xC4..0xC6)
21187 - ext 8 - ext 32 (0xC7..0xC9)
21189 - fixext 1 - fixext 16 (0xD4..0xD8)
21191 @note Any MessagePack output created @ref to_msgpack can be successfully
21192 parsed by @ref from_msgpack.
21194 @note If NaN or Infinity are stored inside a JSON number, they are
21195 serialized properly. This behavior differs from the @ref dump()
21196 function which serializes NaN or Infinity to `null`.
21198 @param[in] j JSON value to serialize
21199 @return MessagePack serialization as byte vector
21201 @complexity Linear in the size of the JSON value @a j.
21203 @liveexample{The example shows the serialization of a JSON value to a byte
21204 vector in MessagePack format.,to_msgpack}
21206 @sa http://msgpack.org
21207 @sa @ref from_msgpack for the analogous deserialization
21208 @sa @ref to_cbor(const basic_json& for the related CBOR format
21209 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
21210 related UBJSON format
21212 @since version 2.0.9
21214 static std::vector<uint8_t> to_msgpack(const basic_json& j)
21216 std::vector<uint8_t> result;
21217 to_msgpack(j, result);
21221 static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
21223 binary_writer<uint8_t>(o).write_msgpack(j);
21226 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
21228 binary_writer<char>(o).write_msgpack(j);
21232 @brief create a UBJSON serialization of a given JSON value
21234 Serializes a given JSON value @a j to a byte vector using the UBJSON
21235 (Universal Binary JSON) serialization format. UBJSON aims to be more compact
21236 than JSON itself, yet more efficient to parse.
21238 The library uses the following mapping from JSON values types to
21239 UBJSON types according to the UBJSON specification:
21241 JSON value type | value/range | UBJSON type | marker
21242 --------------- | --------------------------------- | ----------- | ------
21243 null | `null` | null | `Z`
21244 boolean | `true` | true | `T`
21245 boolean | `false` | false | `F`
21246 number_integer | -9223372036854775808..-2147483649 | int64 | `L`
21247 number_integer | -2147483648..-32769 | int32 | `l`
21248 number_integer | -32768..-129 | int16 | `I`
21249 number_integer | -128..127 | int8 | `i`
21250 number_integer | 128..255 | uint8 | `U`
21251 number_integer | 256..32767 | int16 | `I`
21252 number_integer | 32768..2147483647 | int32 | `l`
21253 number_integer | 2147483648..9223372036854775807 | int64 | `L`
21254 number_unsigned | 0..127 | int8 | `i`
21255 number_unsigned | 128..255 | uint8 | `U`
21256 number_unsigned | 256..32767 | int16 | `I`
21257 number_unsigned | 32768..2147483647 | int32 | `l`
21258 number_unsigned | 2147483648..9223372036854775807 | int64 | `L`
21259 number_float | *any value* | float64 | `D`
21260 string | *with shortest length indicator* | string | `S`
21261 array | *see notes on optimized format* | array | `[`
21262 object | *see notes on optimized format* | map | `{`
21264 @note The mapping is **complete** in the sense that any JSON value type
21265 can be converted to a UBJSON value.
21267 @note The following values can **not** be converted to a UBJSON value:
21268 - strings with more than 9223372036854775807 bytes (theoretical)
21269 - unsigned integer numbers above 9223372036854775807
21271 @note The following markers are not used in the conversion:
21272 - `Z`: no-op values are not created.
21273 - `C`: single-byte strings are serialized with `S` markers.
21275 @note Any UBJSON output created @ref to_ubjson can be successfully parsed
21276 by @ref from_ubjson.
21278 @note If NaN or Infinity are stored inside a JSON number, they are
21279 serialized properly. This behavior differs from the @ref dump()
21280 function which serializes NaN or Infinity to `null`.
21282 @note The optimized formats for containers are supported: Parameter
21283 @a use_size adds size information to the beginning of a container and
21284 removes the closing marker. Parameter @a use_type further checks
21285 whether all elements of a container have the same type and adds the
21286 type marker to the beginning of the container. The @a use_type
21287 parameter must only be used together with @a use_size = true. Note
21288 that @a use_size = true alone may result in larger representations -
21289 the benefit of this parameter is that the receiving side is
21290 immediately informed on the number of elements of the container.
21292 @param[in] j JSON value to serialize
21293 @param[in] use_size whether to add size annotations to container types
21294 @param[in] use_type whether to add type annotations to container types
21295 (must be combined with @a use_size = true)
21296 @return UBJSON serialization as byte vector
21298 @complexity Linear in the size of the JSON value @a j.
21300 @liveexample{The example shows the serialization of a JSON value to a byte
21301 vector in UBJSON format.,to_ubjson}
21303 @sa http://ubjson.org
21304 @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
21305 analogous deserialization
21306 @sa @ref to_cbor(const basic_json& for the related CBOR format
21307 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
21309 @since version 3.1.0
21311 static std::vector<uint8_t> to_ubjson(const basic_json& j,
21312 const bool use_size = false,
21313 const bool use_type = false)
21315 std::vector<uint8_t> result;
21316 to_ubjson(j, result, use_size, use_type);
21320 static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
21321 const bool use_size = false, const bool use_type = false)
21323 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
21326 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
21327 const bool use_size = false, const bool use_type = false)
21329 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
21334 @brief Serializes the given JSON object `j` to BSON and returns a vector
21335 containing the corresponding BSON-representation.
21337 BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are
21338 stored as a single entity (a so-called document).
21340 The library uses the following mapping from JSON values types to BSON types:
21342 JSON value type | value/range | BSON type | marker
21343 --------------- | --------------------------------- | ----------- | ------
21344 null | `null` | null | 0x0A
21345 boolean | `true`, `false` | boolean | 0x08
21346 number_integer | -9223372036854775808..-2147483649 | int64 | 0x12
21347 number_integer | -2147483648..2147483647 | int32 | 0x10
21348 number_integer | 2147483648..9223372036854775807 | int64 | 0x12
21349 number_unsigned | 0..2147483647 | int32 | 0x10
21350 number_unsigned | 2147483648..9223372036854775807 | int64 | 0x12
21351 number_unsigned | 9223372036854775808..18446744073709551615| -- | --
21352 number_float | *any value* | double | 0x01
21353 string | *any value* | string | 0x02
21354 array | *any value* | document | 0x04
21355 object | *any value* | document | 0x03
21357 @warning The mapping is **incomplete**, since only JSON-objects (and things
21358 contained therein) can be serialized to BSON.
21359 Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
21360 and the keys may not contain U+0000, since they are serialized a
21361 zero-terminated c-strings.
21363 @throw out_of_range.407 if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`
21364 @throw out_of_range.409 if a key in `j` contains a NULL (U+0000)
21365 @throw type_error.317 if `!j.is_object()`
21367 @pre The input `j` is required to be an object: `j.is_object() == true`.
21369 @note Any BSON output created via @ref to_bson can be successfully parsed
21372 @param[in] j JSON value to serialize
21373 @return BSON serialization as byte vector
21375 @complexity Linear in the size of the JSON value @a j.
21377 @liveexample{The example shows the serialization of a JSON value to a byte
21378 vector in BSON format.,to_bson}
21380 @sa http://bsonspec.org/spec.html
21381 @sa @ref from_bson(detail::input_adapter&&, const bool strict) for the
21382 analogous deserialization
21383 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
21384 related UBJSON format
21385 @sa @ref to_cbor(const basic_json&) for the related CBOR format
21386 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
21388 static std::vector<uint8_t> to_bson(const basic_json& j)
21390 std::vector<uint8_t> result;
21391 to_bson(j, result);
21396 @brief Serializes the given JSON object `j` to BSON and forwards the
21397 corresponding BSON-representation to the given output_adapter `o`.
21398 @param j The JSON object to convert to BSON.
21399 @param o The output adapter that receives the binary BSON representation.
21400 @pre The input `j` shall be an object: `j.is_object() == true`
21401 @sa @ref to_bson(const basic_json&)
21403 static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
21405 binary_writer<uint8_t>(o).write_bson(j);
21409 @copydoc to_bson(const basic_json&, detail::output_adapter<uint8_t>)
21411 static void to_bson(const basic_json& j, detail::output_adapter<char> o)
21413 binary_writer<char>(o).write_bson(j);
21418 @brief create a JSON value from an input in CBOR format
21420 Deserializes a given input @a i to a JSON value using the CBOR (Concise
21421 Binary Object Representation) serialization format.
21423 The library maps CBOR types to JSON value types as follows:
21425 CBOR type | JSON value type | first byte
21426 ---------------------- | --------------- | ----------
21427 Integer | number_unsigned | 0x00..0x17
21428 Unsigned integer | number_unsigned | 0x18
21429 Unsigned integer | number_unsigned | 0x19
21430 Unsigned integer | number_unsigned | 0x1A
21431 Unsigned integer | number_unsigned | 0x1B
21432 Negative integer | number_integer | 0x20..0x37
21433 Negative integer | number_integer | 0x38
21434 Negative integer | number_integer | 0x39
21435 Negative integer | number_integer | 0x3A
21436 Negative integer | number_integer | 0x3B
21437 Negative integer | number_integer | 0x40..0x57
21438 UTF-8 string | string | 0x60..0x77
21439 UTF-8 string | string | 0x78
21440 UTF-8 string | string | 0x79
21441 UTF-8 string | string | 0x7A
21442 UTF-8 string | string | 0x7B
21443 UTF-8 string | string | 0x7F
21444 array | array | 0x80..0x97
21445 array | array | 0x98
21446 array | array | 0x99
21447 array | array | 0x9A
21448 array | array | 0x9B
21449 array | array | 0x9F
21450 map | object | 0xA0..0xB7
21451 map | object | 0xB8
21452 map | object | 0xB9
21453 map | object | 0xBA
21454 map | object | 0xBB
21455 map | object | 0xBF
21456 False | `false` | 0xF4
21457 True | `true` | 0xF5
21458 Null | `null` | 0xF6
21459 Half-Precision Float | number_float | 0xF9
21460 Single-Precision Float | number_float | 0xFA
21461 Double-Precision Float | number_float | 0xFB
21463 @warning The mapping is **incomplete** in the sense that not all CBOR
21464 types can be converted to a JSON value. The following CBOR types
21465 are not supported and will yield parse errors (parse_error.112):
21466 - byte strings (0x40..0x5F)
21467 - date/time (0xC0..0xC1)
21468 - bignum (0xC2..0xC3)
21469 - decimal fraction (0xC4)
21471 - tagged items (0xC6..0xD4, 0xD8..0xDB)
21472 - expected conversions (0xD5..0xD7)
21473 - simple values (0xE0..0xF3, 0xF8)
21476 @warning CBOR allows map keys of any type, whereas JSON only allows
21477 strings as keys in object values. Therefore, CBOR maps with keys
21478 other than UTF-8 strings are rejected (parse_error.113).
21480 @note Any CBOR output created @ref to_cbor can be successfully parsed by
21483 @param[in] i an input in CBOR format convertible to an input adapter
21484 @param[in] strict whether to expect the input to be consumed until EOF
21486 @param[in] allow_exceptions whether to throw exceptions in case of a
21487 parse error (optional, true by default)
21489 @return deserialized JSON value; in case of a parse error and
21490 @a allow_exceptions set to `false`, the return value will be
21491 value_t::discarded.
21493 @throw parse_error.110 if the given input ends prematurely or the end of
21494 file was not reached when @a strict was set to true
21495 @throw parse_error.112 if unsupported features from CBOR were
21496 used in the given input @a v or if the input is not valid CBOR
21497 @throw parse_error.113 if a string was expected as map key, but not found
21499 @complexity Linear in the size of the input @a i.
21501 @liveexample{The example shows the deserialization of a byte vector in CBOR
21502 format to a JSON value.,from_cbor}
21505 @sa @ref to_cbor(const basic_json&) for the analogous serialization
21506 @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for the
21507 related MessagePack format
21508 @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
21509 related UBJSON format
21511 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
21512 consume input adapters, removed start_index parameter, and added
21513 @a strict parameter since 3.0.0; added @a allow_exceptions parameter
21516 JSON_HEDLEY_WARN_UNUSED_RESULT
21517 static basic_json from_cbor(detail::input_adapter&& i,
21518 const bool strict = true,
21519 const bool allow_exceptions = true)
21522 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21523 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::cbor, &sdp, strict);
21524 return res ? result : basic_json(value_t::discarded);
21528 @copydoc from_cbor(detail::input_adapter&&, const bool, const bool)
21530 template<typename A1, typename A2,
21531 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
21532 JSON_HEDLEY_WARN_UNUSED_RESULT
21533 static basic_json from_cbor(A1 && a1, A2 && a2,
21534 const bool strict = true,
21535 const bool allow_exceptions = true)
21538 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21539 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::cbor, &sdp, strict);
21540 return res ? result : basic_json(value_t::discarded);
21544 @brief create a JSON value from an input in MessagePack format
21546 Deserializes a given input @a i to a JSON value using the MessagePack
21547 serialization format.
21549 The library maps MessagePack types to JSON value types as follows:
21551 MessagePack type | JSON value type | first byte
21552 ---------------- | --------------- | ----------
21553 positive fixint | number_unsigned | 0x00..0x7F
21554 fixmap | object | 0x80..0x8F
21555 fixarray | array | 0x90..0x9F
21556 fixstr | string | 0xA0..0xBF
21557 nil | `null` | 0xC0
21558 false | `false` | 0xC2
21559 true | `true` | 0xC3
21560 float 32 | number_float | 0xCA
21561 float 64 | number_float | 0xCB
21562 uint 8 | number_unsigned | 0xCC
21563 uint 16 | number_unsigned | 0xCD
21564 uint 32 | number_unsigned | 0xCE
21565 uint 64 | number_unsigned | 0xCF
21566 int 8 | number_integer | 0xD0
21567 int 16 | number_integer | 0xD1
21568 int 32 | number_integer | 0xD2
21569 int 64 | number_integer | 0xD3
21570 str 8 | string | 0xD9
21571 str 16 | string | 0xDA
21572 str 32 | string | 0xDB
21573 array 16 | array | 0xDC
21574 array 32 | array | 0xDD
21575 map 16 | object | 0xDE
21576 map 32 | object | 0xDF
21577 negative fixint | number_integer | 0xE0-0xFF
21579 @warning The mapping is **incomplete** in the sense that not all
21580 MessagePack types can be converted to a JSON value. The following
21581 MessagePack types are not supported and will yield parse errors:
21582 - bin 8 - bin 32 (0xC4..0xC6)
21583 - ext 8 - ext 32 (0xC7..0xC9)
21584 - fixext 1 - fixext 16 (0xD4..0xD8)
21586 @note Any MessagePack output created @ref to_msgpack can be successfully
21587 parsed by @ref from_msgpack.
21589 @param[in] i an input in MessagePack format convertible to an input
21591 @param[in] strict whether to expect the input to be consumed until EOF
21593 @param[in] allow_exceptions whether to throw exceptions in case of a
21594 parse error (optional, true by default)
21596 @return deserialized JSON value; in case of a parse error and
21597 @a allow_exceptions set to `false`, the return value will be
21598 value_t::discarded.
21600 @throw parse_error.110 if the given input ends prematurely or the end of
21601 file was not reached when @a strict was set to true
21602 @throw parse_error.112 if unsupported features from MessagePack were
21603 used in the given input @a i or if the input is not valid MessagePack
21604 @throw parse_error.113 if a string was expected as map key, but not found
21606 @complexity Linear in the size of the input @a i.
21608 @liveexample{The example shows the deserialization of a byte vector in
21609 MessagePack format to a JSON value.,from_msgpack}
21611 @sa http://msgpack.org
21612 @sa @ref to_msgpack(const basic_json&) for the analogous serialization
21613 @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
21614 related CBOR format
21615 @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for
21616 the related UBJSON format
21617 @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
21618 the related BSON format
21620 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
21621 consume input adapters, removed start_index parameter, and added
21622 @a strict parameter since 3.0.0; added @a allow_exceptions parameter
21625 JSON_HEDLEY_WARN_UNUSED_RESULT
21626 static basic_json from_msgpack(detail::input_adapter&& i,
21627 const bool strict = true,
21628 const bool allow_exceptions = true)
21631 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21632 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::msgpack, &sdp, strict);
21633 return res ? result : basic_json(value_t::discarded);
21637 @copydoc from_msgpack(detail::input_adapter&&, const bool, const bool)
21639 template<typename A1, typename A2,
21640 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
21641 JSON_HEDLEY_WARN_UNUSED_RESULT
21642 static basic_json from_msgpack(A1 && a1, A2 && a2,
21643 const bool strict = true,
21644 const bool allow_exceptions = true)
21647 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21648 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::msgpack, &sdp, strict);
21649 return res ? result : basic_json(value_t::discarded);
21653 @brief create a JSON value from an input in UBJSON format
21655 Deserializes a given input @a i to a JSON value using the UBJSON (Universal
21656 Binary JSON) serialization format.
21658 The library maps UBJSON types to JSON value types as follows:
21660 UBJSON type | JSON value type | marker
21661 ----------- | --------------------------------------- | ------
21662 no-op | *no value, next value is read* | `N`
21663 null | `null` | `Z`
21664 false | `false` | `F`
21665 true | `true` | `T`
21666 float32 | number_float | `d`
21667 float64 | number_float | `D`
21668 uint8 | number_unsigned | `U`
21669 int8 | number_integer | `i`
21670 int16 | number_integer | `I`
21671 int32 | number_integer | `l`
21672 int64 | number_integer | `L`
21673 string | string | `S`
21674 char | string | `C`
21675 array | array (optimized values are supported) | `[`
21676 object | object (optimized values are supported) | `{`
21678 @note The mapping is **complete** in the sense that any UBJSON value can
21679 be converted to a JSON value.
21681 @param[in] i an input in UBJSON format convertible to an input adapter
21682 @param[in] strict whether to expect the input to be consumed until EOF
21684 @param[in] allow_exceptions whether to throw exceptions in case of a
21685 parse error (optional, true by default)
21687 @return deserialized JSON value; in case of a parse error and
21688 @a allow_exceptions set to `false`, the return value will be
21689 value_t::discarded.
21691 @throw parse_error.110 if the given input ends prematurely or the end of
21692 file was not reached when @a strict was set to true
21693 @throw parse_error.112 if a parse error occurs
21694 @throw parse_error.113 if a string could not be parsed successfully
21696 @complexity Linear in the size of the input @a i.
21698 @liveexample{The example shows the deserialization of a byte vector in
21699 UBJSON format to a JSON value.,from_ubjson}
21701 @sa http://ubjson.org
21702 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
21703 analogous serialization
21704 @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
21705 related CBOR format
21706 @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
21707 the related MessagePack format
21708 @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
21709 the related BSON format
21711 @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
21713 JSON_HEDLEY_WARN_UNUSED_RESULT
21714 static basic_json from_ubjson(detail::input_adapter&& i,
21715 const bool strict = true,
21716 const bool allow_exceptions = true)
21719 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21720 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::ubjson, &sdp, strict);
21721 return res ? result : basic_json(value_t::discarded);
21725 @copydoc from_ubjson(detail::input_adapter&&, const bool, const bool)
21727 template<typename A1, typename A2,
21728 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
21729 JSON_HEDLEY_WARN_UNUSED_RESULT
21730 static basic_json from_ubjson(A1 && a1, A2 && a2,
21731 const bool strict = true,
21732 const bool allow_exceptions = true)
21735 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21736 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::ubjson, &sdp, strict);
21737 return res ? result : basic_json(value_t::discarded);
21741 @brief Create a JSON value from an input in BSON format
21743 Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)
21744 serialization format.
21746 The library maps BSON record types to JSON value types as follows:
21748 BSON type | BSON marker byte | JSON value type
21749 --------------- | ---------------- | ---------------------------
21750 double | 0x01 | number_float
21751 string | 0x02 | string
21752 document | 0x03 | object
21753 array | 0x04 | array
21754 binary | 0x05 | still unsupported
21755 undefined | 0x06 | still unsupported
21756 ObjectId | 0x07 | still unsupported
21757 boolean | 0x08 | boolean
21758 UTC Date-Time | 0x09 | still unsupported
21760 Regular Expr. | 0x0B | still unsupported
21761 DB Pointer | 0x0C | still unsupported
21762 JavaScript Code | 0x0D | still unsupported
21763 Symbol | 0x0E | still unsupported
21764 JavaScript Code | 0x0F | still unsupported
21765 int32 | 0x10 | number_integer
21766 Timestamp | 0x11 | still unsupported
21767 128-bit decimal float | 0x13 | still unsupported
21768 Max Key | 0x7F | still unsupported
21769 Min Key | 0xFF | still unsupported
21771 @warning The mapping is **incomplete**. The unsupported mappings
21772 are indicated in the table above.
21774 @param[in] i an input in BSON format convertible to an input adapter
21775 @param[in] strict whether to expect the input to be consumed until EOF
21777 @param[in] allow_exceptions whether to throw exceptions in case of a
21778 parse error (optional, true by default)
21780 @return deserialized JSON value; in case of a parse error and
21781 @a allow_exceptions set to `false`, the return value will be
21782 value_t::discarded.
21784 @throw parse_error.114 if an unsupported BSON record type is encountered
21786 @complexity Linear in the size of the input @a i.
21788 @liveexample{The example shows the deserialization of a byte vector in
21789 BSON format to a JSON value.,from_bson}
21791 @sa http://bsonspec.org/spec.html
21792 @sa @ref to_bson(const basic_json&) for the analogous serialization
21793 @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
21794 related CBOR format
21795 @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
21796 the related MessagePack format
21797 @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
21798 related UBJSON format
21800 JSON_HEDLEY_WARN_UNUSED_RESULT
21801 static basic_json from_bson(detail::input_adapter&& i,
21802 const bool strict = true,
21803 const bool allow_exceptions = true)
21806 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21807 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::bson, &sdp, strict);
21808 return res ? result : basic_json(value_t::discarded);
21812 @copydoc from_bson(detail::input_adapter&&, const bool, const bool)
21814 template<typename A1, typename A2,
21815 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
21816 JSON_HEDLEY_WARN_UNUSED_RESULT
21817 static basic_json from_bson(A1 && a1, A2 && a2,
21818 const bool strict = true,
21819 const bool allow_exceptions = true)
21822 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21823 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::bson, &sdp, strict);
21824 return res ? result : basic_json(value_t::discarded);
21831 //////////////////////////
21832 // JSON Pointer support //
21833 //////////////////////////
21835 /// @name JSON Pointer functions
21839 @brief access specified element via JSON Pointer
21841 Uses a JSON pointer to retrieve a reference to the respective JSON value.
21842 No bound checking is performed. Similar to @ref operator[](const typename
21843 object_t::key_type&), `null` values are created in arrays and objects if
21847 - If the JSON pointer points to an object key that does not exist, it
21848 is created an filled with a `null` value before a reference to it
21850 - If the JSON pointer points to an array index that does not exist, it
21851 is created an filled with a `null` value before a reference to it
21852 is returned. All indices between the current maximum and the given
21853 index are also filled with `null`.
21854 - The special value `-` is treated as a synonym for the index past the
21857 @param[in] ptr a JSON pointer
21859 @return reference to the element pointed to by @a ptr
21861 @complexity Constant.
21863 @throw parse_error.106 if an array index begins with '0'
21864 @throw parse_error.109 if an array index was not a number
21865 @throw out_of_range.404 if the JSON pointer can not be resolved
21867 @liveexample{The behavior is shown in the example.,operatorjson_pointer}
21869 @since version 2.0.0
21871 reference operator[](const json_pointer& ptr)
21873 return ptr.get_unchecked(this);
21877 @brief access specified element via JSON Pointer
21879 Uses a JSON pointer to retrieve a reference to the respective JSON value.
21880 No bound checking is performed. The function does not change the JSON
21881 value; no `null` values are created. In particular, the the special value
21882 `-` yields an exception.
21884 @param[in] ptr JSON pointer to the desired element
21886 @return const reference to the element pointed to by @a ptr
21888 @complexity Constant.
21890 @throw parse_error.106 if an array index begins with '0'
21891 @throw parse_error.109 if an array index was not a number
21892 @throw out_of_range.402 if the array index '-' is used
21893 @throw out_of_range.404 if the JSON pointer can not be resolved
21895 @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
21897 @since version 2.0.0
21899 const_reference operator[](const json_pointer& ptr) const
21901 return ptr.get_unchecked(this);
21905 @brief access specified element via JSON Pointer
21907 Returns a reference to the element at with specified JSON pointer @a ptr,
21908 with bounds checking.
21910 @param[in] ptr JSON pointer to the desired element
21912 @return reference to the element pointed to by @a ptr
21914 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
21915 begins with '0'. See example below.
21917 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
21918 is not a number. See example below.
21920 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
21921 is out of range. See example below.
21923 @throw out_of_range.402 if the array index '-' is used in the passed JSON
21924 pointer @a ptr. As `at` provides checked access (and no elements are
21925 implicitly inserted), the index '-' is always invalid. See example below.
21927 @throw out_of_range.403 if the JSON pointer describes a key of an object
21928 which cannot be found. See example below.
21930 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
21933 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21934 changes in the JSON value.
21936 @complexity Constant.
21938 @since version 2.0.0
21940 @liveexample{The behavior is shown in the example.,at_json_pointer}
21942 reference at(const json_pointer& ptr)
21944 return ptr.get_checked(this);
21948 @brief access specified element via JSON Pointer
21950 Returns a const reference to the element at with specified JSON pointer @a
21951 ptr, with bounds checking.
21953 @param[in] ptr JSON pointer to the desired element
21955 @return reference to the element pointed to by @a ptr
21957 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
21958 begins with '0'. See example below.
21960 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
21961 is not a number. See example below.
21963 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
21964 is out of range. See example below.
21966 @throw out_of_range.402 if the array index '-' is used in the passed JSON
21967 pointer @a ptr. As `at` provides checked access (and no elements are
21968 implicitly inserted), the index '-' is always invalid. See example below.
21970 @throw out_of_range.403 if the JSON pointer describes a key of an object
21971 which cannot be found. See example below.
21973 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
21976 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21977 changes in the JSON value.
21979 @complexity Constant.
21981 @since version 2.0.0
21983 @liveexample{The behavior is shown in the example.,at_json_pointer_const}
21985 const_reference at(const json_pointer& ptr) const
21987 return ptr.get_checked(this);
21991 @brief return flattened JSON value
21993 The function creates a JSON object whose keys are JSON pointers (see [RFC
21994 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
21995 primitive. The original JSON value can be restored using the @ref
21996 unflatten() function.
21998 @return an object that maps JSON pointers to primitive values
22000 @note Empty objects and arrays are flattened to `null` and will not be
22001 reconstructed correctly by the @ref unflatten() function.
22003 @complexity Linear in the size the JSON value.
22005 @liveexample{The following code shows how a JSON object is flattened to an
22006 object whose keys consist of JSON pointers.,flatten}
22008 @sa @ref unflatten() for the reverse function
22010 @since version 2.0.0
22012 basic_json flatten() const
22014 basic_json result(value_t::object);
22015 json_pointer::flatten("", *this, result);
22020 @brief unflatten a previously flattened JSON value
22022 The function restores the arbitrary nesting of a JSON value that has been
22023 flattened before using the @ref flatten() function. The JSON value must
22024 meet certain constraints:
22025 1. The value must be an object.
22026 2. The keys must be JSON pointers (see
22027 [RFC 6901](https://tools.ietf.org/html/rfc6901))
22028 3. The mapped values must be primitive JSON types.
22030 @return the original JSON from a flattened version
22032 @note Empty objects and arrays are flattened by @ref flatten() to `null`
22033 values and can not unflattened to their original type. Apart from
22034 this example, for a JSON value `j`, the following is always true:
22035 `j == j.flatten().unflatten()`.
22037 @complexity Linear in the size the JSON value.
22039 @throw type_error.314 if value is not an object
22040 @throw type_error.315 if object values are not primitive
22042 @liveexample{The following code shows how a flattened JSON object is
22043 unflattened into the original nested JSON object.,unflatten}
22045 @sa @ref flatten() for the reverse function
22047 @since version 2.0.0
22049 basic_json unflatten() const
22051 return json_pointer::unflatten(*this);
22056 //////////////////////////
22057 // JSON Patch functions //
22058 //////////////////////////
22060 /// @name JSON Patch functions
22064 @brief applies a JSON patch
22066 [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
22067 expressing a sequence of operations to apply to a JSON) document. With
22068 this function, a JSON Patch is applied to the current JSON value by
22069 executing all operations from the patch.
22071 @param[in] json_patch JSON patch document
22072 @return patched document
22074 @note The application of a patch is atomic: Either all operations succeed
22075 and the patched document is returned or an exception is thrown. In
22076 any case, the original value is not changed: the patch is applied
22077 to a copy of the value.
22079 @throw parse_error.104 if the JSON patch does not consist of an array of
22082 @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
22083 attributes are missing); example: `"operation add must have member path"`
22085 @throw out_of_range.401 if an array index is out of range.
22087 @throw out_of_range.403 if a JSON pointer inside the patch could not be
22088 resolved successfully in the current JSON value; example: `"key baz not
22091 @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
22094 @throw other_error.501 if "test" operation was unsuccessful
22096 @complexity Linear in the size of the JSON value and the length of the
22097 JSON patch. As usually only a fraction of the JSON value is affected by
22098 the patch, the complexity can usually be neglected.
22100 @liveexample{The following code shows how a JSON patch is applied to a
22103 @sa @ref diff -- create a JSON patch by comparing two JSON values
22105 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
22106 @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
22108 @since version 2.0.0
22110 basic_json patch(const basic_json& json_patch) const
22112 // make a working copy to apply the patch to
22113 basic_json result = *this;
22115 // the valid JSON Patch operations
22116 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
22118 const auto get_op = [](const std::string & op)
22122 return patch_operations::add;
22124 if (op == "remove")
22126 return patch_operations::remove;
22128 if (op == "replace")
22130 return patch_operations::replace;
22134 return patch_operations::move;
22138 return patch_operations::copy;
22142 return patch_operations::test;
22145 return patch_operations::invalid;
22148 // wrapper for "add" operation; add value at ptr
22149 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
22151 // adding to the root of the target document means replacing it
22158 // make sure the top element of the pointer exists
22159 json_pointer top_pointer = ptr.top();
22160 if (top_pointer != ptr)
22162 result.at(top_pointer);
22165 // get reference to parent of JSON pointer ptr
22166 const auto last_path = ptr.back();
22168 basic_json& parent = result[ptr];
22170 switch (parent.m_type)
22172 case value_t::null:
22173 case value_t::object:
22175 // use operator[] to add value
22176 parent[last_path] = val;
22180 case value_t::array:
22182 if (last_path == "-")
22184 // special case: append to back
22185 parent.push_back(val);
22189 const auto idx = json_pointer::array_index(last_path);
22190 if (JSON_HEDLEY_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
22192 // avoid undefined behavior
22193 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
22196 // default case: insert add offset
22197 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
22202 // if there exists a parent it cannot be primitive
22203 default: // LCOV_EXCL_LINE
22204 assert(false); // LCOV_EXCL_LINE
22208 // wrapper for "remove" operation; remove value at ptr
22209 const auto operation_remove = [&result](json_pointer & ptr)
22211 // get reference to parent of JSON pointer ptr
22212 const auto last_path = ptr.back();
22214 basic_json& parent = result.at(ptr);
22217 if (parent.is_object())
22219 // perform range check
22220 auto it = parent.find(last_path);
22221 if (JSON_HEDLEY_LIKELY(it != parent.end()))
22227 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
22230 else if (parent.is_array())
22232 // note erase performs range check
22233 parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
22237 // type check: top level value must be an array
22238 if (JSON_HEDLEY_UNLIKELY(not json_patch.is_array()))
22240 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
22243 // iterate and apply the operations
22244 for (const auto& val : json_patch)
22246 // wrapper to get a value for an operation
22247 const auto get_value = [&val](const std::string & op,
22248 const std::string & member,
22249 bool string_type) -> basic_json &
22252 auto it = val.m_value.object->find(member);
22254 // context-sensitive error message
22255 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
22257 // check if desired value is present
22258 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
22260 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
22263 // check if result is of type string
22264 if (JSON_HEDLEY_UNLIKELY(string_type and not it->second.is_string()))
22266 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
22269 // no error: return value
22273 // type check: every element of the array must be an object
22274 if (JSON_HEDLEY_UNLIKELY(not val.is_object()))
22276 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
22279 // collect mandatory members
22280 const std::string op = get_value("op", "op", true);
22281 const std::string path = get_value(op, "path", true);
22282 json_pointer ptr(path);
22284 switch (get_op(op))
22286 case patch_operations::add:
22288 operation_add(ptr, get_value("add", "value", false));
22292 case patch_operations::remove:
22294 operation_remove(ptr);
22298 case patch_operations::replace:
22300 // the "path" location must exist - use at()
22301 result.at(ptr) = get_value("replace", "value", false);
22305 case patch_operations::move:
22307 const std::string from_path = get_value("move", "from", true);
22308 json_pointer from_ptr(from_path);
22310 // the "from" location must exist - use at()
22311 basic_json v = result.at(from_ptr);
22313 // The move operation is functionally identical to a
22314 // "remove" operation on the "from" location, followed
22315 // immediately by an "add" operation at the target
22316 // location with the value that was just removed.
22317 operation_remove(from_ptr);
22318 operation_add(ptr, v);
22322 case patch_operations::copy:
22324 const std::string from_path = get_value("copy", "from", true);
22325 const json_pointer from_ptr(from_path);
22327 // the "from" location must exist - use at()
22328 basic_json v = result.at(from_ptr);
22330 // The copy is functionally identical to an "add"
22331 // operation at the target location using the value
22332 // specified in the "from" member.
22333 operation_add(ptr, v);
22337 case patch_operations::test:
22339 bool success = false;
22342 // check if "value" matches the one at "path"
22343 // the "path" location must exist - use at()
22344 success = (result.at(ptr) == get_value("test", "value", false));
22346 JSON_INTERNAL_CATCH (out_of_range&)
22348 // ignore out of range errors: success remains false
22351 // throw an exception if test fails
22352 if (JSON_HEDLEY_UNLIKELY(not success))
22354 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
22362 // op must be "add", "remove", "replace", "move", "copy", or
22364 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
22373 @brief creates a diff as a JSON patch
22375 Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
22376 be changed into the value @a target by calling @ref patch function.
22378 @invariant For two JSON values @a source and @a target, the following code
22379 yields always `true`:
22381 source.patch(diff(source, target)) == target;
22384 @note Currently, only `remove`, `add`, and `replace` operations are
22387 @param[in] source JSON value to compare from
22388 @param[in] target JSON value to compare against
22389 @param[in] path helper value to create JSON pointers
22391 @return a JSON patch to convert the @a source to @a target
22393 @complexity Linear in the lengths of @a source and @a target.
22395 @liveexample{The following code shows how a JSON patch is created as a
22396 diff for two JSON values.,diff}
22398 @sa @ref patch -- apply a JSON patch
22399 @sa @ref merge_patch -- apply a JSON Merge Patch
22401 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
22403 @since version 2.0.0
22405 JSON_HEDLEY_WARN_UNUSED_RESULT
22406 static basic_json diff(const basic_json& source, const basic_json& target,
22407 const std::string& path = "")
22410 basic_json result(value_t::array);
22412 // if the values are the same, return empty patch
22413 if (source == target)
22418 if (source.type() != target.type())
22420 // different types: replace value
22423 {"op", "replace"}, {"path", path}, {"value", target}
22428 switch (source.type())
22430 case value_t::array:
22432 // first pass: traverse common elements
22434 while (i < source.size() and i < target.size())
22436 // recursive call to compare array values at index i
22437 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
22438 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
22442 // i now reached the end of at least one array
22443 // in a second pass, traverse the remaining elements
22445 // remove my remaining elements
22446 const auto end_index = static_cast<difference_type>(result.size());
22447 while (i < source.size())
22449 // add operations in reverse order to avoid invalid
22451 result.insert(result.begin() + end_index, object(
22454 {"path", path + "/" + std::to_string(i)}
22459 // add other remaining elements
22460 while (i < target.size())
22465 {"path", path + "/" + std::to_string(i)},
22466 {"value", target[i]}
22474 case value_t::object:
22476 // first pass: traverse this object's elements
22477 for (auto it = source.cbegin(); it != source.cend(); ++it)
22479 // escape the key name to be used in a JSON patch
22480 const auto key = json_pointer::escape(it.key());
22482 if (target.find(it.key()) != target.end())
22484 // recursive call to compare object values at key it
22485 auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
22486 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
22490 // found a key that is not in o -> remove it
22491 result.push_back(object(
22493 {"op", "remove"}, {"path", path + "/" + key}
22498 // second pass: traverse other object's elements
22499 for (auto it = target.cbegin(); it != target.cend(); ++it)
22501 if (source.find(it.key()) == source.end())
22503 // found a key that is not in this -> add it
22504 const auto key = json_pointer::escape(it.key());
22507 {"op", "add"}, {"path", path + "/" + key},
22508 {"value", it.value()}
22518 // both primitive type: replace value
22521 {"op", "replace"}, {"path", path}, {"value", target}
22532 ////////////////////////////////
22533 // JSON Merge Patch functions //
22534 ////////////////////////////////
22536 /// @name JSON Merge Patch functions
22540 @brief applies a JSON Merge Patch
22542 The merge patch format is primarily intended for use with the HTTP PATCH
22543 method as a means of describing a set of modifications to a target
22544 resource's content. This function applies a merge patch to the current
22547 The function implements the following algorithm from Section 2 of
22548 [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
22551 define MergePatch(Target, Patch):
22552 if Patch is an Object:
22553 if Target is not an Object:
22554 Target = {} // Ignore the contents and set it to an empty Object
22555 for each Name/Value pair in Patch:
22557 if Name exists in Target:
22558 remove the Name/Value pair from Target
22560 Target[Name] = MergePatch(Target[Name], Value)
22566 Thereby, `Target` is the current object; that is, the patch is applied to
22569 @param[in] apply_patch the patch to apply
22571 @complexity Linear in the lengths of @a patch.
22573 @liveexample{The following code shows how a JSON Merge Patch is applied to
22574 a JSON document.,merge_patch}
22576 @sa @ref patch -- apply a JSON patch
22577 @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
22579 @since version 3.0.0
22581 void merge_patch(const basic_json& apply_patch)
22583 if (apply_patch.is_object())
22585 if (not is_object())
22589 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
22591 if (it.value().is_null())
22597 operator[](it.key()).merge_patch(it.value());
22603 *this = apply_patch;
22611 @brief user-defined to_string function for JSON values
22613 This function implements a user-defined to_string for JSON objects.
22615 @param[in] j a JSON object
22616 @return a std::string object
22619 NLOHMANN_BASIC_JSON_TPL_DECLARATION
22620 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
22624 } // namespace nlohmann
22626 ///////////////////////
22627 // nonmember support //
22628 ///////////////////////
22630 // specialization of std::swap, and std::hash
22634 /// hash value for JSON objects
22636 struct hash<nlohmann::json>
22639 @brief return a hash value for a JSON object
22641 @since version 1.0.0
22643 std::size_t operator()(const nlohmann::json& j) const
22645 // a naive hashing via the string representation
22646 const auto& h = hash<nlohmann::json::string_t>();
22647 return h(j.dump());
22651 /// specialization for std::less<value_t>
22652 /// @note: do not remove the space after '<',
22653 /// see https://github.com/nlohmann/json/pull/679
22655 struct less<::nlohmann::detail::value_t>
22658 @brief compare two value_t enum values
22659 @since version 3.0.0
22661 bool operator()(nlohmann::detail::value_t lhs,
22662 nlohmann::detail::value_t rhs) const noexcept
22664 return nlohmann::detail::operator<(lhs, rhs);
22669 @brief exchanges the values of two JSON objects
22671 @since version 1.0.0
22674 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
22675 is_nothrow_move_constructible<nlohmann::json>::value and
22676 is_nothrow_move_assignable<nlohmann::json>::value
22685 @brief user-defined string literal for JSON values
22687 This operator implements a user-defined string literal for JSON objects. It
22688 can be used by adding `"_json"` to a string literal and returns a JSON object
22689 if no parse error occurred.
22691 @param[in] s a string representation of a JSON object
22692 @param[in] n the length of string @a s
22693 @return a JSON object
22695 @since version 1.0.0
22697 JSON_HEDLEY_NON_NULL(1)
22698 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
22700 return nlohmann::json::parse(s, s + n);
22704 @brief user-defined string literal for JSON pointer
22706 This operator implements a user-defined string literal for JSON Pointers. It
22707 can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
22708 object if no parse error occurred.
22710 @param[in] s a string representation of a JSON Pointer
22711 @param[in] n the length of string @a s
22712 @return a JSON pointer object
22714 @since version 2.0.0
22716 JSON_HEDLEY_NON_NULL(1)
22717 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
22719 return nlohmann::json::json_pointer(std::string(s, n));
22722 // #include <nlohmann/detail/macro_unscope.hpp>
22725 // restore GCC/clang diagnostic settings
22726 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
22727 #pragma GCC diagnostic pop
22729 #if defined(__clang__)
22730 #pragma GCC diagnostic pop
22734 #undef JSON_INTERNAL_CATCH
22738 #undef JSON_HAS_CPP_14
22739 #undef JSON_HAS_CPP_17
22740 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
22741 #undef NLOHMANN_BASIC_JSON_TPL
22743 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
22744 #undef JSON_HEDLEY_ALWAYS_INLINE
22745 #undef JSON_HEDLEY_ARM_VERSION
22746 #undef JSON_HEDLEY_ARM_VERSION_CHECK
22747 #undef JSON_HEDLEY_ARRAY_PARAM
22748 #undef JSON_HEDLEY_ASSUME
22749 #undef JSON_HEDLEY_BEGIN_C_DECLS
22750 #undef JSON_HEDLEY_C_DECL
22751 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
22752 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
22753 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
22754 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
22755 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
22756 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
22757 #undef JSON_HEDLEY_CLANG_HAS_WARNING
22758 #undef JSON_HEDLEY_COMPCERT_VERSION
22759 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
22760 #undef JSON_HEDLEY_CONCAT
22761 #undef JSON_HEDLEY_CONCAT_EX
22762 #undef JSON_HEDLEY_CONST
22763 #undef JSON_HEDLEY_CONST_CAST
22764 #undef JSON_HEDLEY_CONSTEXPR
22765 #undef JSON_HEDLEY_CPP_CAST
22766 #undef JSON_HEDLEY_CRAY_VERSION
22767 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
22768 #undef JSON_HEDLEY_DEPRECATED
22769 #undef JSON_HEDLEY_DEPRECATED_FOR
22770 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
22771 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
22772 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
22773 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
22774 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
22775 #undef JSON_HEDLEY_DIAGNOSTIC_POP
22776 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
22777 #undef JSON_HEDLEY_DMC_VERSION
22778 #undef JSON_HEDLEY_DMC_VERSION_CHECK
22779 #undef JSON_HEDLEY_EMPTY_BASES
22780 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
22781 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
22782 #undef JSON_HEDLEY_END_C_DECLS
22783 #undef JSON_HEDLEY_FALL_THROUGH
22784 #undef JSON_HEDLEY_FLAGS
22785 #undef JSON_HEDLEY_FLAGS_CAST
22786 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
22787 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
22788 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
22789 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
22790 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
22791 #undef JSON_HEDLEY_GCC_HAS_FEATURE
22792 #undef JSON_HEDLEY_GCC_HAS_WARNING
22793 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
22794 #undef JSON_HEDLEY_GCC_VERSION
22795 #undef JSON_HEDLEY_GCC_VERSION_CHECK
22796 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
22797 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
22798 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
22799 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
22800 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
22801 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
22802 #undef JSON_HEDLEY_GNUC_HAS_WARNING
22803 #undef JSON_HEDLEY_GNUC_VERSION
22804 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
22805 #undef JSON_HEDLEY_HAS_ATTRIBUTE
22806 #undef JSON_HEDLEY_HAS_BUILTIN
22807 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
22808 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
22809 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
22810 #undef JSON_HEDLEY_HAS_EXTENSION
22811 #undef JSON_HEDLEY_HAS_FEATURE
22812 #undef JSON_HEDLEY_HAS_WARNING
22813 #undef JSON_HEDLEY_IAR_VERSION
22814 #undef JSON_HEDLEY_IAR_VERSION_CHECK
22815 #undef JSON_HEDLEY_IBM_VERSION
22816 #undef JSON_HEDLEY_IBM_VERSION_CHECK
22817 #undef JSON_HEDLEY_IMPORT
22818 #undef JSON_HEDLEY_INLINE
22819 #undef JSON_HEDLEY_INTEL_VERSION
22820 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
22821 #undef JSON_HEDLEY_IS_CONSTANT
22822 #undef JSON_HEDLEY_IS_CONSTEXPR_
22823 #undef JSON_HEDLEY_LIKELY
22824 #undef JSON_HEDLEY_MALLOC
22825 #undef JSON_HEDLEY_MESSAGE
22826 #undef JSON_HEDLEY_MSVC_VERSION
22827 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
22828 #undef JSON_HEDLEY_NEVER_INLINE
22829 #undef JSON_HEDLEY_NO_ESCAPE
22830 #undef JSON_HEDLEY_NON_NULL
22831 #undef JSON_HEDLEY_NO_RETURN
22832 #undef JSON_HEDLEY_NO_THROW
22833 #undef JSON_HEDLEY_NULL
22834 #undef JSON_HEDLEY_PELLES_VERSION
22835 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
22836 #undef JSON_HEDLEY_PGI_VERSION
22837 #undef JSON_HEDLEY_PGI_VERSION_CHECK
22838 #undef JSON_HEDLEY_PREDICT
22839 #undef JSON_HEDLEY_PRINTF_FORMAT
22840 #undef JSON_HEDLEY_PRIVATE
22841 #undef JSON_HEDLEY_PUBLIC
22842 #undef JSON_HEDLEY_PURE
22843 #undef JSON_HEDLEY_REINTERPRET_CAST
22844 #undef JSON_HEDLEY_REQUIRE
22845 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
22846 #undef JSON_HEDLEY_REQUIRE_MSG
22847 #undef JSON_HEDLEY_RESTRICT
22848 #undef JSON_HEDLEY_RETURNS_NON_NULL
22849 #undef JSON_HEDLEY_SENTINEL
22850 #undef JSON_HEDLEY_STATIC_ASSERT
22851 #undef JSON_HEDLEY_STATIC_CAST
22852 #undef JSON_HEDLEY_STRINGIFY
22853 #undef JSON_HEDLEY_STRINGIFY_EX
22854 #undef JSON_HEDLEY_SUNPRO_VERSION
22855 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
22856 #undef JSON_HEDLEY_TINYC_VERSION
22857 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
22858 #undef JSON_HEDLEY_TI_VERSION
22859 #undef JSON_HEDLEY_TI_VERSION_CHECK
22860 #undef JSON_HEDLEY_UNAVAILABLE
22861 #undef JSON_HEDLEY_UNLIKELY
22862 #undef JSON_HEDLEY_UNPREDICTABLE
22863 #undef JSON_HEDLEY_UNREACHABLE
22864 #undef JSON_HEDLEY_UNREACHABLE_RETURN
22865 #undef JSON_HEDLEY_VERSION
22866 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
22867 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
22868 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
22869 #undef JSON_HEDLEY_VERSION_ENCODE
22870 #undef JSON_HEDLEY_WARNING
22871 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
22875 #endif // INCLUDE_NLOHMANN_JSON_HPP_