comparison common/json.h @ 0:a4671277546c tip

created the repository for the thymian project
author ferencd
date Tue, 17 Aug 2021 11:19:54 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:a4671277546c
1 /*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.7.0
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
6
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
17
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29
30 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
31 #define INCLUDE_NLOHMANN_JSON_HPP_
32
33 #define NLOHMANN_JSON_VERSION_MAJOR 3
34 #define NLOHMANN_JSON_VERSION_MINOR 7
35 #define NLOHMANN_JSON_VERSION_PATCH 0
36
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
50
51 // #include <nlohmann/adl_serializer.hpp>
52
53
54 #include <utility>
55
56 // #include <nlohmann/detail/conversions/from_json.hpp>
57
58
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
64 #include <map> // map
65 #include <string> // string
66 #include <tuple> // tuple, make_tuple
67 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
68 #include <unordered_map> // unordered_map
69 #include <utility> // pair, declval
70 #include <valarray> // valarray
71
72 // #include <nlohmann/detail/exceptions.hpp>
73
74
75 #include <exception> // exception
76 #include <stdexcept> // runtime_error
77 #include <string> // to_string
78
79 // #include <nlohmann/detail/input/position_t.hpp>
80
81
82 #include <cstddef> // size_t
83
84 namespace nlohmann
85 {
86 namespace detail
87 {
88 /// struct to capture the start position of the current token
89 struct position_t
90 {
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;
97
98 /// conversion to size_t to preserve SAX interface
99 constexpr operator size_t() const
100 {
101 return chars_read_total;
102 }
103 };
104
105 } // namespace detail
106 } // namespace nlohmann
107
108 // #include <nlohmann/detail/macro_scope.hpp>
109
110
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>
115 *
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
119 * any warranty.
120 *
121 * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
122 * SPDX-License-Identifier: CC0-1.0
123 */
124
125 #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 9)
126 #if defined(JSON_HEDLEY_VERSION)
127 #undef JSON_HEDLEY_VERSION
128 #endif
129 #define JSON_HEDLEY_VERSION 9
130
131 #if defined(JSON_HEDLEY_STRINGIFY_EX)
132 #undef JSON_HEDLEY_STRINGIFY_EX
133 #endif
134 #define JSON_HEDLEY_STRINGIFY_EX(x) #x
135
136 #if defined(JSON_HEDLEY_STRINGIFY)
137 #undef JSON_HEDLEY_STRINGIFY
138 #endif
139 #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
140
141 #if defined(JSON_HEDLEY_CONCAT_EX)
142 #undef JSON_HEDLEY_CONCAT_EX
143 #endif
144 #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
145
146 #if defined(JSON_HEDLEY_CONCAT)
147 #undef JSON_HEDLEY_CONCAT
148 #endif
149 #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
150
151 #if defined(JSON_HEDLEY_VERSION_ENCODE)
152 #undef JSON_HEDLEY_VERSION_ENCODE
153 #endif
154 #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
155
156 #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
157 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
158 #endif
159 #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
160
161 #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
162 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
163 #endif
164 #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
165
166 #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
167 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
168 #endif
169 #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
170
171 #if defined(JSON_HEDLEY_GNUC_VERSION)
172 #undef JSON_HEDLEY_GNUC_VERSION
173 #endif
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)
178 #endif
179
180 #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
181 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
182 #endif
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))
185 #else
186 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
187 #endif
188
189 #if defined(JSON_HEDLEY_MSVC_VERSION)
190 #undef JSON_HEDLEY_MSVC_VERSION
191 #endif
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)
198 #endif
199
200 #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
201 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
202 #endif
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)))
209 #else
210 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
211 #endif
212
213 #if defined(JSON_HEDLEY_INTEL_VERSION)
214 #undef JSON_HEDLEY_INTEL_VERSION
215 #endif
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)
220 #endif
221
222 #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
223 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
224 #endif
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))
227 #else
228 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
229 #endif
230
231 #if defined(JSON_HEDLEY_PGI_VERSION)
232 #undef JSON_HEDLEY_PGI_VERSION
233 #endif
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__)
236 #endif
237
238 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
239 #undef JSON_HEDLEY_PGI_VERSION_CHECK
240 #endif
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))
243 #else
244 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
245 #endif
246
247 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
248 #undef JSON_HEDLEY_SUNPRO_VERSION
249 #endif
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)
258 #endif
259
260 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
261 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
262 #endif
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))
265 #else
266 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
267 #endif
268
269 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
270 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
271 #endif
272 #if defined(__EMSCRIPTEN__)
273 #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
274 #endif
275
276 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
277 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
278 #endif
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))
281 #else
282 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
283 #endif
284
285 #if defined(JSON_HEDLEY_ARM_VERSION)
286 #undef JSON_HEDLEY_ARM_VERSION
287 #endif
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)
292 #endif
293
294 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
295 #undef JSON_HEDLEY_ARM_VERSION_CHECK
296 #endif
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))
299 #else
300 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
301 #endif
302
303 #if defined(JSON_HEDLEY_IBM_VERSION)
304 #undef JSON_HEDLEY_IBM_VERSION
305 #endif
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)
312 #endif
313
314 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
315 #undef JSON_HEDLEY_IBM_VERSION_CHECK
316 #endif
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))
319 #else
320 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
321 #endif
322
323 #if defined(JSON_HEDLEY_TI_VERSION)
324 #undef JSON_HEDLEY_TI_VERSION
325 #endif
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))
328 #endif
329
330 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
331 #undef JSON_HEDLEY_TI_VERSION_CHECK
332 #endif
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))
335 #else
336 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
337 #endif
338
339 #if defined(JSON_HEDLEY_CRAY_VERSION)
340 #undef JSON_HEDLEY_CRAY_VERSION
341 #endif
342 #if defined(_CRAYC)
343 #if defined(_RELEASE_PATCHLEVEL)
344 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
345 #else
346 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
347 #endif
348 #endif
349
350 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
351 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
352 #endif
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))
355 #else
356 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
357 #endif
358
359 #if defined(JSON_HEDLEY_IAR_VERSION)
360 #undef JSON_HEDLEY_IAR_VERSION
361 #endif
362 #if defined(__IAR_SYSTEMS_ICC__)
363 #if __VER__ > 1000
364 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
365 #else
366 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(VER / 100, __VER__ % 100, 0)
367 #endif
368 #endif
369
370 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
371 #undef JSON_HEDLEY_IAR_VERSION_CHECK
372 #endif
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))
375 #else
376 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
377 #endif
378
379 #if defined(JSON_HEDLEY_TINYC_VERSION)
380 #undef JSON_HEDLEY_TINYC_VERSION
381 #endif
382 #if defined(__TINYC__)
383 #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
384 #endif
385
386 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
387 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
388 #endif
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))
391 #else
392 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
393 #endif
394
395 #if defined(JSON_HEDLEY_DMC_VERSION)
396 #undef JSON_HEDLEY_DMC_VERSION
397 #endif
398 #if defined(__DMC__)
399 #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
400 #endif
401
402 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
403 #undef JSON_HEDLEY_DMC_VERSION_CHECK
404 #endif
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))
407 #else
408 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
409 #endif
410
411 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
412 #undef JSON_HEDLEY_COMPCERT_VERSION
413 #endif
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)
416 #endif
417
418 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
419 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
420 #endif
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))
423 #else
424 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
425 #endif
426
427 #if defined(JSON_HEDLEY_PELLES_VERSION)
428 #undef JSON_HEDLEY_PELLES_VERSION
429 #endif
430 #if defined(__POCC__)
431 #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
432 #endif
433
434 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
435 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
436 #endif
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))
439 #else
440 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
441 #endif
442
443 #if defined(JSON_HEDLEY_GCC_VERSION)
444 #undef JSON_HEDLEY_GCC_VERSION
445 #endif
446 #if \
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
455 #endif
456
457 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
458 #undef JSON_HEDLEY_GCC_VERSION_CHECK
459 #endif
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))
462 #else
463 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
464 #endif
465
466 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
467 #undef JSON_HEDLEY_HAS_ATTRIBUTE
468 #endif
469 #if defined(__has_attribute)
470 #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
471 #else
472 #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
473 #endif
474
475 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
476 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
477 #endif
478 #if defined(__has_attribute)
479 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
480 #else
481 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
482 #endif
483
484 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
485 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
486 #endif
487 #if defined(__has_attribute)
488 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
489 #else
490 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
491 #endif
492
493 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
494 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
495 #endif
496 #if defined(__has_cpp_attribute) && defined(__cplusplus)
497 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
498 #else
499 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
500 #endif
501
502 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
503 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
504 #endif
505 #if defined(__has_cpp_attribute) && defined(__cplusplus)
506 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
507 #else
508 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
509 #endif
510
511 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
512 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
513 #endif
514 #if defined(__has_cpp_attribute) && defined(__cplusplus)
515 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
516 #else
517 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
518 #endif
519
520 #if defined(JSON_HEDLEY_HAS_BUILTIN)
521 #undef JSON_HEDLEY_HAS_BUILTIN
522 #endif
523 #if defined(__has_builtin)
524 #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
525 #else
526 #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
527 #endif
528
529 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
530 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
531 #endif
532 #if defined(__has_builtin)
533 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
534 #else
535 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
536 #endif
537
538 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
539 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
540 #endif
541 #if defined(__has_builtin)
542 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
543 #else
544 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
545 #endif
546
547 #if defined(JSON_HEDLEY_HAS_FEATURE)
548 #undef JSON_HEDLEY_HAS_FEATURE
549 #endif
550 #if defined(__has_feature)
551 #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
552 #else
553 #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
554 #endif
555
556 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
557 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
558 #endif
559 #if defined(__has_feature)
560 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
561 #else
562 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
563 #endif
564
565 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
566 #undef JSON_HEDLEY_GCC_HAS_FEATURE
567 #endif
568 #if defined(__has_feature)
569 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
570 #else
571 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
572 #endif
573
574 #if defined(JSON_HEDLEY_HAS_EXTENSION)
575 #undef JSON_HEDLEY_HAS_EXTENSION
576 #endif
577 #if defined(__has_extension)
578 #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
579 #else
580 #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
581 #endif
582
583 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
584 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
585 #endif
586 #if defined(__has_extension)
587 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
588 #else
589 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
590 #endif
591
592 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
593 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
594 #endif
595 #if defined(__has_extension)
596 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
597 #else
598 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
599 #endif
600
601 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
602 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
603 #endif
604 #if defined(__has_declspec_attribute)
605 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
606 #else
607 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
608 #endif
609
610 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
611 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
612 #endif
613 #if defined(__has_declspec_attribute)
614 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
615 #else
616 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
617 #endif
618
619 #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
620 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
621 #endif
622 #if defined(__has_declspec_attribute)
623 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
624 #else
625 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
626 #endif
627
628 #if defined(JSON_HEDLEY_HAS_WARNING)
629 #undef JSON_HEDLEY_HAS_WARNING
630 #endif
631 #if defined(__has_warning)
632 #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
633 #else
634 #define JSON_HEDLEY_HAS_WARNING(warning) (0)
635 #endif
636
637 #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
638 #undef JSON_HEDLEY_GNUC_HAS_WARNING
639 #endif
640 #if defined(__has_warning)
641 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
642 #else
643 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
644 #endif
645
646 #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
647 #undef JSON_HEDLEY_GCC_HAS_WARNING
648 #endif
649 #if defined(__has_warning)
650 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
651 #else
652 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
653 #endif
654
655 #if \
656 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
657 defined(__clang__) || \
658 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
659 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
660 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
661 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
662 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
663 JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) || \
664 JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
665 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
666 JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
667 (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
668 #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
669 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
670 #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
671 #else
672 #define JSON_HEDLEY_PRAGMA(value)
673 #endif
674
675 #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
676 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
677 #endif
678 #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
679 #undef JSON_HEDLEY_DIAGNOSTIC_POP
680 #endif
681 #if defined(__clang__)
682 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
683 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
684 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
685 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
686 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
687 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
688 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
689 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
690 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
691 #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
692 #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
693 #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
694 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
695 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
696 #elif JSON_HEDLEY_TI_VERSION_CHECK(8,1,0)
697 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
698 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
699 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
700 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
701 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
702 #else
703 #define JSON_HEDLEY_DIAGNOSTIC_PUSH
704 #define JSON_HEDLEY_DIAGNOSTIC_POP
705 #endif
706
707 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
708 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
709 #endif
710 #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
711 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
712 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
713 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
714 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
715 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
716 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
717 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
718 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
719 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
720 #elif JSON_HEDLEY_TI_VERSION_CHECK(8,0,0)
721 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
722 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
723 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
724 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
725 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
726 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
727 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
728 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
729 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
730 #else
731 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
732 #endif
733
734 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
735 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
736 #endif
737 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
738 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
739 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
740 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
741 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
742 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
743 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
744 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
745 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
746 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
747 #elif JSON_HEDLEY_TI_VERSION_CHECK(8,0,0)
748 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
749 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
750 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
751 #else
752 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
753 #endif
754
755 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
756 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
757 #endif
758 #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
759 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
760 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
761 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
762 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
763 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
764 #else
765 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
766 #endif
767
768 #if defined(JSON_HEDLEY_DEPRECATED)
769 #undef JSON_HEDLEY_DEPRECATED
770 #endif
771 #if defined(JSON_HEDLEY_DEPRECATED_FOR)
772 #undef JSON_HEDLEY_DEPRECATED_FOR
773 #endif
774 #if defined(__cplusplus) && (__cplusplus >= 201402L)
775 #define JSON_HEDLEY_DEPRECATED(since) [[deprecated("Since " #since)]]
776 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) [[deprecated("Since " #since "; use " #replacement)]]
777 #elif \
778 JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) || \
779 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
780 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
781 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
782 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
783 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
784 JSON_HEDLEY_TI_VERSION_CHECK(8,3,0)
785 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
786 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
787 #elif \
788 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
789 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
790 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
791 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
792 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
793 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
794 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
795 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0)
796 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
797 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
798 #elif \
799 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
800 JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0)
801 #define JSON_HEDLEY_DEPRECATED(since) _declspec(deprecated)
802 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
803 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
804 #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
805 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
806 #else
807 #define JSON_HEDLEY_DEPRECATED(since)
808 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
809 #endif
810
811 #if defined(JSON_HEDLEY_UNAVAILABLE)
812 #undef JSON_HEDLEY_UNAVAILABLE
813 #endif
814 #if \
815 JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
816 JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
817 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
818 #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
819 #else
820 #define JSON_HEDLEY_UNAVAILABLE(available_since)
821 #endif
822
823 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
824 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
825 #endif
826 #if defined(__cplusplus) && (__cplusplus >= 201703L)
827 #define JSON_HEDLEY_WARN_UNUSED_RESULT [[nodiscard]]
828 #elif \
829 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
830 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
831 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
832 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
833 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
834 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
835 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
836 #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
837 #elif defined(_Check_return_) /* SAL */
838 #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
839 #else
840 #define JSON_HEDLEY_WARN_UNUSED_RESULT
841 #endif
842
843 #if defined(JSON_HEDLEY_SENTINEL)
844 #undef JSON_HEDLEY_SENTINEL
845 #endif
846 #if \
847 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
848 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
849 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
850 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0)
851 #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
852 #else
853 #define JSON_HEDLEY_SENTINEL(position)
854 #endif
855
856 #if defined(JSON_HEDLEY_NO_RETURN)
857 #undef JSON_HEDLEY_NO_RETURN
858 #endif
859 #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
860 #define JSON_HEDLEY_NO_RETURN __noreturn
861 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
862 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
863 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
864 #define JSON_HEDLEY_NO_RETURN _Noreturn
865 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
866 #define JSON_HEDLEY_NO_RETURN [[noreturn]]
867 #elif \
868 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
869 JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
870 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
871 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
872 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
873 JSON_HEDLEY_TI_VERSION_CHECK(18,0,0) || \
874 (JSON_HEDLEY_TI_VERSION_CHECK(17,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
875 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
876 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
877 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
878 #elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus)
879 #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
880 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
881 #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
882 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
883 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
884 #else
885 #define JSON_HEDLEY_NO_RETURN
886 #endif
887
888 #if defined(JSON_HEDLEY_UNREACHABLE)
889 #undef JSON_HEDLEY_UNREACHABLE
890 #endif
891 #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
892 #undef JSON_HEDLEY_UNREACHABLE_RETURN
893 #endif
894 #if \
895 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
896 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
897 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
898 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5)
899 #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
900 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
901 #define JSON_HEDLEY_UNREACHABLE() __assume(0)
902 #elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0)
903 #if defined(__cplusplus)
904 #define JSON_HEDLEY_UNREACHABLE() std::_nassert(0)
905 #else
906 #define JSON_HEDLEY_UNREACHABLE() _nassert(0)
907 #endif
908 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return value
909 #elif defined(EXIT_FAILURE)
910 #define JSON_HEDLEY_UNREACHABLE() abort()
911 #else
912 #define JSON_HEDLEY_UNREACHABLE()
913 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return value
914 #endif
915 #if !defined(JSON_HEDLEY_UNREACHABLE_RETURN)
916 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
917 #endif
918
919 #if defined(JSON_HEDLEY_ASSUME)
920 #undef JSON_HEDLEY_ASSUME
921 #endif
922 #if \
923 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
924 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
925 #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
926 #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
927 #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
928 #elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0)
929 #if defined(__cplusplus)
930 #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
931 #else
932 #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
933 #endif
934 #elif \
935 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && !defined(JSON_HEDLEY_ARM_VERSION)) || \
936 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
937 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
938 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5)
939 #define JSON_HEDLEY_ASSUME(expr) ((void) ((expr) ? 1 : (__builtin_unreachable(), 1)))
940 #else
941 #define JSON_HEDLEY_ASSUME(expr) ((void) (expr))
942 #endif
943
944
945 JSON_HEDLEY_DIAGNOSTIC_PUSH
946 #if \
947 JSON_HEDLEY_HAS_WARNING("-Wvariadic-macros") || \
948 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0)
949 #if defined(__clang__)
950 #pragma clang diagnostic ignored "-Wvariadic-macros"
951 #elif defined(JSON_HEDLEY_GCC_VERSION)
952 #pragma GCC diagnostic ignored "-Wvariadic-macros"
953 #endif
954 #endif
955 #if defined(JSON_HEDLEY_NON_NULL)
956 #undef JSON_HEDLEY_NON_NULL
957 #endif
958 #if \
959 JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
960 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
961 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
962 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
963 #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
964 #else
965 #define JSON_HEDLEY_NON_NULL(...)
966 #endif
967 JSON_HEDLEY_DIAGNOSTIC_POP
968
969 #if defined(JSON_HEDLEY_PRINTF_FORMAT)
970 #undef JSON_HEDLEY_PRINTF_FORMAT
971 #endif
972 #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
973 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
974 #elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
975 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
976 #elif \
977 JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
978 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
979 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
980 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
981 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
982 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
983 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
984 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
985 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
986 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
987 #else
988 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
989 #endif
990
991 #if defined(JSON_HEDLEY_CONSTEXPR)
992 #undef JSON_HEDLEY_CONSTEXPR
993 #endif
994 #if defined(__cplusplus)
995 #if __cplusplus >= 201103L
996 #define JSON_HEDLEY_CONSTEXPR constexpr
997 #endif
998 #endif
999 #if !defined(JSON_HEDLEY_CONSTEXPR)
1000 #define JSON_HEDLEY_CONSTEXPR
1001 #endif
1002
1003 #if defined(JSON_HEDLEY_PREDICT)
1004 #undef JSON_HEDLEY_PREDICT
1005 #endif
1006 #if defined(JSON_HEDLEY_LIKELY)
1007 #undef JSON_HEDLEY_LIKELY
1008 #endif
1009 #if defined(JSON_HEDLEY_UNLIKELY)
1010 #undef JSON_HEDLEY_UNLIKELY
1011 #endif
1012 #if defined(JSON_HEDLEY_UNPREDICTABLE)
1013 #undef JSON_HEDLEY_UNPREDICTABLE
1014 #endif
1015 #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1016 #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable(!!(expr))
1017 #endif
1018 #if \
1019 JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) || \
1020 JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0)
1021 # define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability(expr, value, probability)
1022 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1, probability)
1023 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0, probability)
1024 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1025 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1026 #if !defined(JSON_HEDLEY_BUILTIN_UNPREDICTABLE)
1027 #define JSON_HEDLEY_BUILTIN_UNPREDICTABLE(expr) __builtin_expect_with_probability(!!(expr), 1, 0.5)
1028 #endif
1029 #elif \
1030 JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) || \
1031 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1032 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1033 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1034 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1035 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1036 JSON_HEDLEY_TI_VERSION_CHECK(6,1,0) || \
1037 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27)
1038 # define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1039 (((probability) >= 0.9) ? __builtin_expect(!!(expr), (expected)) : (((void) (expected)), !!(expr)))
1040 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1041 (__extension__ ({ \
1042 JSON_HEDLEY_CONSTEXPR double hedley_probability_ = (probability); \
1043 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1044 }))
1045 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1046 (__extension__ ({ \
1047 JSON_HEDLEY_CONSTEXPR double hedley_probability_ = (probability); \
1048 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1049 }))
1050 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1051 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1052 #else
1053 # define JSON_HEDLEY_PREDICT(expr, expected, probability) (((void) (expected)), !!(expr))
1054 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1055 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1056 # define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1057 # define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1058 #endif
1059 #if !defined(JSON_HEDLEY_UNPREDICTABLE)
1060 #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1061 #endif
1062
1063 #if defined(JSON_HEDLEY_MALLOC)
1064 #undef JSON_HEDLEY_MALLOC
1065 #endif
1066 #if \
1067 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1068 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1069 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1070 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1071 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1072 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1073 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
1074 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
1075 #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1076 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(14, 0, 0)
1077 #define JSON_HEDLEY_MALLOC __declspec(restrict)
1078 #else
1079 #define JSON_HEDLEY_MALLOC
1080 #endif
1081
1082 #if defined(JSON_HEDLEY_PURE)
1083 #undef JSON_HEDLEY_PURE
1084 #endif
1085 #if \
1086 JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1087 JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1088 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1089 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1090 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1091 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1092 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
1093 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1094 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1095 #define JSON_HEDLEY_PURE __attribute__((__pure__))
1096 #elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1097 #define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1098 #else
1099 #define JSON_HEDLEY_PURE
1100 #endif
1101
1102 #if defined(JSON_HEDLEY_CONST)
1103 #undef JSON_HEDLEY_CONST
1104 #endif
1105 #if \
1106 JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1107 JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1108 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1109 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1110 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1111 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1112 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
1113 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1114 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1115 #define JSON_HEDLEY_CONST __attribute__((__const__))
1116 #else
1117 #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1118 #endif
1119
1120 #if defined(JSON_HEDLEY_RESTRICT)
1121 #undef JSON_HEDLEY_RESTRICT
1122 #endif
1123 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1124 #define JSON_HEDLEY_RESTRICT restrict
1125 #elif \
1126 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1127 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1128 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1129 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1130 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1131 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1132 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
1133 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1134 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1135 defined(__clang__)
1136 #define JSON_HEDLEY_RESTRICT __restrict
1137 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1138 #define JSON_HEDLEY_RESTRICT _Restrict
1139 #else
1140 #define JSON_HEDLEY_RESTRICT
1141 #endif
1142
1143 #if defined(JSON_HEDLEY_INLINE)
1144 #undef JSON_HEDLEY_INLINE
1145 #endif
1146 #if \
1147 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1148 (defined(__cplusplus) && (__cplusplus >= 199711L))
1149 #define JSON_HEDLEY_INLINE inline
1150 #elif \
1151 defined(JSON_HEDLEY_GCC_VERSION) || \
1152 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1153 #define JSON_HEDLEY_INLINE __inline__
1154 #elif \
1155 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1156 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1157 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0)
1158 #define JSON_HEDLEY_INLINE __inline
1159 #else
1160 #define JSON_HEDLEY_INLINE
1161 #endif
1162
1163 #if defined(JSON_HEDLEY_ALWAYS_INLINE)
1164 #undef JSON_HEDLEY_ALWAYS_INLINE
1165 #endif
1166 #if \
1167 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1168 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1169 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1170 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1171 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1172 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1173 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
1174 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
1175 #define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1176 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0)
1177 #define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1178 #elif JSON_HEDLEY_TI_VERSION_CHECK(7,0,0) && defined(__cplusplus)
1179 #define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1180 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1181 #define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1182 #else
1183 #define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1184 #endif
1185
1186 #if defined(JSON_HEDLEY_NEVER_INLINE)
1187 #undef JSON_HEDLEY_NEVER_INLINE
1188 #endif
1189 #if \
1190 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1191 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1192 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1193 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1194 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1195 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1196 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
1197 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
1198 #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1199 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
1200 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1201 #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1202 #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1203 #elif JSON_HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1204 #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1205 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1206 #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1207 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1208 #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1209 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1210 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1211 #else
1212 #define JSON_HEDLEY_NEVER_INLINE
1213 #endif
1214
1215 #if defined(JSON_HEDLEY_PRIVATE)
1216 #undef JSON_HEDLEY_PRIVATE
1217 #endif
1218 #if defined(JSON_HEDLEY_PUBLIC)
1219 #undef JSON_HEDLEY_PUBLIC
1220 #endif
1221 #if defined(JSON_HEDLEY_IMPORT)
1222 #undef JSON_HEDLEY_IMPORT
1223 #endif
1224 #if defined(_WIN32) || defined(__CYGWIN__)
1225 #define JSON_HEDLEY_PRIVATE
1226 #define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1227 #define JSON_HEDLEY_IMPORT __declspec(dllimport)
1228 #else
1229 #if \
1230 JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1231 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1232 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1233 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1234 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1235 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1236 JSON_HEDLEY_TI_VERSION_CHECK(8,0,0) || \
1237 (JSON_HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_EABI__) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
1238 #define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1239 #define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1240 #else
1241 #define JSON_HEDLEY_PRIVATE
1242 #define JSON_HEDLEY_PUBLIC
1243 #endif
1244 #define JSON_HEDLEY_IMPORT extern
1245 #endif
1246
1247 #if defined(JSON_HEDLEY_NO_THROW)
1248 #undef JSON_HEDLEY_NO_THROW
1249 #endif
1250 #if \
1251 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1252 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1253 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1254 #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1255 #elif \
1256 JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1257 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1258 #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1259 #else
1260 #define JSON_HEDLEY_NO_THROW
1261 #endif
1262
1263 #if defined(JSON_HEDLEY_FALL_THROUGH)
1264 #undef JSON_HEDLEY_FALL_THROUGH
1265 #endif
1266 #if \
1267 defined(__cplusplus) && \
1268 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
1269 !defined(JSON_HEDLEY_PGI_VERSION)
1270 #if \
1271 (__cplusplus >= 201703L) || \
1272 ((__cplusplus >= 201103L) && JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough))
1273 #define JSON_HEDLEY_FALL_THROUGH [[fallthrough]]
1274 #elif (__cplusplus >= 201103L) && JSON_HEDLEY_HAS_CPP_ATTRIBUTE(clang::fallthrough)
1275 #define JSON_HEDLEY_FALL_THROUGH [[clang::fallthrough]]
1276 #elif (__cplusplus >= 201103L) && JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0)
1277 #define JSON_HEDLEY_FALL_THROUGH [[gnu::fallthrough]]
1278 #endif
1279 #endif
1280 #if !defined(JSON_HEDLEY_FALL_THROUGH)
1281 #if JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(fallthrough,7,0,0) && !defined(JSON_HEDLEY_PGI_VERSION)
1282 #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1283 #elif defined(__fallthrough) /* SAL */
1284 #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1285 #else
1286 #define JSON_HEDLEY_FALL_THROUGH
1287 #endif
1288 #endif
1289
1290 #if defined(JSON_HEDLEY_RETURNS_NON_NULL)
1291 #undef JSON_HEDLEY_RETURNS_NON_NULL
1292 #endif
1293 #if \
1294 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1295 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
1296 #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
1297 #elif defined(_Ret_notnull_) /* SAL */
1298 #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
1299 #else
1300 #define JSON_HEDLEY_RETURNS_NON_NULL
1301 #endif
1302
1303 #if defined(JSON_HEDLEY_ARRAY_PARAM)
1304 #undef JSON_HEDLEY_ARRAY_PARAM
1305 #endif
1306 #if \
1307 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1308 !defined(__STDC_NO_VLA__) && \
1309 !defined(__cplusplus) && \
1310 !defined(JSON_HEDLEY_PGI_VERSION) && \
1311 !defined(JSON_HEDLEY_TINYC_VERSION)
1312 #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1313 #else
1314 #define JSON_HEDLEY_ARRAY_PARAM(name)
1315 #endif
1316
1317 #if defined(JSON_HEDLEY_IS_CONSTANT)
1318 #undef JSON_HEDLEY_IS_CONSTANT
1319 #endif
1320 #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1321 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1322 #endif
1323 /* Note the double-underscore. For internal use only; no API
1324 * guarantees! */
1325 #if defined(JSON_HEDLEY__IS_CONSTEXPR)
1326 #undef JSON_HEDLEY__IS_CONSTEXPR
1327 #endif
1328
1329 #if \
1330 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1331 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1332 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1333 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1334 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1335 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1336 JSON_HEDLEY_TI_VERSION_CHECK(6,1,0) || \
1337 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) || \
1338 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
1339 #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1340 #endif
1341 #if !defined(__cplusplus)
1342 # if \
1343 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1344 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1345 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1346 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1347 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1348 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1349 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1350 #if defined(__INTPTR_TYPE__)
1351 #define JSON_HEDLEY__IS_CONSTEXPR(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1352 #else
1353 #include <stdint.h>
1354 #define JSON_HEDLEY__IS_CONSTEXPR(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1355 #endif
1356 # elif \
1357 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && !defined(JSON_HEDLEY_SUNPRO_VERSION) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1358 JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) || \
1359 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1360 JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1361 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1362 JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1363 #if defined(__INTPTR_TYPE__)
1364 #define JSON_HEDLEY__IS_CONSTEXPR(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1365 #else
1366 #include <stdint.h>
1367 #define JSON_HEDLEY__IS_CONSTEXPR(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1368 #endif
1369 # elif \
1370 defined(JSON_HEDLEY_GCC_VERSION) || \
1371 defined(JSON_HEDLEY_INTEL_VERSION) || \
1372 defined(JSON_HEDLEY_TINYC_VERSION) || \
1373 defined(JSON_HEDLEY_TI_VERSION) || \
1374 defined(__clang__)
1375 # define JSON_HEDLEY__IS_CONSTEXPR(expr) ( \
1376 sizeof(void) != \
1377 sizeof(*( \
1378 1 ? \
1379 ((void*) ((expr) * 0L) ) : \
1380 ((struct { char v[sizeof(void) * 2]; } *) 1) \
1381 ) \
1382 ) \
1383 )
1384 # endif
1385 #endif
1386 #if defined(JSON_HEDLEY__IS_CONSTEXPR)
1387 #if !defined(JSON_HEDLEY_IS_CONSTANT)
1388 #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY__IS_CONSTEXPR(expr)
1389 #endif
1390 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY__IS_CONSTEXPR(expr) ? (expr) : (-1))
1391 #else
1392 #if !defined(JSON_HEDLEY_IS_CONSTANT)
1393 #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
1394 #endif
1395 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
1396 #endif
1397
1398 #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
1399 #undef JSON_HEDLEY_BEGIN_C_DECLS
1400 #endif
1401 #if defined(JSON_HEDLEY_END_C_DECLS)
1402 #undef JSON_HEDLEY_END_C_DECLS
1403 #endif
1404 #if defined(JSON_HEDLEY_C_DECL)
1405 #undef JSON_HEDLEY_C_DECL
1406 #endif
1407 #if defined(__cplusplus)
1408 #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
1409 #define JSON_HEDLEY_END_C_DECLS }
1410 #define JSON_HEDLEY_C_DECL extern "C"
1411 #else
1412 #define JSON_HEDLEY_BEGIN_C_DECLS
1413 #define JSON_HEDLEY_END_C_DECLS
1414 #define JSON_HEDLEY_C_DECL
1415 #endif
1416
1417 #if defined(JSON_HEDLEY_STATIC_ASSERT)
1418 #undef JSON_HEDLEY_STATIC_ASSERT
1419 #endif
1420 #if \
1421 !defined(__cplusplus) && ( \
1422 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
1423 JSON_HEDLEY_HAS_FEATURE(c_static_assert) || \
1424 JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
1425 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1426 defined(_Static_assert) \
1427 )
1428 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
1429 #elif \
1430 (defined(__cplusplus) && (__cplusplus >= 201703L)) || \
1431 JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
1432 (defined(__cplusplus) && JSON_HEDLEY_TI_VERSION_CHECK(8,3,0))
1433 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) static_assert(expr, message)
1434 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
1435 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) static_assert(expr)
1436 #else
1437 # define JSON_HEDLEY_STATIC_ASSERT(expr, message)
1438 #endif
1439
1440 #if defined(JSON_HEDLEY_CONST_CAST)
1441 #undef JSON_HEDLEY_CONST_CAST
1442 #endif
1443 #if defined(__cplusplus)
1444 # define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1445 #elif \
1446 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1447 JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1448 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1449 # define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1450 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1451 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1452 ((T) (expr)); \
1453 JSON_HEDLEY_DIAGNOSTIC_POP \
1454 }))
1455 #else
1456 # define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1457 #endif
1458
1459 #if defined(JSON_HEDLEY_REINTERPRET_CAST)
1460 #undef JSON_HEDLEY_REINTERPRET_CAST
1461 #endif
1462 #if defined(__cplusplus)
1463 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1464 #else
1465 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (*((T*) &(expr)))
1466 #endif
1467
1468 #if defined(JSON_HEDLEY_STATIC_CAST)
1469 #undef JSON_HEDLEY_STATIC_CAST
1470 #endif
1471 #if defined(__cplusplus)
1472 #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1473 #else
1474 #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1475 #endif
1476
1477 #if defined(JSON_HEDLEY_CPP_CAST)
1478 #undef JSON_HEDLEY_CPP_CAST
1479 #endif
1480 #if defined(__cplusplus)
1481 #define JSON_HEDLEY_CPP_CAST(T, expr) static_cast<T>(expr)
1482 #else
1483 #define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1484 #endif
1485
1486 #if defined(JSON_HEDLEY_MESSAGE)
1487 #undef JSON_HEDLEY_MESSAGE
1488 #endif
1489 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1490 # define JSON_HEDLEY_MESSAGE(msg) \
1491 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1492 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1493 JSON_HEDLEY_PRAGMA(message msg) \
1494 JSON_HEDLEY_DIAGNOSTIC_POP
1495 #elif \
1496 JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
1497 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1498 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
1499 #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
1500 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
1501 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1502 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1503 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
1504 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1505 #else
1506 # define JSON_HEDLEY_MESSAGE(msg)
1507 #endif
1508
1509 #if defined(JSON_HEDLEY_WARNING)
1510 #undef JSON_HEDLEY_WARNING
1511 #endif
1512 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1513 # define JSON_HEDLEY_WARNING(msg) \
1514 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1515 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1516 JSON_HEDLEY_PRAGMA(clang warning msg) \
1517 JSON_HEDLEY_DIAGNOSTIC_POP
1518 #elif \
1519 JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
1520 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0)
1521 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
1522 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1523 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
1524 #else
1525 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
1526 #endif
1527
1528 #if defined(JSON_HEDLEY_REQUIRE_MSG)
1529 #undef JSON_HEDLEY_REQUIRE_MSG
1530 #endif
1531 #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
1532 # if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
1533 # define JSON_HEDLEY_REQUIRE_MSG(expr, msg) \
1534 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1535 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1536 __attribute__((__diagnose_if__(!(expr), msg, "error"))) \
1537 JSON_HEDLEY_DIAGNOSTIC_POP
1538 # else
1539 # define JSON_HEDLEY_REQUIRE_MSG(expr, msg) __attribute__((__diagnose_if__(!(expr), msg, "error")))
1540 # endif
1541 #else
1542 # define JSON_HEDLEY_REQUIRE_MSG(expr, msg)
1543 #endif
1544
1545 #if defined(JSON_HEDLEY_REQUIRE)
1546 #undef JSON_HEDLEY_REQUIRE
1547 #endif
1548 #define JSON_HEDLEY_REQUIRE(expr) JSON_HEDLEY_REQUIRE_MSG(expr, #expr)
1549
1550 #if defined(JSON_HEDLEY_FLAGS)
1551 #undef JSON_HEDLEY_FLAGS
1552 #endif
1553 #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum)
1554 #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
1555 #endif
1556
1557 #if defined(JSON_HEDLEY_FLAGS_CAST)
1558 #undef JSON_HEDLEY_FLAGS_CAST
1559 #endif
1560 #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
1561 # define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
1562 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1563 _Pragma("warning(disable:188)") \
1564 ((T) (expr)); \
1565 JSON_HEDLEY_DIAGNOSTIC_POP \
1566 }))
1567 #else
1568 # define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
1569 #endif
1570
1571 /* Remaining macros are deprecated. */
1572
1573 #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
1574 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
1575 #endif
1576 #if defined(__clang__)
1577 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
1578 #else
1579 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1580 #endif
1581
1582 #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
1583 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
1584 #endif
1585 #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
1586
1587 #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
1588 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
1589 #endif
1590 #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
1591
1592 #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
1593 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
1594 #endif
1595 #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
1596
1597 #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
1598 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
1599 #endif
1600 #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
1601
1602 #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
1603 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
1604 #endif
1605 #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
1606
1607 #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
1608 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
1609 #endif
1610 #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
1611
1612 #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
1613 #undef JSON_HEDLEY_CLANG_HAS_WARNING
1614 #endif
1615 #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
1616
1617 #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
1618
1619
1620 // This file contains all internal macro definitions
1621 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
1622
1623 // exclude unsupported compilers
1624 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
1625 #if defined(__clang__)
1626 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
1627 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
1628 #endif
1629 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
1630 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
1631 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
1632 #endif
1633 #endif
1634 #endif
1635
1636 // C++ language standard detection
1637 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
1638 #define JSON_HAS_CPP_17
1639 #define JSON_HAS_CPP_14
1640 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
1641 #define JSON_HAS_CPP_14
1642 #endif
1643
1644 // disable float-equal warnings on GCC/clang
1645 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
1646 #pragma GCC diagnostic push
1647 #pragma GCC diagnostic ignored "-Wfloat-equal"
1648 #endif
1649
1650 // disable documentation warnings on clang
1651 #if defined(__clang__)
1652 #pragma GCC diagnostic push
1653 #pragma GCC diagnostic ignored "-Wdocumentation"
1654 #endif
1655
1656 // allow to disable exceptions
1657 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
1658 #define JSON_THROW(exception) throw exception
1659 #define JSON_TRY try
1660 #define JSON_CATCH(exception) catch(exception)
1661 #define JSON_INTERNAL_CATCH(exception) catch(exception)
1662 #else
1663 #include <cstdlib>
1664 #define JSON_THROW(exception) std::abort()
1665 #define JSON_TRY if(true)
1666 #define JSON_CATCH(exception) if(false)
1667 #define JSON_INTERNAL_CATCH(exception) if(false)
1668 #endif
1669
1670 // override exception macros
1671 #if defined(JSON_THROW_USER)
1672 #undef JSON_THROW
1673 #define JSON_THROW JSON_THROW_USER
1674 #endif
1675 #if defined(JSON_TRY_USER)
1676 #undef JSON_TRY
1677 #define JSON_TRY JSON_TRY_USER
1678 #endif
1679 #if defined(JSON_CATCH_USER)
1680 #undef JSON_CATCH
1681 #define JSON_CATCH JSON_CATCH_USER
1682 #undef JSON_INTERNAL_CATCH
1683 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
1684 #endif
1685 #if defined(JSON_INTERNAL_CATCH_USER)
1686 #undef JSON_INTERNAL_CATCH
1687 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
1688 #endif
1689
1690 /*!
1691 @brief macro to briefly define a mapping between an enum and JSON
1692 @def NLOHMANN_JSON_SERIALIZE_ENUM
1693 @since version 3.4.0
1694 */
1695 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
1696 template<typename BasicJsonType> \
1697 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
1698 { \
1699 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
1700 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
1701 auto it = std::find_if(std::begin(m), std::end(m), \
1702 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
1703 { \
1704 return ej_pair.first == e; \
1705 }); \
1706 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
1707 } \
1708 template<typename BasicJsonType> \
1709 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
1710 { \
1711 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
1712 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
1713 auto it = std::find_if(std::begin(m), std::end(m), \
1714 [j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
1715 { \
1716 return ej_pair.second == j; \
1717 }); \
1718 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
1719 }
1720
1721 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
1722 // may be removed in the future once the class is split.
1723
1724 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
1725 template<template<typename, typename, typename...> class ObjectType, \
1726 template<typename, typename...> class ArrayType, \
1727 class StringType, class BooleanType, class NumberIntegerType, \
1728 class NumberUnsignedType, class NumberFloatType, \
1729 template<typename> class AllocatorType, \
1730 template<typename, typename = void> class JSONSerializer>
1731
1732 #define NLOHMANN_BASIC_JSON_TPL \
1733 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
1734 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
1735 AllocatorType, JSONSerializer>
1736
1737
1738 namespace nlohmann
1739 {
1740 namespace detail
1741 {
1742 ////////////////
1743 // exceptions //
1744 ////////////////
1745
1746 /*!
1747 @brief general exception of the @ref basic_json class
1748
1749 This class is an extension of `std::exception` objects with a member @a id for
1750 exception ids. It is used as the base class for all exceptions thrown by the
1751 @ref basic_json class. This class can hence be used as "wildcard" to catch
1752 exceptions.
1753
1754 Subclasses:
1755 - @ref parse_error for exceptions indicating a parse error
1756 - @ref invalid_iterator for exceptions indicating errors with iterators
1757 - @ref type_error for exceptions indicating executing a member function with
1758 a wrong type
1759 - @ref out_of_range for exceptions indicating access out of the defined range
1760 - @ref other_error for exceptions indicating other library errors
1761
1762 @internal
1763 @note To have nothrow-copy-constructible exceptions, we internally use
1764 `std::runtime_error` which can cope with arbitrary-length error messages.
1765 Intermediate strings are built with static functions and then passed to
1766 the actual constructor.
1767 @endinternal
1768
1769 @liveexample{The following code shows how arbitrary library exceptions can be
1770 caught.,exception}
1771
1772 @since version 3.0.0
1773 */
1774 class exception : public std::exception
1775 {
1776 public:
1777 /// returns the explanatory string
1778 JSON_HEDLEY_RETURNS_NON_NULL
1779 const char* what() const noexcept override
1780 {
1781 return m.what();
1782 }
1783
1784 /// the id of the exception
1785 const int id;
1786
1787 protected:
1788 JSON_HEDLEY_NON_NULL(3)
1789 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
1790
1791 static std::string name(const std::string& ename, int id_)
1792 {
1793 return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
1794 }
1795
1796 private:
1797 /// an exception object as storage for error messages
1798 std::runtime_error m;
1799 };
1800
1801 /*!
1802 @brief exception indicating a parse error
1803
1804 This exception is thrown by the library when a parse error occurs. Parse errors
1805 can occur during the deserialization of JSON text, CBOR, MessagePack, as well
1806 as when using JSON Patch.
1807
1808 Member @a byte holds the byte index of the last read character in the input
1809 file.
1810
1811 Exceptions have ids 1xx.
1812
1813 name / id | example message | description
1814 ------------------------------ | --------------- | -------------------------
1815 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.
1816 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.
1817 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.
1818 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.
1819 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.
1820 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`.
1821 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.
1822 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.
1823 json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
1824 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.
1825 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.
1826 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.
1827 json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet).
1828
1829 @note For an input with n bytes, 1 is the index of the first character and n+1
1830 is the index of the terminating null byte or the end of file. This also
1831 holds true when reading a byte vector (CBOR or MessagePack).
1832
1833 @liveexample{The following code shows how a `parse_error` exception can be
1834 caught.,parse_error}
1835
1836 @sa - @ref exception for the base class of the library exceptions
1837 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
1838 @sa - @ref type_error for exceptions indicating executing a member function with
1839 a wrong type
1840 @sa - @ref out_of_range for exceptions indicating access out of the defined range
1841 @sa - @ref other_error for exceptions indicating other library errors
1842
1843 @since version 3.0.0
1844 */
1845 class parse_error : public exception
1846 {
1847 public:
1848 /*!
1849 @brief create a parse error exception
1850 @param[in] id_ the id of the exception
1851 @param[in] pos the position where the error occurred (or with
1852 chars_read_total=0 if the position cannot be
1853 determined)
1854 @param[in] what_arg the explanatory string
1855 @return parse_error object
1856 */
1857 static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
1858 {
1859 std::string w = exception::name("parse_error", id_) + "parse error" +
1860 position_string(pos) + ": " + what_arg;
1861 return parse_error(id_, pos.chars_read_total, w.c_str());
1862 }
1863
1864 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
1865 {
1866 std::string w = exception::name("parse_error", id_) + "parse error" +
1867 (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
1868 ": " + what_arg;
1869 return parse_error(id_, byte_, w.c_str());
1870 }
1871
1872 /*!
1873 @brief byte index of the parse error
1874
1875 The byte index of the last read character in the input file.
1876
1877 @note For an input with n bytes, 1 is the index of the first character and
1878 n+1 is the index of the terminating null byte or the end of file.
1879 This also holds true when reading a byte vector (CBOR or MessagePack).
1880 */
1881 const std::size_t byte;
1882
1883 private:
1884 parse_error(int id_, std::size_t byte_, const char* what_arg)
1885 : exception(id_, what_arg), byte(byte_) {}
1886
1887 static std::string position_string(const position_t& pos)
1888 {
1889 return " at line " + std::to_string(pos.lines_read + 1) +
1890 ", column " + std::to_string(pos.chars_read_current_line);
1891 }
1892 };
1893
1894 /*!
1895 @brief exception indicating errors with iterators
1896
1897 This exception is thrown if iterators passed to a library function do not match
1898 the expected semantics.
1899
1900 Exceptions have ids 2xx.
1901
1902 name / id | example message | description
1903 ----------------------------------- | --------------- | -------------------------
1904 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.
1905 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.
1906 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.
1907 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.
1908 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.
1909 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.
1910 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.
1911 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.
1912 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.
1913 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.
1914 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.
1915 json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
1916 json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
1917 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().
1918
1919 @liveexample{The following code shows how an `invalid_iterator` exception can be
1920 caught.,invalid_iterator}
1921
1922 @sa - @ref exception for the base class of the library exceptions
1923 @sa - @ref parse_error for exceptions indicating a parse error
1924 @sa - @ref type_error for exceptions indicating executing a member function with
1925 a wrong type
1926 @sa - @ref out_of_range for exceptions indicating access out of the defined range
1927 @sa - @ref other_error for exceptions indicating other library errors
1928
1929 @since version 3.0.0
1930 */
1931 class invalid_iterator : public exception
1932 {
1933 public:
1934 static invalid_iterator create(int id_, const std::string& what_arg)
1935 {
1936 std::string w = exception::name("invalid_iterator", id_) + what_arg;
1937 return invalid_iterator(id_, w.c_str());
1938 }
1939
1940 private:
1941 JSON_HEDLEY_NON_NULL(3)
1942 invalid_iterator(int id_, const char* what_arg)
1943 : exception(id_, what_arg) {}
1944 };
1945
1946 /*!
1947 @brief exception indicating executing a member function with a wrong type
1948
1949 This exception is thrown in case of a type error; that is, a library function is
1950 executed on a JSON value whose type does not match the expected semantics.
1951
1952 Exceptions have ids 3xx.
1953
1954 name / id | example message | description
1955 ----------------------------- | --------------- | -------------------------
1956 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.
1957 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.
1958 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 &.
1959 json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
1960 json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
1961 json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
1962 json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
1963 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.
1964 json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
1965 json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
1966 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.
1967 json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
1968 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.
1969 json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
1970 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.
1971 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. |
1972 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) |
1973
1974 @liveexample{The following code shows how a `type_error` exception can be
1975 caught.,type_error}
1976
1977 @sa - @ref exception for the base class of the library exceptions
1978 @sa - @ref parse_error for exceptions indicating a parse error
1979 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
1980 @sa - @ref out_of_range for exceptions indicating access out of the defined range
1981 @sa - @ref other_error for exceptions indicating other library errors
1982
1983 @since version 3.0.0
1984 */
1985 class type_error : public exception
1986 {
1987 public:
1988 static type_error create(int id_, const std::string& what_arg)
1989 {
1990 std::string w = exception::name("type_error", id_) + what_arg;
1991 return type_error(id_, w.c_str());
1992 }
1993
1994 private:
1995 JSON_HEDLEY_NON_NULL(3)
1996 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
1997 };
1998
1999 /*!
2000 @brief exception indicating access out of the defined range
2001
2002 This exception is thrown in case a library function is called on an input
2003 parameter that exceeds the expected range, for instance in case of array
2004 indices or nonexisting object keys.
2005
2006 Exceptions have ids 4xx.
2007
2008 name / id | example message | description
2009 ------------------------------- | --------------- | -------------------------
2010 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.
2011 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.
2012 json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
2013 json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
2014 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.
2015 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.
2016 json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. |
2017 json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |
2018 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 |
2019
2020 @liveexample{The following code shows how an `out_of_range` exception can be
2021 caught.,out_of_range}
2022
2023 @sa - @ref exception for the base class of the library exceptions
2024 @sa - @ref parse_error for exceptions indicating a parse error
2025 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2026 @sa - @ref type_error for exceptions indicating executing a member function with
2027 a wrong type
2028 @sa - @ref other_error for exceptions indicating other library errors
2029
2030 @since version 3.0.0
2031 */
2032 class out_of_range : public exception
2033 {
2034 public:
2035 static out_of_range create(int id_, const std::string& what_arg)
2036 {
2037 std::string w = exception::name("out_of_range", id_) + what_arg;
2038 return out_of_range(id_, w.c_str());
2039 }
2040
2041 private:
2042 JSON_HEDLEY_NON_NULL(3)
2043 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
2044 };
2045
2046 /*!
2047 @brief exception indicating other library errors
2048
2049 This exception is thrown in case of errors that cannot be classified with the
2050 other exception types.
2051
2052 Exceptions have ids 5xx.
2053
2054 name / id | example message | description
2055 ------------------------------ | --------------- | -------------------------
2056 json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
2057
2058 @sa - @ref exception for the base class of the library exceptions
2059 @sa - @ref parse_error for exceptions indicating a parse error
2060 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2061 @sa - @ref type_error for exceptions indicating executing a member function with
2062 a wrong type
2063 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2064
2065 @liveexample{The following code shows how an `other_error` exception can be
2066 caught.,other_error}
2067
2068 @since version 3.0.0
2069 */
2070 class other_error : public exception
2071 {
2072 public:
2073 static other_error create(int id_, const std::string& what_arg)
2074 {
2075 std::string w = exception::name("other_error", id_) + what_arg;
2076 return other_error(id_, w.c_str());
2077 }
2078
2079 private:
2080 JSON_HEDLEY_NON_NULL(3)
2081 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2082 };
2083 } // namespace detail
2084 } // namespace nlohmann
2085
2086 // #include <nlohmann/detail/macro_scope.hpp>
2087
2088 // #include <nlohmann/detail/meta/cpp_future.hpp>
2089
2090
2091 #include <ciso646> // not
2092 #include <cstddef> // size_t
2093 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
2094
2095 namespace nlohmann
2096 {
2097 namespace detail
2098 {
2099 // alias templates to reduce boilerplate
2100 template<bool B, typename T = void>
2101 using enable_if_t = typename std::enable_if<B, T>::type;
2102
2103 template<typename T>
2104 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
2105
2106 // implementation of C++14 index_sequence and affiliates
2107 // source: https://stackoverflow.com/a/32223343
2108 template<std::size_t... Ints>
2109 struct index_sequence
2110 {
2111 using type = index_sequence;
2112 using value_type = std::size_t;
2113 static constexpr std::size_t size() noexcept
2114 {
2115 return sizeof...(Ints);
2116 }
2117 };
2118
2119 template<class Sequence1, class Sequence2>
2120 struct merge_and_renumber;
2121
2122 template<std::size_t... I1, std::size_t... I2>
2123 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
2124 : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
2125
2126 template<std::size_t N>
2127 struct make_index_sequence
2128 : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
2129 typename make_index_sequence < N - N / 2 >::type > {};
2130
2131 template<> struct make_index_sequence<0> : index_sequence<> {};
2132 template<> struct make_index_sequence<1> : index_sequence<0> {};
2133
2134 template<typename... Ts>
2135 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
2136
2137 // dispatch utility (taken from ranges-v3)
2138 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
2139 template<> struct priority_tag<0> {};
2140
2141 // taken from ranges-v3
2142 template<typename T>
2143 struct static_const
2144 {
2145 static constexpr T value{};
2146 };
2147
2148 template<typename T>
2149 constexpr T static_const<T>::value;
2150 } // namespace detail
2151 } // namespace nlohmann
2152
2153 // #include <nlohmann/detail/meta/type_traits.hpp>
2154
2155
2156 #include <ciso646> // not
2157 #include <limits> // numeric_limits
2158 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
2159 #include <utility> // declval
2160
2161 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
2162
2163
2164 #include <iterator> // random_access_iterator_tag
2165
2166 // #include <nlohmann/detail/meta/void_t.hpp>
2167
2168
2169 namespace nlohmann
2170 {
2171 namespace detail
2172 {
2173 template <typename ...Ts> struct make_void
2174 {
2175 using type = void;
2176 };
2177 template <typename ...Ts> using void_t = typename make_void<Ts...>::type;
2178 } // namespace detail
2179 } // namespace nlohmann
2180
2181 // #include <nlohmann/detail/meta/cpp_future.hpp>
2182
2183
2184 namespace nlohmann
2185 {
2186 namespace detail
2187 {
2188 template <typename It, typename = void>
2189 struct iterator_types {};
2190
2191 template <typename It>
2192 struct iterator_types <
2193 It,
2194 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
2195 typename It::reference, typename It::iterator_category >>
2196 {
2197 using difference_type = typename It::difference_type;
2198 using value_type = typename It::value_type;
2199 using pointer = typename It::pointer;
2200 using reference = typename It::reference;
2201 using iterator_category = typename It::iterator_category;
2202 };
2203
2204 // This is required as some compilers implement std::iterator_traits in a way that
2205 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
2206 template <typename T, typename = void>
2207 struct iterator_traits
2208 {
2209 };
2210
2211 template <typename T>
2212 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
2213 : iterator_types<T>
2214 {
2215 };
2216
2217 template <typename T>
2218 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
2219 {
2220 using iterator_category = std::random_access_iterator_tag;
2221 using value_type = T;
2222 using difference_type = ptrdiff_t;
2223 using pointer = T*;
2224 using reference = T&;
2225 };
2226 } // namespace detail
2227 } // namespace nlohmann
2228
2229 // #include <nlohmann/detail/macro_scope.hpp>
2230
2231 // #include <nlohmann/detail/meta/cpp_future.hpp>
2232
2233 // #include <nlohmann/detail/meta/detected.hpp>
2234
2235
2236 #include <type_traits>
2237
2238 // #include <nlohmann/detail/meta/void_t.hpp>
2239
2240
2241 // http://en.cppreference.com/w/cpp/experimental/is_detected
2242 namespace nlohmann
2243 {
2244 namespace detail
2245 {
2246 struct nonesuch
2247 {
2248 nonesuch() = delete;
2249 ~nonesuch() = delete;
2250 nonesuch(nonesuch const&) = delete;
2251 nonesuch(nonesuch const&&) = delete;
2252 void operator=(nonesuch const&) = delete;
2253 void operator=(nonesuch&&) = delete;
2254 };
2255
2256 template <class Default,
2257 class AlwaysVoid,
2258 template <class...> class Op,
2259 class... Args>
2260 struct detector
2261 {
2262 using value_t = std::false_type;
2263 using type = Default;
2264 };
2265
2266 template <class Default, template <class...> class Op, class... Args>
2267 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2268 {
2269 using value_t = std::true_type;
2270 using type = Op<Args...>;
2271 };
2272
2273 template <template <class...> class Op, class... Args>
2274 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2275
2276 template <template <class...> class Op, class... Args>
2277 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2278
2279 template <class Default, template <class...> class Op, class... Args>
2280 using detected_or = detector<Default, void, Op, Args...>;
2281
2282 template <class Default, template <class...> class Op, class... Args>
2283 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2284
2285 template <class Expected, template <class...> class Op, class... Args>
2286 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2287
2288 template <class To, template <class...> class Op, class... Args>
2289 using is_detected_convertible =
2290 std::is_convertible<detected_t<Op, Args...>, To>;
2291 } // namespace detail
2292 } // namespace nlohmann
2293
2294 // #include <nlohmann/json_fwd.hpp>
2295 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
2296 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
2297
2298 #include <cstdint> // int64_t, uint64_t
2299 #include <map> // map
2300 #include <memory> // allocator
2301 #include <string> // string
2302 #include <vector> // vector
2303
2304 /*!
2305 @brief namespace for Niels Lohmann
2306 @see https://github.com/nlohmann
2307 @since version 1.0.0
2308 */
2309 namespace nlohmann
2310 {
2311 /*!
2312 @brief default JSONSerializer template argument
2313
2314 This serializer ignores the template arguments and uses ADL
2315 ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
2316 for serialization.
2317 */
2318 template<typename T = void, typename SFINAE = void>
2319 struct adl_serializer;
2320
2321 template<template<typename U, typename V, typename... Args> class ObjectType =
2322 std::map,
2323 template<typename U, typename... Args> class ArrayType = std::vector,
2324 class StringType = std::string, class BooleanType = bool,
2325 class NumberIntegerType = std::int64_t,
2326 class NumberUnsignedType = std::uint64_t,
2327 class NumberFloatType = double,
2328 template<typename U> class AllocatorType = std::allocator,
2329 template<typename T, typename SFINAE = void> class JSONSerializer =
2330 adl_serializer>
2331 class basic_json;
2332
2333 /*!
2334 @brief JSON Pointer
2335
2336 A JSON pointer defines a string syntax for identifying a specific value
2337 within a JSON document. It can be used with functions `at` and
2338 `operator[]`. Furthermore, JSON pointers are the base for JSON patches.
2339
2340 @sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
2341
2342 @since version 2.0.0
2343 */
2344 template<typename BasicJsonType>
2345 class json_pointer;
2346
2347 /*!
2348 @brief default JSON class
2349
2350 This type is the default specialization of the @ref basic_json class which
2351 uses the standard template types.
2352
2353 @since version 1.0.0
2354 */
2355 using json = basic_json<>;
2356 } // namespace nlohmann
2357
2358 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
2359
2360
2361 namespace nlohmann
2362 {
2363 /*!
2364 @brief detail namespace with internal helper functions
2365
2366 This namespace collects functions that should not be exposed,
2367 implementations of some @ref basic_json methods, and meta-programming helpers.
2368
2369 @since version 2.1.0
2370 */
2371 namespace detail
2372 {
2373 /////////////
2374 // helpers //
2375 /////////////
2376
2377 // Note to maintainers:
2378 //
2379 // Every trait in this file expects a non CV-qualified type.
2380 // The only exceptions are in the 'aliases for detected' section
2381 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
2382 //
2383 // In this case, T has to be properly CV-qualified to constraint the function arguments
2384 // (e.g. to_json(BasicJsonType&, const T&))
2385
2386 template<typename> struct is_basic_json : std::false_type {};
2387
2388 NLOHMANN_BASIC_JSON_TPL_DECLARATION
2389 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
2390
2391 //////////////////////////
2392 // aliases for detected //
2393 //////////////////////////
2394
2395 template <typename T>
2396 using mapped_type_t = typename T::mapped_type;
2397
2398 template <typename T>
2399 using key_type_t = typename T::key_type;
2400
2401 template <typename T>
2402 using value_type_t = typename T::value_type;
2403
2404 template <typename T>
2405 using difference_type_t = typename T::difference_type;
2406
2407 template <typename T>
2408 using pointer_t = typename T::pointer;
2409
2410 template <typename T>
2411 using reference_t = typename T::reference;
2412
2413 template <typename T>
2414 using iterator_category_t = typename T::iterator_category;
2415
2416 template <typename T>
2417 using iterator_t = typename T::iterator;
2418
2419 template <typename T, typename... Args>
2420 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
2421
2422 template <typename T, typename... Args>
2423 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
2424
2425 template <typename T, typename U>
2426 using get_template_function = decltype(std::declval<T>().template get<U>());
2427
2428 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
2429 template <typename BasicJsonType, typename T, typename = void>
2430 struct has_from_json : std::false_type {};
2431
2432 template <typename BasicJsonType, typename T>
2433 struct has_from_json<BasicJsonType, T,
2434 enable_if_t<not is_basic_json<T>::value>>
2435 {
2436 using serializer = typename BasicJsonType::template json_serializer<T, void>;
2437
2438 static constexpr bool value =
2439 is_detected_exact<void, from_json_function, serializer,
2440 const BasicJsonType&, T&>::value;
2441 };
2442
2443 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
2444 // this overload is used for non-default-constructible user-defined-types
2445 template <typename BasicJsonType, typename T, typename = void>
2446 struct has_non_default_from_json : std::false_type {};
2447
2448 template<typename BasicJsonType, typename T>
2449 struct has_non_default_from_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
2450 {
2451 using serializer = typename BasicJsonType::template json_serializer<T, void>;
2452
2453 static constexpr bool value =
2454 is_detected_exact<T, from_json_function, serializer,
2455 const BasicJsonType&>::value;
2456 };
2457
2458 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
2459 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
2460 template <typename BasicJsonType, typename T, typename = void>
2461 struct has_to_json : std::false_type {};
2462
2463 template <typename BasicJsonType, typename T>
2464 struct has_to_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
2465 {
2466 using serializer = typename BasicJsonType::template json_serializer<T, void>;
2467
2468 static constexpr bool value =
2469 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
2470 T>::value;
2471 };
2472
2473
2474 ///////////////////
2475 // is_ functions //
2476 ///////////////////
2477
2478 template <typename T, typename = void>
2479 struct is_iterator_traits : std::false_type {};
2480
2481 template <typename T>
2482 struct is_iterator_traits<iterator_traits<T>>
2483 {
2484 private:
2485 using traits = iterator_traits<T>;
2486
2487 public:
2488 static constexpr auto value =
2489 is_detected<value_type_t, traits>::value &&
2490 is_detected<difference_type_t, traits>::value &&
2491 is_detected<pointer_t, traits>::value &&
2492 is_detected<iterator_category_t, traits>::value &&
2493 is_detected<reference_t, traits>::value;
2494 };
2495
2496 // source: https://stackoverflow.com/a/37193089/4116453
2497
2498 template <typename T, typename = void>
2499 struct is_complete_type : std::false_type {};
2500
2501 template <typename T>
2502 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
2503
2504 template <typename BasicJsonType, typename CompatibleObjectType,
2505 typename = void>
2506 struct is_compatible_object_type_impl : std::false_type {};
2507
2508 template <typename BasicJsonType, typename CompatibleObjectType>
2509 struct is_compatible_object_type_impl <
2510 BasicJsonType, CompatibleObjectType,
2511 enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value and
2512 is_detected<key_type_t, CompatibleObjectType>::value >>
2513 {
2514
2515 using object_t = typename BasicJsonType::object_t;
2516
2517 // macOS's is_constructible does not play well with nonesuch...
2518 static constexpr bool value =
2519 std::is_constructible<typename object_t::key_type,
2520 typename CompatibleObjectType::key_type>::value and
2521 std::is_constructible<typename object_t::mapped_type,
2522 typename CompatibleObjectType::mapped_type>::value;
2523 };
2524
2525 template <typename BasicJsonType, typename CompatibleObjectType>
2526 struct is_compatible_object_type
2527 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
2528
2529 template <typename BasicJsonType, typename ConstructibleObjectType,
2530 typename = void>
2531 struct is_constructible_object_type_impl : std::false_type {};
2532
2533 template <typename BasicJsonType, typename ConstructibleObjectType>
2534 struct is_constructible_object_type_impl <
2535 BasicJsonType, ConstructibleObjectType,
2536 enable_if_t<is_detected<mapped_type_t, ConstructibleObjectType>::value and
2537 is_detected<key_type_t, ConstructibleObjectType>::value >>
2538 {
2539 using object_t = typename BasicJsonType::object_t;
2540
2541 static constexpr bool value =
2542 (std::is_default_constructible<ConstructibleObjectType>::value and
2543 (std::is_move_assignable<ConstructibleObjectType>::value or
2544 std::is_copy_assignable<ConstructibleObjectType>::value) and
2545 (std::is_constructible<typename ConstructibleObjectType::key_type,
2546 typename object_t::key_type>::value and
2547 std::is_same <
2548 typename object_t::mapped_type,
2549 typename ConstructibleObjectType::mapped_type >::value)) or
2550 (has_from_json<BasicJsonType,
2551 typename ConstructibleObjectType::mapped_type>::value or
2552 has_non_default_from_json <
2553 BasicJsonType,
2554 typename ConstructibleObjectType::mapped_type >::value);
2555 };
2556
2557 template <typename BasicJsonType, typename ConstructibleObjectType>
2558 struct is_constructible_object_type
2559 : is_constructible_object_type_impl<BasicJsonType,
2560 ConstructibleObjectType> {};
2561
2562 template <typename BasicJsonType, typename CompatibleStringType,
2563 typename = void>
2564 struct is_compatible_string_type_impl : std::false_type {};
2565
2566 template <typename BasicJsonType, typename CompatibleStringType>
2567 struct is_compatible_string_type_impl <
2568 BasicJsonType, CompatibleStringType,
2569 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
2570 value_type_t, CompatibleStringType>::value >>
2571 {
2572 static constexpr auto value =
2573 std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
2574 };
2575
2576 template <typename BasicJsonType, typename ConstructibleStringType>
2577 struct is_compatible_string_type
2578 : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
2579
2580 template <typename BasicJsonType, typename ConstructibleStringType,
2581 typename = void>
2582 struct is_constructible_string_type_impl : std::false_type {};
2583
2584 template <typename BasicJsonType, typename ConstructibleStringType>
2585 struct is_constructible_string_type_impl <
2586 BasicJsonType, ConstructibleStringType,
2587 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
2588 value_type_t, ConstructibleStringType>::value >>
2589 {
2590 static constexpr auto value =
2591 std::is_constructible<ConstructibleStringType,
2592 typename BasicJsonType::string_t>::value;
2593 };
2594
2595 template <typename BasicJsonType, typename ConstructibleStringType>
2596 struct is_constructible_string_type
2597 : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
2598
2599 template <typename BasicJsonType, typename CompatibleArrayType, typename = void>
2600 struct is_compatible_array_type_impl : std::false_type {};
2601
2602 template <typename BasicJsonType, typename CompatibleArrayType>
2603 struct is_compatible_array_type_impl <
2604 BasicJsonType, CompatibleArrayType,
2605 enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value and
2606 is_detected<iterator_t, CompatibleArrayType>::value and
2607 // This is needed because json_reverse_iterator has a ::iterator type...
2608 // Therefore it is detected as a CompatibleArrayType.
2609 // The real fix would be to have an Iterable concept.
2610 not is_iterator_traits<
2611 iterator_traits<CompatibleArrayType>>::value >>
2612 {
2613 static constexpr bool value =
2614 std::is_constructible<BasicJsonType,
2615 typename CompatibleArrayType::value_type>::value;
2616 };
2617
2618 template <typename BasicJsonType, typename CompatibleArrayType>
2619 struct is_compatible_array_type
2620 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
2621
2622 template <typename BasicJsonType, typename ConstructibleArrayType, typename = void>
2623 struct is_constructible_array_type_impl : std::false_type {};
2624
2625 template <typename BasicJsonType, typename ConstructibleArrayType>
2626 struct is_constructible_array_type_impl <
2627 BasicJsonType, ConstructibleArrayType,
2628 enable_if_t<std::is_same<ConstructibleArrayType,
2629 typename BasicJsonType::value_type>::value >>
2630 : std::true_type {};
2631
2632 template <typename BasicJsonType, typename ConstructibleArrayType>
2633 struct is_constructible_array_type_impl <
2634 BasicJsonType, ConstructibleArrayType,
2635 enable_if_t<not std::is_same<ConstructibleArrayType,
2636 typename BasicJsonType::value_type>::value and
2637 std::is_default_constructible<ConstructibleArrayType>::value and
2638 (std::is_move_assignable<ConstructibleArrayType>::value or
2639 std::is_copy_assignable<ConstructibleArrayType>::value) and
2640 is_detected<value_type_t, ConstructibleArrayType>::value and
2641 is_detected<iterator_t, ConstructibleArrayType>::value and
2642 is_complete_type<
2643 detected_t<value_type_t, ConstructibleArrayType>>::value >>
2644 {
2645 static constexpr bool value =
2646 // This is needed because json_reverse_iterator has a ::iterator type,
2647 // furthermore, std::back_insert_iterator (and other iterators) have a
2648 // base class `iterator`... Therefore it is detected as a
2649 // ConstructibleArrayType. The real fix would be to have an Iterable
2650 // concept.
2651 not is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value and
2652
2653 (std::is_same<typename ConstructibleArrayType::value_type,
2654 typename BasicJsonType::array_t::value_type>::value or
2655 has_from_json<BasicJsonType,
2656 typename ConstructibleArrayType::value_type>::value or
2657 has_non_default_from_json <
2658 BasicJsonType, typename ConstructibleArrayType::value_type >::value);
2659 };
2660
2661 template <typename BasicJsonType, typename ConstructibleArrayType>
2662 struct is_constructible_array_type
2663 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
2664
2665 template <typename RealIntegerType, typename CompatibleNumberIntegerType,
2666 typename = void>
2667 struct is_compatible_integer_type_impl : std::false_type {};
2668
2669 template <typename RealIntegerType, typename CompatibleNumberIntegerType>
2670 struct is_compatible_integer_type_impl <
2671 RealIntegerType, CompatibleNumberIntegerType,
2672 enable_if_t<std::is_integral<RealIntegerType>::value and
2673 std::is_integral<CompatibleNumberIntegerType>::value and
2674 not std::is_same<bool, CompatibleNumberIntegerType>::value >>
2675 {
2676 // is there an assert somewhere on overflows?
2677 using RealLimits = std::numeric_limits<RealIntegerType>;
2678 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
2679
2680 static constexpr auto value =
2681 std::is_constructible<RealIntegerType,
2682 CompatibleNumberIntegerType>::value and
2683 CompatibleLimits::is_integer and
2684 RealLimits::is_signed == CompatibleLimits::is_signed;
2685 };
2686
2687 template <typename RealIntegerType, typename CompatibleNumberIntegerType>
2688 struct is_compatible_integer_type
2689 : is_compatible_integer_type_impl<RealIntegerType,
2690 CompatibleNumberIntegerType> {};
2691
2692 template <typename BasicJsonType, typename CompatibleType, typename = void>
2693 struct is_compatible_type_impl: std::false_type {};
2694
2695 template <typename BasicJsonType, typename CompatibleType>
2696 struct is_compatible_type_impl <
2697 BasicJsonType, CompatibleType,
2698 enable_if_t<is_complete_type<CompatibleType>::value >>
2699 {
2700 static constexpr bool value =
2701 has_to_json<BasicJsonType, CompatibleType>::value;
2702 };
2703
2704 template <typename BasicJsonType, typename CompatibleType>
2705 struct is_compatible_type
2706 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
2707 } // namespace detail
2708 } // namespace nlohmann
2709
2710 // #include <nlohmann/detail/value_t.hpp>
2711
2712
2713 #include <array> // array
2714 #include <ciso646> // and
2715 #include <cstddef> // size_t
2716 #include <cstdint> // uint8_t
2717 #include <string> // string
2718
2719 namespace nlohmann
2720 {
2721 namespace detail
2722 {
2723 ///////////////////////////
2724 // JSON type enumeration //
2725 ///////////////////////////
2726
2727 /*!
2728 @brief the JSON type enumeration
2729
2730 This enumeration collects the different JSON types. It is internally used to
2731 distinguish the stored values, and the functions @ref basic_json::is_null(),
2732 @ref basic_json::is_object(), @ref basic_json::is_array(),
2733 @ref basic_json::is_string(), @ref basic_json::is_boolean(),
2734 @ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
2735 @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
2736 @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
2737 @ref basic_json::is_structured() rely on it.
2738
2739 @note There are three enumeration entries (number_integer, number_unsigned, and
2740 number_float), because the library distinguishes these three types for numbers:
2741 @ref basic_json::number_unsigned_t is used for unsigned integers,
2742 @ref basic_json::number_integer_t is used for signed integers, and
2743 @ref basic_json::number_float_t is used for floating-point numbers or to
2744 approximate integers which do not fit in the limits of their respective type.
2745
2746 @sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
2747 value with the default value for a given type
2748
2749 @since version 1.0.0
2750 */
2751 enum class value_t : std::uint8_t
2752 {
2753 null, ///< null value
2754 object, ///< object (unordered set of name/value pairs)
2755 array, ///< array (ordered collection of values)
2756 string, ///< string value
2757 boolean, ///< boolean value
2758 number_integer, ///< number value (signed integer)
2759 number_unsigned, ///< number value (unsigned integer)
2760 number_float, ///< number value (floating-point)
2761 discarded ///< discarded by the the parser callback function
2762 };
2763
2764 /*!
2765 @brief comparison operator for JSON types
2766
2767 Returns an ordering that is similar to Python:
2768 - order: null < boolean < number < object < array < string
2769 - furthermore, each type is not smaller than itself
2770 - discarded values are not comparable
2771
2772 @since version 1.0.0
2773 */
2774 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2775 {
2776 static constexpr std::array<std::uint8_t, 8> order = {{
2777 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
2778 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */
2779 }
2780 };
2781
2782 const auto l_index = static_cast<std::size_t>(lhs);
2783 const auto r_index = static_cast<std::size_t>(rhs);
2784 return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
2785 }
2786 } // namespace detail
2787 } // namespace nlohmann
2788
2789
2790 namespace nlohmann
2791 {
2792 namespace detail
2793 {
2794 template<typename BasicJsonType>
2795 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
2796 {
2797 if (JSON_HEDLEY_UNLIKELY(not j.is_null()))
2798 {
2799 JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
2800 }
2801 n = nullptr;
2802 }
2803
2804 // overloads for basic_json template parameters
2805 template<typename BasicJsonType, typename ArithmeticType,
2806 enable_if_t<std::is_arithmetic<ArithmeticType>::value and
2807 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
2808 int> = 0>
2809 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
2810 {
2811 switch (static_cast<value_t>(j))
2812 {
2813 case value_t::number_unsigned:
2814 {
2815 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
2816 break;
2817 }
2818 case value_t::number_integer:
2819 {
2820 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
2821 break;
2822 }
2823 case value_t::number_float:
2824 {
2825 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
2826 break;
2827 }
2828
2829 default:
2830 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
2831 }
2832 }
2833
2834 template<typename BasicJsonType>
2835 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
2836 {
2837 if (JSON_HEDLEY_UNLIKELY(not j.is_boolean()))
2838 {
2839 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
2840 }
2841 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
2842 }
2843
2844 template<typename BasicJsonType>
2845 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
2846 {
2847 if (JSON_HEDLEY_UNLIKELY(not j.is_string()))
2848 {
2849 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
2850 }
2851 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
2852 }
2853
2854 template <
2855 typename BasicJsonType, typename ConstructibleStringType,
2856 enable_if_t <
2857 is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value and
2858 not std::is_same<typename BasicJsonType::string_t,
2859 ConstructibleStringType>::value,
2860 int > = 0 >
2861 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
2862 {
2863 if (JSON_HEDLEY_UNLIKELY(not j.is_string()))
2864 {
2865 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
2866 }
2867
2868 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
2869 }
2870
2871 template<typename BasicJsonType>
2872 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
2873 {
2874 get_arithmetic_value(j, val);
2875 }
2876
2877 template<typename BasicJsonType>
2878 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
2879 {
2880 get_arithmetic_value(j, val);
2881 }
2882
2883 template<typename BasicJsonType>
2884 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
2885 {
2886 get_arithmetic_value(j, val);
2887 }
2888
2889 template<typename BasicJsonType, typename EnumType,
2890 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
2891 void from_json(const BasicJsonType& j, EnumType& e)
2892 {
2893 typename std::underlying_type<EnumType>::type val;
2894 get_arithmetic_value(j, val);
2895 e = static_cast<EnumType>(val);
2896 }
2897
2898 // forward_list doesn't have an insert method
2899 template<typename BasicJsonType, typename T, typename Allocator,
2900 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
2901 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
2902 {
2903 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
2904 {
2905 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
2906 }
2907 l.clear();
2908 std::transform(j.rbegin(), j.rend(),
2909 std::front_inserter(l), [](const BasicJsonType & i)
2910 {
2911 return i.template get<T>();
2912 });
2913 }
2914
2915 // valarray doesn't have an insert method
2916 template<typename BasicJsonType, typename T,
2917 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
2918 void from_json(const BasicJsonType& j, std::valarray<T>& l)
2919 {
2920 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
2921 {
2922 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
2923 }
2924 l.resize(j.size());
2925 std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
2926 }
2927
2928 template <typename BasicJsonType, typename T, std::size_t N>
2929 auto from_json(const BasicJsonType& j, T (&arr)[N])
2930 -> decltype(j.template get<T>(), void())
2931 {
2932 for (std::size_t i = 0; i < N; ++i)
2933 {
2934 arr[i] = j.at(i).template get<T>();
2935 }
2936 }
2937
2938 template<typename BasicJsonType>
2939 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
2940 {
2941 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
2942 }
2943
2944 template <typename BasicJsonType, typename T, std::size_t N>
2945 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
2946 priority_tag<2> /*unused*/)
2947 -> decltype(j.template get<T>(), void())
2948 {
2949 for (std::size_t i = 0; i < N; ++i)
2950 {
2951 arr[i] = j.at(i).template get<T>();
2952 }
2953 }
2954
2955 template<typename BasicJsonType, typename ConstructibleArrayType>
2956 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
2957 -> decltype(
2958 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
2959 j.template get<typename ConstructibleArrayType::value_type>(),
2960 void())
2961 {
2962 using std::end;
2963
2964 ConstructibleArrayType ret;
2965 ret.reserve(j.size());
2966 std::transform(j.begin(), j.end(),
2967 std::inserter(ret, end(ret)), [](const BasicJsonType & i)
2968 {
2969 // get<BasicJsonType>() returns *this, this won't call a from_json
2970 // method when value_type is BasicJsonType
2971 return i.template get<typename ConstructibleArrayType::value_type>();
2972 });
2973 arr = std::move(ret);
2974 }
2975
2976 template <typename BasicJsonType, typename ConstructibleArrayType>
2977 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
2978 priority_tag<0> /*unused*/)
2979 {
2980 using std::end;
2981
2982 ConstructibleArrayType ret;
2983 std::transform(
2984 j.begin(), j.end(), std::inserter(ret, end(ret)),
2985 [](const BasicJsonType & i)
2986 {
2987 // get<BasicJsonType>() returns *this, this won't call a from_json
2988 // method when value_type is BasicJsonType
2989 return i.template get<typename ConstructibleArrayType::value_type>();
2990 });
2991 arr = std::move(ret);
2992 }
2993
2994 template <typename BasicJsonType, typename ConstructibleArrayType,
2995 enable_if_t <
2996 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value and
2997 not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value and
2998 not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value and
2999 not is_basic_json<ConstructibleArrayType>::value,
3000 int > = 0 >
3001
3002 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
3003 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
3004 j.template get<typename ConstructibleArrayType::value_type>(),
3005 void())
3006 {
3007 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3008 {
3009 JSON_THROW(type_error::create(302, "type must be array, but is " +
3010 std::string(j.type_name())));
3011 }
3012
3013 from_json_array_impl(j, arr, priority_tag<3> {});
3014 }
3015
3016 template<typename BasicJsonType, typename ConstructibleObjectType,
3017 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
3018 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
3019 {
3020 if (JSON_HEDLEY_UNLIKELY(not j.is_object()))
3021 {
3022 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
3023 }
3024
3025 ConstructibleObjectType ret;
3026 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
3027 using value_type = typename ConstructibleObjectType::value_type;
3028 std::transform(
3029 inner_object->begin(), inner_object->end(),
3030 std::inserter(ret, ret.begin()),
3031 [](typename BasicJsonType::object_t::value_type const & p)
3032 {
3033 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
3034 });
3035 obj = std::move(ret);
3036 }
3037
3038 // overload for arithmetic types, not chosen for basic_json template arguments
3039 // (BooleanType, etc..); note: Is it really necessary to provide explicit
3040 // overloads for boolean_t etc. in case of a custom BooleanType which is not
3041 // an arithmetic type?
3042 template<typename BasicJsonType, typename ArithmeticType,
3043 enable_if_t <
3044 std::is_arithmetic<ArithmeticType>::value and
3045 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
3046 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
3047 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
3048 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3049 int> = 0>
3050 void from_json(const BasicJsonType& j, ArithmeticType& val)
3051 {
3052 switch (static_cast<value_t>(j))
3053 {
3054 case value_t::number_unsigned:
3055 {
3056 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3057 break;
3058 }
3059 case value_t::number_integer:
3060 {
3061 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3062 break;
3063 }
3064 case value_t::number_float:
3065 {
3066 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3067 break;
3068 }
3069 case value_t::boolean:
3070 {
3071 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
3072 break;
3073 }
3074
3075 default:
3076 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
3077 }
3078 }
3079
3080 template<typename BasicJsonType, typename A1, typename A2>
3081 void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
3082 {
3083 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
3084 }
3085
3086 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
3087 void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
3088 {
3089 t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
3090 }
3091
3092 template<typename BasicJsonType, typename... Args>
3093 void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
3094 {
3095 from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
3096 }
3097
3098 template <typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
3099 typename = enable_if_t<not std::is_constructible<
3100 typename BasicJsonType::string_t, Key>::value>>
3101 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
3102 {
3103 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3104 {
3105 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3106 }
3107 m.clear();
3108 for (const auto& p : j)
3109 {
3110 if (JSON_HEDLEY_UNLIKELY(not p.is_array()))
3111 {
3112 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3113 }
3114 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3115 }
3116 }
3117
3118 template <typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
3119 typename = enable_if_t<not std::is_constructible<
3120 typename BasicJsonType::string_t, Key>::value>>
3121 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
3122 {
3123 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3124 {
3125 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3126 }
3127 m.clear();
3128 for (const auto& p : j)
3129 {
3130 if (JSON_HEDLEY_UNLIKELY(not p.is_array()))
3131 {
3132 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3133 }
3134 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3135 }
3136 }
3137
3138 struct from_json_fn
3139 {
3140 template<typename BasicJsonType, typename T>
3141 auto operator()(const BasicJsonType& j, T& val) const
3142 noexcept(noexcept(from_json(j, val)))
3143 -> decltype(from_json(j, val), void())
3144 {
3145 return from_json(j, val);
3146 }
3147 };
3148 } // namespace detail
3149
3150 /// namespace to hold default `from_json` function
3151 /// to see why this is required:
3152 /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
3153 namespace
3154 {
3155 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
3156 } // namespace
3157 } // namespace nlohmann
3158
3159 // #include <nlohmann/detail/conversions/to_json.hpp>
3160
3161
3162 #include <algorithm> // copy
3163 #include <ciso646> // or, and, not
3164 #include <iterator> // begin, end
3165 #include <string> // string
3166 #include <tuple> // tuple, get
3167 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
3168 #include <utility> // move, forward, declval, pair
3169 #include <valarray> // valarray
3170 #include <vector> // vector
3171
3172 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
3173
3174
3175 #include <cstddef> // size_t
3176 #include <iterator> // input_iterator_tag
3177 #include <string> // string, to_string
3178 #include <tuple> // tuple_size, get, tuple_element
3179
3180 // #include <nlohmann/detail/meta/type_traits.hpp>
3181
3182 // #include <nlohmann/detail/value_t.hpp>
3183
3184
3185 namespace nlohmann
3186 {
3187 namespace detail
3188 {
3189 template <typename IteratorType> class iteration_proxy_value
3190 {
3191 public:
3192 using difference_type = std::ptrdiff_t;
3193 using value_type = iteration_proxy_value;
3194 using pointer = value_type * ;
3195 using reference = value_type & ;
3196 using iterator_category = std::input_iterator_tag;
3197
3198 private:
3199 /// the iterator
3200 IteratorType anchor;
3201 /// an index for arrays (used to create key names)
3202 std::size_t array_index = 0;
3203 /// last stringified array index
3204 mutable std::size_t array_index_last = 0;
3205 /// a string representation of the array index
3206 mutable std::string array_index_str = "0";
3207 /// an empty string (to return a reference for primitive values)
3208 const std::string empty_str = "";
3209
3210 public:
3211 explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
3212
3213 /// dereference operator (needed for range-based for)
3214 iteration_proxy_value& operator*()
3215 {
3216 return *this;
3217 }
3218
3219 /// increment operator (needed for range-based for)
3220 iteration_proxy_value& operator++()
3221 {
3222 ++anchor;
3223 ++array_index;
3224
3225 return *this;
3226 }
3227
3228 /// equality operator (needed for InputIterator)
3229 bool operator==(const iteration_proxy_value& o) const
3230 {
3231 return anchor == o.anchor;
3232 }
3233
3234 /// inequality operator (needed for range-based for)
3235 bool operator!=(const iteration_proxy_value& o) const
3236 {
3237 return anchor != o.anchor;
3238 }
3239
3240 /// return key of the iterator
3241 const std::string& key() const
3242 {
3243 assert(anchor.m_object != nullptr);
3244
3245 switch (anchor.m_object->type())
3246 {
3247 // use integer array index as key
3248 case value_t::array:
3249 {
3250 if (array_index != array_index_last)
3251 {
3252 array_index_str = std::to_string(array_index);
3253 array_index_last = array_index;
3254 }
3255 return array_index_str;
3256 }
3257
3258 // use key from the object
3259 case value_t::object:
3260 return anchor.key();
3261
3262 // use an empty key for all primitive types
3263 default:
3264 return empty_str;
3265 }
3266 }
3267
3268 /// return value of the iterator
3269 typename IteratorType::reference value() const
3270 {
3271 return anchor.value();
3272 }
3273 };
3274
3275 /// proxy class for the items() function
3276 template<typename IteratorType> class iteration_proxy
3277 {
3278 private:
3279 /// the container to iterate
3280 typename IteratorType::reference container;
3281
3282 public:
3283 /// construct iteration proxy from a container
3284 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
3285 : container(cont) {}
3286
3287 /// return iterator begin (needed for range-based for)
3288 iteration_proxy_value<IteratorType> begin() noexcept
3289 {
3290 return iteration_proxy_value<IteratorType>(container.begin());
3291 }
3292
3293 /// return iterator end (needed for range-based for)
3294 iteration_proxy_value<IteratorType> end() noexcept
3295 {
3296 return iteration_proxy_value<IteratorType>(container.end());
3297 }
3298 };
3299 // Structured Bindings Support
3300 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3301 // And see https://github.com/nlohmann/json/pull/1391
3302 template <std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
3303 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
3304 {
3305 return i.key();
3306 }
3307 // Structured Bindings Support
3308 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3309 // And see https://github.com/nlohmann/json/pull/1391
3310 template <std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
3311 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
3312 {
3313 return i.value();
3314 }
3315 } // namespace detail
3316 } // namespace nlohmann
3317
3318 // The Addition to the STD Namespace is required to add
3319 // Structured Bindings Support to the iteration_proxy_value class
3320 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3321 // And see https://github.com/nlohmann/json/pull/1391
3322 namespace std
3323 {
3324 #if defined(__clang__)
3325 // Fix: https://github.com/nlohmann/json/issues/1401
3326 #pragma clang diagnostic push
3327 #pragma clang diagnostic ignored "-Wmismatched-tags"
3328 #endif
3329 template <typename IteratorType>
3330 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
3331 : public std::integral_constant<std::size_t, 2> {};
3332
3333 template <std::size_t N, typename IteratorType>
3334 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
3335 {
3336 public:
3337 using type = decltype(
3338 get<N>(std::declval <
3339 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
3340 };
3341 #if defined(__clang__)
3342 #pragma clang diagnostic pop
3343 #endif
3344 } // namespace std
3345
3346 // #include <nlohmann/detail/meta/cpp_future.hpp>
3347
3348 // #include <nlohmann/detail/meta/type_traits.hpp>
3349
3350 // #include <nlohmann/detail/value_t.hpp>
3351
3352
3353 namespace nlohmann
3354 {
3355 namespace detail
3356 {
3357 //////////////////
3358 // constructors //
3359 //////////////////
3360
3361 template<value_t> struct external_constructor;
3362
3363 template<>
3364 struct external_constructor<value_t::boolean>
3365 {
3366 template<typename BasicJsonType>
3367 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
3368 {
3369 j.m_type = value_t::boolean;
3370 j.m_value = b;
3371 j.assert_invariant();
3372 }
3373 };
3374
3375 template<>
3376 struct external_constructor<value_t::string>
3377 {
3378 template<typename BasicJsonType>
3379 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
3380 {
3381 j.m_type = value_t::string;
3382 j.m_value = s;
3383 j.assert_invariant();
3384 }
3385
3386 template<typename BasicJsonType>
3387 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
3388 {
3389 j.m_type = value_t::string;
3390 j.m_value = std::move(s);
3391 j.assert_invariant();
3392 }
3393
3394 template<typename BasicJsonType, typename CompatibleStringType,
3395 enable_if_t<not std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
3396 int> = 0>
3397 static void construct(BasicJsonType& j, const CompatibleStringType& str)
3398 {
3399 j.m_type = value_t::string;
3400 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
3401 j.assert_invariant();
3402 }
3403 };
3404
3405 template<>
3406 struct external_constructor<value_t::number_float>
3407 {
3408 template<typename BasicJsonType>
3409 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
3410 {
3411 j.m_type = value_t::number_float;
3412 j.m_value = val;
3413 j.assert_invariant();
3414 }
3415 };
3416
3417 template<>
3418 struct external_constructor<value_t::number_unsigned>
3419 {
3420 template<typename BasicJsonType>
3421 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
3422 {
3423 j.m_type = value_t::number_unsigned;
3424 j.m_value = val;
3425 j.assert_invariant();
3426 }
3427 };
3428
3429 template<>
3430 struct external_constructor<value_t::number_integer>
3431 {
3432 template<typename BasicJsonType>
3433 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
3434 {
3435 j.m_type = value_t::number_integer;
3436 j.m_value = val;
3437 j.assert_invariant();
3438 }
3439 };
3440
3441 template<>
3442 struct external_constructor<value_t::array>
3443 {
3444 template<typename BasicJsonType>
3445 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
3446 {
3447 j.m_type = value_t::array;
3448 j.m_value = arr;
3449 j.assert_invariant();
3450 }
3451
3452 template<typename BasicJsonType>
3453 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
3454 {
3455 j.m_type = value_t::array;
3456 j.m_value = std::move(arr);
3457 j.assert_invariant();
3458 }
3459
3460 template<typename BasicJsonType, typename CompatibleArrayType,
3461 enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
3462 int> = 0>
3463 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
3464 {
3465 using std::begin;
3466 using std::end;
3467 j.m_type = value_t::array;
3468 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
3469 j.assert_invariant();
3470 }
3471
3472 template<typename BasicJsonType>
3473 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
3474 {
3475 j.m_type = value_t::array;
3476 j.m_value = value_t::array;
3477 j.m_value.array->reserve(arr.size());
3478 for (const bool x : arr)
3479 {
3480 j.m_value.array->push_back(x);
3481 }
3482 j.assert_invariant();
3483 }
3484
3485 template<typename BasicJsonType, typename T,
3486 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
3487 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
3488 {
3489 j.m_type = value_t::array;
3490 j.m_value = value_t::array;
3491 j.m_value.array->resize(arr.size());
3492 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
3493 j.assert_invariant();
3494 }
3495 };
3496
3497 template<>
3498 struct external_constructor<value_t::object>
3499 {
3500 template<typename BasicJsonType>
3501 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
3502 {
3503 j.m_type = value_t::object;
3504 j.m_value = obj;
3505 j.assert_invariant();
3506 }
3507
3508 template<typename BasicJsonType>
3509 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
3510 {
3511 j.m_type = value_t::object;
3512 j.m_value = std::move(obj);
3513 j.assert_invariant();
3514 }
3515
3516 template<typename BasicJsonType, typename CompatibleObjectType,
3517 enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0>
3518 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
3519 {
3520 using std::begin;
3521 using std::end;
3522
3523 j.m_type = value_t::object;
3524 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
3525 j.assert_invariant();
3526 }
3527 };
3528
3529 /////////////
3530 // to_json //
3531 /////////////
3532
3533 template<typename BasicJsonType, typename T,
3534 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
3535 void to_json(BasicJsonType& j, T b) noexcept
3536 {
3537 external_constructor<value_t::boolean>::construct(j, b);
3538 }
3539
3540 template<typename BasicJsonType, typename CompatibleString,
3541 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
3542 void to_json(BasicJsonType& j, const CompatibleString& s)
3543 {
3544 external_constructor<value_t::string>::construct(j, s);
3545 }
3546
3547 template<typename BasicJsonType>
3548 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
3549 {
3550 external_constructor<value_t::string>::construct(j, std::move(s));
3551 }
3552
3553 template<typename BasicJsonType, typename FloatType,
3554 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
3555 void to_json(BasicJsonType& j, FloatType val) noexcept
3556 {
3557 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
3558 }
3559
3560 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
3561 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
3562 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
3563 {
3564 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
3565 }
3566
3567 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
3568 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
3569 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
3570 {
3571 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
3572 }
3573
3574 template<typename BasicJsonType, typename EnumType,
3575 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
3576 void to_json(BasicJsonType& j, EnumType e) noexcept
3577 {
3578 using underlying_type = typename std::underlying_type<EnumType>::type;
3579 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
3580 }
3581
3582 template<typename BasicJsonType>
3583 void to_json(BasicJsonType& j, const std::vector<bool>& e)
3584 {
3585 external_constructor<value_t::array>::construct(j, e);
3586 }
3587
3588 template <typename BasicJsonType, typename CompatibleArrayType,
3589 enable_if_t<is_compatible_array_type<BasicJsonType,
3590 CompatibleArrayType>::value and
3591 not is_compatible_object_type<
3592 BasicJsonType, CompatibleArrayType>::value and
3593 not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
3594 not is_basic_json<CompatibleArrayType>::value,
3595 int> = 0>
3596 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
3597 {
3598 external_constructor<value_t::array>::construct(j, arr);
3599 }
3600
3601 template<typename BasicJsonType, typename T,
3602 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
3603 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
3604 {
3605 external_constructor<value_t::array>::construct(j, std::move(arr));
3606 }
3607
3608 template<typename BasicJsonType>
3609 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
3610 {
3611 external_constructor<value_t::array>::construct(j, std::move(arr));
3612 }
3613
3614 template<typename BasicJsonType, typename CompatibleObjectType,
3615 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value and not is_basic_json<CompatibleObjectType>::value, int> = 0>
3616 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
3617 {
3618 external_constructor<value_t::object>::construct(j, obj);
3619 }
3620
3621 template<typename BasicJsonType>
3622 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
3623 {
3624 external_constructor<value_t::object>::construct(j, std::move(obj));
3625 }
3626
3627 template <
3628 typename BasicJsonType, typename T, std::size_t N,
3629 enable_if_t<not std::is_constructible<typename BasicJsonType::string_t,
3630 const T(&)[N]>::value,
3631 int> = 0 >
3632 void to_json(BasicJsonType& j, const T(&arr)[N])
3633 {
3634 external_constructor<value_t::array>::construct(j, arr);
3635 }
3636
3637 template<typename BasicJsonType, typename... Args>
3638 void to_json(BasicJsonType& j, const std::pair<Args...>& p)
3639 {
3640 j = { p.first, p.second };
3641 }
3642
3643 // for https://github.com/nlohmann/json/pull/1134
3644 template < typename BasicJsonType, typename T,
3645 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
3646 void to_json(BasicJsonType& j, const T& b)
3647 {
3648 j = { {b.key(), b.value()} };
3649 }
3650
3651 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
3652 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
3653 {
3654 j = { std::get<Idx>(t)... };
3655 }
3656
3657 template<typename BasicJsonType, typename... Args>
3658 void to_json(BasicJsonType& j, const std::tuple<Args...>& t)
3659 {
3660 to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
3661 }
3662
3663 struct to_json_fn
3664 {
3665 template<typename BasicJsonType, typename T>
3666 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
3667 -> decltype(to_json(j, std::forward<T>(val)), void())
3668 {
3669 return to_json(j, std::forward<T>(val));
3670 }
3671 };
3672 } // namespace detail
3673
3674 /// namespace to hold default `to_json` function
3675 namespace
3676 {
3677 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
3678 } // namespace
3679 } // namespace nlohmann
3680
3681
3682 namespace nlohmann
3683 {
3684
3685 template<typename, typename>
3686 struct adl_serializer
3687 {
3688 /*!
3689 @brief convert a JSON value to any value type
3690
3691 This function is usually called by the `get()` function of the
3692 @ref basic_json class (either explicit or via conversion operators).
3693
3694 @param[in] j JSON value to read from
3695 @param[in,out] val value to write to
3696 */
3697 template<typename BasicJsonType, typename ValueType>
3698 static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
3699 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
3700 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
3701 {
3702 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
3703 }
3704
3705 /*!
3706 @brief convert any value type to a JSON value
3707
3708 This function is usually called by the constructors of the @ref basic_json
3709 class.
3710
3711 @param[in,out] j JSON value to write to
3712 @param[in] val value to read from
3713 */
3714 template <typename BasicJsonType, typename ValueType>
3715 static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
3716 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
3717 -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void())
3718 {
3719 ::nlohmann::to_json(j, std::forward<ValueType>(val));
3720 }
3721 };
3722
3723 } // namespace nlohmann
3724
3725 // #include <nlohmann/detail/conversions/from_json.hpp>
3726
3727 // #include <nlohmann/detail/conversions/to_json.hpp>
3728
3729 // #include <nlohmann/detail/exceptions.hpp>
3730
3731 // #include <nlohmann/detail/input/binary_reader.hpp>
3732
3733
3734 #include <algorithm> // generate_n
3735 #include <array> // array
3736 #include <cassert> // assert
3737 #include <cmath> // ldexp
3738 #include <cstddef> // size_t
3739 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
3740 #include <cstdio> // snprintf
3741 #include <cstring> // memcpy
3742 #include <iterator> // back_inserter
3743 #include <limits> // numeric_limits
3744 #include <string> // char_traits, string
3745 #include <utility> // make_pair, move
3746
3747 // #include <nlohmann/detail/exceptions.hpp>
3748
3749 // #include <nlohmann/detail/input/input_adapters.hpp>
3750
3751
3752 #include <array> // array
3753 #include <cassert> // assert
3754 #include <cstddef> // size_t
3755 #include <cstdio> //FILE *
3756 #include <cstring> // strlen
3757 #include <istream> // istream
3758 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
3759 #include <memory> // shared_ptr, make_shared, addressof
3760 #include <numeric> // accumulate
3761 #include <string> // string, char_traits
3762 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
3763 #include <utility> // pair, declval
3764
3765 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
3766
3767 // #include <nlohmann/detail/macro_scope.hpp>
3768
3769
3770 namespace nlohmann
3771 {
3772 namespace detail
3773 {
3774 /// the supported input formats
3775 enum class input_format_t { json, cbor, msgpack, ubjson, bson };
3776
3777 ////////////////////
3778 // input adapters //
3779 ////////////////////
3780
3781 /*!
3782 @brief abstract input adapter interface
3783
3784 Produces a stream of std::char_traits<char>::int_type characters from a
3785 std::istream, a buffer, or some other input type. Accepts the return of
3786 exactly one non-EOF character for future input. The int_type characters
3787 returned consist of all valid char values as positive values (typically
3788 unsigned char), plus an EOF value outside that range, specified by the value
3789 of the function std::char_traits<char>::eof(). This value is typically -1, but
3790 could be any arbitrary value which is not a valid char value.
3791 */
3792 struct input_adapter_protocol
3793 {
3794 /// get a character [0,255] or std::char_traits<char>::eof().
3795 virtual std::char_traits<char>::int_type get_character() = 0;
3796 virtual ~input_adapter_protocol() = default;
3797 };
3798
3799 /// a type to simplify interfaces
3800 using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
3801
3802 /*!
3803 Input adapter for stdio file access. This adapter read only 1 byte and do not use any
3804 buffer. This adapter is a very low level adapter.
3805 */
3806 class file_input_adapter : public input_adapter_protocol
3807 {
3808 public:
3809 JSON_HEDLEY_NON_NULL(2)
3810 explicit file_input_adapter(std::FILE* f) noexcept
3811 : m_file(f)
3812 {}
3813
3814 // make class move-only
3815 file_input_adapter(const file_input_adapter&) = delete;
3816 file_input_adapter(file_input_adapter&&) = default;
3817 file_input_adapter& operator=(const file_input_adapter&) = delete;
3818 file_input_adapter& operator=(file_input_adapter&&) = default;
3819 ~file_input_adapter() override = default;
3820
3821 std::char_traits<char>::int_type get_character() noexcept override
3822 {
3823 return std::fgetc(m_file);
3824 }
3825
3826 private:
3827 /// the file pointer to read from
3828 std::FILE* m_file;
3829 };
3830
3831
3832 /*!
3833 Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
3834 beginning of input. Does not support changing the underlying std::streambuf
3835 in mid-input. Maintains underlying std::istream and std::streambuf to support
3836 subsequent use of standard std::istream operations to process any input
3837 characters following those used in parsing the JSON input. Clears the
3838 std::istream flags; any input errors (e.g., EOF) will be detected by the first
3839 subsequent call for input from the std::istream.
3840 */
3841 class input_stream_adapter : public input_adapter_protocol
3842 {
3843 public:
3844 ~input_stream_adapter() override
3845 {
3846 // clear stream flags; we use underlying streambuf I/O, do not
3847 // maintain ifstream flags, except eof
3848 is.clear(is.rdstate() & std::ios::eofbit);
3849 }
3850
3851 explicit input_stream_adapter(std::istream& i)
3852 : is(i), sb(*i.rdbuf())
3853 {}
3854
3855 // delete because of pointer members
3856 input_stream_adapter(const input_stream_adapter&) = delete;
3857 input_stream_adapter& operator=(input_stream_adapter&) = delete;
3858 input_stream_adapter(input_stream_adapter&&) = delete;
3859 input_stream_adapter& operator=(input_stream_adapter&&) = delete;
3860
3861 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
3862 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
3863 // end up as the same value, eg. 0xFFFFFFFF.
3864 std::char_traits<char>::int_type get_character() override
3865 {
3866 auto res = sb.sbumpc();
3867 // set eof manually, as we don't use the istream interface.
3868 if (res == EOF)
3869 {
3870 is.clear(is.rdstate() | std::ios::eofbit);
3871 }
3872 return res;
3873 }
3874
3875 private:
3876 /// the associated input stream
3877 std::istream& is;
3878 std::streambuf& sb;
3879 };
3880
3881 /// input adapter for buffer input
3882 class input_buffer_adapter : public input_adapter_protocol
3883 {
3884 public:
3885 JSON_HEDLEY_NON_NULL(2)
3886 input_buffer_adapter(const char* b, const std::size_t l) noexcept
3887 : cursor(b), limit(b + l)
3888 {}
3889
3890 // delete because of pointer members
3891 input_buffer_adapter(const input_buffer_adapter&) = delete;
3892 input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
3893 input_buffer_adapter(input_buffer_adapter&&) = delete;
3894 input_buffer_adapter& operator=(input_buffer_adapter&&) = delete;
3895 ~input_buffer_adapter() override = default;
3896
3897 std::char_traits<char>::int_type get_character() noexcept override
3898 {
3899 if (JSON_HEDLEY_LIKELY(cursor < limit))
3900 {
3901 return std::char_traits<char>::to_int_type(*(cursor++));
3902 }
3903
3904 return std::char_traits<char>::eof();
3905 }
3906
3907 private:
3908 /// pointer to the current character
3909 const char* cursor;
3910 /// pointer past the last character
3911 const char* const limit;
3912 };
3913
3914 template<typename WideStringType, size_t T>
3915 struct wide_string_input_helper
3916 {
3917 // UTF-32
3918 static void fill_buffer(const WideStringType& str,
3919 size_t& current_wchar,
3920 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
3921 size_t& utf8_bytes_index,
3922 size_t& utf8_bytes_filled)
3923 {
3924 utf8_bytes_index = 0;
3925
3926 if (current_wchar == str.size())
3927 {
3928 utf8_bytes[0] = std::char_traits<char>::eof();
3929 utf8_bytes_filled = 1;
3930 }
3931 else
3932 {
3933 // get the current character
3934 const auto wc = static_cast<unsigned int>(str[current_wchar++]);
3935
3936 // UTF-32 to UTF-8 encoding
3937 if (wc < 0x80)
3938 {
3939 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
3940 utf8_bytes_filled = 1;
3941 }
3942 else if (wc <= 0x7FF)
3943 {
3944 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u) & 0x1Fu));
3945 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
3946 utf8_bytes_filled = 2;
3947 }
3948 else if (wc <= 0xFFFF)
3949 {
3950 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u) & 0x0Fu));
3951 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
3952 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
3953 utf8_bytes_filled = 3;
3954 }
3955 else if (wc <= 0x10FFFF)
3956 {
3957 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((wc >> 18u) & 0x07u));
3958 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 12u) & 0x3Fu));
3959 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
3960 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
3961 utf8_bytes_filled = 4;
3962 }
3963 else
3964 {
3965 // unknown character
3966 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
3967 utf8_bytes_filled = 1;
3968 }
3969 }
3970 }
3971 };
3972
3973 template<typename WideStringType>
3974 struct wide_string_input_helper<WideStringType, 2>
3975 {
3976 // UTF-16
3977 static void fill_buffer(const WideStringType& str,
3978 size_t& current_wchar,
3979 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
3980 size_t& utf8_bytes_index,
3981 size_t& utf8_bytes_filled)
3982 {
3983 utf8_bytes_index = 0;
3984
3985 if (current_wchar == str.size())
3986 {
3987 utf8_bytes[0] = std::char_traits<char>::eof();
3988 utf8_bytes_filled = 1;
3989 }
3990 else
3991 {
3992 // get the current character
3993 const auto wc = static_cast<unsigned int>(str[current_wchar++]);
3994
3995 // UTF-16 to UTF-8 encoding
3996 if (wc < 0x80)
3997 {
3998 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
3999 utf8_bytes_filled = 1;
4000 }
4001 else if (wc <= 0x7FF)
4002 {
4003 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u)));
4004 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
4005 utf8_bytes_filled = 2;
4006 }
4007 else if (0xD800 > wc or wc >= 0xE000)
4008 {
4009 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u)));
4010 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
4011 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
4012 utf8_bytes_filled = 3;
4013 }
4014 else
4015 {
4016 if (current_wchar < str.size())
4017 {
4018 const auto wc2 = static_cast<unsigned int>(str[current_wchar++]);
4019 const auto charcode = 0x10000u + (((wc & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
4020 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
4021 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
4022 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
4023 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
4024 utf8_bytes_filled = 4;
4025 }
4026 else
4027 {
4028 // unknown character
4029 ++current_wchar;
4030 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4031 utf8_bytes_filled = 1;
4032 }
4033 }
4034 }
4035 }
4036 };
4037
4038 template<typename WideStringType>
4039 class wide_string_input_adapter : public input_adapter_protocol
4040 {
4041 public:
4042 explicit wide_string_input_adapter(const WideStringType& w) noexcept
4043 : str(w)
4044 {}
4045
4046 std::char_traits<char>::int_type get_character() noexcept override
4047 {
4048 // check if buffer needs to be filled
4049 if (utf8_bytes_index == utf8_bytes_filled)
4050 {
4051 fill_buffer<sizeof(typename WideStringType::value_type)>();
4052
4053 assert(utf8_bytes_filled > 0);
4054 assert(utf8_bytes_index == 0);
4055 }
4056
4057 // use buffer
4058 assert(utf8_bytes_filled > 0);
4059 assert(utf8_bytes_index < utf8_bytes_filled);
4060 return utf8_bytes[utf8_bytes_index++];
4061 }
4062
4063 private:
4064 template<size_t T>
4065 void fill_buffer()
4066 {
4067 wide_string_input_helper<WideStringType, T>::fill_buffer(str, current_wchar, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
4068 }
4069
4070 /// the wstring to process
4071 const WideStringType& str;
4072
4073 /// index of the current wchar in str
4074 std::size_t current_wchar = 0;
4075
4076 /// a buffer for UTF-8 bytes
4077 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
4078
4079 /// index to the utf8_codes array for the next valid byte
4080 std::size_t utf8_bytes_index = 0;
4081 /// number of valid bytes in the utf8_codes array
4082 std::size_t utf8_bytes_filled = 0;
4083 };
4084
4085 class input_adapter
4086 {
4087 public:
4088 // native support
4089 JSON_HEDLEY_NON_NULL(2)
4090 input_adapter(std::FILE* file)
4091 : ia(std::make_shared<file_input_adapter>(file)) {}
4092 /// input adapter for input stream
4093 input_adapter(std::istream& i)
4094 : ia(std::make_shared<input_stream_adapter>(i)) {}
4095
4096 /// input adapter for input stream
4097 input_adapter(std::istream&& i)
4098 : ia(std::make_shared<input_stream_adapter>(i)) {}
4099
4100 input_adapter(const std::wstring& ws)
4101 : ia(std::make_shared<wide_string_input_adapter<std::wstring>>(ws)) {}
4102
4103 input_adapter(const std::u16string& ws)
4104 : ia(std::make_shared<wide_string_input_adapter<std::u16string>>(ws)) {}
4105
4106 input_adapter(const std::u32string& ws)
4107 : ia(std::make_shared<wide_string_input_adapter<std::u32string>>(ws)) {}
4108
4109 /// input adapter for buffer
4110 template<typename CharT,
4111 typename std::enable_if<
4112 std::is_pointer<CharT>::value and
4113 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
4114 sizeof(typename std::remove_pointer<CharT>::type) == 1,
4115 int>::type = 0>
4116 input_adapter(CharT b, std::size_t l)
4117 : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
4118
4119 // derived support
4120
4121 /// input adapter for string literal
4122 template<typename CharT,
4123 typename std::enable_if<
4124 std::is_pointer<CharT>::value and
4125 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
4126 sizeof(typename std::remove_pointer<CharT>::type) == 1,
4127 int>::type = 0>
4128 input_adapter(CharT b)
4129 : input_adapter(reinterpret_cast<const char*>(b),
4130 std::strlen(reinterpret_cast<const char*>(b))) {}
4131
4132 /// input adapter for iterator range with contiguous storage
4133 template<class IteratorType,
4134 typename std::enable_if<
4135 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
4136 int>::type = 0>
4137 input_adapter(IteratorType first, IteratorType last)
4138 {
4139 #ifndef NDEBUG
4140 // assertion to check that the iterator range is indeed contiguous,
4141 // see http://stackoverflow.com/a/35008842/266378 for more discussion
4142 const auto is_contiguous = std::accumulate(
4143 first, last, std::pair<bool, int>(true, 0),
4144 [&first](std::pair<bool, int> res, decltype(*first) val)
4145 {
4146 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
4147 return res;
4148 }).first;
4149 assert(is_contiguous);
4150 #endif
4151
4152 // assertion to check that each element is 1 byte long
4153 static_assert(
4154 sizeof(typename iterator_traits<IteratorType>::value_type) == 1,
4155 "each element in the iterator range must have the size of 1 byte");
4156
4157 const auto len = static_cast<size_t>(std::distance(first, last));
4158 if (JSON_HEDLEY_LIKELY(len > 0))
4159 {
4160 // there is at least one element: use the address of first
4161 ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
4162 }
4163 else
4164 {
4165 // the address of first cannot be used: use nullptr
4166 ia = std::make_shared<input_buffer_adapter>(nullptr, len);
4167 }
4168 }
4169
4170 /// input adapter for array
4171 template<class T, std::size_t N>
4172 input_adapter(T (&array)[N])
4173 : input_adapter(std::begin(array), std::end(array)) {}
4174
4175 /// input adapter for contiguous container
4176 template<class ContiguousContainer, typename
4177 std::enable_if<not std::is_pointer<ContiguousContainer>::value and
4178 std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
4179 int>::type = 0>
4180 input_adapter(const ContiguousContainer& c)
4181 : input_adapter(std::begin(c), std::end(c)) {}
4182
4183 operator input_adapter_t()
4184 {
4185 return ia;
4186 }
4187
4188 private:
4189 /// the actual adapter
4190 input_adapter_t ia = nullptr;
4191 };
4192 } // namespace detail
4193 } // namespace nlohmann
4194
4195 // #include <nlohmann/detail/input/json_sax.hpp>
4196
4197
4198 #include <cassert> // assert
4199 #include <cstddef>
4200 #include <string> // string
4201 #include <utility> // move
4202 #include <vector> // vector
4203
4204 // #include <nlohmann/detail/exceptions.hpp>
4205
4206 // #include <nlohmann/detail/macro_scope.hpp>
4207
4208
4209 namespace nlohmann
4210 {
4211
4212 /*!
4213 @brief SAX interface
4214
4215 This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
4216 Each function is called in different situations while the input is parsed. The
4217 boolean return value informs the parser whether to continue processing the
4218 input.
4219 */
4220 template<typename BasicJsonType>
4221 struct json_sax
4222 {
4223 /// type for (signed) integers
4224 using number_integer_t = typename BasicJsonType::number_integer_t;
4225 /// type for unsigned integers
4226 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4227 /// type for floating-point numbers
4228 using number_float_t = typename BasicJsonType::number_float_t;
4229 /// type for strings
4230 using string_t = typename BasicJsonType::string_t;
4231
4232 /*!
4233 @brief a null value was read
4234 @return whether parsing should proceed
4235 */
4236 virtual bool null() = 0;
4237
4238 /*!
4239 @brief a boolean value was read
4240 @param[in] val boolean value
4241 @return whether parsing should proceed
4242 */
4243 virtual bool boolean(bool val) = 0;
4244
4245 /*!
4246 @brief an integer number was read
4247 @param[in] val integer value
4248 @return whether parsing should proceed
4249 */
4250 virtual bool number_integer(number_integer_t val) = 0;
4251
4252 /*!
4253 @brief an unsigned integer number was read
4254 @param[in] val unsigned integer value
4255 @return whether parsing should proceed
4256 */
4257 virtual bool number_unsigned(number_unsigned_t val) = 0;
4258
4259 /*!
4260 @brief an floating-point number was read
4261 @param[in] val floating-point value
4262 @param[in] s raw token value
4263 @return whether parsing should proceed
4264 */
4265 virtual bool number_float(number_float_t val, const string_t& s) = 0;
4266
4267 /*!
4268 @brief a string was read
4269 @param[in] val string value
4270 @return whether parsing should proceed
4271 @note It is safe to move the passed string.
4272 */
4273 virtual bool string(string_t& val) = 0;
4274
4275 /*!
4276 @brief the beginning of an object was read
4277 @param[in] elements number of object elements or -1 if unknown
4278 @return whether parsing should proceed
4279 @note binary formats may report the number of elements
4280 */
4281 virtual bool start_object(std::size_t elements) = 0;
4282
4283 /*!
4284 @brief an object key was read
4285 @param[in] val object key
4286 @return whether parsing should proceed
4287 @note It is safe to move the passed string.
4288 */
4289 virtual bool key(string_t& val) = 0;
4290
4291 /*!
4292 @brief the end of an object was read
4293 @return whether parsing should proceed
4294 */
4295 virtual bool end_object() = 0;
4296
4297 /*!
4298 @brief the beginning of an array was read
4299 @param[in] elements number of array elements or -1 if unknown
4300 @return whether parsing should proceed
4301 @note binary formats may report the number of elements
4302 */
4303 virtual bool start_array(std::size_t elements) = 0;
4304
4305 /*!
4306 @brief the end of an array was read
4307 @return whether parsing should proceed
4308 */
4309 virtual bool end_array() = 0;
4310
4311 /*!
4312 @brief a parse error occurred
4313 @param[in] position the position in the input where the error occurs
4314 @param[in] last_token the last read token
4315 @param[in] ex an exception object describing the error
4316 @return whether parsing should proceed (must return false)
4317 */
4318 virtual bool parse_error(std::size_t position,
4319 const std::string& last_token,
4320 const detail::exception& ex) = 0;
4321
4322 virtual ~json_sax() = default;
4323 };
4324
4325
4326 namespace detail
4327 {
4328 /*!
4329 @brief SAX implementation to create a JSON value from SAX events
4330
4331 This class implements the @ref json_sax interface and processes the SAX events
4332 to create a JSON value which makes it basically a DOM parser. The structure or
4333 hierarchy of the JSON value is managed by the stack `ref_stack` which contains
4334 a pointer to the respective array or object for each recursion depth.
4335
4336 After successful parsing, the value that is passed by reference to the
4337 constructor contains the parsed value.
4338
4339 @tparam BasicJsonType the JSON type
4340 */
4341 template<typename BasicJsonType>
4342 class json_sax_dom_parser
4343 {
4344 public:
4345 using number_integer_t = typename BasicJsonType::number_integer_t;
4346 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4347 using number_float_t = typename BasicJsonType::number_float_t;
4348 using string_t = typename BasicJsonType::string_t;
4349
4350 /*!
4351 @param[in, out] r reference to a JSON value that is manipulated while
4352 parsing
4353 @param[in] allow_exceptions_ whether parse errors yield exceptions
4354 */
4355 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
4356 : root(r), allow_exceptions(allow_exceptions_)
4357 {}
4358
4359 // make class move-only
4360 json_sax_dom_parser(const json_sax_dom_parser&) = delete;
4361 json_sax_dom_parser(json_sax_dom_parser&&) = default;
4362 json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
4363 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
4364 ~json_sax_dom_parser() = default;
4365
4366 bool null()
4367 {
4368 handle_value(nullptr);
4369 return true;
4370 }
4371
4372 bool boolean(bool val)
4373 {
4374 handle_value(val);
4375 return true;
4376 }
4377
4378 bool number_integer(number_integer_t val)
4379 {
4380 handle_value(val);
4381 return true;
4382 }
4383
4384 bool number_unsigned(number_unsigned_t val)
4385 {
4386 handle_value(val);
4387 return true;
4388 }
4389
4390 bool number_float(number_float_t val, const string_t& /*unused*/)
4391 {
4392 handle_value(val);
4393 return true;
4394 }
4395
4396 bool string(string_t& val)
4397 {
4398 handle_value(val);
4399 return true;
4400 }
4401
4402 bool start_object(std::size_t len)
4403 {
4404 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
4405
4406 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4407 {
4408 JSON_THROW(out_of_range::create(408,
4409 "excessive object size: " + std::to_string(len)));
4410 }
4411
4412 return true;
4413 }
4414
4415 bool key(string_t& val)
4416 {
4417 // add null at given key and store the reference for later
4418 object_element = &(ref_stack.back()->m_value.object->operator[](val));
4419 return true;
4420 }
4421
4422 bool end_object()
4423 {
4424 ref_stack.pop_back();
4425 return true;
4426 }
4427
4428 bool start_array(std::size_t len)
4429 {
4430 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
4431
4432 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4433 {
4434 JSON_THROW(out_of_range::create(408,
4435 "excessive array size: " + std::to_string(len)));
4436 }
4437
4438 return true;
4439 }
4440
4441 bool end_array()
4442 {
4443 ref_stack.pop_back();
4444 return true;
4445 }
4446
4447 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
4448 const detail::exception& ex)
4449 {
4450 errored = true;
4451 if (allow_exceptions)
4452 {
4453 // determine the proper exception type from the id
4454 switch ((ex.id / 100) % 100)
4455 {
4456 case 1:
4457 JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
4458 case 4:
4459 JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
4460 // LCOV_EXCL_START
4461 case 2:
4462 JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
4463 case 3:
4464 JSON_THROW(*static_cast<const detail::type_error*>(&ex));
4465 case 5:
4466 JSON_THROW(*static_cast<const detail::other_error*>(&ex));
4467 default:
4468 assert(false);
4469 // LCOV_EXCL_STOP
4470 }
4471 }
4472 return false;
4473 }
4474
4475 constexpr bool is_errored() const
4476 {
4477 return errored;
4478 }
4479
4480 private:
4481 /*!
4482 @invariant If the ref stack is empty, then the passed value will be the new
4483 root.
4484 @invariant If the ref stack contains a value, then it is an array or an
4485 object to which we can add elements
4486 */
4487 template<typename Value>
4488 JSON_HEDLEY_RETURNS_NON_NULL
4489 BasicJsonType* handle_value(Value&& v)
4490 {
4491 if (ref_stack.empty())
4492 {
4493 root = BasicJsonType(std::forward<Value>(v));
4494 return &root;
4495 }
4496
4497 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
4498
4499 if (ref_stack.back()->is_array())
4500 {
4501 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
4502 return &(ref_stack.back()->m_value.array->back());
4503 }
4504
4505 assert(ref_stack.back()->is_object());
4506 assert(object_element);
4507 *object_element = BasicJsonType(std::forward<Value>(v));
4508 return object_element;
4509 }
4510
4511 /// the parsed JSON value
4512 BasicJsonType& root;
4513 /// stack to model hierarchy of values
4514 std::vector<BasicJsonType*> ref_stack {};
4515 /// helper to hold the reference for the next object element
4516 BasicJsonType* object_element = nullptr;
4517 /// whether a syntax error occurred
4518 bool errored = false;
4519 /// whether to throw exceptions in case of errors
4520 const bool allow_exceptions = true;
4521 };
4522
4523 template<typename BasicJsonType>
4524 class json_sax_dom_callback_parser
4525 {
4526 public:
4527 using number_integer_t = typename BasicJsonType::number_integer_t;
4528 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4529 using number_float_t = typename BasicJsonType::number_float_t;
4530 using string_t = typename BasicJsonType::string_t;
4531 using parser_callback_t = typename BasicJsonType::parser_callback_t;
4532 using parse_event_t = typename BasicJsonType::parse_event_t;
4533
4534 json_sax_dom_callback_parser(BasicJsonType& r,
4535 const parser_callback_t cb,
4536 const bool allow_exceptions_ = true)
4537 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
4538 {
4539 keep_stack.push_back(true);
4540 }
4541
4542 // make class move-only
4543 json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
4544 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default;
4545 json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
4546 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default;
4547 ~json_sax_dom_callback_parser() = default;
4548
4549 bool null()
4550 {
4551 handle_value(nullptr);
4552 return true;
4553 }
4554
4555 bool boolean(bool val)
4556 {
4557 handle_value(val);
4558 return true;
4559 }
4560
4561 bool number_integer(number_integer_t val)
4562 {
4563 handle_value(val);
4564 return true;
4565 }
4566
4567 bool number_unsigned(number_unsigned_t val)
4568 {
4569 handle_value(val);
4570 return true;
4571 }
4572
4573 bool number_float(number_float_t val, const string_t& /*unused*/)
4574 {
4575 handle_value(val);
4576 return true;
4577 }
4578
4579 bool string(string_t& val)
4580 {
4581 handle_value(val);
4582 return true;
4583 }
4584
4585 bool start_object(std::size_t len)
4586 {
4587 // check callback for object start
4588 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
4589 keep_stack.push_back(keep);
4590
4591 auto val = handle_value(BasicJsonType::value_t::object, true);
4592 ref_stack.push_back(val.second);
4593
4594 // check object limit
4595 if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4596 {
4597 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
4598 }
4599
4600 return true;
4601 }
4602
4603 bool key(string_t& val)
4604 {
4605 BasicJsonType k = BasicJsonType(val);
4606
4607 // check callback for key
4608 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
4609 key_keep_stack.push_back(keep);
4610
4611 // add discarded value at given key and store the reference for later
4612 if (keep and ref_stack.back())
4613 {
4614 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
4615 }
4616
4617 return true;
4618 }
4619
4620 bool end_object()
4621 {
4622 if (ref_stack.back() and not callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
4623 {
4624 // discard object
4625 *ref_stack.back() = discarded;
4626 }
4627
4628 assert(not ref_stack.empty());
4629 assert(not keep_stack.empty());
4630 ref_stack.pop_back();
4631 keep_stack.pop_back();
4632
4633 if (not ref_stack.empty() and ref_stack.back() and ref_stack.back()->is_object())
4634 {
4635 // remove discarded value
4636 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
4637 {
4638 if (it->is_discarded())
4639 {
4640 ref_stack.back()->erase(it);
4641 break;
4642 }
4643 }
4644 }
4645
4646 return true;
4647 }
4648
4649 bool start_array(std::size_t len)
4650 {
4651 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
4652 keep_stack.push_back(keep);
4653
4654 auto val = handle_value(BasicJsonType::value_t::array, true);
4655 ref_stack.push_back(val.second);
4656
4657 // check array limit
4658 if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
4659 {
4660 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
4661 }
4662
4663 return true;
4664 }
4665
4666 bool end_array()
4667 {
4668 bool keep = true;
4669
4670 if (ref_stack.back())
4671 {
4672 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
4673 if (not keep)
4674 {
4675 // discard array
4676 *ref_stack.back() = discarded;
4677 }
4678 }
4679
4680 assert(not ref_stack.empty());
4681 assert(not keep_stack.empty());
4682 ref_stack.pop_back();
4683 keep_stack.pop_back();
4684
4685 // remove discarded value
4686 if (not keep and not ref_stack.empty() and ref_stack.back()->is_array())
4687 {
4688 ref_stack.back()->m_value.array->pop_back();
4689 }
4690
4691 return true;
4692 }
4693
4694 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
4695 const detail::exception& ex)
4696 {
4697 errored = true;
4698 if (allow_exceptions)
4699 {
4700 // determine the proper exception type from the id
4701 switch ((ex.id / 100) % 100)
4702 {
4703 case 1:
4704 JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
4705 case 4:
4706 JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
4707 // LCOV_EXCL_START
4708 case 2:
4709 JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
4710 case 3:
4711 JSON_THROW(*static_cast<const detail::type_error*>(&ex));
4712 case 5:
4713 JSON_THROW(*static_cast<const detail::other_error*>(&ex));
4714 default:
4715 assert(false);
4716 // LCOV_EXCL_STOP
4717 }
4718 }
4719 return false;
4720 }
4721
4722 constexpr bool is_errored() const
4723 {
4724 return errored;
4725 }
4726
4727 private:
4728 /*!
4729 @param[in] v value to add to the JSON value we build during parsing
4730 @param[in] skip_callback whether we should skip calling the callback
4731 function; this is required after start_array() and
4732 start_object() SAX events, because otherwise we would call the
4733 callback function with an empty array or object, respectively.
4734
4735 @invariant If the ref stack is empty, then the passed value will be the new
4736 root.
4737 @invariant If the ref stack contains a value, then it is an array or an
4738 object to which we can add elements
4739
4740 @return pair of boolean (whether value should be kept) and pointer (to the
4741 passed value in the ref_stack hierarchy; nullptr if not kept)
4742 */
4743 template<typename Value>
4744 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
4745 {
4746 assert(not keep_stack.empty());
4747
4748 // do not handle this value if we know it would be added to a discarded
4749 // container
4750 if (not keep_stack.back())
4751 {
4752 return {false, nullptr};
4753 }
4754
4755 // create value
4756 auto value = BasicJsonType(std::forward<Value>(v));
4757
4758 // check callback
4759 const bool keep = skip_callback or callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
4760
4761 // do not handle this value if we just learnt it shall be discarded
4762 if (not keep)
4763 {
4764 return {false, nullptr};
4765 }
4766
4767 if (ref_stack.empty())
4768 {
4769 root = std::move(value);
4770 return {true, &root};
4771 }
4772
4773 // skip this value if we already decided to skip the parent
4774 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
4775 if (not ref_stack.back())
4776 {
4777 return {false, nullptr};
4778 }
4779
4780 // we now only expect arrays and objects
4781 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
4782
4783 // array
4784 if (ref_stack.back()->is_array())
4785 {
4786 ref_stack.back()->m_value.array->push_back(std::move(value));
4787 return {true, &(ref_stack.back()->m_value.array->back())};
4788 }
4789
4790 // object
4791 assert(ref_stack.back()->is_object());
4792 // check if we should store an element for the current key
4793 assert(not key_keep_stack.empty());
4794 const bool store_element = key_keep_stack.back();
4795 key_keep_stack.pop_back();
4796
4797 if (not store_element)
4798 {
4799 return {false, nullptr};
4800 }
4801
4802 assert(object_element);
4803 *object_element = std::move(value);
4804 return {true, object_element};
4805 }
4806
4807 /// the parsed JSON value
4808 BasicJsonType& root;
4809 /// stack to model hierarchy of values
4810 std::vector<BasicJsonType*> ref_stack {};
4811 /// stack to manage which values to keep
4812 std::vector<bool> keep_stack {};
4813 /// stack to manage which object keys to keep
4814 std::vector<bool> key_keep_stack {};
4815 /// helper to hold the reference for the next object element
4816 BasicJsonType* object_element = nullptr;
4817 /// whether a syntax error occurred
4818 bool errored = false;
4819 /// callback function
4820 const parser_callback_t callback = nullptr;
4821 /// whether to throw exceptions in case of errors
4822 const bool allow_exceptions = true;
4823 /// a discarded value for the callback
4824 BasicJsonType discarded = BasicJsonType::value_t::discarded;
4825 };
4826
4827 template<typename BasicJsonType>
4828 class json_sax_acceptor
4829 {
4830 public:
4831 using number_integer_t = typename BasicJsonType::number_integer_t;
4832 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4833 using number_float_t = typename BasicJsonType::number_float_t;
4834 using string_t = typename BasicJsonType::string_t;
4835
4836 bool null()
4837 {
4838 return true;
4839 }
4840
4841 bool boolean(bool /*unused*/)
4842 {
4843 return true;
4844 }
4845
4846 bool number_integer(number_integer_t /*unused*/)
4847 {
4848 return true;
4849 }
4850
4851 bool number_unsigned(number_unsigned_t /*unused*/)
4852 {
4853 return true;
4854 }
4855
4856 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
4857 {
4858 return true;
4859 }
4860
4861 bool string(string_t& /*unused*/)
4862 {
4863 return true;
4864 }
4865
4866 bool start_object(std::size_t /*unused*/ = std::size_t(-1))
4867 {
4868 return true;
4869 }
4870
4871 bool key(string_t& /*unused*/)
4872 {
4873 return true;
4874 }
4875
4876 bool end_object()
4877 {
4878 return true;
4879 }
4880
4881 bool start_array(std::size_t /*unused*/ = std::size_t(-1))
4882 {
4883 return true;
4884 }
4885
4886 bool end_array()
4887 {
4888 return true;
4889 }
4890
4891 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
4892 {
4893 return false;
4894 }
4895 };
4896 } // namespace detail
4897
4898 } // namespace nlohmann
4899
4900 // #include <nlohmann/detail/macro_scope.hpp>
4901
4902 // #include <nlohmann/detail/meta/is_sax.hpp>
4903
4904
4905 #include <cstdint> // size_t
4906 #include <utility> // declval
4907 #include <string> // string
4908
4909 // #include <nlohmann/detail/meta/detected.hpp>
4910
4911 // #include <nlohmann/detail/meta/type_traits.hpp>
4912
4913
4914 namespace nlohmann
4915 {
4916 namespace detail
4917 {
4918 template <typename T>
4919 using null_function_t = decltype(std::declval<T&>().null());
4920
4921 template <typename T>
4922 using boolean_function_t =
4923 decltype(std::declval<T&>().boolean(std::declval<bool>()));
4924
4925 template <typename T, typename Integer>
4926 using number_integer_function_t =
4927 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
4928
4929 template <typename T, typename Unsigned>
4930 using number_unsigned_function_t =
4931 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
4932
4933 template <typename T, typename Float, typename String>
4934 using number_float_function_t = decltype(std::declval<T&>().number_float(
4935 std::declval<Float>(), std::declval<const String&>()));
4936
4937 template <typename T, typename String>
4938 using string_function_t =
4939 decltype(std::declval<T&>().string(std::declval<String&>()));
4940
4941 template <typename T>
4942 using start_object_function_t =
4943 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
4944
4945 template <typename T, typename String>
4946 using key_function_t =
4947 decltype(std::declval<T&>().key(std::declval<String&>()));
4948
4949 template <typename T>
4950 using end_object_function_t = decltype(std::declval<T&>().end_object());
4951
4952 template <typename T>
4953 using start_array_function_t =
4954 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
4955
4956 template <typename T>
4957 using end_array_function_t = decltype(std::declval<T&>().end_array());
4958
4959 template <typename T, typename Exception>
4960 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
4961 std::declval<std::size_t>(), std::declval<const std::string&>(),
4962 std::declval<const Exception&>()));
4963
4964 template <typename SAX, typename BasicJsonType>
4965 struct is_sax
4966 {
4967 private:
4968 static_assert(is_basic_json<BasicJsonType>::value,
4969 "BasicJsonType must be of type basic_json<...>");
4970
4971 using number_integer_t = typename BasicJsonType::number_integer_t;
4972 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4973 using number_float_t = typename BasicJsonType::number_float_t;
4974 using string_t = typename BasicJsonType::string_t;
4975 using exception_t = typename BasicJsonType::exception;
4976
4977 public:
4978 static constexpr bool value =
4979 is_detected_exact<bool, null_function_t, SAX>::value &&
4980 is_detected_exact<bool, boolean_function_t, SAX>::value &&
4981 is_detected_exact<bool, number_integer_function_t, SAX,
4982 number_integer_t>::value &&
4983 is_detected_exact<bool, number_unsigned_function_t, SAX,
4984 number_unsigned_t>::value &&
4985 is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
4986 string_t>::value &&
4987 is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
4988 is_detected_exact<bool, start_object_function_t, SAX>::value &&
4989 is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
4990 is_detected_exact<bool, end_object_function_t, SAX>::value &&
4991 is_detected_exact<bool, start_array_function_t, SAX>::value &&
4992 is_detected_exact<bool, end_array_function_t, SAX>::value &&
4993 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
4994 };
4995
4996 template <typename SAX, typename BasicJsonType>
4997 struct is_sax_static_asserts
4998 {
4999 private:
5000 static_assert(is_basic_json<BasicJsonType>::value,
5001 "BasicJsonType must be of type basic_json<...>");
5002
5003 using number_integer_t = typename BasicJsonType::number_integer_t;
5004 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5005 using number_float_t = typename BasicJsonType::number_float_t;
5006 using string_t = typename BasicJsonType::string_t;
5007 using exception_t = typename BasicJsonType::exception;
5008
5009 public:
5010 static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
5011 "Missing/invalid function: bool null()");
5012 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
5013 "Missing/invalid function: bool boolean(bool)");
5014 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
5015 "Missing/invalid function: bool boolean(bool)");
5016 static_assert(
5017 is_detected_exact<bool, number_integer_function_t, SAX,
5018 number_integer_t>::value,
5019 "Missing/invalid function: bool number_integer(number_integer_t)");
5020 static_assert(
5021 is_detected_exact<bool, number_unsigned_function_t, SAX,
5022 number_unsigned_t>::value,
5023 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
5024 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
5025 number_float_t, string_t>::value,
5026 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
5027 static_assert(
5028 is_detected_exact<bool, string_function_t, SAX, string_t>::value,
5029 "Missing/invalid function: bool string(string_t&)");
5030 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
5031 "Missing/invalid function: bool start_object(std::size_t)");
5032 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
5033 "Missing/invalid function: bool key(string_t&)");
5034 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
5035 "Missing/invalid function: bool end_object()");
5036 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
5037 "Missing/invalid function: bool start_array(std::size_t)");
5038 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
5039 "Missing/invalid function: bool end_array()");
5040 static_assert(
5041 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
5042 "Missing/invalid function: bool parse_error(std::size_t, const "
5043 "std::string&, const exception&)");
5044 };
5045 } // namespace detail
5046 } // namespace nlohmann
5047
5048 // #include <nlohmann/detail/value_t.hpp>
5049
5050
5051 namespace nlohmann
5052 {
5053 namespace detail
5054 {
5055 ///////////////////
5056 // binary reader //
5057 ///////////////////
5058
5059 /*!
5060 @brief deserialization of CBOR, MessagePack, and UBJSON values
5061 */
5062 template<typename BasicJsonType, typename SAX = json_sax_dom_parser<BasicJsonType>>
5063 class binary_reader
5064 {
5065 using number_integer_t = typename BasicJsonType::number_integer_t;
5066 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5067 using number_float_t = typename BasicJsonType::number_float_t;
5068 using string_t = typename BasicJsonType::string_t;
5069 using json_sax_t = SAX;
5070
5071 public:
5072 /*!
5073 @brief create a binary reader
5074
5075 @param[in] adapter input adapter to read from
5076 */
5077 explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
5078 {
5079 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
5080 assert(ia);
5081 }
5082
5083 // make class move-only
5084 binary_reader(const binary_reader&) = delete;
5085 binary_reader(binary_reader&&) = default;
5086 binary_reader& operator=(const binary_reader&) = delete;
5087 binary_reader& operator=(binary_reader&&) = default;
5088 ~binary_reader() = default;
5089
5090 /*!
5091 @param[in] format the binary format to parse
5092 @param[in] sax_ a SAX event processor
5093 @param[in] strict whether to expect the input to be consumed completed
5094
5095 @return
5096 */
5097 JSON_HEDLEY_NON_NULL(3)
5098 bool sax_parse(const input_format_t format,
5099 json_sax_t* sax_,
5100 const bool strict = true)
5101 {
5102 sax = sax_;
5103 bool result = false;
5104
5105 switch (format)
5106 {
5107 case input_format_t::bson:
5108 result = parse_bson_internal();
5109 break;
5110
5111 case input_format_t::cbor:
5112 result = parse_cbor_internal();
5113 break;
5114
5115 case input_format_t::msgpack:
5116 result = parse_msgpack_internal();
5117 break;
5118
5119 case input_format_t::ubjson:
5120 result = parse_ubjson_internal();
5121 break;
5122
5123 default: // LCOV_EXCL_LINE
5124 assert(false); // LCOV_EXCL_LINE
5125 }
5126
5127 // strict mode: next byte must be EOF
5128 if (result and strict)
5129 {
5130 if (format == input_format_t::ubjson)
5131 {
5132 get_ignore_noop();
5133 }
5134 else
5135 {
5136 get();
5137 }
5138
5139 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char>::eof()))
5140 {
5141 return sax->parse_error(chars_read, get_token_string(),
5142 parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
5143 }
5144 }
5145
5146 return result;
5147 }
5148
5149 /*!
5150 @brief determine system byte order
5151
5152 @return true if and only if system's byte order is little endian
5153
5154 @note from http://stackoverflow.com/a/1001328/266378
5155 */
5156 static constexpr bool little_endianess(int num = 1) noexcept
5157 {
5158 return *reinterpret_cast<char*>(&num) == 1;
5159 }
5160
5161 private:
5162 //////////
5163 // BSON //
5164 //////////
5165
5166 /*!
5167 @brief Reads in a BSON-object and passes it to the SAX-parser.
5168 @return whether a valid BSON-value was passed to the SAX parser
5169 */
5170 bool parse_bson_internal()
5171 {
5172 std::int32_t document_size;
5173 get_number<std::int32_t, true>(input_format_t::bson, document_size);
5174
5175 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
5176 {
5177 return false;
5178 }
5179
5180 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(/*is_array*/false)))
5181 {
5182 return false;
5183 }
5184
5185 return sax->end_object();
5186 }
5187
5188 /*!
5189 @brief Parses a C-style string from the BSON input.
5190 @param[in, out] result A reference to the string variable where the read
5191 string is to be stored.
5192 @return `true` if the \x00-byte indicating the end of the string was
5193 encountered before the EOF; false` indicates an unexpected EOF.
5194 */
5195 bool get_bson_cstr(string_t& result)
5196 {
5197 auto out = std::back_inserter(result);
5198 while (true)
5199 {
5200 get();
5201 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "cstring")))
5202 {
5203 return false;
5204 }
5205 if (current == 0x00)
5206 {
5207 return true;
5208 }
5209 *out++ = static_cast<char>(current);
5210 }
5211
5212 return true;
5213 }
5214
5215 /*!
5216 @brief Parses a zero-terminated string of length @a len from the BSON
5217 input.
5218 @param[in] len The length (including the zero-byte at the end) of the
5219 string to be read.
5220 @param[in, out] result A reference to the string variable where the read
5221 string is to be stored.
5222 @tparam NumberType The type of the length @a len
5223 @pre len >= 1
5224 @return `true` if the string was successfully parsed
5225 */
5226 template<typename NumberType>
5227 bool get_bson_string(const NumberType len, string_t& result)
5228 {
5229 if (JSON_HEDLEY_UNLIKELY(len < 1))
5230 {
5231 auto last_token = get_token_string();
5232 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")));
5233 }
5234
5235 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) and get() != std::char_traits<char>::eof();
5236 }
5237
5238 /*!
5239 @brief Read a BSON document element of the given @a element_type.
5240 @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html
5241 @param[in] element_type_parse_position The position in the input stream,
5242 where the `element_type` was read.
5243 @warning Not all BSON element types are supported yet. An unsupported
5244 @a element_type will give rise to a parse_error.114:
5245 Unsupported BSON record type 0x...
5246 @return whether a valid BSON-object/array was passed to the SAX parser
5247 */
5248 bool parse_bson_element_internal(const int element_type,
5249 const std::size_t element_type_parse_position)
5250 {
5251 switch (element_type)
5252 {
5253 case 0x01: // double
5254 {
5255 double number;
5256 return get_number<double, true>(input_format_t::bson, number) and sax->number_float(static_cast<number_float_t>(number), "");
5257 }
5258
5259 case 0x02: // string
5260 {
5261 std::int32_t len;
5262 string_t value;
5263 return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_string(len, value) and sax->string(value);
5264 }
5265
5266 case 0x03: // object
5267 {
5268 return parse_bson_internal();
5269 }
5270
5271 case 0x04: // array
5272 {
5273 return parse_bson_array();
5274 }
5275
5276 case 0x08: // boolean
5277 {
5278 return sax->boolean(get() != 0);
5279 }
5280
5281 case 0x0A: // null
5282 {
5283 return sax->null();
5284 }
5285
5286 case 0x10: // int32
5287 {
5288 std::int32_t value;
5289 return get_number<std::int32_t, true>(input_format_t::bson, value) and sax->number_integer(value);
5290 }
5291
5292 case 0x12: // int64
5293 {
5294 std::int64_t value;
5295 return get_number<std::int64_t, true>(input_format_t::bson, value) and sax->number_integer(value);
5296 }
5297
5298 default: // anything else not supported (yet)
5299 {
5300 std::array<char, 3> cr{{}};
5301 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type));
5302 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())));
5303 }
5304 }
5305 }
5306
5307 /*!
5308 @brief Read a BSON element list (as specified in the BSON-spec)
5309
5310 The same binary layout is used for objects and arrays, hence it must be
5311 indicated with the argument @a is_array which one is expected
5312 (true --> array, false --> object).
5313
5314 @param[in] is_array Determines if the element list being read is to be
5315 treated as an object (@a is_array == false), or as an
5316 array (@a is_array == true).
5317 @return whether a valid BSON-object/array was passed to the SAX parser
5318 */
5319 bool parse_bson_element_list(const bool is_array)
5320 {
5321 string_t key;
5322 while (int element_type = get())
5323 {
5324 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list")))
5325 {
5326 return false;
5327 }
5328
5329 const std::size_t element_type_parse_position = chars_read;
5330 if (JSON_HEDLEY_UNLIKELY(not get_bson_cstr(key)))
5331 {
5332 return false;
5333 }
5334
5335 if (not is_array and not sax->key(key))
5336 {
5337 return false;
5338 }
5339
5340 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
5341 {
5342 return false;
5343 }
5344
5345 // get_bson_cstr only appends
5346 key.clear();
5347 }
5348
5349 return true;
5350 }
5351
5352 /*!
5353 @brief Reads an array from the BSON input and passes it to the SAX-parser.
5354 @return whether a valid BSON-array was passed to the SAX parser
5355 */
5356 bool parse_bson_array()
5357 {
5358 std::int32_t document_size;
5359 get_number<std::int32_t, true>(input_format_t::bson, document_size);
5360
5361 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
5362 {
5363 return false;
5364 }
5365
5366 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(/*is_array*/true)))
5367 {
5368 return false;
5369 }
5370
5371 return sax->end_array();
5372 }
5373
5374 //////////
5375 // CBOR //
5376 //////////
5377
5378 /*!
5379 @param[in] get_char whether a new character should be retrieved from the
5380 input (true, default) or whether the last read
5381 character should be considered instead
5382
5383 @return whether a valid CBOR value was passed to the SAX parser
5384 */
5385 bool parse_cbor_internal(const bool get_char = true)
5386 {
5387 switch (get_char ? get() : current)
5388 {
5389 // EOF
5390 case std::char_traits<char>::eof():
5391 return unexpect_eof(input_format_t::cbor, "value");
5392
5393 // Integer 0x00..0x17 (0..23)
5394 case 0x00:
5395 case 0x01:
5396 case 0x02:
5397 case 0x03:
5398 case 0x04:
5399 case 0x05:
5400 case 0x06:
5401 case 0x07:
5402 case 0x08:
5403 case 0x09:
5404 case 0x0A:
5405 case 0x0B:
5406 case 0x0C:
5407 case 0x0D:
5408 case 0x0E:
5409 case 0x0F:
5410 case 0x10:
5411 case 0x11:
5412 case 0x12:
5413 case 0x13:
5414 case 0x14:
5415 case 0x15:
5416 case 0x16:
5417 case 0x17:
5418 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
5419
5420 case 0x18: // Unsigned integer (one-byte uint8_t follows)
5421 {
5422 std::uint8_t number;
5423 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
5424 }
5425
5426 case 0x19: // Unsigned integer (two-byte uint16_t follows)
5427 {
5428 std::uint16_t number;
5429 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
5430 }
5431
5432 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
5433 {
5434 std::uint32_t number;
5435 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
5436 }
5437
5438 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
5439 {
5440 std::uint64_t number;
5441 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
5442 }
5443
5444 // Negative integer -1-0x00..-1-0x17 (-1..-24)
5445 case 0x20:
5446 case 0x21:
5447 case 0x22:
5448 case 0x23:
5449 case 0x24:
5450 case 0x25:
5451 case 0x26:
5452 case 0x27:
5453 case 0x28:
5454 case 0x29:
5455 case 0x2A:
5456 case 0x2B:
5457 case 0x2C:
5458 case 0x2D:
5459 case 0x2E:
5460 case 0x2F:
5461 case 0x30:
5462 case 0x31:
5463 case 0x32:
5464 case 0x33:
5465 case 0x34:
5466 case 0x35:
5467 case 0x36:
5468 case 0x37:
5469 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
5470
5471 case 0x38: // Negative integer (one-byte uint8_t follows)
5472 {
5473 std::uint8_t number;
5474 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
5475 }
5476
5477 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
5478 {
5479 std::uint16_t number;
5480 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
5481 }
5482
5483 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
5484 {
5485 std::uint32_t number;
5486 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
5487 }
5488
5489 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
5490 {
5491 std::uint64_t number;
5492 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1)
5493 - static_cast<number_integer_t>(number));
5494 }
5495
5496 // UTF-8 string (0x00..0x17 bytes follow)
5497 case 0x60:
5498 case 0x61:
5499 case 0x62:
5500 case 0x63:
5501 case 0x64:
5502 case 0x65:
5503 case 0x66:
5504 case 0x67:
5505 case 0x68:
5506 case 0x69:
5507 case 0x6A:
5508 case 0x6B:
5509 case 0x6C:
5510 case 0x6D:
5511 case 0x6E:
5512 case 0x6F:
5513 case 0x70:
5514 case 0x71:
5515 case 0x72:
5516 case 0x73:
5517 case 0x74:
5518 case 0x75:
5519 case 0x76:
5520 case 0x77:
5521 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
5522 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
5523 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
5524 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
5525 case 0x7F: // UTF-8 string (indefinite length)
5526 {
5527 string_t s;
5528 return get_cbor_string(s) and sax->string(s);
5529 }
5530
5531 // array (0x00..0x17 data items follow)
5532 case 0x80:
5533 case 0x81:
5534 case 0x82:
5535 case 0x83:
5536 case 0x84:
5537 case 0x85:
5538 case 0x86:
5539 case 0x87:
5540 case 0x88:
5541 case 0x89:
5542 case 0x8A:
5543 case 0x8B:
5544 case 0x8C:
5545 case 0x8D:
5546 case 0x8E:
5547 case 0x8F:
5548 case 0x90:
5549 case 0x91:
5550 case 0x92:
5551 case 0x93:
5552 case 0x94:
5553 case 0x95:
5554 case 0x96:
5555 case 0x97:
5556 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
5557
5558 case 0x98: // array (one-byte uint8_t for n follows)
5559 {
5560 std::uint8_t len;
5561 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
5562 }
5563
5564 case 0x99: // array (two-byte uint16_t for n follow)
5565 {
5566 std::uint16_t len;
5567 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
5568 }
5569
5570 case 0x9A: // array (four-byte uint32_t for n follow)
5571 {
5572 std::uint32_t len;
5573 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
5574 }
5575
5576 case 0x9B: // array (eight-byte uint64_t for n follow)
5577 {
5578 std::uint64_t len;
5579 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
5580 }
5581
5582 case 0x9F: // array (indefinite length)
5583 return get_cbor_array(std::size_t(-1));
5584
5585 // map (0x00..0x17 pairs of data items follow)
5586 case 0xA0:
5587 case 0xA1:
5588 case 0xA2:
5589 case 0xA3:
5590 case 0xA4:
5591 case 0xA5:
5592 case 0xA6:
5593 case 0xA7:
5594 case 0xA8:
5595 case 0xA9:
5596 case 0xAA:
5597 case 0xAB:
5598 case 0xAC:
5599 case 0xAD:
5600 case 0xAE:
5601 case 0xAF:
5602 case 0xB0:
5603 case 0xB1:
5604 case 0xB2:
5605 case 0xB3:
5606 case 0xB4:
5607 case 0xB5:
5608 case 0xB6:
5609 case 0xB7:
5610 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
5611
5612 case 0xB8: // map (one-byte uint8_t for n follows)
5613 {
5614 std::uint8_t len;
5615 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
5616 }
5617
5618 case 0xB9: // map (two-byte uint16_t for n follow)
5619 {
5620 std::uint16_t len;
5621 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
5622 }
5623
5624 case 0xBA: // map (four-byte uint32_t for n follow)
5625 {
5626 std::uint32_t len;
5627 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
5628 }
5629
5630 case 0xBB: // map (eight-byte uint64_t for n follow)
5631 {
5632 std::uint64_t len;
5633 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
5634 }
5635
5636 case 0xBF: // map (indefinite length)
5637 return get_cbor_object(std::size_t(-1));
5638
5639 case 0xF4: // false
5640 return sax->boolean(false);
5641
5642 case 0xF5: // true
5643 return sax->boolean(true);
5644
5645 case 0xF6: // null
5646 return sax->null();
5647
5648 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
5649 {
5650 const int byte1_raw = get();
5651 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
5652 {
5653 return false;
5654 }
5655 const int byte2_raw = get();
5656 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
5657 {
5658 return false;
5659 }
5660
5661 const auto byte1 = static_cast<unsigned char>(byte1_raw);
5662 const auto byte2 = static_cast<unsigned char>(byte2_raw);
5663
5664 // code from RFC 7049, Appendix D, Figure 3:
5665 // As half-precision floating-point numbers were only added
5666 // to IEEE 754 in 2008, today's programming platforms often
5667 // still only have limited support for them. It is very
5668 // easy to include at least decoding support for them even
5669 // without such support. An example of a small decoder for
5670 // half-precision floating-point numbers in the C language
5671 // is shown in Fig. 3.
5672 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
5673 const double val = [&half]
5674 {
5675 const int exp = (half >> 10u) & 0x1Fu;
5676 const unsigned int mant = half & 0x3FFu;
5677 assert(0 <= exp and exp <= 32);
5678 assert(0 <= mant and mant <= 1024);
5679 switch (exp)
5680 {
5681 case 0:
5682 return std::ldexp(mant, -24);
5683 case 31:
5684 return (mant == 0)
5685 ? std::numeric_limits<double>::infinity()
5686 : std::numeric_limits<double>::quiet_NaN();
5687 default:
5688 return std::ldexp(mant + 1024, exp - 25);
5689 }
5690 }();
5691 return sax->number_float((half & 0x8000u) != 0
5692 ? static_cast<number_float_t>(-val)
5693 : static_cast<number_float_t>(val), "");
5694 }
5695
5696 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
5697 {
5698 float number;
5699 return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
5700 }
5701
5702 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
5703 {
5704 double number;
5705 return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
5706 }
5707
5708 default: // anything else (0xFF is handled inside the other types)
5709 {
5710 auto last_token = get_token_string();
5711 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")));
5712 }
5713 }
5714 }
5715
5716 /*!
5717 @brief reads a CBOR string
5718
5719 This function first reads starting bytes to determine the expected
5720 string length and then copies this number of bytes into a string.
5721 Additionally, CBOR's strings with indefinite lengths are supported.
5722
5723 @param[out] result created string
5724
5725 @return whether string creation completed
5726 */
5727 bool get_cbor_string(string_t& result)
5728 {
5729 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "string")))
5730 {
5731 return false;
5732 }
5733
5734 switch (current)
5735 {
5736 // UTF-8 string (0x00..0x17 bytes follow)
5737 case 0x60:
5738 case 0x61:
5739 case 0x62:
5740 case 0x63:
5741 case 0x64:
5742 case 0x65:
5743 case 0x66:
5744 case 0x67:
5745 case 0x68:
5746 case 0x69:
5747 case 0x6A:
5748 case 0x6B:
5749 case 0x6C:
5750 case 0x6D:
5751 case 0x6E:
5752 case 0x6F:
5753 case 0x70:
5754 case 0x71:
5755 case 0x72:
5756 case 0x73:
5757 case 0x74:
5758 case 0x75:
5759 case 0x76:
5760 case 0x77:
5761 {
5762 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
5763 }
5764
5765 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
5766 {
5767 std::uint8_t len;
5768 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
5769 }
5770
5771 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
5772 {
5773 std::uint16_t len;
5774 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
5775 }
5776
5777 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
5778 {
5779 std::uint32_t len;
5780 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
5781 }
5782
5783 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
5784 {
5785 std::uint64_t len;
5786 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
5787 }
5788
5789 case 0x7F: // UTF-8 string (indefinite length)
5790 {
5791 while (get() != 0xFF)
5792 {
5793 string_t chunk;
5794 if (not get_cbor_string(chunk))
5795 {
5796 return false;
5797 }
5798 result.append(chunk);
5799 }
5800 return true;
5801 }
5802
5803 default:
5804 {
5805 auto last_token = get_token_string();
5806 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")));
5807 }
5808 }
5809 }
5810
5811 /*!
5812 @param[in] len the length of the array or std::size_t(-1) for an
5813 array of indefinite size
5814 @return whether array creation completed
5815 */
5816 bool get_cbor_array(const std::size_t len)
5817 {
5818 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len)))
5819 {
5820 return false;
5821 }
5822
5823 if (len != std::size_t(-1))
5824 {
5825 for (std::size_t i = 0; i < len; ++i)
5826 {
5827 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
5828 {
5829 return false;
5830 }
5831 }
5832 }
5833 else
5834 {
5835 while (get() != 0xFF)
5836 {
5837 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal(false)))
5838 {
5839 return false;
5840 }
5841 }
5842 }
5843
5844 return sax->end_array();
5845 }
5846
5847 /*!
5848 @param[in] len the length of the object or std::size_t(-1) for an
5849 object of indefinite size
5850 @return whether object creation completed
5851 */
5852 bool get_cbor_object(const std::size_t len)
5853 {
5854 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len)))
5855 {
5856 return false;
5857 }
5858
5859 string_t key;
5860 if (len != std::size_t(-1))
5861 {
5862 for (std::size_t i = 0; i < len; ++i)
5863 {
5864 get();
5865 if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
5866 {
5867 return false;
5868 }
5869
5870 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
5871 {
5872 return false;
5873 }
5874 key.clear();
5875 }
5876 }
5877 else
5878 {
5879 while (get() != 0xFF)
5880 {
5881 if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
5882 {
5883 return false;
5884 }
5885
5886 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
5887 {
5888 return false;
5889 }
5890 key.clear();
5891 }
5892 }
5893
5894 return sax->end_object();
5895 }
5896
5897 /////////////
5898 // MsgPack //
5899 /////////////
5900
5901 /*!
5902 @return whether a valid MessagePack value was passed to the SAX parser
5903 */
5904 bool parse_msgpack_internal()
5905 {
5906 switch (get())
5907 {
5908 // EOF
5909 case std::char_traits<char>::eof():
5910 return unexpect_eof(input_format_t::msgpack, "value");
5911
5912 // positive fixint
5913 case 0x00:
5914 case 0x01:
5915 case 0x02:
5916 case 0x03:
5917 case 0x04:
5918 case 0x05:
5919 case 0x06:
5920 case 0x07:
5921 case 0x08:
5922 case 0x09:
5923 case 0x0A:
5924 case 0x0B:
5925 case 0x0C:
5926 case 0x0D:
5927 case 0x0E:
5928 case 0x0F:
5929 case 0x10:
5930 case 0x11:
5931 case 0x12:
5932 case 0x13:
5933 case 0x14:
5934 case 0x15:
5935 case 0x16:
5936 case 0x17:
5937 case 0x18:
5938 case 0x19:
5939 case 0x1A:
5940 case 0x1B:
5941 case 0x1C:
5942 case 0x1D:
5943 case 0x1E:
5944 case 0x1F:
5945 case 0x20:
5946 case 0x21:
5947 case 0x22:
5948 case 0x23:
5949 case 0x24:
5950 case 0x25:
5951 case 0x26:
5952 case 0x27:
5953 case 0x28:
5954 case 0x29:
5955 case 0x2A:
5956 case 0x2B:
5957 case 0x2C:
5958 case 0x2D:
5959 case 0x2E:
5960 case 0x2F:
5961 case 0x30:
5962 case 0x31:
5963 case 0x32:
5964 case 0x33:
5965 case 0x34:
5966 case 0x35:
5967 case 0x36:
5968 case 0x37:
5969 case 0x38:
5970 case 0x39:
5971 case 0x3A:
5972 case 0x3B:
5973 case 0x3C:
5974 case 0x3D:
5975 case 0x3E:
5976 case 0x3F:
5977 case 0x40:
5978 case 0x41:
5979 case 0x42:
5980 case 0x43:
5981 case 0x44:
5982 case 0x45:
5983 case 0x46:
5984 case 0x47:
5985 case 0x48:
5986 case 0x49:
5987 case 0x4A:
5988 case 0x4B:
5989 case 0x4C:
5990 case 0x4D:
5991 case 0x4E:
5992 case 0x4F:
5993 case 0x50:
5994 case 0x51:
5995 case 0x52:
5996 case 0x53:
5997 case 0x54:
5998 case 0x55:
5999 case 0x56:
6000 case 0x57:
6001 case 0x58:
6002 case 0x59:
6003 case 0x5A:
6004 case 0x5B:
6005 case 0x5C:
6006 case 0x5D:
6007 case 0x5E:
6008 case 0x5F:
6009 case 0x60:
6010 case 0x61:
6011 case 0x62:
6012 case 0x63:
6013 case 0x64:
6014 case 0x65:
6015 case 0x66:
6016 case 0x67:
6017 case 0x68:
6018 case 0x69:
6019 case 0x6A:
6020 case 0x6B:
6021 case 0x6C:
6022 case 0x6D:
6023 case 0x6E:
6024 case 0x6F:
6025 case 0x70:
6026 case 0x71:
6027 case 0x72:
6028 case 0x73:
6029 case 0x74:
6030 case 0x75:
6031 case 0x76:
6032 case 0x77:
6033 case 0x78:
6034 case 0x79:
6035 case 0x7A:
6036 case 0x7B:
6037 case 0x7C:
6038 case 0x7D:
6039 case 0x7E:
6040 case 0x7F:
6041 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
6042
6043 // fixmap
6044 case 0x80:
6045 case 0x81:
6046 case 0x82:
6047 case 0x83:
6048 case 0x84:
6049 case 0x85:
6050 case 0x86:
6051 case 0x87:
6052 case 0x88:
6053 case 0x89:
6054 case 0x8A:
6055 case 0x8B:
6056 case 0x8C:
6057 case 0x8D:
6058 case 0x8E:
6059 case 0x8F:
6060 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
6061
6062 // fixarray
6063 case 0x90:
6064 case 0x91:
6065 case 0x92:
6066 case 0x93:
6067 case 0x94:
6068 case 0x95:
6069 case 0x96:
6070 case 0x97:
6071 case 0x98:
6072 case 0x99:
6073 case 0x9A:
6074 case 0x9B:
6075 case 0x9C:
6076 case 0x9D:
6077 case 0x9E:
6078 case 0x9F:
6079 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
6080
6081 // fixstr
6082 case 0xA0:
6083 case 0xA1:
6084 case 0xA2:
6085 case 0xA3:
6086 case 0xA4:
6087 case 0xA5:
6088 case 0xA6:
6089 case 0xA7:
6090 case 0xA8:
6091 case 0xA9:
6092 case 0xAA:
6093 case 0xAB:
6094 case 0xAC:
6095 case 0xAD:
6096 case 0xAE:
6097 case 0xAF:
6098 case 0xB0:
6099 case 0xB1:
6100 case 0xB2:
6101 case 0xB3:
6102 case 0xB4:
6103 case 0xB5:
6104 case 0xB6:
6105 case 0xB7:
6106 case 0xB8:
6107 case 0xB9:
6108 case 0xBA:
6109 case 0xBB:
6110 case 0xBC:
6111 case 0xBD:
6112 case 0xBE:
6113 case 0xBF:
6114 case 0xD9: // str 8
6115 case 0xDA: // str 16
6116 case 0xDB: // str 32
6117 {
6118 string_t s;
6119 return get_msgpack_string(s) and sax->string(s);
6120 }
6121
6122 case 0xC0: // nil
6123 return sax->null();
6124
6125 case 0xC2: // false
6126 return sax->boolean(false);
6127
6128 case 0xC3: // true
6129 return sax->boolean(true);
6130
6131 case 0xCA: // float 32
6132 {
6133 float number;
6134 return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
6135 }
6136
6137 case 0xCB: // float 64
6138 {
6139 double number;
6140 return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
6141 }
6142
6143 case 0xCC: // uint 8
6144 {
6145 std::uint8_t number;
6146 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
6147 }
6148
6149 case 0xCD: // uint 16
6150 {
6151 std::uint16_t number;
6152 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
6153 }
6154
6155 case 0xCE: // uint 32
6156 {
6157 std::uint32_t number;
6158 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
6159 }
6160
6161 case 0xCF: // uint 64
6162 {
6163 std::uint64_t number;
6164 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
6165 }
6166
6167 case 0xD0: // int 8
6168 {
6169 std::int8_t number;
6170 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
6171 }
6172
6173 case 0xD1: // int 16
6174 {
6175 std::int16_t number;
6176 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
6177 }
6178
6179 case 0xD2: // int 32
6180 {
6181 std::int32_t number;
6182 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
6183 }
6184
6185 case 0xD3: // int 64
6186 {
6187 std::int64_t number;
6188 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
6189 }
6190
6191 case 0xDC: // array 16
6192 {
6193 std::uint16_t len;
6194 return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
6195 }
6196
6197 case 0xDD: // array 32
6198 {
6199 std::uint32_t len;
6200 return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
6201 }
6202
6203 case 0xDE: // map 16
6204 {
6205 std::uint16_t len;
6206 return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
6207 }
6208
6209 case 0xDF: // map 32
6210 {
6211 std::uint32_t len;
6212 return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
6213 }
6214
6215 // negative fixint
6216 case 0xE0:
6217 case 0xE1:
6218 case 0xE2:
6219 case 0xE3:
6220 case 0xE4:
6221 case 0xE5:
6222 case 0xE6:
6223 case 0xE7:
6224 case 0xE8:
6225 case 0xE9:
6226 case 0xEA:
6227 case 0xEB:
6228 case 0xEC:
6229 case 0xED:
6230 case 0xEE:
6231 case 0xEF:
6232 case 0xF0:
6233 case 0xF1:
6234 case 0xF2:
6235 case 0xF3:
6236 case 0xF4:
6237 case 0xF5:
6238 case 0xF6:
6239 case 0xF7:
6240 case 0xF8:
6241 case 0xF9:
6242 case 0xFA:
6243 case 0xFB:
6244 case 0xFC:
6245 case 0xFD:
6246 case 0xFE:
6247 case 0xFF:
6248 return sax->number_integer(static_cast<std::int8_t>(current));
6249
6250 default: // anything else
6251 {
6252 auto last_token = get_token_string();
6253 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")));
6254 }
6255 }
6256 }
6257
6258 /*!
6259 @brief reads a MessagePack string
6260
6261 This function first reads starting bytes to determine the expected
6262 string length and then copies this number of bytes into a string.
6263
6264 @param[out] result created string
6265
6266 @return whether string creation completed
6267 */
6268 bool get_msgpack_string(string_t& result)
6269 {
6270 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string")))
6271 {
6272 return false;
6273 }
6274
6275 switch (current)
6276 {
6277 // fixstr
6278 case 0xA0:
6279 case 0xA1:
6280 case 0xA2:
6281 case 0xA3:
6282 case 0xA4:
6283 case 0xA5:
6284 case 0xA6:
6285 case 0xA7:
6286 case 0xA8:
6287 case 0xA9:
6288 case 0xAA:
6289 case 0xAB:
6290 case 0xAC:
6291 case 0xAD:
6292 case 0xAE:
6293 case 0xAF:
6294 case 0xB0:
6295 case 0xB1:
6296 case 0xB2:
6297 case 0xB3:
6298 case 0xB4:
6299 case 0xB5:
6300 case 0xB6:
6301 case 0xB7:
6302 case 0xB8:
6303 case 0xB9:
6304 case 0xBA:
6305 case 0xBB:
6306 case 0xBC:
6307 case 0xBD:
6308 case 0xBE:
6309 case 0xBF:
6310 {
6311 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
6312 }
6313
6314 case 0xD9: // str 8
6315 {
6316 std::uint8_t len;
6317 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
6318 }
6319
6320 case 0xDA: // str 16
6321 {
6322 std::uint16_t len;
6323 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
6324 }
6325
6326 case 0xDB: // str 32
6327 {
6328 std::uint32_t len;
6329 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
6330 }
6331
6332 default:
6333 {
6334 auto last_token = get_token_string();
6335 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")));
6336 }
6337 }
6338 }
6339
6340 /*!
6341 @param[in] len the length of the array
6342 @return whether array creation completed
6343 */
6344 bool get_msgpack_array(const std::size_t len)
6345 {
6346 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len)))
6347 {
6348 return false;
6349 }
6350
6351 for (std::size_t i = 0; i < len; ++i)
6352 {
6353 if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal()))
6354 {
6355 return false;
6356 }
6357 }
6358
6359 return sax->end_array();
6360 }
6361
6362 /*!
6363 @param[in] len the length of the object
6364 @return whether object creation completed
6365 */
6366 bool get_msgpack_object(const std::size_t len)
6367 {
6368 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len)))
6369 {
6370 return false;
6371 }
6372
6373 string_t key;
6374 for (std::size_t i = 0; i < len; ++i)
6375 {
6376 get();
6377 if (JSON_HEDLEY_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
6378 {
6379 return false;
6380 }
6381
6382 if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal()))
6383 {
6384 return false;
6385 }
6386 key.clear();
6387 }
6388
6389 return sax->end_object();
6390 }
6391
6392 ////////////
6393 // UBJSON //
6394 ////////////
6395
6396 /*!
6397 @param[in] get_char whether a new character should be retrieved from the
6398 input (true, default) or whether the last read
6399 character should be considered instead
6400
6401 @return whether a valid UBJSON value was passed to the SAX parser
6402 */
6403 bool parse_ubjson_internal(const bool get_char = true)
6404 {
6405 return get_ubjson_value(get_char ? get_ignore_noop() : current);
6406 }
6407
6408 /*!
6409 @brief reads a UBJSON string
6410
6411 This function is either called after reading the 'S' byte explicitly
6412 indicating a string, or in case of an object key where the 'S' byte can be
6413 left out.
6414
6415 @param[out] result created string
6416 @param[in] get_char whether a new character should be retrieved from the
6417 input (true, default) or whether the last read
6418 character should be considered instead
6419
6420 @return whether string creation completed
6421 */
6422 bool get_ubjson_string(string_t& result, const bool get_char = true)
6423 {
6424 if (get_char)
6425 {
6426 get(); // TODO(niels): may we ignore N here?
6427 }
6428
6429 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
6430 {
6431 return false;
6432 }
6433
6434 switch (current)
6435 {
6436 case 'U':
6437 {
6438 std::uint8_t len;
6439 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
6440 }
6441
6442 case 'i':
6443 {
6444 std::int8_t len;
6445 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
6446 }
6447
6448 case 'I':
6449 {
6450 std::int16_t len;
6451 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
6452 }
6453
6454 case 'l':
6455 {
6456 std::int32_t len;
6457 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
6458 }
6459
6460 case 'L':
6461 {
6462 std::int64_t len;
6463 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
6464 }
6465
6466 default:
6467 auto last_token = get_token_string();
6468 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")));
6469 }
6470 }
6471
6472 /*!
6473 @param[out] result determined size
6474 @return whether size determination completed
6475 */
6476 bool get_ubjson_size_value(std::size_t& result)
6477 {
6478 switch (get_ignore_noop())
6479 {
6480 case 'U':
6481 {
6482 std::uint8_t number;
6483 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
6484 {
6485 return false;
6486 }
6487 result = static_cast<std::size_t>(number);
6488 return true;
6489 }
6490
6491 case 'i':
6492 {
6493 std::int8_t number;
6494 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
6495 {
6496 return false;
6497 }
6498 result = static_cast<std::size_t>(number);
6499 return true;
6500 }
6501
6502 case 'I':
6503 {
6504 std::int16_t number;
6505 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
6506 {
6507 return false;
6508 }
6509 result = static_cast<std::size_t>(number);
6510 return true;
6511 }
6512
6513 case 'l':
6514 {
6515 std::int32_t number;
6516 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
6517 {
6518 return false;
6519 }
6520 result = static_cast<std::size_t>(number);
6521 return true;
6522 }
6523
6524 case 'L':
6525 {
6526 std::int64_t number;
6527 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
6528 {
6529 return false;
6530 }
6531 result = static_cast<std::size_t>(number);
6532 return true;
6533 }
6534
6535 default:
6536 {
6537 auto last_token = get_token_string();
6538 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")));
6539 }
6540 }
6541 }
6542
6543 /*!
6544 @brief determine the type and size for a container
6545
6546 In the optimized UBJSON format, a type and a size can be provided to allow
6547 for a more compact representation.
6548
6549 @param[out] result pair of the size and the type
6550
6551 @return whether pair creation completed
6552 */
6553 bool get_ubjson_size_type(std::pair<std::size_t, int>& result)
6554 {
6555 result.first = string_t::npos; // size
6556 result.second = 0; // type
6557
6558 get_ignore_noop();
6559
6560 if (current == '$')
6561 {
6562 result.second = get(); // must not ignore 'N', because 'N' maybe the type
6563 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "type")))
6564 {
6565 return false;
6566 }
6567
6568 get_ignore_noop();
6569 if (JSON_HEDLEY_UNLIKELY(current != '#'))
6570 {
6571 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
6572 {
6573 return false;
6574 }
6575 auto last_token = get_token_string();
6576 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")));
6577 }
6578
6579 return get_ubjson_size_value(result.first);
6580 }
6581
6582 if (current == '#')
6583 {
6584 return get_ubjson_size_value(result.first);
6585 }
6586
6587 return true;
6588 }
6589
6590 /*!
6591 @param prefix the previously read or set type prefix
6592 @return whether value creation completed
6593 */
6594 bool get_ubjson_value(const int prefix)
6595 {
6596 switch (prefix)
6597 {
6598 case std::char_traits<char>::eof(): // EOF
6599 return unexpect_eof(input_format_t::ubjson, "value");
6600
6601 case 'T': // true
6602 return sax->boolean(true);
6603 case 'F': // false
6604 return sax->boolean(false);
6605
6606 case 'Z': // null
6607 return sax->null();
6608
6609 case 'U':
6610 {
6611 std::uint8_t number;
6612 return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number);
6613 }
6614
6615 case 'i':
6616 {
6617 std::int8_t number;
6618 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
6619 }
6620
6621 case 'I':
6622 {
6623 std::int16_t number;
6624 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
6625 }
6626
6627 case 'l':
6628 {
6629 std::int32_t number;
6630 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
6631 }
6632
6633 case 'L':
6634 {
6635 std::int64_t number;
6636 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
6637 }
6638
6639 case 'd':
6640 {
6641 float number;
6642 return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
6643 }
6644
6645 case 'D':
6646 {
6647 double number;
6648 return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
6649 }
6650
6651 case 'C': // char
6652 {
6653 get();
6654 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char")))
6655 {
6656 return false;
6657 }
6658 if (JSON_HEDLEY_UNLIKELY(current > 127))
6659 {
6660 auto last_token = get_token_string();
6661 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")));
6662 }
6663 string_t s(1, static_cast<char>(current));
6664 return sax->string(s);
6665 }
6666
6667 case 'S': // string
6668 {
6669 string_t s;
6670 return get_ubjson_string(s) and sax->string(s);
6671 }
6672
6673 case '[': // array
6674 return get_ubjson_array();
6675
6676 case '{': // object
6677 return get_ubjson_object();
6678
6679 default: // anything else
6680 {
6681 auto last_token = get_token_string();
6682 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")));
6683 }
6684 }
6685 }
6686
6687 /*!
6688 @return whether array creation completed
6689 */
6690 bool get_ubjson_array()
6691 {
6692 std::pair<std::size_t, int> size_and_type;
6693 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
6694 {
6695 return false;
6696 }
6697
6698 if (size_and_type.first != string_t::npos)
6699 {
6700 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(size_and_type.first)))
6701 {
6702 return false;
6703 }
6704
6705 if (size_and_type.second != 0)
6706 {
6707 if (size_and_type.second != 'N')
6708 {
6709 for (std::size_t i = 0; i < size_and_type.first; ++i)
6710 {
6711 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second)))
6712 {
6713 return false;
6714 }
6715 }
6716 }
6717 }
6718 else
6719 {
6720 for (std::size_t i = 0; i < size_and_type.first; ++i)
6721 {
6722 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
6723 {
6724 return false;
6725 }
6726 }
6727 }
6728 }
6729 else
6730 {
6731 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
6732 {
6733 return false;
6734 }
6735
6736 while (current != ']')
6737 {
6738 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal(false)))
6739 {
6740 return false;
6741 }
6742 get_ignore_noop();
6743 }
6744 }
6745
6746 return sax->end_array();
6747 }
6748
6749 /*!
6750 @return whether object creation completed
6751 */
6752 bool get_ubjson_object()
6753 {
6754 std::pair<std::size_t, int> size_and_type;
6755 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
6756 {
6757 return false;
6758 }
6759
6760 string_t key;
6761 if (size_and_type.first != string_t::npos)
6762 {
6763 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(size_and_type.first)))
6764 {
6765 return false;
6766 }
6767
6768 if (size_and_type.second != 0)
6769 {
6770 for (std::size_t i = 0; i < size_and_type.first; ++i)
6771 {
6772 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
6773 {
6774 return false;
6775 }
6776 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second)))
6777 {
6778 return false;
6779 }
6780 key.clear();
6781 }
6782 }
6783 else
6784 {
6785 for (std::size_t i = 0; i < size_and_type.first; ++i)
6786 {
6787 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
6788 {
6789 return false;
6790 }
6791 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
6792 {
6793 return false;
6794 }
6795 key.clear();
6796 }
6797 }
6798 }
6799 else
6800 {
6801 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
6802 {
6803 return false;
6804 }
6805
6806 while (current != '}')
6807 {
6808 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key, false) or not sax->key(key)))
6809 {
6810 return false;
6811 }
6812 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
6813 {
6814 return false;
6815 }
6816 get_ignore_noop();
6817 key.clear();
6818 }
6819 }
6820
6821 return sax->end_object();
6822 }
6823
6824 ///////////////////////
6825 // Utility functions //
6826 ///////////////////////
6827
6828 /*!
6829 @brief get next character from the input
6830
6831 This function provides the interface to the used input adapter. It does
6832 not throw in case the input reached EOF, but returns a -'ve valued
6833 `std::char_traits<char>::eof()` in that case.
6834
6835 @return character read from the input
6836 */
6837 int get()
6838 {
6839 ++chars_read;
6840 return current = ia->get_character();
6841 }
6842
6843 /*!
6844 @return character read from the input after ignoring all 'N' entries
6845 */
6846 int get_ignore_noop()
6847 {
6848 do
6849 {
6850 get();
6851 }
6852 while (current == 'N');
6853
6854 return current;
6855 }
6856
6857 /*
6858 @brief read a number from the input
6859
6860 @tparam NumberType the type of the number
6861 @param[in] format the current format (for diagnostics)
6862 @param[out] result number of type @a NumberType
6863
6864 @return whether conversion completed
6865
6866 @note This function needs to respect the system's endianess, because
6867 bytes in CBOR, MessagePack, and UBJSON are stored in network order
6868 (big endian) and therefore need reordering on little endian systems.
6869 */
6870 template<typename NumberType, bool InputIsLittleEndian = false>
6871 bool get_number(const input_format_t format, NumberType& result)
6872 {
6873 // step 1: read input into array with system's byte order
6874 std::array<std::uint8_t, sizeof(NumberType)> vec;
6875 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
6876 {
6877 get();
6878 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format, "number")))
6879 {
6880 return false;
6881 }
6882
6883 // reverse byte order prior to conversion if necessary
6884 if (is_little_endian != InputIsLittleEndian)
6885 {
6886 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
6887 }
6888 else
6889 {
6890 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
6891 }
6892 }
6893
6894 // step 2: convert array into number of type T and return
6895 std::memcpy(&result, vec.data(), sizeof(NumberType));
6896 return true;
6897 }
6898
6899 /*!
6900 @brief create a string by reading characters from the input
6901
6902 @tparam NumberType the type of the number
6903 @param[in] format the current format (for diagnostics)
6904 @param[in] len number of characters to read
6905 @param[out] result string created by reading @a len bytes
6906
6907 @return whether string creation completed
6908
6909 @note We can not reserve @a len bytes for the result, because @a len
6910 may be too large. Usually, @ref unexpect_eof() detects the end of
6911 the input before we run out of string memory.
6912 */
6913 template<typename NumberType>
6914 bool get_string(const input_format_t format,
6915 const NumberType len,
6916 string_t& result)
6917 {
6918 bool success = true;
6919 std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
6920 {
6921 get();
6922 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format, "string")))
6923 {
6924 success = false;
6925 }
6926 return static_cast<char>(current);
6927 });
6928 return success;
6929 }
6930
6931 /*!
6932 @param[in] format the current format (for diagnostics)
6933 @param[in] context further context information (for diagnostics)
6934 @return whether the last read character is not EOF
6935 */
6936 JSON_HEDLEY_NON_NULL(3)
6937 bool unexpect_eof(const input_format_t format, const char* context) const
6938 {
6939 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char>::eof()))
6940 {
6941 return sax->parse_error(chars_read, "<end of file>",
6942 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
6943 }
6944 return true;
6945 }
6946
6947 /*!
6948 @return a string representation of the last read byte
6949 */
6950 std::string get_token_string() const
6951 {
6952 std::array<char, 3> cr{{}};
6953 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current));
6954 return std::string{cr.data()};
6955 }
6956
6957 /*!
6958 @param[in] format the current format
6959 @param[in] detail a detailed error message
6960 @param[in] context further contect information
6961 @return a message string to use in the parse_error exceptions
6962 */
6963 std::string exception_message(const input_format_t format,
6964 const std::string& detail,
6965 const std::string& context) const
6966 {
6967 std::string error_msg = "syntax error while parsing ";
6968
6969 switch (format)
6970 {
6971 case input_format_t::cbor:
6972 error_msg += "CBOR";
6973 break;
6974
6975 case input_format_t::msgpack:
6976 error_msg += "MessagePack";
6977 break;
6978
6979 case input_format_t::ubjson:
6980 error_msg += "UBJSON";
6981 break;
6982
6983 case input_format_t::bson:
6984 error_msg += "BSON";
6985 break;
6986
6987 default: // LCOV_EXCL_LINE
6988 assert(false); // LCOV_EXCL_LINE
6989 }
6990
6991 return error_msg + " " + context + ": " + detail;
6992 }
6993
6994 private:
6995 /// input adapter
6996 input_adapter_t ia = nullptr;
6997
6998 /// the current character
6999 int current = std::char_traits<char>::eof();
7000
7001 /// the number of characters read
7002 std::size_t chars_read = 0;
7003
7004 /// whether we can assume little endianess
7005 const bool is_little_endian = little_endianess();
7006
7007 /// the SAX parser
7008 json_sax_t* sax = nullptr;
7009 };
7010 } // namespace detail
7011 } // namespace nlohmann
7012
7013 // #include <nlohmann/detail/input/input_adapters.hpp>
7014
7015 // #include <nlohmann/detail/input/lexer.hpp>
7016
7017
7018 #include <array> // array
7019 #include <clocale> // localeconv
7020 #include <cstddef> // size_t
7021 #include <cstdio> // snprintf
7022 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
7023 #include <initializer_list> // initializer_list
7024 #include <string> // char_traits, string
7025 #include <utility> // move
7026 #include <vector> // vector
7027
7028 // #include <nlohmann/detail/input/input_adapters.hpp>
7029
7030 // #include <nlohmann/detail/input/position_t.hpp>
7031
7032 // #include <nlohmann/detail/macro_scope.hpp>
7033
7034
7035 namespace nlohmann
7036 {
7037 namespace detail
7038 {
7039 ///////////
7040 // lexer //
7041 ///////////
7042
7043 /*!
7044 @brief lexical analysis
7045
7046 This class organizes the lexical analysis during JSON deserialization.
7047 */
7048 template<typename BasicJsonType>
7049 class lexer
7050 {
7051 using number_integer_t = typename BasicJsonType::number_integer_t;
7052 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7053 using number_float_t = typename BasicJsonType::number_float_t;
7054 using string_t = typename BasicJsonType::string_t;
7055
7056 public:
7057 /// token types for the parser
7058 enum class token_type
7059 {
7060 uninitialized, ///< indicating the scanner is uninitialized
7061 literal_true, ///< the `true` literal
7062 literal_false, ///< the `false` literal
7063 literal_null, ///< the `null` literal
7064 value_string, ///< a string -- use get_string() for actual value
7065 value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value
7066 value_integer, ///< a signed integer -- use get_number_integer() for actual value
7067 value_float, ///< an floating point number -- use get_number_float() for actual value
7068 begin_array, ///< the character for array begin `[`
7069 begin_object, ///< the character for object begin `{`
7070 end_array, ///< the character for array end `]`
7071 end_object, ///< the character for object end `}`
7072 name_separator, ///< the name separator `:`
7073 value_separator, ///< the value separator `,`
7074 parse_error, ///< indicating a parse error
7075 end_of_input, ///< indicating the end of the input buffer
7076 literal_or_value ///< a literal or the begin of a value (only for diagnostics)
7077 };
7078
7079 /// return name of values of type token_type (only used for errors)
7080 JSON_HEDLEY_RETURNS_NON_NULL
7081 JSON_HEDLEY_CONST
7082 static const char* token_type_name(const token_type t) noexcept
7083 {
7084 switch (t)
7085 {
7086 case token_type::uninitialized:
7087 return "<uninitialized>";
7088 case token_type::literal_true:
7089 return "true literal";
7090 case token_type::literal_false:
7091 return "false literal";
7092 case token_type::literal_null:
7093 return "null literal";
7094 case token_type::value_string:
7095 return "string literal";
7096 case lexer::token_type::value_unsigned:
7097 case lexer::token_type::value_integer:
7098 case lexer::token_type::value_float:
7099 return "number literal";
7100 case token_type::begin_array:
7101 return "'['";
7102 case token_type::begin_object:
7103 return "'{'";
7104 case token_type::end_array:
7105 return "']'";
7106 case token_type::end_object:
7107 return "'}'";
7108 case token_type::name_separator:
7109 return "':'";
7110 case token_type::value_separator:
7111 return "','";
7112 case token_type::parse_error:
7113 return "<parse error>";
7114 case token_type::end_of_input:
7115 return "end of input";
7116 case token_type::literal_or_value:
7117 return "'[', '{', or a literal";
7118 // LCOV_EXCL_START
7119 default: // catch non-enum values
7120 return "unknown token";
7121 // LCOV_EXCL_STOP
7122 }
7123 }
7124
7125 explicit lexer(detail::input_adapter_t&& adapter)
7126 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
7127
7128 // delete because of pointer members
7129 lexer(const lexer&) = delete;
7130 lexer(lexer&&) = delete;
7131 lexer& operator=(lexer&) = delete;
7132 lexer& operator=(lexer&&) = delete;
7133 ~lexer() = default;
7134
7135 private:
7136 /////////////////////
7137 // locales
7138 /////////////////////
7139
7140 /// return the locale-dependent decimal point
7141 JSON_HEDLEY_PURE
7142 static char get_decimal_point() noexcept
7143 {
7144 const auto loc = localeconv();
7145 assert(loc != nullptr);
7146 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
7147 }
7148
7149 /////////////////////
7150 // scan functions
7151 /////////////////////
7152
7153 /*!
7154 @brief get codepoint from 4 hex characters following `\u`
7155
7156 For input "\u c1 c2 c3 c4" the codepoint is:
7157 (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
7158 = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
7159
7160 Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
7161 must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
7162 conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
7163 between the ASCII value of the character and the desired integer value.
7164
7165 @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
7166 non-hex character)
7167 */
7168 int get_codepoint()
7169 {
7170 // this function only makes sense after reading `\u`
7171 assert(current == 'u');
7172 int codepoint = 0;
7173
7174 const auto factors = { 12u, 8u, 4u, 0u };
7175 for (const auto factor : factors)
7176 {
7177 get();
7178
7179 if (current >= '0' and current <= '9')
7180 {
7181 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
7182 }
7183 else if (current >= 'A' and current <= 'F')
7184 {
7185 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
7186 }
7187 else if (current >= 'a' and current <= 'f')
7188 {
7189 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
7190 }
7191 else
7192 {
7193 return -1;
7194 }
7195 }
7196
7197 assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
7198 return codepoint;
7199 }
7200
7201 /*!
7202 @brief check if the next byte(s) are inside a given range
7203
7204 Adds the current byte and, for each passed range, reads a new byte and
7205 checks if it is inside the range. If a violation was detected, set up an
7206 error message and return false. Otherwise, return true.
7207
7208 @param[in] ranges list of integers; interpreted as list of pairs of
7209 inclusive lower and upper bound, respectively
7210
7211 @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
7212 1, 2, or 3 pairs. This precondition is enforced by an assertion.
7213
7214 @return true if and only if no range violation was detected
7215 */
7216 bool next_byte_in_range(std::initializer_list<int> ranges)
7217 {
7218 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
7219 add(current);
7220
7221 for (auto range = ranges.begin(); range != ranges.end(); ++range)
7222 {
7223 get();
7224 if (JSON_HEDLEY_LIKELY(*range <= current and current <= *(++range)))
7225 {
7226 add(current);
7227 }
7228 else
7229 {
7230 error_message = "invalid string: ill-formed UTF-8 byte";
7231 return false;
7232 }
7233 }
7234
7235 return true;
7236 }
7237
7238 /*!
7239 @brief scan a string literal
7240
7241 This function scans a string according to Sect. 7 of RFC 7159. While
7242 scanning, bytes are escaped and copied into buffer token_buffer. Then the
7243 function returns successfully, token_buffer is *not* null-terminated (as it
7244 may contain \0 bytes), and token_buffer.size() is the number of bytes in the
7245 string.
7246
7247 @return token_type::value_string if string could be successfully scanned,
7248 token_type::parse_error otherwise
7249
7250 @note In case of errors, variable error_message contains a textual
7251 description.
7252 */
7253 token_type scan_string()
7254 {
7255 // reset token_buffer (ignore opening quote)
7256 reset();
7257
7258 // we entered the function by reading an open quote
7259 assert(current == '\"');
7260
7261 while (true)
7262 {
7263 // get next character
7264 switch (get())
7265 {
7266 // end of file while parsing string
7267 case std::char_traits<char>::eof():
7268 {
7269 error_message = "invalid string: missing closing quote";
7270 return token_type::parse_error;
7271 }
7272
7273 // closing quote
7274 case '\"':
7275 {
7276 return token_type::value_string;
7277 }
7278
7279 // escapes
7280 case '\\':
7281 {
7282 switch (get())
7283 {
7284 // quotation mark
7285 case '\"':
7286 add('\"');
7287 break;
7288 // reverse solidus
7289 case '\\':
7290 add('\\');
7291 break;
7292 // solidus
7293 case '/':
7294 add('/');
7295 break;
7296 // backspace
7297 case 'b':
7298 add('\b');
7299 break;
7300 // form feed
7301 case 'f':
7302 add('\f');
7303 break;
7304 // line feed
7305 case 'n':
7306 add('\n');
7307 break;
7308 // carriage return
7309 case 'r':
7310 add('\r');
7311 break;
7312 // tab
7313 case 't':
7314 add('\t');
7315 break;
7316
7317 // unicode escapes
7318 case 'u':
7319 {
7320 const int codepoint1 = get_codepoint();
7321 int codepoint = codepoint1; // start with codepoint1
7322
7323 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
7324 {
7325 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7326 return token_type::parse_error;
7327 }
7328
7329 // check if code point is a high surrogate
7330 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
7331 {
7332 // expect next \uxxxx entry
7333 if (JSON_HEDLEY_LIKELY(get() == '\\' and get() == 'u'))
7334 {
7335 const int codepoint2 = get_codepoint();
7336
7337 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
7338 {
7339 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7340 return token_type::parse_error;
7341 }
7342
7343 // check if codepoint2 is a low surrogate
7344 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
7345 {
7346 // overwrite codepoint
7347 codepoint = static_cast<int>(
7348 // high surrogate occupies the most significant 22 bits
7349 (static_cast<unsigned int>(codepoint1) << 10u)
7350 // low surrogate occupies the least significant 15 bits
7351 + static_cast<unsigned int>(codepoint2)
7352 // there is still the 0xD800, 0xDC00 and 0x10000 noise
7353 // in the result so we have to subtract with:
7354 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
7355 - 0x35FDC00u);
7356 }
7357 else
7358 {
7359 error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
7360 return token_type::parse_error;
7361 }
7362 }
7363 else
7364 {
7365 error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
7366 return token_type::parse_error;
7367 }
7368 }
7369 else
7370 {
7371 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
7372 {
7373 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
7374 return token_type::parse_error;
7375 }
7376 }
7377
7378 // result of the above calculation yields a proper codepoint
7379 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
7380
7381 // translate codepoint into bytes
7382 if (codepoint < 0x80)
7383 {
7384 // 1-byte characters: 0xxxxxxx (ASCII)
7385 add(codepoint);
7386 }
7387 else if (codepoint <= 0x7FF)
7388 {
7389 // 2-byte characters: 110xxxxx 10xxxxxx
7390 add(static_cast<int>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
7391 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7392 }
7393 else if (codepoint <= 0xFFFF)
7394 {
7395 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7396 add(static_cast<int>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7397 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7398 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7399 }
7400 else
7401 {
7402 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7403 add(static_cast<int>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7404 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7405 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7406 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7407 }
7408
7409 break;
7410 }
7411
7412 // other characters after escape
7413 default:
7414 error_message = "invalid string: forbidden character after backslash";
7415 return token_type::parse_error;
7416 }
7417
7418 break;
7419 }
7420
7421 // invalid control characters
7422 case 0x00:
7423 {
7424 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7425 return token_type::parse_error;
7426 }
7427
7428 case 0x01:
7429 {
7430 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7431 return token_type::parse_error;
7432 }
7433
7434 case 0x02:
7435 {
7436 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7437 return token_type::parse_error;
7438 }
7439
7440 case 0x03:
7441 {
7442 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7443 return token_type::parse_error;
7444 }
7445
7446 case 0x04:
7447 {
7448 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7449 return token_type::parse_error;
7450 }
7451
7452 case 0x05:
7453 {
7454 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7455 return token_type::parse_error;
7456 }
7457
7458 case 0x06:
7459 {
7460 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7461 return token_type::parse_error;
7462 }
7463
7464 case 0x07:
7465 {
7466 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7467 return token_type::parse_error;
7468 }
7469
7470 case 0x08:
7471 {
7472 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7473 return token_type::parse_error;
7474 }
7475
7476 case 0x09:
7477 {
7478 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7479 return token_type::parse_error;
7480 }
7481
7482 case 0x0A:
7483 {
7484 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7485 return token_type::parse_error;
7486 }
7487
7488 case 0x0B:
7489 {
7490 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7491 return token_type::parse_error;
7492 }
7493
7494 case 0x0C:
7495 {
7496 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7497 return token_type::parse_error;
7498 }
7499
7500 case 0x0D:
7501 {
7502 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7503 return token_type::parse_error;
7504 }
7505
7506 case 0x0E:
7507 {
7508 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7509 return token_type::parse_error;
7510 }
7511
7512 case 0x0F:
7513 {
7514 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7515 return token_type::parse_error;
7516 }
7517
7518 case 0x10:
7519 {
7520 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7521 return token_type::parse_error;
7522 }
7523
7524 case 0x11:
7525 {
7526 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7527 return token_type::parse_error;
7528 }
7529
7530 case 0x12:
7531 {
7532 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7533 return token_type::parse_error;
7534 }
7535
7536 case 0x13:
7537 {
7538 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7539 return token_type::parse_error;
7540 }
7541
7542 case 0x14:
7543 {
7544 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7545 return token_type::parse_error;
7546 }
7547
7548 case 0x15:
7549 {
7550 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7551 return token_type::parse_error;
7552 }
7553
7554 case 0x16:
7555 {
7556 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7557 return token_type::parse_error;
7558 }
7559
7560 case 0x17:
7561 {
7562 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7563 return token_type::parse_error;
7564 }
7565
7566 case 0x18:
7567 {
7568 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7569 return token_type::parse_error;
7570 }
7571
7572 case 0x19:
7573 {
7574 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7575 return token_type::parse_error;
7576 }
7577
7578 case 0x1A:
7579 {
7580 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7581 return token_type::parse_error;
7582 }
7583
7584 case 0x1B:
7585 {
7586 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7587 return token_type::parse_error;
7588 }
7589
7590 case 0x1C:
7591 {
7592 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7593 return token_type::parse_error;
7594 }
7595
7596 case 0x1D:
7597 {
7598 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7599 return token_type::parse_error;
7600 }
7601
7602 case 0x1E:
7603 {
7604 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7605 return token_type::parse_error;
7606 }
7607
7608 case 0x1F:
7609 {
7610 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7611 return token_type::parse_error;
7612 }
7613
7614 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7615 case 0x20:
7616 case 0x21:
7617 case 0x23:
7618 case 0x24:
7619 case 0x25:
7620 case 0x26:
7621 case 0x27:
7622 case 0x28:
7623 case 0x29:
7624 case 0x2A:
7625 case 0x2B:
7626 case 0x2C:
7627 case 0x2D:
7628 case 0x2E:
7629 case 0x2F:
7630 case 0x30:
7631 case 0x31:
7632 case 0x32:
7633 case 0x33:
7634 case 0x34:
7635 case 0x35:
7636 case 0x36:
7637 case 0x37:
7638 case 0x38:
7639 case 0x39:
7640 case 0x3A:
7641 case 0x3B:
7642 case 0x3C:
7643 case 0x3D:
7644 case 0x3E:
7645 case 0x3F:
7646 case 0x40:
7647 case 0x41:
7648 case 0x42:
7649 case 0x43:
7650 case 0x44:
7651 case 0x45:
7652 case 0x46:
7653 case 0x47:
7654 case 0x48:
7655 case 0x49:
7656 case 0x4A:
7657 case 0x4B:
7658 case 0x4C:
7659 case 0x4D:
7660 case 0x4E:
7661 case 0x4F:
7662 case 0x50:
7663 case 0x51:
7664 case 0x52:
7665 case 0x53:
7666 case 0x54:
7667 case 0x55:
7668 case 0x56:
7669 case 0x57:
7670 case 0x58:
7671 case 0x59:
7672 case 0x5A:
7673 case 0x5B:
7674 case 0x5D:
7675 case 0x5E:
7676 case 0x5F:
7677 case 0x60:
7678 case 0x61:
7679 case 0x62:
7680 case 0x63:
7681 case 0x64:
7682 case 0x65:
7683 case 0x66:
7684 case 0x67:
7685 case 0x68:
7686 case 0x69:
7687 case 0x6A:
7688 case 0x6B:
7689 case 0x6C:
7690 case 0x6D:
7691 case 0x6E:
7692 case 0x6F:
7693 case 0x70:
7694 case 0x71:
7695 case 0x72:
7696 case 0x73:
7697 case 0x74:
7698 case 0x75:
7699 case 0x76:
7700 case 0x77:
7701 case 0x78:
7702 case 0x79:
7703 case 0x7A:
7704 case 0x7B:
7705 case 0x7C:
7706 case 0x7D:
7707 case 0x7E:
7708 case 0x7F:
7709 {
7710 add(current);
7711 break;
7712 }
7713
7714 // U+0080..U+07FF: bytes C2..DF 80..BF
7715 case 0xC2:
7716 case 0xC3:
7717 case 0xC4:
7718 case 0xC5:
7719 case 0xC6:
7720 case 0xC7:
7721 case 0xC8:
7722 case 0xC9:
7723 case 0xCA:
7724 case 0xCB:
7725 case 0xCC:
7726 case 0xCD:
7727 case 0xCE:
7728 case 0xCF:
7729 case 0xD0:
7730 case 0xD1:
7731 case 0xD2:
7732 case 0xD3:
7733 case 0xD4:
7734 case 0xD5:
7735 case 0xD6:
7736 case 0xD7:
7737 case 0xD8:
7738 case 0xD9:
7739 case 0xDA:
7740 case 0xDB:
7741 case 0xDC:
7742 case 0xDD:
7743 case 0xDE:
7744 case 0xDF:
7745 {
7746 if (JSON_HEDLEY_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
7747 {
7748 return token_type::parse_error;
7749 }
7750 break;
7751 }
7752
7753 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7754 case 0xE0:
7755 {
7756 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7757 {
7758 return token_type::parse_error;
7759 }
7760 break;
7761 }
7762
7763 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7764 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7765 case 0xE1:
7766 case 0xE2:
7767 case 0xE3:
7768 case 0xE4:
7769 case 0xE5:
7770 case 0xE6:
7771 case 0xE7:
7772 case 0xE8:
7773 case 0xE9:
7774 case 0xEA:
7775 case 0xEB:
7776 case 0xEC:
7777 case 0xEE:
7778 case 0xEF:
7779 {
7780 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
7781 {
7782 return token_type::parse_error;
7783 }
7784 break;
7785 }
7786
7787 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7788 case 0xED:
7789 {
7790 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
7791 {
7792 return token_type::parse_error;
7793 }
7794 break;
7795 }
7796
7797 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7798 case 0xF0:
7799 {
7800 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7801 {
7802 return token_type::parse_error;
7803 }
7804 break;
7805 }
7806
7807 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7808 case 0xF1:
7809 case 0xF2:
7810 case 0xF3:
7811 {
7812 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7813 {
7814 return token_type::parse_error;
7815 }
7816 break;
7817 }
7818
7819 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7820 case 0xF4:
7821 {
7822 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
7823 {
7824 return token_type::parse_error;
7825 }
7826 break;
7827 }
7828
7829 // remaining bytes (80..C1 and F5..FF) are ill-formed
7830 default:
7831 {
7832 error_message = "invalid string: ill-formed UTF-8 byte";
7833 return token_type::parse_error;
7834 }
7835 }
7836 }
7837 }
7838
7839 JSON_HEDLEY_NON_NULL(2)
7840 static void strtof(float& f, const char* str, char** endptr) noexcept
7841 {
7842 f = std::strtof(str, endptr);
7843 }
7844
7845 JSON_HEDLEY_NON_NULL(2)
7846 static void strtof(double& f, const char* str, char** endptr) noexcept
7847 {
7848 f = std::strtod(str, endptr);
7849 }
7850
7851 JSON_HEDLEY_NON_NULL(2)
7852 static void strtof(long double& f, const char* str, char** endptr) noexcept
7853 {
7854 f = std::strtold(str, endptr);
7855 }
7856
7857 /*!
7858 @brief scan a number literal
7859
7860 This function scans a string according to Sect. 6 of RFC 7159.
7861
7862 The function is realized with a deterministic finite state machine derived
7863 from the grammar described in RFC 7159. Starting in state "init", the
7864 input is read and used to determined the next state. Only state "done"
7865 accepts the number. State "error" is a trap state to model errors. In the
7866 table below, "anything" means any character but the ones listed before.
7867
7868 state | 0 | 1-9 | e E | + | - | . | anything
7869 ---------|----------|----------|----------|---------|---------|----------|-----------
7870 init | zero | any1 | [error] | [error] | minus | [error] | [error]
7871 minus | zero | any1 | [error] | [error] | [error] | [error] | [error]
7872 zero | done | done | exponent | done | done | decimal1 | done
7873 any1 | any1 | any1 | exponent | done | done | decimal1 | done
7874 decimal1 | decimal2 | [error] | [error] | [error] | [error] | [error] | [error]
7875 decimal2 | decimal2 | decimal2 | exponent | done | done | done | done
7876 exponent | any2 | any2 | [error] | sign | sign | [error] | [error]
7877 sign | any2 | any2 | [error] | [error] | [error] | [error] | [error]
7878 any2 | any2 | any2 | done | done | done | done | done
7879
7880 The state machine is realized with one label per state (prefixed with
7881 "scan_number_") and `goto` statements between them. The state machine
7882 contains cycles, but any cycle can be left when EOF is read. Therefore,
7883 the function is guaranteed to terminate.
7884
7885 During scanning, the read bytes are stored in token_buffer. This string is
7886 then converted to a signed integer, an unsigned integer, or a
7887 floating-point number.
7888
7889 @return token_type::value_unsigned, token_type::value_integer, or
7890 token_type::value_float if number could be successfully scanned,
7891 token_type::parse_error otherwise
7892
7893 @note The scanner is independent of the current locale. Internally, the
7894 locale's decimal point is used instead of `.` to work with the
7895 locale-dependent converters.
7896 */
7897 token_type scan_number() // lgtm [cpp/use-of-goto]
7898 {
7899 // reset token_buffer to store the number's bytes
7900 reset();
7901
7902 // the type of the parsed number; initially set to unsigned; will be
7903 // changed if minus sign, decimal point or exponent is read
7904 token_type number_type = token_type::value_unsigned;
7905
7906 // state (init): we just found out we need to scan a number
7907 switch (current)
7908 {
7909 case '-':
7910 {
7911 add(current);
7912 goto scan_number_minus;
7913 }
7914
7915 case '0':
7916 {
7917 add(current);
7918 goto scan_number_zero;
7919 }
7920
7921 case '1':
7922 case '2':
7923 case '3':
7924 case '4':
7925 case '5':
7926 case '6':
7927 case '7':
7928 case '8':
7929 case '9':
7930 {
7931 add(current);
7932 goto scan_number_any1;
7933 }
7934
7935 // all other characters are rejected outside scan_number()
7936 default: // LCOV_EXCL_LINE
7937 assert(false); // LCOV_EXCL_LINE
7938 }
7939
7940 scan_number_minus:
7941 // state: we just parsed a leading minus sign
7942 number_type = token_type::value_integer;
7943 switch (get())
7944 {
7945 case '0':
7946 {
7947 add(current);
7948 goto scan_number_zero;
7949 }
7950
7951 case '1':
7952 case '2':
7953 case '3':
7954 case '4':
7955 case '5':
7956 case '6':
7957 case '7':
7958 case '8':
7959 case '9':
7960 {
7961 add(current);
7962 goto scan_number_any1;
7963 }
7964
7965 default:
7966 {
7967 error_message = "invalid number; expected digit after '-'";
7968 return token_type::parse_error;
7969 }
7970 }
7971
7972 scan_number_zero:
7973 // state: we just parse a zero (maybe with a leading minus sign)
7974 switch (get())
7975 {
7976 case '.':
7977 {
7978 add(decimal_point_char);
7979 goto scan_number_decimal1;
7980 }
7981
7982 case 'e':
7983 case 'E':
7984 {
7985 add(current);
7986 goto scan_number_exponent;
7987 }
7988
7989 default:
7990 goto scan_number_done;
7991 }
7992
7993 scan_number_any1:
7994 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7995 switch (get())
7996 {
7997 case '0':
7998 case '1':
7999 case '2':
8000 case '3':
8001 case '4':
8002 case '5':
8003 case '6':
8004 case '7':
8005 case '8':
8006 case '9':
8007 {
8008 add(current);
8009 goto scan_number_any1;
8010 }
8011
8012 case '.':
8013 {
8014 add(decimal_point_char);
8015 goto scan_number_decimal1;
8016 }
8017
8018 case 'e':
8019 case 'E':
8020 {
8021 add(current);
8022 goto scan_number_exponent;
8023 }
8024
8025 default:
8026 goto scan_number_done;
8027 }
8028
8029 scan_number_decimal1:
8030 // state: we just parsed a decimal point
8031 number_type = token_type::value_float;
8032 switch (get())
8033 {
8034 case '0':
8035 case '1':
8036 case '2':
8037 case '3':
8038 case '4':
8039 case '5':
8040 case '6':
8041 case '7':
8042 case '8':
8043 case '9':
8044 {
8045 add(current);
8046 goto scan_number_decimal2;
8047 }
8048
8049 default:
8050 {
8051 error_message = "invalid number; expected digit after '.'";
8052 return token_type::parse_error;
8053 }
8054 }
8055
8056 scan_number_decimal2:
8057 // we just parsed at least one number after a decimal point
8058 switch (get())
8059 {
8060 case '0':
8061 case '1':
8062 case '2':
8063 case '3':
8064 case '4':
8065 case '5':
8066 case '6':
8067 case '7':
8068 case '8':
8069 case '9':
8070 {
8071 add(current);
8072 goto scan_number_decimal2;
8073 }
8074
8075 case 'e':
8076 case 'E':
8077 {
8078 add(current);
8079 goto scan_number_exponent;
8080 }
8081
8082 default:
8083 goto scan_number_done;
8084 }
8085
8086 scan_number_exponent:
8087 // we just parsed an exponent
8088 number_type = token_type::value_float;
8089 switch (get())
8090 {
8091 case '+':
8092 case '-':
8093 {
8094 add(current);
8095 goto scan_number_sign;
8096 }
8097
8098 case '0':
8099 case '1':
8100 case '2':
8101 case '3':
8102 case '4':
8103 case '5':
8104 case '6':
8105 case '7':
8106 case '8':
8107 case '9':
8108 {
8109 add(current);
8110 goto scan_number_any2;
8111 }
8112
8113 default:
8114 {
8115 error_message =
8116 "invalid number; expected '+', '-', or digit after exponent";
8117 return token_type::parse_error;
8118 }
8119 }
8120
8121 scan_number_sign:
8122 // we just parsed an exponent sign
8123 switch (get())
8124 {
8125 case '0':
8126 case '1':
8127 case '2':
8128 case '3':
8129 case '4':
8130 case '5':
8131 case '6':
8132 case '7':
8133 case '8':
8134 case '9':
8135 {
8136 add(current);
8137 goto scan_number_any2;
8138 }
8139
8140 default:
8141 {
8142 error_message = "invalid number; expected digit after exponent sign";
8143 return token_type::parse_error;
8144 }
8145 }
8146
8147 scan_number_any2:
8148 // we just parsed a number after the exponent or exponent sign
8149 switch (get())
8150 {
8151 case '0':
8152 case '1':
8153 case '2':
8154 case '3':
8155 case '4':
8156 case '5':
8157 case '6':
8158 case '7':
8159 case '8':
8160 case '9':
8161 {
8162 add(current);
8163 goto scan_number_any2;
8164 }
8165
8166 default:
8167 goto scan_number_done;
8168 }
8169
8170 scan_number_done:
8171 // unget the character after the number (we only read it to know that
8172 // we are done scanning a number)
8173 unget();
8174
8175 char* endptr = nullptr;
8176 errno = 0;
8177
8178 // try to parse integers first and fall back to floats
8179 if (number_type == token_type::value_unsigned)
8180 {
8181 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
8182
8183 // we checked the number format before
8184 assert(endptr == token_buffer.data() + token_buffer.size());
8185
8186 if (errno == 0)
8187 {
8188 value_unsigned = static_cast<number_unsigned_t>(x);
8189 if (value_unsigned == x)
8190 {
8191 return token_type::value_unsigned;
8192 }
8193 }
8194 }
8195 else if (number_type == token_type::value_integer)
8196 {
8197 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
8198
8199 // we checked the number format before
8200 assert(endptr == token_buffer.data() + token_buffer.size());
8201
8202 if (errno == 0)
8203 {
8204 value_integer = static_cast<number_integer_t>(x);
8205 if (value_integer == x)
8206 {
8207 return token_type::value_integer;
8208 }
8209 }
8210 }
8211
8212 // this code is reached if we parse a floating-point number or if an
8213 // integer conversion above failed
8214 strtof(value_float, token_buffer.data(), &endptr);
8215
8216 // we checked the number format before
8217 assert(endptr == token_buffer.data() + token_buffer.size());
8218
8219 return token_type::value_float;
8220 }
8221
8222 /*!
8223 @param[in] literal_text the literal text to expect
8224 @param[in] length the length of the passed literal text
8225 @param[in] return_type the token type to return on success
8226 */
8227 JSON_HEDLEY_NON_NULL(2)
8228 token_type scan_literal(const char* literal_text, const std::size_t length,
8229 token_type return_type)
8230 {
8231 assert(current == literal_text[0]);
8232 for (std::size_t i = 1; i < length; ++i)
8233 {
8234 if (JSON_HEDLEY_UNLIKELY(get() != literal_text[i]))
8235 {
8236 error_message = "invalid literal";
8237 return token_type::parse_error;
8238 }
8239 }
8240 return return_type;
8241 }
8242
8243 /////////////////////
8244 // input management
8245 /////////////////////
8246
8247 /// reset token_buffer; current character is beginning of token
8248 void reset() noexcept
8249 {
8250 token_buffer.clear();
8251 token_string.clear();
8252 token_string.push_back(std::char_traits<char>::to_char_type(current));
8253 }
8254
8255 /*
8256 @brief get next character from the input
8257
8258 This function provides the interface to the used input adapter. It does
8259 not throw in case the input reached EOF, but returns a
8260 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
8261 for use in error messages.
8262
8263 @return character read from the input
8264 */
8265 std::char_traits<char>::int_type get()
8266 {
8267 ++position.chars_read_total;
8268 ++position.chars_read_current_line;
8269
8270 if (next_unget)
8271 {
8272 // just reset the next_unget variable and work with current
8273 next_unget = false;
8274 }
8275 else
8276 {
8277 current = ia->get_character();
8278 }
8279
8280 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char>::eof()))
8281 {
8282 token_string.push_back(std::char_traits<char>::to_char_type(current));
8283 }
8284
8285 if (current == '\n')
8286 {
8287 ++position.lines_read;
8288 position.chars_read_current_line = 0;
8289 }
8290
8291 return current;
8292 }
8293
8294 /*!
8295 @brief unget current character (read it again on next get)
8296
8297 We implement unget by setting variable next_unget to true. The input is not
8298 changed - we just simulate ungetting by modifying chars_read_total,
8299 chars_read_current_line, and token_string. The next call to get() will
8300 behave as if the unget character is read again.
8301 */
8302 void unget()
8303 {
8304 next_unget = true;
8305
8306 --position.chars_read_total;
8307
8308 // in case we "unget" a newline, we have to also decrement the lines_read
8309 if (position.chars_read_current_line == 0)
8310 {
8311 if (position.lines_read > 0)
8312 {
8313 --position.lines_read;
8314 }
8315 }
8316 else
8317 {
8318 --position.chars_read_current_line;
8319 }
8320
8321 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char>::eof()))
8322 {
8323 assert(not token_string.empty());
8324 token_string.pop_back();
8325 }
8326 }
8327
8328 /// add a character to token_buffer
8329 void add(int c)
8330 {
8331 token_buffer.push_back(std::char_traits<char>::to_char_type(c));
8332 }
8333
8334 public:
8335 /////////////////////
8336 // value getters
8337 /////////////////////
8338
8339 /// return integer value
8340 constexpr number_integer_t get_number_integer() const noexcept
8341 {
8342 return value_integer;
8343 }
8344
8345 /// return unsigned integer value
8346 constexpr number_unsigned_t get_number_unsigned() const noexcept
8347 {
8348 return value_unsigned;
8349 }
8350
8351 /// return floating-point value
8352 constexpr number_float_t get_number_float() const noexcept
8353 {
8354 return value_float;
8355 }
8356
8357 /// return current string value (implicitly resets the token; useful only once)
8358 string_t& get_string()
8359 {
8360 return token_buffer;
8361 }
8362
8363 /////////////////////
8364 // diagnostics
8365 /////////////////////
8366
8367 /// return position of last read token
8368 constexpr position_t get_position() const noexcept
8369 {
8370 return position;
8371 }
8372
8373 /// return the last read token (for errors only). Will never contain EOF
8374 /// (an arbitrary value that is not a valid char value, often -1), because
8375 /// 255 may legitimately occur. May contain NUL, which should be escaped.
8376 std::string get_token_string() const
8377 {
8378 // escape control characters
8379 std::string result;
8380 for (const auto c : token_string)
8381 {
8382 if ('\x00' <= c and c <= '\x1F')
8383 {
8384 // escape control characters
8385 std::array<char, 9> cs{{}};
8386 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c));
8387 result += cs.data();
8388 }
8389 else
8390 {
8391 // add character as is
8392 result.push_back(c);
8393 }
8394 }
8395
8396 return result;
8397 }
8398
8399 /// return syntax error message
8400 JSON_HEDLEY_RETURNS_NON_NULL
8401 constexpr const char* get_error_message() const noexcept
8402 {
8403 return error_message;
8404 }
8405
8406 /////////////////////
8407 // actual scanner
8408 /////////////////////
8409
8410 /*!
8411 @brief skip the UTF-8 byte order mark
8412 @return true iff there is no BOM or the correct BOM has been skipped
8413 */
8414 bool skip_bom()
8415 {
8416 if (get() == 0xEF)
8417 {
8418 // check if we completely parse the BOM
8419 return get() == 0xBB and get() == 0xBF;
8420 }
8421
8422 // the first character is not the beginning of the BOM; unget it to
8423 // process is later
8424 unget();
8425 return true;
8426 }
8427
8428 token_type scan()
8429 {
8430 // initially, skip the BOM
8431 if (position.chars_read_total == 0 and not skip_bom())
8432 {
8433 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8434 return token_type::parse_error;
8435 }
8436
8437 // read next character and ignore whitespace
8438 do
8439 {
8440 get();
8441 }
8442 while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
8443
8444 switch (current)
8445 {
8446 // structural characters
8447 case '[':
8448 return token_type::begin_array;
8449 case ']':
8450 return token_type::end_array;
8451 case '{':
8452 return token_type::begin_object;
8453 case '}':
8454 return token_type::end_object;
8455 case ':':
8456 return token_type::name_separator;
8457 case ',':
8458 return token_type::value_separator;
8459
8460 // literals
8461 case 't':
8462 return scan_literal("true", 4, token_type::literal_true);
8463 case 'f':
8464 return scan_literal("false", 5, token_type::literal_false);
8465 case 'n':
8466 return scan_literal("null", 4, token_type::literal_null);
8467
8468 // string
8469 case '\"':
8470 return scan_string();
8471
8472 // number
8473 case '-':
8474 case '0':
8475 case '1':
8476 case '2':
8477 case '3':
8478 case '4':
8479 case '5':
8480 case '6':
8481 case '7':
8482 case '8':
8483 case '9':
8484 return scan_number();
8485
8486 // end of input (the null byte is needed when parsing from
8487 // string literals)
8488 case '\0':
8489 case std::char_traits<char>::eof():
8490 return token_type::end_of_input;
8491
8492 // error
8493 default:
8494 error_message = "invalid literal";
8495 return token_type::parse_error;
8496 }
8497 }
8498
8499 private:
8500 /// input adapter
8501 detail::input_adapter_t ia = nullptr;
8502
8503 /// the current character
8504 std::char_traits<char>::int_type current = std::char_traits<char>::eof();
8505
8506 /// whether the next get() call should just return current
8507 bool next_unget = false;
8508
8509 /// the start position of the current token
8510 position_t position {};
8511
8512 /// raw input token string (for error messages)
8513 std::vector<char> token_string {};
8514
8515 /// buffer for variable-length tokens (numbers, strings)
8516 string_t token_buffer {};
8517
8518 /// a description of occurred lexer errors
8519 const char* error_message = "";
8520
8521 // number values
8522 number_integer_t value_integer = 0;
8523 number_unsigned_t value_unsigned = 0;
8524 number_float_t value_float = 0;
8525
8526 /// the decimal point
8527 const char decimal_point_char = '.';
8528 };
8529 } // namespace detail
8530 } // namespace nlohmann
8531
8532 // #include <nlohmann/detail/input/parser.hpp>
8533
8534
8535 #include <cassert> // assert
8536 #include <cmath> // isfinite
8537 #include <cstdint> // uint8_t
8538 #include <functional> // function
8539 #include <string> // string
8540 #include <utility> // move
8541 #include <vector> // vector
8542
8543 // #include <nlohmann/detail/exceptions.hpp>
8544
8545 // #include <nlohmann/detail/input/input_adapters.hpp>
8546
8547 // #include <nlohmann/detail/input/json_sax.hpp>
8548
8549 // #include <nlohmann/detail/input/lexer.hpp>
8550
8551 // #include <nlohmann/detail/macro_scope.hpp>
8552
8553 // #include <nlohmann/detail/meta/is_sax.hpp>
8554
8555 // #include <nlohmann/detail/value_t.hpp>
8556
8557
8558 namespace nlohmann
8559 {
8560 namespace detail
8561 {
8562 ////////////
8563 // parser //
8564 ////////////
8565
8566 /*!
8567 @brief syntax analysis
8568
8569 This class implements a recursive decent parser.
8570 */
8571 template<typename BasicJsonType>
8572 class parser
8573 {
8574 using number_integer_t = typename BasicJsonType::number_integer_t;
8575 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8576 using number_float_t = typename BasicJsonType::number_float_t;
8577 using string_t = typename BasicJsonType::string_t;
8578 using lexer_t = lexer<BasicJsonType>;
8579 using token_type = typename lexer_t::token_type;
8580
8581 public:
8582 enum class parse_event_t : uint8_t
8583 {
8584 /// the parser read `{` and started to process a JSON object
8585 object_start,
8586 /// the parser read `}` and finished processing a JSON object
8587 object_end,
8588 /// the parser read `[` and started to process a JSON array
8589 array_start,
8590 /// the parser read `]` and finished processing a JSON array
8591 array_end,
8592 /// the parser read a key of a value in an object
8593 key,
8594 /// the parser finished reading a JSON value
8595 value
8596 };
8597
8598 using parser_callback_t =
8599 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
8600
8601 /// a parser reading from an input adapter
8602 explicit parser(detail::input_adapter_t&& adapter,
8603 const parser_callback_t cb = nullptr,
8604 const bool allow_exceptions_ = true)
8605 : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
8606 {
8607 // read first token
8608 get_token();
8609 }
8610
8611 /*!
8612 @brief public parser interface
8613
8614 @param[in] strict whether to expect the last token to be EOF
8615 @param[in,out] result parsed JSON value
8616
8617 @throw parse_error.101 in case of an unexpected token
8618 @throw parse_error.102 if to_unicode fails or surrogate error
8619 @throw parse_error.103 if to_unicode fails
8620 */
8621 void parse(const bool strict, BasicJsonType& result)
8622 {
8623 if (callback)
8624 {
8625 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
8626 sax_parse_internal(&sdp);
8627 result.assert_invariant();
8628
8629 // in strict mode, input must be completely read
8630 if (strict and (get_token() != token_type::end_of_input))
8631 {
8632 sdp.parse_error(m_lexer.get_position(),
8633 m_lexer.get_token_string(),
8634 parse_error::create(101, m_lexer.get_position(),
8635 exception_message(token_type::end_of_input, "value")));
8636 }
8637
8638 // in case of an error, return discarded value
8639 if (sdp.is_errored())
8640 {
8641 result = value_t::discarded;
8642 return;
8643 }
8644
8645 // set top-level value to null if it was discarded by the callback
8646 // function
8647 if (result.is_discarded())
8648 {
8649 result = nullptr;
8650 }
8651 }
8652 else
8653 {
8654 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
8655 sax_parse_internal(&sdp);
8656 result.assert_invariant();
8657
8658 // in strict mode, input must be completely read
8659 if (strict and (get_token() != token_type::end_of_input))
8660 {
8661 sdp.parse_error(m_lexer.get_position(),
8662 m_lexer.get_token_string(),
8663 parse_error::create(101, m_lexer.get_position(),
8664 exception_message(token_type::end_of_input, "value")));
8665 }
8666
8667 // in case of an error, return discarded value
8668 if (sdp.is_errored())
8669 {
8670 result = value_t::discarded;
8671 return;
8672 }
8673 }
8674 }
8675
8676 /*!
8677 @brief public accept interface
8678
8679 @param[in] strict whether to expect the last token to be EOF
8680 @return whether the input is a proper JSON text
8681 */
8682 bool accept(const bool strict = true)
8683 {
8684 json_sax_acceptor<BasicJsonType> sax_acceptor;
8685 return sax_parse(&sax_acceptor, strict);
8686 }
8687
8688 template <typename SAX>
8689 JSON_HEDLEY_NON_NULL(2)
8690 bool sax_parse(SAX* sax, const bool strict = true)
8691 {
8692 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
8693 const bool result = sax_parse_internal(sax);
8694
8695 // strict mode: next byte must be EOF
8696 if (result and strict and (get_token() != token_type::end_of_input))
8697 {
8698 return sax->parse_error(m_lexer.get_position(),
8699 m_lexer.get_token_string(),
8700 parse_error::create(101, m_lexer.get_position(),
8701 exception_message(token_type::end_of_input, "value")));
8702 }
8703
8704 return result;
8705 }
8706
8707 private:
8708 template <typename SAX>
8709 JSON_HEDLEY_NON_NULL(2)
8710 bool sax_parse_internal(SAX* sax)
8711 {
8712 // stack to remember the hierarchy of structured values we are parsing
8713 // true = array; false = object
8714 std::vector<bool> states;
8715 // value to avoid a goto (see comment where set to true)
8716 bool skip_to_state_evaluation = false;
8717
8718 while (true)
8719 {
8720 if (not skip_to_state_evaluation)
8721 {
8722 // invariant: get_token() was called before each iteration
8723 switch (last_token)
8724 {
8725 case token_type::begin_object:
8726 {
8727 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
8728 {
8729 return false;
8730 }
8731
8732 // closing } -> we are done
8733 if (get_token() == token_type::end_object)
8734 {
8735 if (JSON_HEDLEY_UNLIKELY(not sax->end_object()))
8736 {
8737 return false;
8738 }
8739 break;
8740 }
8741
8742 // parse key
8743 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
8744 {
8745 return sax->parse_error(m_lexer.get_position(),
8746 m_lexer.get_token_string(),
8747 parse_error::create(101, m_lexer.get_position(),
8748 exception_message(token_type::value_string, "object key")));
8749 }
8750 if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
8751 {
8752 return false;
8753 }
8754
8755 // parse separator (:)
8756 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
8757 {
8758 return sax->parse_error(m_lexer.get_position(),
8759 m_lexer.get_token_string(),
8760 parse_error::create(101, m_lexer.get_position(),
8761 exception_message(token_type::name_separator, "object separator")));
8762 }
8763
8764 // remember we are now inside an object
8765 states.push_back(false);
8766
8767 // parse values
8768 get_token();
8769 continue;
8770 }
8771
8772 case token_type::begin_array:
8773 {
8774 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
8775 {
8776 return false;
8777 }
8778
8779 // closing ] -> we are done
8780 if (get_token() == token_type::end_array)
8781 {
8782 if (JSON_HEDLEY_UNLIKELY(not sax->end_array()))
8783 {
8784 return false;
8785 }
8786 break;
8787 }
8788
8789 // remember we are now inside an array
8790 states.push_back(true);
8791
8792 // parse values (no need to call get_token)
8793 continue;
8794 }
8795
8796 case token_type::value_float:
8797 {
8798 const auto res = m_lexer.get_number_float();
8799
8800 if (JSON_HEDLEY_UNLIKELY(not std::isfinite(res)))
8801 {
8802 return sax->parse_error(m_lexer.get_position(),
8803 m_lexer.get_token_string(),
8804 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
8805 }
8806
8807 if (JSON_HEDLEY_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
8808 {
8809 return false;
8810 }
8811
8812 break;
8813 }
8814
8815 case token_type::literal_false:
8816 {
8817 if (JSON_HEDLEY_UNLIKELY(not sax->boolean(false)))
8818 {
8819 return false;
8820 }
8821 break;
8822 }
8823
8824 case token_type::literal_null:
8825 {
8826 if (JSON_HEDLEY_UNLIKELY(not sax->null()))
8827 {
8828 return false;
8829 }
8830 break;
8831 }
8832
8833 case token_type::literal_true:
8834 {
8835 if (JSON_HEDLEY_UNLIKELY(not sax->boolean(true)))
8836 {
8837 return false;
8838 }
8839 break;
8840 }
8841
8842 case token_type::value_integer:
8843 {
8844 if (JSON_HEDLEY_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
8845 {
8846 return false;
8847 }
8848 break;
8849 }
8850
8851 case token_type::value_string:
8852 {
8853 if (JSON_HEDLEY_UNLIKELY(not sax->string(m_lexer.get_string())))
8854 {
8855 return false;
8856 }
8857 break;
8858 }
8859
8860 case token_type::value_unsigned:
8861 {
8862 if (JSON_HEDLEY_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
8863 {
8864 return false;
8865 }
8866 break;
8867 }
8868
8869 case token_type::parse_error:
8870 {
8871 // using "uninitialized" to avoid "expected" message
8872 return sax->parse_error(m_lexer.get_position(),
8873 m_lexer.get_token_string(),
8874 parse_error::create(101, m_lexer.get_position(),
8875 exception_message(token_type::uninitialized, "value")));
8876 }
8877
8878 default: // the last token was unexpected
8879 {
8880 return sax->parse_error(m_lexer.get_position(),
8881 m_lexer.get_token_string(),
8882 parse_error::create(101, m_lexer.get_position(),
8883 exception_message(token_type::literal_or_value, "value")));
8884 }
8885 }
8886 }
8887 else
8888 {
8889 skip_to_state_evaluation = false;
8890 }
8891
8892 // we reached this line after we successfully parsed a value
8893 if (states.empty())
8894 {
8895 // empty stack: we reached the end of the hierarchy: done
8896 return true;
8897 }
8898
8899 if (states.back()) // array
8900 {
8901 // comma -> next value
8902 if (get_token() == token_type::value_separator)
8903 {
8904 // parse a new value
8905 get_token();
8906 continue;
8907 }
8908
8909 // closing ]
8910 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
8911 {
8912 if (JSON_HEDLEY_UNLIKELY(not sax->end_array()))
8913 {
8914 return false;
8915 }
8916
8917 // We are done with this array. Before we can parse a
8918 // new value, we need to evaluate the new state first.
8919 // By setting skip_to_state_evaluation to false, we
8920 // are effectively jumping to the beginning of this if.
8921 assert(not states.empty());
8922 states.pop_back();
8923 skip_to_state_evaluation = true;
8924 continue;
8925 }
8926
8927 return sax->parse_error(m_lexer.get_position(),
8928 m_lexer.get_token_string(),
8929 parse_error::create(101, m_lexer.get_position(),
8930 exception_message(token_type::end_array, "array")));
8931 }
8932 else // object
8933 {
8934 // comma -> next value
8935 if (get_token() == token_type::value_separator)
8936 {
8937 // parse key
8938 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
8939 {
8940 return sax->parse_error(m_lexer.get_position(),
8941 m_lexer.get_token_string(),
8942 parse_error::create(101, m_lexer.get_position(),
8943 exception_message(token_type::value_string, "object key")));
8944 }
8945
8946 if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
8947 {
8948 return false;
8949 }
8950
8951 // parse separator (:)
8952 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
8953 {
8954 return sax->parse_error(m_lexer.get_position(),
8955 m_lexer.get_token_string(),
8956 parse_error::create(101, m_lexer.get_position(),
8957 exception_message(token_type::name_separator, "object separator")));
8958 }
8959
8960 // parse values
8961 get_token();
8962 continue;
8963 }
8964
8965 // closing }
8966 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
8967 {
8968 if (JSON_HEDLEY_UNLIKELY(not sax->end_object()))
8969 {
8970 return false;
8971 }
8972
8973 // We are done with this object. Before we can parse a
8974 // new value, we need to evaluate the new state first.
8975 // By setting skip_to_state_evaluation to false, we
8976 // are effectively jumping to the beginning of this if.
8977 assert(not states.empty());
8978 states.pop_back();
8979 skip_to_state_evaluation = true;
8980 continue;
8981 }
8982
8983 return sax->parse_error(m_lexer.get_position(),
8984 m_lexer.get_token_string(),
8985 parse_error::create(101, m_lexer.get_position(),
8986 exception_message(token_type::end_object, "object")));
8987 }
8988 }
8989 }
8990
8991 /// get next token from lexer
8992 token_type get_token()
8993 {
8994 return last_token = m_lexer.scan();
8995 }
8996
8997 std::string exception_message(const token_type expected, const std::string& context)
8998 {
8999 std::string error_msg = "syntax error ";
9000
9001 if (not context.empty())
9002 {
9003 error_msg += "while parsing " + context + " ";
9004 }
9005
9006 error_msg += "- ";
9007
9008 if (last_token == token_type::parse_error)
9009 {
9010 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
9011 m_lexer.get_token_string() + "'";
9012 }
9013 else
9014 {
9015 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
9016 }
9017
9018 if (expected != token_type::uninitialized)
9019 {
9020 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
9021 }
9022
9023 return error_msg;
9024 }
9025
9026 private:
9027 /// callback function
9028 const parser_callback_t callback = nullptr;
9029 /// the type of the last read token
9030 token_type last_token = token_type::uninitialized;
9031 /// the lexer
9032 lexer_t m_lexer;
9033 /// whether to throw exceptions in case of errors
9034 const bool allow_exceptions = true;
9035 };
9036 } // namespace detail
9037 } // namespace nlohmann
9038
9039 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
9040
9041
9042 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
9043
9044
9045 #include <cstddef> // ptrdiff_t
9046 #include <limits> // numeric_limits
9047
9048 namespace nlohmann
9049 {
9050 namespace detail
9051 {
9052 /*
9053 @brief an iterator for primitive JSON types
9054
9055 This class models an iterator for primitive JSON types (boolean, number,
9056 string). It's only purpose is to allow the iterator/const_iterator classes
9057 to "iterate" over primitive values. Internally, the iterator is modeled by
9058 a `difference_type` variable. Value begin_value (`0`) models the begin,
9059 end_value (`1`) models past the end.
9060 */
9061 class primitive_iterator_t
9062 {
9063 private:
9064 using difference_type = std::ptrdiff_t;
9065 static constexpr difference_type begin_value = 0;
9066 static constexpr difference_type end_value = begin_value + 1;
9067
9068 /// iterator as signed integer type
9069 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
9070
9071 public:
9072 constexpr difference_type get_value() const noexcept
9073 {
9074 return m_it;
9075 }
9076
9077 /// set iterator to a defined beginning
9078 void set_begin() noexcept
9079 {
9080 m_it = begin_value;
9081 }
9082
9083 /// set iterator to a defined past the end
9084 void set_end() noexcept
9085 {
9086 m_it = end_value;
9087 }
9088
9089 /// return whether the iterator can be dereferenced
9090 constexpr bool is_begin() const noexcept
9091 {
9092 return m_it == begin_value;
9093 }
9094
9095 /// return whether the iterator is at end
9096 constexpr bool is_end() const noexcept
9097 {
9098 return m_it == end_value;
9099 }
9100
9101 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
9102 {
9103 return lhs.m_it == rhs.m_it;
9104 }
9105
9106 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
9107 {
9108 return lhs.m_it < rhs.m_it;
9109 }
9110
9111 primitive_iterator_t operator+(difference_type n) noexcept
9112 {
9113 auto result = *this;
9114 result += n;
9115 return result;
9116 }
9117
9118 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
9119 {
9120 return lhs.m_it - rhs.m_it;
9121 }
9122
9123 primitive_iterator_t& operator++() noexcept
9124 {
9125 ++m_it;
9126 return *this;
9127 }
9128
9129 primitive_iterator_t const operator++(int) noexcept
9130 {
9131 auto result = *this;
9132 ++m_it;
9133 return result;
9134 }
9135
9136 primitive_iterator_t& operator--() noexcept
9137 {
9138 --m_it;
9139 return *this;
9140 }
9141
9142 primitive_iterator_t const operator--(int) noexcept
9143 {
9144 auto result = *this;
9145 --m_it;
9146 return result;
9147 }
9148
9149 primitive_iterator_t& operator+=(difference_type n) noexcept
9150 {
9151 m_it += n;
9152 return *this;
9153 }
9154
9155 primitive_iterator_t& operator-=(difference_type n) noexcept
9156 {
9157 m_it -= n;
9158 return *this;
9159 }
9160 };
9161 } // namespace detail
9162 } // namespace nlohmann
9163
9164
9165 namespace nlohmann
9166 {
9167 namespace detail
9168 {
9169 /*!
9170 @brief an iterator value
9171
9172 @note This structure could easily be a union, but MSVC currently does not allow
9173 unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
9174 */
9175 template<typename BasicJsonType> struct internal_iterator
9176 {
9177 /// iterator for JSON objects
9178 typename BasicJsonType::object_t::iterator object_iterator {};
9179 /// iterator for JSON arrays
9180 typename BasicJsonType::array_t::iterator array_iterator {};
9181 /// generic iterator for all other types
9182 primitive_iterator_t primitive_iterator {};
9183 };
9184 } // namespace detail
9185 } // namespace nlohmann
9186
9187 // #include <nlohmann/detail/iterators/iter_impl.hpp>
9188
9189
9190 #include <ciso646> // not
9191 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
9192 #include <type_traits> // conditional, is_const, remove_const
9193
9194 // #include <nlohmann/detail/exceptions.hpp>
9195
9196 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
9197
9198 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
9199
9200 // #include <nlohmann/detail/macro_scope.hpp>
9201
9202 // #include <nlohmann/detail/meta/cpp_future.hpp>
9203
9204 // #include <nlohmann/detail/meta/type_traits.hpp>
9205
9206 // #include <nlohmann/detail/value_t.hpp>
9207
9208
9209 namespace nlohmann
9210 {
9211 namespace detail
9212 {
9213 // forward declare, to be able to friend it later on
9214 template<typename IteratorType> class iteration_proxy;
9215 template<typename IteratorType> class iteration_proxy_value;
9216
9217 /*!
9218 @brief a template for a bidirectional iterator for the @ref basic_json class
9219 This class implements a both iterators (iterator and const_iterator) for the
9220 @ref basic_json class.
9221 @note An iterator is called *initialized* when a pointer to a JSON value has
9222 been set (e.g., by a constructor or a copy assignment). If the iterator is
9223 default-constructed, it is *uninitialized* and most methods are undefined.
9224 **The library uses assertions to detect calls on uninitialized iterators.**
9225 @requirement The class satisfies the following concept requirements:
9226 -
9227 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
9228 The iterator that can be moved can be moved in both directions (i.e.
9229 incremented and decremented).
9230 @since version 1.0.0, simplified in version 2.0.9, change to bidirectional
9231 iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
9232 */
9233 template<typename BasicJsonType>
9234 class iter_impl
9235 {
9236 /// allow basic_json to access private members
9237 friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
9238 friend BasicJsonType;
9239 friend iteration_proxy<iter_impl>;
9240 friend iteration_proxy_value<iter_impl>;
9241
9242 using object_t = typename BasicJsonType::object_t;
9243 using array_t = typename BasicJsonType::array_t;
9244 // make sure BasicJsonType is basic_json or const basic_json
9245 static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
9246 "iter_impl only accepts (const) basic_json");
9247
9248 public:
9249
9250 /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
9251 /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
9252 /// A user-defined iterator should provide publicly accessible typedefs named
9253 /// iterator_category, value_type, difference_type, pointer, and reference.
9254 /// Note that value_type is required to be non-const, even for constant iterators.
9255 using iterator_category = std::bidirectional_iterator_tag;
9256
9257 /// the type of the values when the iterator is dereferenced
9258 using value_type = typename BasicJsonType::value_type;
9259 /// a type to represent differences between iterators
9260 using difference_type = typename BasicJsonType::difference_type;
9261 /// defines a pointer to the type iterated over (value_type)
9262 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
9263 typename BasicJsonType::const_pointer,
9264 typename BasicJsonType::pointer>::type;
9265 /// defines a reference to the type iterated over (value_type)
9266 using reference =
9267 typename std::conditional<std::is_const<BasicJsonType>::value,
9268 typename BasicJsonType::const_reference,
9269 typename BasicJsonType::reference>::type;
9270
9271 /// default constructor
9272 iter_impl() = default;
9273
9274 /*!
9275 @brief constructor for a given JSON instance
9276 @param[in] object pointer to a JSON object for this iterator
9277 @pre object != nullptr
9278 @post The iterator is initialized; i.e. `m_object != nullptr`.
9279 */
9280 explicit iter_impl(pointer object) noexcept : m_object(object)
9281 {
9282 assert(m_object != nullptr);
9283
9284 switch (m_object->m_type)
9285 {
9286 case value_t::object:
9287 {
9288 m_it.object_iterator = typename object_t::iterator();
9289 break;
9290 }
9291
9292 case value_t::array:
9293 {
9294 m_it.array_iterator = typename array_t::iterator();
9295 break;
9296 }
9297
9298 default:
9299 {
9300 m_it.primitive_iterator = primitive_iterator_t();
9301 break;
9302 }
9303 }
9304 }
9305
9306 /*!
9307 @note The conventional copy constructor and copy assignment are implicitly
9308 defined. Combined with the following converting constructor and
9309 assignment, they support: (1) copy from iterator to iterator, (2)
9310 copy from const iterator to const iterator, and (3) conversion from
9311 iterator to const iterator. However conversion from const iterator
9312 to iterator is not defined.
9313 */
9314
9315 /*!
9316 @brief const copy constructor
9317 @param[in] other const iterator to copy from
9318 @note This copy constuctor had to be defined explicitely to circumvent a bug
9319 occuring on msvc v19.0 compiler (VS 2015) debug build. For more
9320 information refer to: https://github.com/nlohmann/json/issues/1608
9321 */
9322 iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
9323 : m_object(other.m_object), m_it(other.m_it)
9324 {}
9325
9326 /*!
9327 @brief converting assignment
9328 @param[in] other const iterator to copy from
9329 @return const/non-const iterator
9330 @note It is not checked whether @a other is initialized.
9331 */
9332 iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
9333 {
9334 m_object = other.m_object;
9335 m_it = other.m_it;
9336 return *this;
9337 }
9338
9339 /*!
9340 @brief converting constructor
9341 @param[in] other non-const iterator to copy from
9342 @note It is not checked whether @a other is initialized.
9343 */
9344 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
9345 : m_object(other.m_object), m_it(other.m_it)
9346 {}
9347
9348 /*!
9349 @brief converting assignment
9350 @param[in] other non-const iterator to copy from
9351 @return const/non-const iterator
9352 @note It is not checked whether @a other is initialized.
9353 */
9354 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
9355 {
9356 m_object = other.m_object;
9357 m_it = other.m_it;
9358 return *this;
9359 }
9360
9361 private:
9362 /*!
9363 @brief set the iterator to the first value
9364 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9365 */
9366 void set_begin() noexcept
9367 {
9368 assert(m_object != nullptr);
9369
9370 switch (m_object->m_type)
9371 {
9372 case value_t::object:
9373 {
9374 m_it.object_iterator = m_object->m_value.object->begin();
9375 break;
9376 }
9377
9378 case value_t::array:
9379 {
9380 m_it.array_iterator = m_object->m_value.array->begin();
9381 break;
9382 }
9383
9384 case value_t::null:
9385 {
9386 // set to end so begin()==end() is true: null is empty
9387 m_it.primitive_iterator.set_end();
9388 break;
9389 }
9390
9391 default:
9392 {
9393 m_it.primitive_iterator.set_begin();
9394 break;
9395 }
9396 }
9397 }
9398
9399 /*!
9400 @brief set the iterator past the last value
9401 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9402 */
9403 void set_end() noexcept
9404 {
9405 assert(m_object != nullptr);
9406
9407 switch (m_object->m_type)
9408 {
9409 case value_t::object:
9410 {
9411 m_it.object_iterator = m_object->m_value.object->end();
9412 break;
9413 }
9414
9415 case value_t::array:
9416 {
9417 m_it.array_iterator = m_object->m_value.array->end();
9418 break;
9419 }
9420
9421 default:
9422 {
9423 m_it.primitive_iterator.set_end();
9424 break;
9425 }
9426 }
9427 }
9428
9429 public:
9430 /*!
9431 @brief return a reference to the value pointed to by the iterator
9432 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9433 */
9434 reference operator*() const
9435 {
9436 assert(m_object != nullptr);
9437
9438 switch (m_object->m_type)
9439 {
9440 case value_t::object:
9441 {
9442 assert(m_it.object_iterator != m_object->m_value.object->end());
9443 return m_it.object_iterator->second;
9444 }
9445
9446 case value_t::array:
9447 {
9448 assert(m_it.array_iterator != m_object->m_value.array->end());
9449 return *m_it.array_iterator;
9450 }
9451
9452 case value_t::null:
9453 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
9454
9455 default:
9456 {
9457 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
9458 {
9459 return *m_object;
9460 }
9461
9462 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
9463 }
9464 }
9465 }
9466
9467 /*!
9468 @brief dereference the iterator
9469 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9470 */
9471 pointer operator->() const
9472 {
9473 assert(m_object != nullptr);
9474
9475 switch (m_object->m_type)
9476 {
9477 case value_t::object:
9478 {
9479 assert(m_it.object_iterator != m_object->m_value.object->end());
9480 return &(m_it.object_iterator->second);
9481 }
9482
9483 case value_t::array:
9484 {
9485 assert(m_it.array_iterator != m_object->m_value.array->end());
9486 return &*m_it.array_iterator;
9487 }
9488
9489 default:
9490 {
9491 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
9492 {
9493 return m_object;
9494 }
9495
9496 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
9497 }
9498 }
9499 }
9500
9501 /*!
9502 @brief post-increment (it++)
9503 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9504 */
9505 iter_impl const operator++(int)
9506 {
9507 auto result = *this;
9508 ++(*this);
9509 return result;
9510 }
9511
9512 /*!
9513 @brief pre-increment (++it)
9514 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9515 */
9516 iter_impl& operator++()
9517 {
9518 assert(m_object != nullptr);
9519
9520 switch (m_object->m_type)
9521 {
9522 case value_t::object:
9523 {
9524 std::advance(m_it.object_iterator, 1);
9525 break;
9526 }
9527
9528 case value_t::array:
9529 {
9530 std::advance(m_it.array_iterator, 1);
9531 break;
9532 }
9533
9534 default:
9535 {
9536 ++m_it.primitive_iterator;
9537 break;
9538 }
9539 }
9540
9541 return *this;
9542 }
9543
9544 /*!
9545 @brief post-decrement (it--)
9546 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9547 */
9548 iter_impl const operator--(int)
9549 {
9550 auto result = *this;
9551 --(*this);
9552 return result;
9553 }
9554
9555 /*!
9556 @brief pre-decrement (--it)
9557 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9558 */
9559 iter_impl& operator--()
9560 {
9561 assert(m_object != nullptr);
9562
9563 switch (m_object->m_type)
9564 {
9565 case value_t::object:
9566 {
9567 std::advance(m_it.object_iterator, -1);
9568 break;
9569 }
9570
9571 case value_t::array:
9572 {
9573 std::advance(m_it.array_iterator, -1);
9574 break;
9575 }
9576
9577 default:
9578 {
9579 --m_it.primitive_iterator;
9580 break;
9581 }
9582 }
9583
9584 return *this;
9585 }
9586
9587 /*!
9588 @brief comparison: equal
9589 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9590 */
9591 bool operator==(const iter_impl& other) const
9592 {
9593 // if objects are not the same, the comparison is undefined
9594 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
9595 {
9596 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
9597 }
9598
9599 assert(m_object != nullptr);
9600
9601 switch (m_object->m_type)
9602 {
9603 case value_t::object:
9604 return (m_it.object_iterator == other.m_it.object_iterator);
9605
9606 case value_t::array:
9607 return (m_it.array_iterator == other.m_it.array_iterator);
9608
9609 default:
9610 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
9611 }
9612 }
9613
9614 /*!
9615 @brief comparison: not equal
9616 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9617 */
9618 bool operator!=(const iter_impl& other) const
9619 {
9620 return not operator==(other);
9621 }
9622
9623 /*!
9624 @brief comparison: smaller
9625 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9626 */
9627 bool operator<(const iter_impl& other) const
9628 {
9629 // if objects are not the same, the comparison is undefined
9630 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
9631 {
9632 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
9633 }
9634
9635 assert(m_object != nullptr);
9636
9637 switch (m_object->m_type)
9638 {
9639 case value_t::object:
9640 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
9641
9642 case value_t::array:
9643 return (m_it.array_iterator < other.m_it.array_iterator);
9644
9645 default:
9646 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
9647 }
9648 }
9649
9650 /*!
9651 @brief comparison: less than or equal
9652 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9653 */
9654 bool operator<=(const iter_impl& other) const
9655 {
9656 return not other.operator < (*this);
9657 }
9658
9659 /*!
9660 @brief comparison: greater than
9661 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9662 */
9663 bool operator>(const iter_impl& other) const
9664 {
9665 return not operator<=(other);
9666 }
9667
9668 /*!
9669 @brief comparison: greater than or equal
9670 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9671 */
9672 bool operator>=(const iter_impl& other) const
9673 {
9674 return not operator<(other);
9675 }
9676
9677 /*!
9678 @brief add to iterator
9679 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9680 */
9681 iter_impl& operator+=(difference_type i)
9682 {
9683 assert(m_object != nullptr);
9684
9685 switch (m_object->m_type)
9686 {
9687 case value_t::object:
9688 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
9689
9690 case value_t::array:
9691 {
9692 std::advance(m_it.array_iterator, i);
9693 break;
9694 }
9695
9696 default:
9697 {
9698 m_it.primitive_iterator += i;
9699 break;
9700 }
9701 }
9702
9703 return *this;
9704 }
9705
9706 /*!
9707 @brief subtract from iterator
9708 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9709 */
9710 iter_impl& operator-=(difference_type i)
9711 {
9712 return operator+=(-i);
9713 }
9714
9715 /*!
9716 @brief add to iterator
9717 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9718 */
9719 iter_impl operator+(difference_type i) const
9720 {
9721 auto result = *this;
9722 result += i;
9723 return result;
9724 }
9725
9726 /*!
9727 @brief addition of distance and iterator
9728 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9729 */
9730 friend iter_impl operator+(difference_type i, const iter_impl& it)
9731 {
9732 auto result = it;
9733 result += i;
9734 return result;
9735 }
9736
9737 /*!
9738 @brief subtract from iterator
9739 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9740 */
9741 iter_impl operator-(difference_type i) const
9742 {
9743 auto result = *this;
9744 result -= i;
9745 return result;
9746 }
9747
9748 /*!
9749 @brief return difference
9750 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9751 */
9752 difference_type operator-(const iter_impl& other) const
9753 {
9754 assert(m_object != nullptr);
9755
9756 switch (m_object->m_type)
9757 {
9758 case value_t::object:
9759 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
9760
9761 case value_t::array:
9762 return m_it.array_iterator - other.m_it.array_iterator;
9763
9764 default:
9765 return m_it.primitive_iterator - other.m_it.primitive_iterator;
9766 }
9767 }
9768
9769 /*!
9770 @brief access to successor
9771 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9772 */
9773 reference operator[](difference_type n) const
9774 {
9775 assert(m_object != nullptr);
9776
9777 switch (m_object->m_type)
9778 {
9779 case value_t::object:
9780 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
9781
9782 case value_t::array:
9783 return *std::next(m_it.array_iterator, n);
9784
9785 case value_t::null:
9786 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
9787
9788 default:
9789 {
9790 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
9791 {
9792 return *m_object;
9793 }
9794
9795 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
9796 }
9797 }
9798 }
9799
9800 /*!
9801 @brief return the key of an object iterator
9802 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9803 */
9804 const typename object_t::key_type& key() const
9805 {
9806 assert(m_object != nullptr);
9807
9808 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
9809 {
9810 return m_it.object_iterator->first;
9811 }
9812
9813 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
9814 }
9815
9816 /*!
9817 @brief return the value of an iterator
9818 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9819 */
9820 reference value() const
9821 {
9822 return operator*();
9823 }
9824
9825 private:
9826 /// associated JSON instance
9827 pointer m_object = nullptr;
9828 /// the actual iterator of the associated instance
9829 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
9830 };
9831 } // namespace detail
9832 } // namespace nlohmann
9833
9834 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
9835
9836 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
9837
9838
9839 #include <cstddef> // ptrdiff_t
9840 #include <iterator> // reverse_iterator
9841 #include <utility> // declval
9842
9843 namespace nlohmann
9844 {
9845 namespace detail
9846 {
9847 //////////////////////
9848 // reverse_iterator //
9849 //////////////////////
9850
9851 /*!
9852 @brief a template for a reverse iterator class
9853
9854 @tparam Base the base iterator type to reverse. Valid types are @ref
9855 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
9856 create @ref const_reverse_iterator).
9857
9858 @requirement The class satisfies the following concept requirements:
9859 -
9860 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
9861 The iterator that can be moved can be moved in both directions (i.e.
9862 incremented and decremented).
9863 - [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
9864 It is possible to write to the pointed-to element (only if @a Base is
9865 @ref iterator).
9866
9867 @since version 1.0.0
9868 */
9869 template<typename Base>
9870 class json_reverse_iterator : public std::reverse_iterator<Base>
9871 {
9872 public:
9873 using difference_type = std::ptrdiff_t;
9874 /// shortcut to the reverse iterator adapter
9875 using base_iterator = std::reverse_iterator<Base>;
9876 /// the reference type for the pointed-to element
9877 using reference = typename Base::reference;
9878
9879 /// create reverse iterator from iterator
9880 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
9881 : base_iterator(it) {}
9882
9883 /// create reverse iterator from base class
9884 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
9885
9886 /// post-increment (it++)
9887 json_reverse_iterator const operator++(int)
9888 {
9889 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
9890 }
9891
9892 /// pre-increment (++it)
9893 json_reverse_iterator& operator++()
9894 {
9895 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
9896 }
9897
9898 /// post-decrement (it--)
9899 json_reverse_iterator const operator--(int)
9900 {
9901 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
9902 }
9903
9904 /// pre-decrement (--it)
9905 json_reverse_iterator& operator--()
9906 {
9907 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
9908 }
9909
9910 /// add to iterator
9911 json_reverse_iterator& operator+=(difference_type i)
9912 {
9913 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
9914 }
9915
9916 /// add to iterator
9917 json_reverse_iterator operator+(difference_type i) const
9918 {
9919 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
9920 }
9921
9922 /// subtract from iterator
9923 json_reverse_iterator operator-(difference_type i) const
9924 {
9925 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
9926 }
9927
9928 /// return difference
9929 difference_type operator-(const json_reverse_iterator& other) const
9930 {
9931 return base_iterator(*this) - base_iterator(other);
9932 }
9933
9934 /// access to successor
9935 reference operator[](difference_type n) const
9936 {
9937 return *(this->operator+(n));
9938 }
9939
9940 /// return the key of an object iterator
9941 auto key() const -> decltype(std::declval<Base>().key())
9942 {
9943 auto it = --this->base();
9944 return it.key();
9945 }
9946
9947 /// return the value of an iterator
9948 reference value() const
9949 {
9950 auto it = --this->base();
9951 return it.operator * ();
9952 }
9953 };
9954 } // namespace detail
9955 } // namespace nlohmann
9956
9957 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
9958
9959 // #include <nlohmann/detail/json_pointer.hpp>
9960
9961
9962 #include <algorithm> // all_of
9963 #include <cassert> // assert
9964 #include <cctype> // isdigit
9965 #include <numeric> // accumulate
9966 #include <string> // string
9967 #include <utility> // move
9968 #include <vector> // vector
9969
9970 // #include <nlohmann/detail/exceptions.hpp>
9971
9972 // #include <nlohmann/detail/macro_scope.hpp>
9973
9974 // #include <nlohmann/detail/value_t.hpp>
9975
9976
9977 namespace nlohmann
9978 {
9979 template<typename BasicJsonType>
9980 class json_pointer
9981 {
9982 // allow basic_json to access private members
9983 NLOHMANN_BASIC_JSON_TPL_DECLARATION
9984 friend class basic_json;
9985
9986 public:
9987 /*!
9988 @brief create JSON pointer
9989
9990 Create a JSON pointer according to the syntax described in
9991 [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
9992
9993 @param[in] s string representing the JSON pointer; if omitted, the empty
9994 string is assumed which references the whole JSON value
9995
9996 @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
9997 not begin with a slash (`/`); see example below
9998
9999 @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
10000 not followed by `0` (representing `~`) or `1` (representing `/`); see
10001 example below
10002
10003 @liveexample{The example shows the construction several valid JSON pointers
10004 as well as the exceptional behavior.,json_pointer}
10005
10006 @since version 2.0.0
10007 */
10008 explicit json_pointer(const std::string& s = "")
10009 : reference_tokens(split(s))
10010 {}
10011
10012 /*!
10013 @brief return a string representation of the JSON pointer
10014
10015 @invariant For each JSON pointer `ptr`, it holds:
10016 @code {.cpp}
10017 ptr == json_pointer(ptr.to_string());
10018 @endcode
10019
10020 @return a string representation of the JSON pointer
10021
10022 @liveexample{The example shows the result of `to_string`.,json_pointer__to_string}
10023
10024 @since version 2.0.0
10025 */
10026 std::string to_string() const
10027 {
10028 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
10029 std::string{},
10030 [](const std::string & a, const std::string & b)
10031 {
10032 return a + "/" + escape(b);
10033 });
10034 }
10035
10036 /// @copydoc to_string()
10037 operator std::string() const
10038 {
10039 return to_string();
10040 }
10041
10042 /*!
10043 @brief append another JSON pointer at the end of this JSON pointer
10044
10045 @param[in] ptr JSON pointer to append
10046 @return JSON pointer with @a ptr appended
10047
10048 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
10049
10050 @complexity Linear in the length of @a ptr.
10051
10052 @sa @ref operator/=(std::string) to append a reference token
10053 @sa @ref operator/=(std::size_t) to append an array index
10054 @sa @ref operator/(const json_pointer&, const json_pointer&) for a binary operator
10055
10056 @since version 3.6.0
10057 */
10058 json_pointer& operator/=(const json_pointer& ptr)
10059 {
10060 reference_tokens.insert(reference_tokens.end(),
10061 ptr.reference_tokens.begin(),
10062 ptr.reference_tokens.end());
10063 return *this;
10064 }
10065
10066 /*!
10067 @brief append an unescaped reference token at the end of this JSON pointer
10068
10069 @param[in] token reference token to append
10070 @return JSON pointer with @a token appended without escaping @a token
10071
10072 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
10073
10074 @complexity Amortized constant.
10075
10076 @sa @ref operator/=(const json_pointer&) to append a JSON pointer
10077 @sa @ref operator/=(std::size_t) to append an array index
10078 @sa @ref operator/(const json_pointer&, std::size_t) for a binary operator
10079
10080 @since version 3.6.0
10081 */
10082 json_pointer& operator/=(std::string token)
10083 {
10084 push_back(std::move(token));
10085 return *this;
10086 }
10087
10088 /*!
10089 @brief append an array index at the end of this JSON pointer
10090
10091 @param[in] array_index array index ot append
10092 @return JSON pointer with @a array_index appended
10093
10094 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
10095
10096 @complexity Amortized constant.
10097
10098 @sa @ref operator/=(const json_pointer&) to append a JSON pointer
10099 @sa @ref operator/=(std::string) to append a reference token
10100 @sa @ref operator/(const json_pointer&, std::string) for a binary operator
10101
10102 @since version 3.6.0
10103 */
10104 json_pointer& operator/=(std::size_t array_index)
10105 {
10106 return *this /= std::to_string(array_index);
10107 }
10108
10109 /*!
10110 @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
10111
10112 @param[in] lhs JSON pointer
10113 @param[in] rhs JSON pointer
10114 @return a new JSON pointer with @a rhs appended to @a lhs
10115
10116 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
10117
10118 @complexity Linear in the length of @a lhs and @a rhs.
10119
10120 @sa @ref operator/=(const json_pointer&) to append a JSON pointer
10121
10122 @since version 3.6.0
10123 */
10124 friend json_pointer operator/(const json_pointer& lhs,
10125 const json_pointer& rhs)
10126 {
10127 return json_pointer(lhs) /= rhs;
10128 }
10129
10130 /*!
10131 @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
10132
10133 @param[in] ptr JSON pointer
10134 @param[in] token reference token
10135 @return a new JSON pointer with unescaped @a token appended to @a ptr
10136
10137 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
10138
10139 @complexity Linear in the length of @a ptr.
10140
10141 @sa @ref operator/=(std::string) to append a reference token
10142
10143 @since version 3.6.0
10144 */
10145 friend json_pointer operator/(const json_pointer& ptr, std::string token)
10146 {
10147 return json_pointer(ptr) /= std::move(token);
10148 }
10149
10150 /*!
10151 @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
10152
10153 @param[in] ptr JSON pointer
10154 @param[in] array_index array index
10155 @return a new JSON pointer with @a array_index appended to @a ptr
10156
10157 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
10158
10159 @complexity Linear in the length of @a ptr.
10160
10161 @sa @ref operator/=(std::size_t) to append an array index
10162
10163 @since version 3.6.0
10164 */
10165 friend json_pointer operator/(const json_pointer& ptr, std::size_t array_index)
10166 {
10167 return json_pointer(ptr) /= array_index;
10168 }
10169
10170 /*!
10171 @brief returns the parent of this JSON pointer
10172
10173 @return parent of this JSON pointer; in case this JSON pointer is the root,
10174 the root itself is returned
10175
10176 @complexity Linear in the length of the JSON pointer.
10177
10178 @liveexample{The example shows the result of `parent_pointer` for different
10179 JSON Pointers.,json_pointer__parent_pointer}
10180
10181 @since version 3.6.0
10182 */
10183 json_pointer parent_pointer() const
10184 {
10185 if (empty())
10186 {
10187 return *this;
10188 }
10189
10190 json_pointer res = *this;
10191 res.pop_back();
10192 return res;
10193 }
10194
10195 /*!
10196 @brief remove last reference token
10197
10198 @pre not `empty()`
10199
10200 @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back}
10201
10202 @complexity Constant.
10203
10204 @throw out_of_range.405 if JSON pointer has no parent
10205
10206 @since version 3.6.0
10207 */
10208 void pop_back()
10209 {
10210 if (JSON_HEDLEY_UNLIKELY(empty()))
10211 {
10212 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
10213 }
10214
10215 reference_tokens.pop_back();
10216 }
10217
10218 /*!
10219 @brief return last reference token
10220
10221 @pre not `empty()`
10222 @return last reference token
10223
10224 @liveexample{The example shows the usage of `back`.,json_pointer__back}
10225
10226 @complexity Constant.
10227
10228 @throw out_of_range.405 if JSON pointer has no parent
10229
10230 @since version 3.6.0
10231 */
10232 const std::string& back()
10233 {
10234 if (JSON_HEDLEY_UNLIKELY(empty()))
10235 {
10236 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
10237 }
10238
10239 return reference_tokens.back();
10240 }
10241
10242 /*!
10243 @brief append an unescaped token at the end of the reference pointer
10244
10245 @param[in] token token to add
10246
10247 @complexity Amortized constant.
10248
10249 @liveexample{The example shows the result of `push_back` for different
10250 JSON Pointers.,json_pointer__push_back}
10251
10252 @since version 3.6.0
10253 */
10254 void push_back(const std::string& token)
10255 {
10256 reference_tokens.push_back(token);
10257 }
10258
10259 /// @copydoc push_back(const std::string&)
10260 void push_back(std::string&& token)
10261 {
10262 reference_tokens.push_back(std::move(token));
10263 }
10264
10265 /*!
10266 @brief return whether pointer points to the root document
10267
10268 @return true iff the JSON pointer points to the root document
10269
10270 @complexity Constant.
10271
10272 @exceptionsafety No-throw guarantee: this function never throws exceptions.
10273
10274 @liveexample{The example shows the result of `empty` for different JSON
10275 Pointers.,json_pointer__empty}
10276
10277 @since version 3.6.0
10278 */
10279 bool empty() const noexcept
10280 {
10281 return reference_tokens.empty();
10282 }
10283
10284 private:
10285 /*!
10286 @param[in] s reference token to be converted into an array index
10287
10288 @return integer representation of @a s
10289
10290 @throw out_of_range.404 if string @a s could not be converted to an integer
10291 */
10292 static int array_index(const std::string& s)
10293 {
10294 std::size_t processed_chars = 0;
10295 const int res = std::stoi(s, &processed_chars);
10296
10297 // check if the string was completely read
10298 if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
10299 {
10300 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
10301 }
10302
10303 return res;
10304 }
10305
10306 json_pointer top() const
10307 {
10308 if (JSON_HEDLEY_UNLIKELY(empty()))
10309 {
10310 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
10311 }
10312
10313 json_pointer result = *this;
10314 result.reference_tokens = {reference_tokens[0]};
10315 return result;
10316 }
10317
10318 /*!
10319 @brief create and return a reference to the pointed to value
10320
10321 @complexity Linear in the number of reference tokens.
10322
10323 @throw parse_error.109 if array index is not a number
10324 @throw type_error.313 if value cannot be unflattened
10325 */
10326 BasicJsonType& get_and_create(BasicJsonType& j) const
10327 {
10328 using size_type = typename BasicJsonType::size_type;
10329 auto result = &j;
10330
10331 // in case no reference tokens exist, return a reference to the JSON value
10332 // j which will be overwritten by a primitive value
10333 for (const auto& reference_token : reference_tokens)
10334 {
10335 switch (result->type())
10336 {
10337 case detail::value_t::null:
10338 {
10339 if (reference_token == "0")
10340 {
10341 // start a new array if reference token is 0
10342 result = &result->operator[](0);
10343 }
10344 else
10345 {
10346 // start a new object otherwise
10347 result = &result->operator[](reference_token);
10348 }
10349 break;
10350 }
10351
10352 case detail::value_t::object:
10353 {
10354 // create an entry in the object
10355 result = &result->operator[](reference_token);
10356 break;
10357 }
10358
10359 case detail::value_t::array:
10360 {
10361 // create an entry in the array
10362 JSON_TRY
10363 {
10364 result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
10365 }
10366 JSON_CATCH(std::invalid_argument&)
10367 {
10368 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10369 }
10370 break;
10371 }
10372
10373 /*
10374 The following code is only reached if there exists a reference
10375 token _and_ the current value is primitive. In this case, we have
10376 an error situation, because primitive values may only occur as
10377 single value; that is, with an empty list of reference tokens.
10378 */
10379 default:
10380 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
10381 }
10382 }
10383
10384 return *result;
10385 }
10386
10387 /*!
10388 @brief return a reference to the pointed to value
10389
10390 @note This version does not throw if a value is not present, but tries to
10391 create nested values instead. For instance, calling this function
10392 with pointer `"/this/that"` on a null value is equivalent to calling
10393 `operator[]("this").operator[]("that")` on that value, effectively
10394 changing the null value to an object.
10395
10396 @param[in] ptr a JSON value
10397
10398 @return reference to the JSON value pointed to by the JSON pointer
10399
10400 @complexity Linear in the length of the JSON pointer.
10401
10402 @throw parse_error.106 if an array index begins with '0'
10403 @throw parse_error.109 if an array index was not a number
10404 @throw out_of_range.404 if the JSON pointer can not be resolved
10405 */
10406 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
10407 {
10408 using size_type = typename BasicJsonType::size_type;
10409 for (const auto& reference_token : reference_tokens)
10410 {
10411 // convert null values to arrays or objects before continuing
10412 if (ptr->is_null())
10413 {
10414 // check if reference token is a number
10415 const bool nums =
10416 std::all_of(reference_token.begin(), reference_token.end(),
10417 [](const unsigned char x)
10418 {
10419 return std::isdigit(x);
10420 });
10421
10422 // change value to array for numbers or "-" or to object otherwise
10423 *ptr = (nums or reference_token == "-")
10424 ? detail::value_t::array
10425 : detail::value_t::object;
10426 }
10427
10428 switch (ptr->type())
10429 {
10430 case detail::value_t::object:
10431 {
10432 // use unchecked object access
10433 ptr = &ptr->operator[](reference_token);
10434 break;
10435 }
10436
10437 case detail::value_t::array:
10438 {
10439 // error condition (cf. RFC 6901, Sect. 4)
10440 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10441 {
10442 JSON_THROW(detail::parse_error::create(106, 0,
10443 "array index '" + reference_token +
10444 "' must not begin with '0'"));
10445 }
10446
10447 if (reference_token == "-")
10448 {
10449 // explicitly treat "-" as index beyond the end
10450 ptr = &ptr->operator[](ptr->m_value.array->size());
10451 }
10452 else
10453 {
10454 // convert array index to number; unchecked access
10455 JSON_TRY
10456 {
10457 ptr = &ptr->operator[](
10458 static_cast<size_type>(array_index(reference_token)));
10459 }
10460 JSON_CATCH(std::invalid_argument&)
10461 {
10462 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10463 }
10464 }
10465 break;
10466 }
10467
10468 default:
10469 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
10470 }
10471 }
10472
10473 return *ptr;
10474 }
10475
10476 /*!
10477 @throw parse_error.106 if an array index begins with '0'
10478 @throw parse_error.109 if an array index was not a number
10479 @throw out_of_range.402 if the array index '-' is used
10480 @throw out_of_range.404 if the JSON pointer can not be resolved
10481 */
10482 BasicJsonType& get_checked(BasicJsonType* ptr) const
10483 {
10484 using size_type = typename BasicJsonType::size_type;
10485 for (const auto& reference_token : reference_tokens)
10486 {
10487 switch (ptr->type())
10488 {
10489 case detail::value_t::object:
10490 {
10491 // note: at performs range check
10492 ptr = &ptr->at(reference_token);
10493 break;
10494 }
10495
10496 case detail::value_t::array:
10497 {
10498 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
10499 {
10500 // "-" always fails the range check
10501 JSON_THROW(detail::out_of_range::create(402,
10502 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
10503 ") is out of range"));
10504 }
10505
10506 // error condition (cf. RFC 6901, Sect. 4)
10507 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10508 {
10509 JSON_THROW(detail::parse_error::create(106, 0,
10510 "array index '" + reference_token +
10511 "' must not begin with '0'"));
10512 }
10513
10514 // note: at performs range check
10515 JSON_TRY
10516 {
10517 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
10518 }
10519 JSON_CATCH(std::invalid_argument&)
10520 {
10521 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10522 }
10523 break;
10524 }
10525
10526 default:
10527 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
10528 }
10529 }
10530
10531 return *ptr;
10532 }
10533
10534 /*!
10535 @brief return a const reference to the pointed to value
10536
10537 @param[in] ptr a JSON value
10538
10539 @return const reference to the JSON value pointed to by the JSON
10540 pointer
10541
10542 @throw parse_error.106 if an array index begins with '0'
10543 @throw parse_error.109 if an array index was not a number
10544 @throw out_of_range.402 if the array index '-' is used
10545 @throw out_of_range.404 if the JSON pointer can not be resolved
10546 */
10547 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
10548 {
10549 using size_type = typename BasicJsonType::size_type;
10550 for (const auto& reference_token : reference_tokens)
10551 {
10552 switch (ptr->type())
10553 {
10554 case detail::value_t::object:
10555 {
10556 // use unchecked object access
10557 ptr = &ptr->operator[](reference_token);
10558 break;
10559 }
10560
10561 case detail::value_t::array:
10562 {
10563 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
10564 {
10565 // "-" cannot be used for const access
10566 JSON_THROW(detail::out_of_range::create(402,
10567 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
10568 ") is out of range"));
10569 }
10570
10571 // error condition (cf. RFC 6901, Sect. 4)
10572 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10573 {
10574 JSON_THROW(detail::parse_error::create(106, 0,
10575 "array index '" + reference_token +
10576 "' must not begin with '0'"));
10577 }
10578
10579 // use unchecked array access
10580 JSON_TRY
10581 {
10582 ptr = &ptr->operator[](
10583 static_cast<size_type>(array_index(reference_token)));
10584 }
10585 JSON_CATCH(std::invalid_argument&)
10586 {
10587 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10588 }
10589 break;
10590 }
10591
10592 default:
10593 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
10594 }
10595 }
10596
10597 return *ptr;
10598 }
10599
10600 /*!
10601 @throw parse_error.106 if an array index begins with '0'
10602 @throw parse_error.109 if an array index was not a number
10603 @throw out_of_range.402 if the array index '-' is used
10604 @throw out_of_range.404 if the JSON pointer can not be resolved
10605 */
10606 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
10607 {
10608 using size_type = typename BasicJsonType::size_type;
10609 for (const auto& reference_token : reference_tokens)
10610 {
10611 switch (ptr->type())
10612 {
10613 case detail::value_t::object:
10614 {
10615 // note: at performs range check
10616 ptr = &ptr->at(reference_token);
10617 break;
10618 }
10619
10620 case detail::value_t::array:
10621 {
10622 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
10623 {
10624 // "-" always fails the range check
10625 JSON_THROW(detail::out_of_range::create(402,
10626 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
10627 ") is out of range"));
10628 }
10629
10630 // error condition (cf. RFC 6901, Sect. 4)
10631 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10632 {
10633 JSON_THROW(detail::parse_error::create(106, 0,
10634 "array index '" + reference_token +
10635 "' must not begin with '0'"));
10636 }
10637
10638 // note: at performs range check
10639 JSON_TRY
10640 {
10641 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
10642 }
10643 JSON_CATCH(std::invalid_argument&)
10644 {
10645 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10646 }
10647 break;
10648 }
10649
10650 default:
10651 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
10652 }
10653 }
10654
10655 return *ptr;
10656 }
10657
10658 /*!
10659 @throw parse_error.106 if an array index begins with '0'
10660 @throw parse_error.109 if an array index was not a number
10661 */
10662 bool contains(const BasicJsonType* ptr) const
10663 {
10664 using size_type = typename BasicJsonType::size_type;
10665 for (const auto& reference_token : reference_tokens)
10666 {
10667 switch (ptr->type())
10668 {
10669 case detail::value_t::object:
10670 {
10671 if (not ptr->contains(reference_token))
10672 {
10673 // we did not find the key in the object
10674 return false;
10675 }
10676
10677 ptr = &ptr->operator[](reference_token);
10678 break;
10679 }
10680
10681 case detail::value_t::array:
10682 {
10683 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
10684 {
10685 // "-" always fails the range check
10686 return false;
10687 }
10688
10689 // error condition (cf. RFC 6901, Sect. 4)
10690 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
10691 {
10692 JSON_THROW(detail::parse_error::create(106, 0,
10693 "array index '" + reference_token +
10694 "' must not begin with '0'"));
10695 }
10696
10697 JSON_TRY
10698 {
10699 const auto idx = static_cast<size_type>(array_index(reference_token));
10700 if (idx >= ptr->size())
10701 {
10702 // index out of range
10703 return false;
10704 }
10705
10706 ptr = &ptr->operator[](idx);
10707 break;
10708 }
10709 JSON_CATCH(std::invalid_argument&)
10710 {
10711 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
10712 }
10713 break;
10714 }
10715
10716 default:
10717 {
10718 // we do not expect primitive values if there is still a
10719 // reference token to process
10720 return false;
10721 }
10722 }
10723 }
10724
10725 // no reference token left means we found a primitive value
10726 return true;
10727 }
10728
10729 /*!
10730 @brief split the string input to reference tokens
10731
10732 @note This function is only called by the json_pointer constructor.
10733 All exceptions below are documented there.
10734
10735 @throw parse_error.107 if the pointer is not empty or begins with '/'
10736 @throw parse_error.108 if character '~' is not followed by '0' or '1'
10737 */
10738 static std::vector<std::string> split(const std::string& reference_string)
10739 {
10740 std::vector<std::string> result;
10741
10742 // special case: empty reference string -> no reference tokens
10743 if (reference_string.empty())
10744 {
10745 return result;
10746 }
10747
10748 // check if nonempty reference string begins with slash
10749 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
10750 {
10751 JSON_THROW(detail::parse_error::create(107, 1,
10752 "JSON pointer must be empty or begin with '/' - was: '" +
10753 reference_string + "'"));
10754 }
10755
10756 // extract the reference tokens:
10757 // - slash: position of the last read slash (or end of string)
10758 // - start: position after the previous slash
10759 for (
10760 // search for the first slash after the first character
10761 std::size_t slash = reference_string.find_first_of('/', 1),
10762 // set the beginning of the first reference token
10763 start = 1;
10764 // we can stop if start == 0 (if slash == std::string::npos)
10765 start != 0;
10766 // set the beginning of the next reference token
10767 // (will eventually be 0 if slash == std::string::npos)
10768 start = (slash == std::string::npos) ? 0 : slash + 1,
10769 // find next slash
10770 slash = reference_string.find_first_of('/', start))
10771 {
10772 // use the text between the beginning of the reference token
10773 // (start) and the last slash (slash).
10774 auto reference_token = reference_string.substr(start, slash - start);
10775
10776 // check reference tokens are properly escaped
10777 for (std::size_t pos = reference_token.find_first_of('~');
10778 pos != std::string::npos;
10779 pos = reference_token.find_first_of('~', pos + 1))
10780 {
10781 assert(reference_token[pos] == '~');
10782
10783 // ~ must be followed by 0 or 1
10784 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 or
10785 (reference_token[pos + 1] != '0' and
10786 reference_token[pos + 1] != '1')))
10787 {
10788 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
10789 }
10790 }
10791
10792 // finally, store the reference token
10793 unescape(reference_token);
10794 result.push_back(reference_token);
10795 }
10796
10797 return result;
10798 }
10799
10800 /*!
10801 @brief replace all occurrences of a substring by another string
10802
10803 @param[in,out] s the string to manipulate; changed so that all
10804 occurrences of @a f are replaced with @a t
10805 @param[in] f the substring to replace with @a t
10806 @param[in] t the string to replace @a f
10807
10808 @pre The search string @a f must not be empty. **This precondition is
10809 enforced with an assertion.**
10810
10811 @since version 2.0.0
10812 */
10813 static void replace_substring(std::string& s, const std::string& f,
10814 const std::string& t)
10815 {
10816 assert(not f.empty());
10817 for (auto pos = s.find(f); // find first occurrence of f
10818 pos != std::string::npos; // make sure f was found
10819 s.replace(pos, f.size(), t), // replace with t, and
10820 pos = s.find(f, pos + t.size())) // find next occurrence of f
10821 {}
10822 }
10823
10824 /// escape "~" to "~0" and "/" to "~1"
10825 static std::string escape(std::string s)
10826 {
10827 replace_substring(s, "~", "~0");
10828 replace_substring(s, "/", "~1");
10829 return s;
10830 }
10831
10832 /// unescape "~1" to tilde and "~0" to slash (order is important!)
10833 static void unescape(std::string& s)
10834 {
10835 replace_substring(s, "~1", "/");
10836 replace_substring(s, "~0", "~");
10837 }
10838
10839 /*!
10840 @param[in] reference_string the reference string to the current value
10841 @param[in] value the value to consider
10842 @param[in,out] result the result object to insert values to
10843
10844 @note Empty objects or arrays are flattened to `null`.
10845 */
10846 static void flatten(const std::string& reference_string,
10847 const BasicJsonType& value,
10848 BasicJsonType& result)
10849 {
10850 switch (value.type())
10851 {
10852 case detail::value_t::array:
10853 {
10854 if (value.m_value.array->empty())
10855 {
10856 // flatten empty array as null
10857 result[reference_string] = nullptr;
10858 }
10859 else
10860 {
10861 // iterate array and use index as reference string
10862 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
10863 {
10864 flatten(reference_string + "/" + std::to_string(i),
10865 value.m_value.array->operator[](i), result);
10866 }
10867 }
10868 break;
10869 }
10870
10871 case detail::value_t::object:
10872 {
10873 if (value.m_value.object->empty())
10874 {
10875 // flatten empty object as null
10876 result[reference_string] = nullptr;
10877 }
10878 else
10879 {
10880 // iterate object and use keys as reference string
10881 for (const auto& element : *value.m_value.object)
10882 {
10883 flatten(reference_string + "/" + escape(element.first), element.second, result);
10884 }
10885 }
10886 break;
10887 }
10888
10889 default:
10890 {
10891 // add primitive value with its reference string
10892 result[reference_string] = value;
10893 break;
10894 }
10895 }
10896 }
10897
10898 /*!
10899 @param[in] value flattened JSON
10900
10901 @return unflattened JSON
10902
10903 @throw parse_error.109 if array index is not a number
10904 @throw type_error.314 if value is not an object
10905 @throw type_error.315 if object values are not primitive
10906 @throw type_error.313 if value cannot be unflattened
10907 */
10908 static BasicJsonType
10909 unflatten(const BasicJsonType& value)
10910 {
10911 if (JSON_HEDLEY_UNLIKELY(not value.is_object()))
10912 {
10913 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
10914 }
10915
10916 BasicJsonType result;
10917
10918 // iterate the JSON object values
10919 for (const auto& element : *value.m_value.object)
10920 {
10921 if (JSON_HEDLEY_UNLIKELY(not element.second.is_primitive()))
10922 {
10923 JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
10924 }
10925
10926 // assign value to reference pointed to by JSON pointer; Note that if
10927 // the JSON pointer is "" (i.e., points to the whole value), function
10928 // get_and_create returns a reference to result itself. An assignment
10929 // will then create a primitive value.
10930 json_pointer(element.first).get_and_create(result) = element.second;
10931 }
10932
10933 return result;
10934 }
10935
10936 /*!
10937 @brief compares two JSON pointers for equality
10938
10939 @param[in] lhs JSON pointer to compare
10940 @param[in] rhs JSON pointer to compare
10941 @return whether @a lhs is equal to @a rhs
10942
10943 @complexity Linear in the length of the JSON pointer
10944
10945 @exceptionsafety No-throw guarantee: this function never throws exceptions.
10946 */
10947 friend bool operator==(json_pointer const& lhs,
10948 json_pointer const& rhs) noexcept
10949 {
10950 return lhs.reference_tokens == rhs.reference_tokens;
10951 }
10952
10953 /*!
10954 @brief compares two JSON pointers for inequality
10955
10956 @param[in] lhs JSON pointer to compare
10957 @param[in] rhs JSON pointer to compare
10958 @return whether @a lhs is not equal @a rhs
10959
10960 @complexity Linear in the length of the JSON pointer
10961
10962 @exceptionsafety No-throw guarantee: this function never throws exceptions.
10963 */
10964 friend bool operator!=(json_pointer const& lhs,
10965 json_pointer const& rhs) noexcept
10966 {
10967 return not (lhs == rhs);
10968 }
10969
10970 /// the reference tokens
10971 std::vector<std::string> reference_tokens;
10972 };
10973 } // namespace nlohmann
10974
10975 // #include <nlohmann/detail/json_ref.hpp>
10976
10977
10978 #include <initializer_list>
10979 #include <utility>
10980
10981 // #include <nlohmann/detail/meta/type_traits.hpp>
10982
10983
10984 namespace nlohmann
10985 {
10986 namespace detail
10987 {
10988 template<typename BasicJsonType>
10989 class json_ref
10990 {
10991 public:
10992 using value_type = BasicJsonType;
10993
10994 json_ref(value_type&& value)
10995 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
10996 {}
10997
10998 json_ref(const value_type& value)
10999 : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
11000 {}
11001
11002 json_ref(std::initializer_list<json_ref> init)
11003 : owned_value(init), value_ref(&owned_value), is_rvalue(true)
11004 {}
11005
11006 template <
11007 class... Args,
11008 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
11009 json_ref(Args && ... args)
11010 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value),
11011 is_rvalue(true) {}
11012
11013 // class should be movable only
11014 json_ref(json_ref&&) = default;
11015 json_ref(const json_ref&) = delete;
11016 json_ref& operator=(const json_ref&) = delete;
11017 json_ref& operator=(json_ref&&) = delete;
11018 ~json_ref() = default;
11019
11020 value_type moved_or_copied() const
11021 {
11022 if (is_rvalue)
11023 {
11024 return std::move(*value_ref);
11025 }
11026 return *value_ref;
11027 }
11028
11029 value_type const& operator*() const
11030 {
11031 return *static_cast<value_type const*>(value_ref);
11032 }
11033
11034 value_type const* operator->() const
11035 {
11036 return static_cast<value_type const*>(value_ref);
11037 }
11038
11039 private:
11040 mutable value_type owned_value = nullptr;
11041 value_type* value_ref = nullptr;
11042 const bool is_rvalue;
11043 };
11044 } // namespace detail
11045 } // namespace nlohmann
11046
11047 // #include <nlohmann/detail/macro_scope.hpp>
11048
11049 // #include <nlohmann/detail/meta/cpp_future.hpp>
11050
11051 // #include <nlohmann/detail/meta/type_traits.hpp>
11052
11053 // #include <nlohmann/detail/output/binary_writer.hpp>
11054
11055
11056 #include <algorithm> // reverse
11057 #include <array> // array
11058 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
11059 #include <cstring> // memcpy
11060 #include <limits> // numeric_limits
11061 #include <string> // string
11062
11063 // #include <nlohmann/detail/input/binary_reader.hpp>
11064
11065 // #include <nlohmann/detail/macro_scope.hpp>
11066
11067 // #include <nlohmann/detail/output/output_adapters.hpp>
11068
11069
11070 #include <algorithm> // copy
11071 #include <cstddef> // size_t
11072 #include <ios> // streamsize
11073 #include <iterator> // back_inserter
11074 #include <memory> // shared_ptr, make_shared
11075 #include <ostream> // basic_ostream
11076 #include <string> // basic_string
11077 #include <vector> // vector
11078 // #include <nlohmann/detail/macro_scope.hpp>
11079
11080
11081 namespace nlohmann
11082 {
11083 namespace detail
11084 {
11085 /// abstract output adapter interface
11086 template<typename CharType> struct output_adapter_protocol
11087 {
11088 virtual void write_character(CharType c) = 0;
11089 virtual void write_characters(const CharType* s, std::size_t length) = 0;
11090 virtual ~output_adapter_protocol() = default;
11091 };
11092
11093 /// a type to simplify interfaces
11094 template<typename CharType>
11095 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
11096
11097 /// output adapter for byte vectors
11098 template<typename CharType>
11099 class output_vector_adapter : public output_adapter_protocol<CharType>
11100 {
11101 public:
11102 explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
11103 : v(vec)
11104 {}
11105
11106 void write_character(CharType c) override
11107 {
11108 v.push_back(c);
11109 }
11110
11111 JSON_HEDLEY_NON_NULL(2)
11112 void write_characters(const CharType* s, std::size_t length) override
11113 {
11114 std::copy(s, s + length, std::back_inserter(v));
11115 }
11116
11117 private:
11118 std::vector<CharType>& v;
11119 };
11120
11121 /// output adapter for output streams
11122 template<typename CharType>
11123 class output_stream_adapter : public output_adapter_protocol<CharType>
11124 {
11125 public:
11126 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
11127 : stream(s)
11128 {}
11129
11130 void write_character(CharType c) override
11131 {
11132 stream.put(c);
11133 }
11134
11135 JSON_HEDLEY_NON_NULL(2)
11136 void write_characters(const CharType* s, std::size_t length) override
11137 {
11138 stream.write(s, static_cast<std::streamsize>(length));
11139 }
11140
11141 private:
11142 std::basic_ostream<CharType>& stream;
11143 };
11144
11145 /// output adapter for basic_string
11146 template<typename CharType, typename StringType = std::basic_string<CharType>>
11147 class output_string_adapter : public output_adapter_protocol<CharType>
11148 {
11149 public:
11150 explicit output_string_adapter(StringType& s) noexcept
11151 : str(s)
11152 {}
11153
11154 void write_character(CharType c) override
11155 {
11156 str.push_back(c);
11157 }
11158
11159 JSON_HEDLEY_NON_NULL(2)
11160 void write_characters(const CharType* s, std::size_t length) override
11161 {
11162 str.append(s, length);
11163 }
11164
11165 private:
11166 StringType& str;
11167 };
11168
11169 template<typename CharType, typename StringType = std::basic_string<CharType>>
11170 class output_adapter
11171 {
11172 public:
11173 output_adapter(std::vector<CharType>& vec)
11174 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
11175
11176 output_adapter(std::basic_ostream<CharType>& s)
11177 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
11178
11179 output_adapter(StringType& s)
11180 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
11181
11182 operator output_adapter_t<CharType>()
11183 {
11184 return oa;
11185 }
11186
11187 private:
11188 output_adapter_t<CharType> oa = nullptr;
11189 };
11190 } // namespace detail
11191 } // namespace nlohmann
11192
11193
11194 namespace nlohmann
11195 {
11196 namespace detail
11197 {
11198 ///////////////////
11199 // binary writer //
11200 ///////////////////
11201
11202 /*!
11203 @brief serialization to CBOR and MessagePack values
11204 */
11205 template<typename BasicJsonType, typename CharType>
11206 class binary_writer
11207 {
11208 using string_t = typename BasicJsonType::string_t;
11209
11210 public:
11211 /*!
11212 @brief create a binary writer
11213
11214 @param[in] adapter output adapter to write to
11215 */
11216 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
11217 {
11218 assert(oa);
11219 }
11220
11221 /*!
11222 @param[in] j JSON value to serialize
11223 @pre j.type() == value_t::object
11224 */
11225 void write_bson(const BasicJsonType& j)
11226 {
11227 switch (j.type())
11228 {
11229 case value_t::object:
11230 {
11231 write_bson_object(*j.m_value.object);
11232 break;
11233 }
11234
11235 default:
11236 {
11237 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
11238 }
11239 }
11240 }
11241
11242 /*!
11243 @param[in] j JSON value to serialize
11244 */
11245 void write_cbor(const BasicJsonType& j)
11246 {
11247 switch (j.type())
11248 {
11249 case value_t::null:
11250 {
11251 oa->write_character(to_char_type(0xF6));
11252 break;
11253 }
11254
11255 case value_t::boolean:
11256 {
11257 oa->write_character(j.m_value.boolean
11258 ? to_char_type(0xF5)
11259 : to_char_type(0xF4));
11260 break;
11261 }
11262
11263 case value_t::number_integer:
11264 {
11265 if (j.m_value.number_integer >= 0)
11266 {
11267 // CBOR does not differentiate between positive signed
11268 // integers and unsigned integers. Therefore, we used the
11269 // code from the value_t::number_unsigned case here.
11270 if (j.m_value.number_integer <= 0x17)
11271 {
11272 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
11273 }
11274 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
11275 {
11276 oa->write_character(to_char_type(0x18));
11277 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
11278 }
11279 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
11280 {
11281 oa->write_character(to_char_type(0x19));
11282 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
11283 }
11284 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
11285 {
11286 oa->write_character(to_char_type(0x1A));
11287 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
11288 }
11289 else
11290 {
11291 oa->write_character(to_char_type(0x1B));
11292 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
11293 }
11294 }
11295 else
11296 {
11297 // The conversions below encode the sign in the first
11298 // byte, and the value is converted to a positive number.
11299 const auto positive_number = -1 - j.m_value.number_integer;
11300 if (j.m_value.number_integer >= -24)
11301 {
11302 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
11303 }
11304 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
11305 {
11306 oa->write_character(to_char_type(0x38));
11307 write_number(static_cast<std::uint8_t>(positive_number));
11308 }
11309 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
11310 {
11311 oa->write_character(to_char_type(0x39));
11312 write_number(static_cast<std::uint16_t>(positive_number));
11313 }
11314 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
11315 {
11316 oa->write_character(to_char_type(0x3A));
11317 write_number(static_cast<std::uint32_t>(positive_number));
11318 }
11319 else
11320 {
11321 oa->write_character(to_char_type(0x3B));
11322 write_number(static_cast<std::uint64_t>(positive_number));
11323 }
11324 }
11325 break;
11326 }
11327
11328 case value_t::number_unsigned:
11329 {
11330 if (j.m_value.number_unsigned <= 0x17)
11331 {
11332 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
11333 }
11334 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
11335 {
11336 oa->write_character(to_char_type(0x18));
11337 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
11338 }
11339 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
11340 {
11341 oa->write_character(to_char_type(0x19));
11342 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
11343 }
11344 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
11345 {
11346 oa->write_character(to_char_type(0x1A));
11347 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
11348 }
11349 else
11350 {
11351 oa->write_character(to_char_type(0x1B));
11352 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
11353 }
11354 break;
11355 }
11356
11357 case value_t::number_float:
11358 {
11359 oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
11360 write_number(j.m_value.number_float);
11361 break;
11362 }
11363
11364 case value_t::string:
11365 {
11366 // step 1: write control byte and the string length
11367 const auto N = j.m_value.string->size();
11368 if (N <= 0x17)
11369 {
11370 write_number(static_cast<std::uint8_t>(0x60 + N));
11371 }
11372 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
11373 {
11374 oa->write_character(to_char_type(0x78));
11375 write_number(static_cast<std::uint8_t>(N));
11376 }
11377 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
11378 {
11379 oa->write_character(to_char_type(0x79));
11380 write_number(static_cast<std::uint16_t>(N));
11381 }
11382 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
11383 {
11384 oa->write_character(to_char_type(0x7A));
11385 write_number(static_cast<std::uint32_t>(N));
11386 }
11387 // LCOV_EXCL_START
11388 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
11389 {
11390 oa->write_character(to_char_type(0x7B));
11391 write_number(static_cast<std::uint64_t>(N));
11392 }
11393 // LCOV_EXCL_STOP
11394
11395 // step 2: write the string
11396 oa->write_characters(
11397 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
11398 j.m_value.string->size());
11399 break;
11400 }
11401
11402 case value_t::array:
11403 {
11404 // step 1: write control byte and the array size
11405 const auto N = j.m_value.array->size();
11406 if (N <= 0x17)
11407 {
11408 write_number(static_cast<std::uint8_t>(0x80 + N));
11409 }
11410 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
11411 {
11412 oa->write_character(to_char_type(0x98));
11413 write_number(static_cast<std::uint8_t>(N));
11414 }
11415 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
11416 {
11417 oa->write_character(to_char_type(0x99));
11418 write_number(static_cast<std::uint16_t>(N));
11419 }
11420 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
11421 {
11422 oa->write_character(to_char_type(0x9A));
11423 write_number(static_cast<std::uint32_t>(N));
11424 }
11425 // LCOV_EXCL_START
11426 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
11427 {
11428 oa->write_character(to_char_type(0x9B));
11429 write_number(static_cast<std::uint64_t>(N));
11430 }
11431 // LCOV_EXCL_STOP
11432
11433 // step 2: write each element
11434 for (const auto& el : *j.m_value.array)
11435 {
11436 write_cbor(el);
11437 }
11438 break;
11439 }
11440
11441 case value_t::object:
11442 {
11443 // step 1: write control byte and the object size
11444 const auto N = j.m_value.object->size();
11445 if (N <= 0x17)
11446 {
11447 write_number(static_cast<std::uint8_t>(0xA0 + N));
11448 }
11449 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
11450 {
11451 oa->write_character(to_char_type(0xB8));
11452 write_number(static_cast<std::uint8_t>(N));
11453 }
11454 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
11455 {
11456 oa->write_character(to_char_type(0xB9));
11457 write_number(static_cast<std::uint16_t>(N));
11458 }
11459 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
11460 {
11461 oa->write_character(to_char_type(0xBA));
11462 write_number(static_cast<std::uint32_t>(N));
11463 }
11464 // LCOV_EXCL_START
11465 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
11466 {
11467 oa->write_character(to_char_type(0xBB));
11468 write_number(static_cast<std::uint64_t>(N));
11469 }
11470 // LCOV_EXCL_STOP
11471
11472 // step 2: write each element
11473 for (const auto& el : *j.m_value.object)
11474 {
11475 write_cbor(el.first);
11476 write_cbor(el.second);
11477 }
11478 break;
11479 }
11480
11481 default:
11482 break;
11483 }
11484 }
11485
11486 /*!
11487 @param[in] j JSON value to serialize
11488 */
11489 void write_msgpack(const BasicJsonType& j)
11490 {
11491 switch (j.type())
11492 {
11493 case value_t::null: // nil
11494 {
11495 oa->write_character(to_char_type(0xC0));
11496 break;
11497 }
11498
11499 case value_t::boolean: // true and false
11500 {
11501 oa->write_character(j.m_value.boolean
11502 ? to_char_type(0xC3)
11503 : to_char_type(0xC2));
11504 break;
11505 }
11506
11507 case value_t::number_integer:
11508 {
11509 if (j.m_value.number_integer >= 0)
11510 {
11511 // MessagePack does not differentiate between positive
11512 // signed integers and unsigned integers. Therefore, we used
11513 // the code from the value_t::number_unsigned case here.
11514 if (j.m_value.number_unsigned < 128)
11515 {
11516 // positive fixnum
11517 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
11518 }
11519 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
11520 {
11521 // uint 8
11522 oa->write_character(to_char_type(0xCC));
11523 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
11524 }
11525 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
11526 {
11527 // uint 16
11528 oa->write_character(to_char_type(0xCD));
11529 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
11530 }
11531 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
11532 {
11533 // uint 32
11534 oa->write_character(to_char_type(0xCE));
11535 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
11536 }
11537 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
11538 {
11539 // uint 64
11540 oa->write_character(to_char_type(0xCF));
11541 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
11542 }
11543 }
11544 else
11545 {
11546 if (j.m_value.number_integer >= -32)
11547 {
11548 // negative fixnum
11549 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
11550 }
11551 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() and
11552 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
11553 {
11554 // int 8
11555 oa->write_character(to_char_type(0xD0));
11556 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
11557 }
11558 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() and
11559 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
11560 {
11561 // int 16
11562 oa->write_character(to_char_type(0xD1));
11563 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
11564 }
11565 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() and
11566 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
11567 {
11568 // int 32
11569 oa->write_character(to_char_type(0xD2));
11570 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
11571 }
11572 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() and
11573 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
11574 {
11575 // int 64
11576 oa->write_character(to_char_type(0xD3));
11577 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
11578 }
11579 }
11580 break;
11581 }
11582
11583 case value_t::number_unsigned:
11584 {
11585 if (j.m_value.number_unsigned < 128)
11586 {
11587 // positive fixnum
11588 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
11589 }
11590 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
11591 {
11592 // uint 8
11593 oa->write_character(to_char_type(0xCC));
11594 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
11595 }
11596 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
11597 {
11598 // uint 16
11599 oa->write_character(to_char_type(0xCD));
11600 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
11601 }
11602 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
11603 {
11604 // uint 32
11605 oa->write_character(to_char_type(0xCE));
11606 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
11607 }
11608 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
11609 {
11610 // uint 64
11611 oa->write_character(to_char_type(0xCF));
11612 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
11613 }
11614 break;
11615 }
11616
11617 case value_t::number_float:
11618 {
11619 oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
11620 write_number(j.m_value.number_float);
11621 break;
11622 }
11623
11624 case value_t::string:
11625 {
11626 // step 1: write control byte and the string length
11627 const auto N = j.m_value.string->size();
11628 if (N <= 31)
11629 {
11630 // fixstr
11631 write_number(static_cast<std::uint8_t>(0xA0 | N));
11632 }
11633 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
11634 {
11635 // str 8
11636 oa->write_character(to_char_type(0xD9));
11637 write_number(static_cast<std::uint8_t>(N));
11638 }
11639 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
11640 {
11641 // str 16
11642 oa->write_character(to_char_type(0xDA));
11643 write_number(static_cast<std::uint16_t>(N));
11644 }
11645 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
11646 {
11647 // str 32
11648 oa->write_character(to_char_type(0xDB));
11649 write_number(static_cast<std::uint32_t>(N));
11650 }
11651
11652 // step 2: write the string
11653 oa->write_characters(
11654 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
11655 j.m_value.string->size());
11656 break;
11657 }
11658
11659 case value_t::array:
11660 {
11661 // step 1: write control byte and the array size
11662 const auto N = j.m_value.array->size();
11663 if (N <= 15)
11664 {
11665 // fixarray
11666 write_number(static_cast<std::uint8_t>(0x90 | N));
11667 }
11668 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
11669 {
11670 // array 16
11671 oa->write_character(to_char_type(0xDC));
11672 write_number(static_cast<std::uint16_t>(N));
11673 }
11674 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
11675 {
11676 // array 32
11677 oa->write_character(to_char_type(0xDD));
11678 write_number(static_cast<std::uint32_t>(N));
11679 }
11680
11681 // step 2: write each element
11682 for (const auto& el : *j.m_value.array)
11683 {
11684 write_msgpack(el);
11685 }
11686 break;
11687 }
11688
11689 case value_t::object:
11690 {
11691 // step 1: write control byte and the object size
11692 const auto N = j.m_value.object->size();
11693 if (N <= 15)
11694 {
11695 // fixmap
11696 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
11697 }
11698 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
11699 {
11700 // map 16
11701 oa->write_character(to_char_type(0xDE));
11702 write_number(static_cast<std::uint16_t>(N));
11703 }
11704 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
11705 {
11706 // map 32
11707 oa->write_character(to_char_type(0xDF));
11708 write_number(static_cast<std::uint32_t>(N));
11709 }
11710
11711 // step 2: write each element
11712 for (const auto& el : *j.m_value.object)
11713 {
11714 write_msgpack(el.first);
11715 write_msgpack(el.second);
11716 }
11717 break;
11718 }
11719
11720 default:
11721 break;
11722 }
11723 }
11724
11725 /*!
11726 @param[in] j JSON value to serialize
11727 @param[in] use_count whether to use '#' prefixes (optimized format)
11728 @param[in] use_type whether to use '$' prefixes (optimized format)
11729 @param[in] add_prefix whether prefixes need to be used for this value
11730 */
11731 void write_ubjson(const BasicJsonType& j, const bool use_count,
11732 const bool use_type, const bool add_prefix = true)
11733 {
11734 switch (j.type())
11735 {
11736 case value_t::null:
11737 {
11738 if (add_prefix)
11739 {
11740 oa->write_character(to_char_type('Z'));
11741 }
11742 break;
11743 }
11744
11745 case value_t::boolean:
11746 {
11747 if (add_prefix)
11748 {
11749 oa->write_character(j.m_value.boolean
11750 ? to_char_type('T')
11751 : to_char_type('F'));
11752 }
11753 break;
11754 }
11755
11756 case value_t::number_integer:
11757 {
11758 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
11759 break;
11760 }
11761
11762 case value_t::number_unsigned:
11763 {
11764 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
11765 break;
11766 }
11767
11768 case value_t::number_float:
11769 {
11770 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
11771 break;
11772 }
11773
11774 case value_t::string:
11775 {
11776 if (add_prefix)
11777 {
11778 oa->write_character(to_char_type('S'));
11779 }
11780 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
11781 oa->write_characters(
11782 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
11783 j.m_value.string->size());
11784 break;
11785 }
11786
11787 case value_t::array:
11788 {
11789 if (add_prefix)
11790 {
11791 oa->write_character(to_char_type('['));
11792 }
11793
11794 bool prefix_required = true;
11795 if (use_type and not j.m_value.array->empty())
11796 {
11797 assert(use_count);
11798 const CharType first_prefix = ubjson_prefix(j.front());
11799 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
11800 [this, first_prefix](const BasicJsonType & v)
11801 {
11802 return ubjson_prefix(v) == first_prefix;
11803 });
11804
11805 if (same_prefix)
11806 {
11807 prefix_required = false;
11808 oa->write_character(to_char_type('$'));
11809 oa->write_character(first_prefix);
11810 }
11811 }
11812
11813 if (use_count)
11814 {
11815 oa->write_character(to_char_type('#'));
11816 write_number_with_ubjson_prefix(j.m_value.array->size(), true);
11817 }
11818
11819 for (const auto& el : *j.m_value.array)
11820 {
11821 write_ubjson(el, use_count, use_type, prefix_required);
11822 }
11823
11824 if (not use_count)
11825 {
11826 oa->write_character(to_char_type(']'));
11827 }
11828
11829 break;
11830 }
11831
11832 case value_t::object:
11833 {
11834 if (add_prefix)
11835 {
11836 oa->write_character(to_char_type('{'));
11837 }
11838
11839 bool prefix_required = true;
11840 if (use_type and not j.m_value.object->empty())
11841 {
11842 assert(use_count);
11843 const CharType first_prefix = ubjson_prefix(j.front());
11844 const bool same_prefix = std::all_of(j.begin(), j.end(),
11845 [this, first_prefix](const BasicJsonType & v)
11846 {
11847 return ubjson_prefix(v) == first_prefix;
11848 });
11849
11850 if (same_prefix)
11851 {
11852 prefix_required = false;
11853 oa->write_character(to_char_type('$'));
11854 oa->write_character(first_prefix);
11855 }
11856 }
11857
11858 if (use_count)
11859 {
11860 oa->write_character(to_char_type('#'));
11861 write_number_with_ubjson_prefix(j.m_value.object->size(), true);
11862 }
11863
11864 for (const auto& el : *j.m_value.object)
11865 {
11866 write_number_with_ubjson_prefix(el.first.size(), true);
11867 oa->write_characters(
11868 reinterpret_cast<const CharType*>(el.first.c_str()),
11869 el.first.size());
11870 write_ubjson(el.second, use_count, use_type, prefix_required);
11871 }
11872
11873 if (not use_count)
11874 {
11875 oa->write_character(to_char_type('}'));
11876 }
11877
11878 break;
11879 }
11880
11881 default:
11882 break;
11883 }
11884 }
11885
11886 private:
11887 //////////
11888 // BSON //
11889 //////////
11890
11891 /*!
11892 @return The size of a BSON document entry header, including the id marker
11893 and the entry name size (and its null-terminator).
11894 */
11895 static std::size_t calc_bson_entry_header_size(const string_t& name)
11896 {
11897 const auto it = name.find(static_cast<typename string_t::value_type>(0));
11898 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
11899 {
11900 JSON_THROW(out_of_range::create(409,
11901 "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
11902 }
11903
11904 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
11905 }
11906
11907 /*!
11908 @brief Writes the given @a element_type and @a name to the output adapter
11909 */
11910 void write_bson_entry_header(const string_t& name,
11911 const std::uint8_t element_type)
11912 {
11913 oa->write_character(to_char_type(element_type)); // boolean
11914 oa->write_characters(
11915 reinterpret_cast<const CharType*>(name.c_str()),
11916 name.size() + 1u);
11917 }
11918
11919 /*!
11920 @brief Writes a BSON element with key @a name and boolean value @a value
11921 */
11922 void write_bson_boolean(const string_t& name,
11923 const bool value)
11924 {
11925 write_bson_entry_header(name, 0x08);
11926 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
11927 }
11928
11929 /*!
11930 @brief Writes a BSON element with key @a name and double value @a value
11931 */
11932 void write_bson_double(const string_t& name,
11933 const double value)
11934 {
11935 write_bson_entry_header(name, 0x01);
11936 write_number<double, true>(value);
11937 }
11938
11939 /*!
11940 @return The size of the BSON-encoded string in @a value
11941 */
11942 static std::size_t calc_bson_string_size(const string_t& value)
11943 {
11944 return sizeof(std::int32_t) + value.size() + 1ul;
11945 }
11946
11947 /*!
11948 @brief Writes a BSON element with key @a name and string value @a value
11949 */
11950 void write_bson_string(const string_t& name,
11951 const string_t& value)
11952 {
11953 write_bson_entry_header(name, 0x02);
11954
11955 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
11956 oa->write_characters(
11957 reinterpret_cast<const CharType*>(value.c_str()),
11958 value.size() + 1);
11959 }
11960
11961 /*!
11962 @brief Writes a BSON element with key @a name and null value
11963 */
11964 void write_bson_null(const string_t& name)
11965 {
11966 write_bson_entry_header(name, 0x0A);
11967 }
11968
11969 /*!
11970 @return The size of the BSON-encoded integer @a value
11971 */
11972 static std::size_t calc_bson_integer_size(const std::int64_t value)
11973 {
11974 return (std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)()
11975 ? sizeof(std::int32_t)
11976 : sizeof(std::int64_t);
11977 }
11978
11979 /*!
11980 @brief Writes a BSON element with key @a name and integer @a value
11981 */
11982 void write_bson_integer(const string_t& name,
11983 const std::int64_t value)
11984 {
11985 if ((std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)())
11986 {
11987 write_bson_entry_header(name, 0x10); // int32
11988 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
11989 }
11990 else
11991 {
11992 write_bson_entry_header(name, 0x12); // int64
11993 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
11994 }
11995 }
11996
11997 /*!
11998 @return The size of the BSON-encoded unsigned integer in @a j
11999 */
12000 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
12001 {
12002 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
12003 ? sizeof(std::int32_t)
12004 : sizeof(std::int64_t);
12005 }
12006
12007 /*!
12008 @brief Writes a BSON element with key @a name and unsigned @a value
12009 */
12010 void write_bson_unsigned(const string_t& name,
12011 const std::uint64_t value)
12012 {
12013 if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
12014 {
12015 write_bson_entry_header(name, 0x10 /* int32 */);
12016 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
12017 }
12018 else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
12019 {
12020 write_bson_entry_header(name, 0x12 /* int64 */);
12021 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
12022 }
12023 else
12024 {
12025 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
12026 }
12027 }
12028
12029 /*!
12030 @brief Writes a BSON element with key @a name and object @a value
12031 */
12032 void write_bson_object_entry(const string_t& name,
12033 const typename BasicJsonType::object_t& value)
12034 {
12035 write_bson_entry_header(name, 0x03); // object
12036 write_bson_object(value);
12037 }
12038
12039 /*!
12040 @return The size of the BSON-encoded array @a value
12041 */
12042 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
12043 {
12044 std::size_t embedded_document_size = 0ul;
12045 std::size_t array_index = 0ul;
12046
12047 for (const auto& el : value)
12048 {
12049 embedded_document_size += calc_bson_element_size(std::to_string(array_index++), el);
12050 }
12051
12052 return sizeof(std::int32_t) + embedded_document_size + 1ul;
12053 }
12054
12055 /*!
12056 @brief Writes a BSON element with key @a name and array @a value
12057 */
12058 void write_bson_array(const string_t& name,
12059 const typename BasicJsonType::array_t& value)
12060 {
12061 write_bson_entry_header(name, 0x04); // array
12062 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
12063
12064 std::size_t array_index = 0ul;
12065
12066 for (const auto& el : value)
12067 {
12068 write_bson_element(std::to_string(array_index++), el);
12069 }
12070
12071 oa->write_character(to_char_type(0x00));
12072 }
12073
12074 /*!
12075 @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
12076 @return The calculated size for the BSON document entry for @a j with the given @a name.
12077 */
12078 static std::size_t calc_bson_element_size(const string_t& name,
12079 const BasicJsonType& j)
12080 {
12081 const auto header_size = calc_bson_entry_header_size(name);
12082 switch (j.type())
12083 {
12084 case value_t::object:
12085 return header_size + calc_bson_object_size(*j.m_value.object);
12086
12087 case value_t::array:
12088 return header_size + calc_bson_array_size(*j.m_value.array);
12089
12090 case value_t::boolean:
12091 return header_size + 1ul;
12092
12093 case value_t::number_float:
12094 return header_size + 8ul;
12095
12096 case value_t::number_integer:
12097 return header_size + calc_bson_integer_size(j.m_value.number_integer);
12098
12099 case value_t::number_unsigned:
12100 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
12101
12102 case value_t::string:
12103 return header_size + calc_bson_string_size(*j.m_value.string);
12104
12105 case value_t::null:
12106 return header_size + 0ul;
12107
12108 // LCOV_EXCL_START
12109 default:
12110 assert(false);
12111 return 0ul;
12112 // LCOV_EXCL_STOP
12113 }
12114 }
12115
12116 /*!
12117 @brief Serializes the JSON value @a j to BSON and associates it with the
12118 key @a name.
12119 @param name The name to associate with the JSON entity @a j within the
12120 current BSON document
12121 @return The size of the BSON entry
12122 */
12123 void write_bson_element(const string_t& name,
12124 const BasicJsonType& j)
12125 {
12126 switch (j.type())
12127 {
12128 case value_t::object:
12129 return write_bson_object_entry(name, *j.m_value.object);
12130
12131 case value_t::array:
12132 return write_bson_array(name, *j.m_value.array);
12133
12134 case value_t::boolean:
12135 return write_bson_boolean(name, j.m_value.boolean);
12136
12137 case value_t::number_float:
12138 return write_bson_double(name, j.m_value.number_float);
12139
12140 case value_t::number_integer:
12141 return write_bson_integer(name, j.m_value.number_integer);
12142
12143 case value_t::number_unsigned:
12144 return write_bson_unsigned(name, j.m_value.number_unsigned);
12145
12146 case value_t::string:
12147 return write_bson_string(name, *j.m_value.string);
12148
12149 case value_t::null:
12150 return write_bson_null(name);
12151
12152 // LCOV_EXCL_START
12153 default:
12154 assert(false);
12155 return;
12156 // LCOV_EXCL_STOP
12157 }
12158 }
12159
12160 /*!
12161 @brief Calculates the size of the BSON serialization of the given
12162 JSON-object @a j.
12163 @param[in] j JSON value to serialize
12164 @pre j.type() == value_t::object
12165 */
12166 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
12167 {
12168 std::size_t document_size = std::accumulate(value.begin(), value.end(), 0ul,
12169 [](size_t result, const typename BasicJsonType::object_t::value_type & el)
12170 {
12171 return result += calc_bson_element_size(el.first, el.second);
12172 });
12173
12174 return sizeof(std::int32_t) + document_size + 1ul;
12175 }
12176
12177 /*!
12178 @param[in] j JSON value to serialize
12179 @pre j.type() == value_t::object
12180 */
12181 void write_bson_object(const typename BasicJsonType::object_t& value)
12182 {
12183 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
12184
12185 for (const auto& el : value)
12186 {
12187 write_bson_element(el.first, el.second);
12188 }
12189
12190 oa->write_character(to_char_type(0x00));
12191 }
12192
12193 //////////
12194 // CBOR //
12195 //////////
12196
12197 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
12198 {
12199 return to_char_type(0xFA); // Single-Precision Float
12200 }
12201
12202 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
12203 {
12204 return to_char_type(0xFB); // Double-Precision Float
12205 }
12206
12207 /////////////
12208 // MsgPack //
12209 /////////////
12210
12211 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
12212 {
12213 return to_char_type(0xCA); // float 32
12214 }
12215
12216 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
12217 {
12218 return to_char_type(0xCB); // float 64
12219 }
12220
12221 ////////////
12222 // UBJSON //
12223 ////////////
12224
12225 // UBJSON: write number (floating point)
12226 template<typename NumberType, typename std::enable_if<
12227 std::is_floating_point<NumberType>::value, int>::type = 0>
12228 void write_number_with_ubjson_prefix(const NumberType n,
12229 const bool add_prefix)
12230 {
12231 if (add_prefix)
12232 {
12233 oa->write_character(get_ubjson_float_prefix(n));
12234 }
12235 write_number(n);
12236 }
12237
12238 // UBJSON: write number (unsigned integer)
12239 template<typename NumberType, typename std::enable_if<
12240 std::is_unsigned<NumberType>::value, int>::type = 0>
12241 void write_number_with_ubjson_prefix(const NumberType n,
12242 const bool add_prefix)
12243 {
12244 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
12245 {
12246 if (add_prefix)
12247 {
12248 oa->write_character(to_char_type('i')); // int8
12249 }
12250 write_number(static_cast<std::uint8_t>(n));
12251 }
12252 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
12253 {
12254 if (add_prefix)
12255 {
12256 oa->write_character(to_char_type('U')); // uint8
12257 }
12258 write_number(static_cast<std::uint8_t>(n));
12259 }
12260 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
12261 {
12262 if (add_prefix)
12263 {
12264 oa->write_character(to_char_type('I')); // int16
12265 }
12266 write_number(static_cast<std::int16_t>(n));
12267 }
12268 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
12269 {
12270 if (add_prefix)
12271 {
12272 oa->write_character(to_char_type('l')); // int32
12273 }
12274 write_number(static_cast<std::int32_t>(n));
12275 }
12276 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
12277 {
12278 if (add_prefix)
12279 {
12280 oa->write_character(to_char_type('L')); // int64
12281 }
12282 write_number(static_cast<std::int64_t>(n));
12283 }
12284 else
12285 {
12286 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
12287 }
12288 }
12289
12290 // UBJSON: write number (signed integer)
12291 template<typename NumberType, typename std::enable_if<
12292 std::is_signed<NumberType>::value and
12293 not std::is_floating_point<NumberType>::value, int>::type = 0>
12294 void write_number_with_ubjson_prefix(const NumberType n,
12295 const bool add_prefix)
12296 {
12297 if ((std::numeric_limits<std::int8_t>::min)() <= n and n <= (std::numeric_limits<std::int8_t>::max)())
12298 {
12299 if (add_prefix)
12300 {
12301 oa->write_character(to_char_type('i')); // int8
12302 }
12303 write_number(static_cast<std::int8_t>(n));
12304 }
12305 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)()))
12306 {
12307 if (add_prefix)
12308 {
12309 oa->write_character(to_char_type('U')); // uint8
12310 }
12311 write_number(static_cast<std::uint8_t>(n));
12312 }
12313 else if ((std::numeric_limits<std::int16_t>::min)() <= n and n <= (std::numeric_limits<std::int16_t>::max)())
12314 {
12315 if (add_prefix)
12316 {
12317 oa->write_character(to_char_type('I')); // int16
12318 }
12319 write_number(static_cast<std::int16_t>(n));
12320 }
12321 else if ((std::numeric_limits<std::int32_t>::min)() <= n and n <= (std::numeric_limits<std::int32_t>::max)())
12322 {
12323 if (add_prefix)
12324 {
12325 oa->write_character(to_char_type('l')); // int32
12326 }
12327 write_number(static_cast<std::int32_t>(n));
12328 }
12329 else if ((std::numeric_limits<std::int64_t>::min)() <= n and n <= (std::numeric_limits<std::int64_t>::max)())
12330 {
12331 if (add_prefix)
12332 {
12333 oa->write_character(to_char_type('L')); // int64
12334 }
12335 write_number(static_cast<std::int64_t>(n));
12336 }
12337 // LCOV_EXCL_START
12338 else
12339 {
12340 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
12341 }
12342 // LCOV_EXCL_STOP
12343 }
12344
12345 /*!
12346 @brief determine the type prefix of container values
12347
12348 @note This function does not need to be 100% accurate when it comes to
12349 integer limits. In case a number exceeds the limits of int64_t,
12350 this will be detected by a later call to function
12351 write_number_with_ubjson_prefix. Therefore, we return 'L' for any
12352 value that does not fit the previous limits.
12353 */
12354 CharType ubjson_prefix(const BasicJsonType& j) const noexcept
12355 {
12356 switch (j.type())
12357 {
12358 case value_t::null:
12359 return 'Z';
12360
12361 case value_t::boolean:
12362 return j.m_value.boolean ? 'T' : 'F';
12363
12364 case value_t::number_integer:
12365 {
12366 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)())
12367 {
12368 return 'i';
12369 }
12370 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)())
12371 {
12372 return 'U';
12373 }
12374 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)())
12375 {
12376 return 'I';
12377 }
12378 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)())
12379 {
12380 return 'l';
12381 }
12382 // no check and assume int64_t (see note above)
12383 return 'L';
12384 }
12385
12386 case value_t::number_unsigned:
12387 {
12388 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
12389 {
12390 return 'i';
12391 }
12392 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
12393 {
12394 return 'U';
12395 }
12396 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
12397 {
12398 return 'I';
12399 }
12400 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
12401 {
12402 return 'l';
12403 }
12404 // no check and assume int64_t (see note above)
12405 return 'L';
12406 }
12407
12408 case value_t::number_float:
12409 return get_ubjson_float_prefix(j.m_value.number_float);
12410
12411 case value_t::string:
12412 return 'S';
12413
12414 case value_t::array:
12415 return '[';
12416
12417 case value_t::object:
12418 return '{';
12419
12420 default: // discarded values
12421 return 'N';
12422 }
12423 }
12424
12425 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
12426 {
12427 return 'd'; // float 32
12428 }
12429
12430 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
12431 {
12432 return 'D'; // float 64
12433 }
12434
12435 ///////////////////////
12436 // Utility functions //
12437 ///////////////////////
12438
12439 /*
12440 @brief write a number to output input
12441 @param[in] n number of type @a NumberType
12442 @tparam NumberType the type of the number
12443 @tparam OutputIsLittleEndian Set to true if output data is
12444 required to be little endian
12445
12446 @note This function needs to respect the system's endianess, because bytes
12447 in CBOR, MessagePack, and UBJSON are stored in network order (big
12448 endian) and therefore need reordering on little endian systems.
12449 */
12450 template<typename NumberType, bool OutputIsLittleEndian = false>
12451 void write_number(const NumberType n)
12452 {
12453 // step 1: write number to array of length NumberType
12454 std::array<CharType, sizeof(NumberType)> vec;
12455 std::memcpy(vec.data(), &n, sizeof(NumberType));
12456
12457 // step 2: write array to output (with possible reordering)
12458 if (is_little_endian != OutputIsLittleEndian)
12459 {
12460 // reverse byte order prior to conversion if necessary
12461 std::reverse(vec.begin(), vec.end());
12462 }
12463
12464 oa->write_characters(vec.data(), sizeof(NumberType));
12465 }
12466
12467 public:
12468 // The following to_char_type functions are implement the conversion
12469 // between uint8_t and CharType. In case CharType is not unsigned,
12470 // such a conversion is required to allow values greater than 128.
12471 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
12472 template < typename C = CharType,
12473 enable_if_t < std::is_signed<C>::value and std::is_signed<char>::value > * = nullptr >
12474 static constexpr CharType to_char_type(std::uint8_t x) noexcept
12475 {
12476 return *reinterpret_cast<char*>(&x);
12477 }
12478
12479 template < typename C = CharType,
12480 enable_if_t < std::is_signed<C>::value and std::is_unsigned<char>::value > * = nullptr >
12481 static CharType to_char_type(std::uint8_t x) noexcept
12482 {
12483 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
12484 static_assert(std::is_pod<CharType>::value, "CharType must be POD");
12485 CharType result;
12486 std::memcpy(&result, &x, sizeof(x));
12487 return result;
12488 }
12489
12490 template<typename C = CharType,
12491 enable_if_t<std::is_unsigned<C>::value>* = nullptr>
12492 static constexpr CharType to_char_type(std::uint8_t x) noexcept
12493 {
12494 return x;
12495 }
12496
12497 template < typename InputCharType, typename C = CharType,
12498 enable_if_t <
12499 std::is_signed<C>::value and
12500 std::is_signed<char>::value and
12501 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
12502 > * = nullptr >
12503 static constexpr CharType to_char_type(InputCharType x) noexcept
12504 {
12505 return x;
12506 }
12507
12508 private:
12509 /// whether we can assume little endianess
12510 const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
12511
12512 /// the output
12513 output_adapter_t<CharType> oa = nullptr;
12514 };
12515 } // namespace detail
12516 } // namespace nlohmann
12517
12518 // #include <nlohmann/detail/output/output_adapters.hpp>
12519
12520 // #include <nlohmann/detail/output/serializer.hpp>
12521
12522
12523 #include <algorithm> // reverse, remove, fill, find, none_of
12524 #include <array> // array
12525 #include <cassert> // assert
12526 #include <ciso646> // and, or
12527 #include <clocale> // localeconv, lconv
12528 #include <cmath> // labs, isfinite, isnan, signbit
12529 #include <cstddef> // size_t, ptrdiff_t
12530 #include <cstdint> // uint8_t
12531 #include <cstdio> // snprintf
12532 #include <limits> // numeric_limits
12533 #include <string> // string
12534 #include <type_traits> // is_same
12535 #include <utility> // move
12536
12537 // #include <nlohmann/detail/conversions/to_chars.hpp>
12538
12539
12540 #include <array> // array
12541 #include <cassert> // assert
12542 #include <ciso646> // or, and, not
12543 #include <cmath> // signbit, isfinite
12544 #include <cstdint> // intN_t, uintN_t
12545 #include <cstring> // memcpy, memmove
12546 #include <limits> // numeric_limits
12547 #include <type_traits> // conditional
12548 // #include <nlohmann/detail/macro_scope.hpp>
12549
12550
12551 namespace nlohmann
12552 {
12553 namespace detail
12554 {
12555
12556 /*!
12557 @brief implements the Grisu2 algorithm for binary to decimal floating-point
12558 conversion.
12559
12560 This implementation is a slightly modified version of the reference
12561 implementation which may be obtained from
12562 http://florian.loitsch.com/publications (bench.tar.gz).
12563
12564 The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
12565
12566 For a detailed description of the algorithm see:
12567
12568 [1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
12569 Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
12570 Language Design and Implementation, PLDI 2010
12571 [2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
12572 Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
12573 Design and Implementation, PLDI 1996
12574 */
12575 namespace dtoa_impl
12576 {
12577
12578 template <typename Target, typename Source>
12579 Target reinterpret_bits(const Source source)
12580 {
12581 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
12582
12583 Target target;
12584 std::memcpy(&target, &source, sizeof(Source));
12585 return target;
12586 }
12587
12588 struct diyfp // f * 2^e
12589 {
12590 static constexpr int kPrecision = 64; // = q
12591
12592 std::uint64_t f = 0;
12593 int e = 0;
12594
12595 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
12596
12597 /*!
12598 @brief returns x - y
12599 @pre x.e == y.e and x.f >= y.f
12600 */
12601 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
12602 {
12603 assert(x.e == y.e);
12604 assert(x.f >= y.f);
12605
12606 return {x.f - y.f, x.e};
12607 }
12608
12609 /*!
12610 @brief returns x * y
12611 @note The result is rounded. (Only the upper q bits are returned.)
12612 */
12613 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
12614 {
12615 static_assert(kPrecision == 64, "internal error");
12616
12617 // Computes:
12618 // f = round((x.f * y.f) / 2^q)
12619 // e = x.e + y.e + q
12620
12621 // Emulate the 64-bit * 64-bit multiplication:
12622 //
12623 // p = u * v
12624 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
12625 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
12626 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
12627 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
12628 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
12629 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
12630 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
12631 //
12632 // (Since Q might be larger than 2^32 - 1)
12633 //
12634 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
12635 //
12636 // (Q_hi + H does not overflow a 64-bit int)
12637 //
12638 // = p_lo + 2^64 p_hi
12639
12640 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
12641 const std::uint64_t u_hi = x.f >> 32u;
12642 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
12643 const std::uint64_t v_hi = y.f >> 32u;
12644
12645 const std::uint64_t p0 = u_lo * v_lo;
12646 const std::uint64_t p1 = u_lo * v_hi;
12647 const std::uint64_t p2 = u_hi * v_lo;
12648 const std::uint64_t p3 = u_hi * v_hi;
12649
12650 const std::uint64_t p0_hi = p0 >> 32u;
12651 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
12652 const std::uint64_t p1_hi = p1 >> 32u;
12653 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
12654 const std::uint64_t p2_hi = p2 >> 32u;
12655
12656 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
12657
12658 // The full product might now be computed as
12659 //
12660 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
12661 // p_lo = p0_lo + (Q << 32)
12662 //
12663 // But in this particular case here, the full p_lo is not required.
12664 // Effectively we only need to add the highest bit in p_lo to p_hi (and
12665 // Q_hi + 1 does not overflow).
12666
12667 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
12668
12669 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
12670
12671 return {h, x.e + y.e + 64};
12672 }
12673
12674 /*!
12675 @brief normalize x such that the significand is >= 2^(q-1)
12676 @pre x.f != 0
12677 */
12678 static diyfp normalize(diyfp x) noexcept
12679 {
12680 assert(x.f != 0);
12681
12682 while ((x.f >> 63u) == 0)
12683 {
12684 x.f <<= 1u;
12685 x.e--;
12686 }
12687
12688 return x;
12689 }
12690
12691 /*!
12692 @brief normalize x such that the result has the exponent E
12693 @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
12694 */
12695 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
12696 {
12697 const int delta = x.e - target_exponent;
12698
12699 assert(delta >= 0);
12700 assert(((x.f << delta) >> delta) == x.f);
12701
12702 return {x.f << delta, target_exponent};
12703 }
12704 };
12705
12706 struct boundaries
12707 {
12708 diyfp w;
12709 diyfp minus;
12710 diyfp plus;
12711 };
12712
12713 /*!
12714 Compute the (normalized) diyfp representing the input number 'value' and its
12715 boundaries.
12716
12717 @pre value must be finite and positive
12718 */
12719 template <typename FloatType>
12720 boundaries compute_boundaries(FloatType value)
12721 {
12722 assert(std::isfinite(value));
12723 assert(value > 0);
12724
12725 // Convert the IEEE representation into a diyfp.
12726 //
12727 // If v is denormal:
12728 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
12729 // If v is normalized:
12730 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
12731
12732 static_assert(std::numeric_limits<FloatType>::is_iec559,
12733 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
12734
12735 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
12736 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
12737 constexpr int kMinExp = 1 - kBias;
12738 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
12739
12740 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
12741
12742 const std::uint64_t bits = reinterpret_bits<bits_type>(value);
12743 const std::uint64_t E = bits >> (kPrecision - 1);
12744 const std::uint64_t F = bits & (kHiddenBit - 1);
12745
12746 const bool is_denormal = E == 0;
12747 const diyfp v = is_denormal
12748 ? diyfp(F, kMinExp)
12749 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
12750
12751 // Compute the boundaries m- and m+ of the floating-point value
12752 // v = f * 2^e.
12753 //
12754 // Determine v- and v+, the floating-point predecessor and successor if v,
12755 // respectively.
12756 //
12757 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
12758 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
12759 //
12760 // v+ = v + 2^e
12761 //
12762 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
12763 // between m- and m+ round to v, regardless of how the input rounding
12764 // algorithm breaks ties.
12765 //
12766 // ---+-------------+-------------+-------------+-------------+--- (A)
12767 // v- m- v m+ v+
12768 //
12769 // -----------------+------+------+-------------+-------------+--- (B)
12770 // v- m- v m+ v+
12771
12772 const bool lower_boundary_is_closer = F == 0 and E > 1;
12773 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
12774 const diyfp m_minus = lower_boundary_is_closer
12775 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
12776 : diyfp(2 * v.f - 1, v.e - 1); // (A)
12777
12778 // Determine the normalized w+ = m+.
12779 const diyfp w_plus = diyfp::normalize(m_plus);
12780
12781 // Determine w- = m- such that e_(w-) = e_(w+).
12782 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
12783
12784 return {diyfp::normalize(v), w_minus, w_plus};
12785 }
12786
12787 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
12788 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
12789 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
12790 //
12791 // alpha <= e = e_c + e_w + q <= gamma
12792 //
12793 // or
12794 //
12795 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
12796 // <= f_c * f_w * 2^gamma
12797 //
12798 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
12799 //
12800 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
12801 //
12802 // or
12803 //
12804 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
12805 //
12806 // The choice of (alpha,gamma) determines the size of the table and the form of
12807 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
12808 // in practice:
12809 //
12810 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
12811 // processed independently: An integral part p1, and a fractional part p2:
12812 //
12813 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
12814 // = (f div 2^-e) + (f mod 2^-e) * 2^e
12815 // = p1 + p2 * 2^e
12816 //
12817 // The conversion of p1 into decimal form requires a series of divisions and
12818 // modulos by (a power of) 10. These operations are faster for 32-bit than for
12819 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
12820 // achieved by choosing
12821 //
12822 // -e >= 32 or e <= -32 := gamma
12823 //
12824 // In order to convert the fractional part
12825 //
12826 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
12827 //
12828 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
12829 // d[-i] are extracted in order:
12830 //
12831 // (10 * p2) div 2^-e = d[-1]
12832 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
12833 //
12834 // The multiplication by 10 must not overflow. It is sufficient to choose
12835 //
12836 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
12837 //
12838 // Since p2 = f mod 2^-e < 2^-e,
12839 //
12840 // -e <= 60 or e >= -60 := alpha
12841
12842 constexpr int kAlpha = -60;
12843 constexpr int kGamma = -32;
12844
12845 struct cached_power // c = f * 2^e ~= 10^k
12846 {
12847 std::uint64_t f;
12848 int e;
12849 int k;
12850 };
12851
12852 /*!
12853 For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
12854 power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
12855 satisfies (Definition 3.2 from [1])
12856
12857 alpha <= e_c + e + q <= gamma.
12858 */
12859 inline cached_power get_cached_power_for_binary_exponent(int e)
12860 {
12861 // Now
12862 //
12863 // alpha <= e_c + e + q <= gamma (1)
12864 // ==> f_c * 2^alpha <= c * 2^e * 2^q
12865 //
12866 // and since the c's are normalized, 2^(q-1) <= f_c,
12867 //
12868 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
12869 // ==> 2^(alpha - e - 1) <= c
12870 //
12871 // If c were an exakt power of ten, i.e. c = 10^k, one may determine k as
12872 //
12873 // k = ceil( log_10( 2^(alpha - e - 1) ) )
12874 // = ceil( (alpha - e - 1) * log_10(2) )
12875 //
12876 // From the paper:
12877 // "In theory the result of the procedure could be wrong since c is rounded,
12878 // and the computation itself is approximated [...]. In practice, however,
12879 // this simple function is sufficient."
12880 //
12881 // For IEEE double precision floating-point numbers converted into
12882 // normalized diyfp's w = f * 2^e, with q = 64,
12883 //
12884 // e >= -1022 (min IEEE exponent)
12885 // -52 (p - 1)
12886 // -52 (p - 1, possibly normalize denormal IEEE numbers)
12887 // -11 (normalize the diyfp)
12888 // = -1137
12889 //
12890 // and
12891 //
12892 // e <= +1023 (max IEEE exponent)
12893 // -52 (p - 1)
12894 // -11 (normalize the diyfp)
12895 // = 960
12896 //
12897 // This binary exponent range [-1137,960] results in a decimal exponent
12898 // range [-307,324]. One does not need to store a cached power for each
12899 // k in this range. For each such k it suffices to find a cached power
12900 // such that the exponent of the product lies in [alpha,gamma].
12901 // This implies that the difference of the decimal exponents of adjacent
12902 // table entries must be less than or equal to
12903 //
12904 // floor( (gamma - alpha) * log_10(2) ) = 8.
12905 //
12906 // (A smaller distance gamma-alpha would require a larger table.)
12907
12908 // NB:
12909 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
12910
12911 constexpr int kCachedPowersMinDecExp = -300;
12912 constexpr int kCachedPowersDecStep = 8;
12913
12914 static constexpr std::array<cached_power, 79> kCachedPowers =
12915 {
12916 {
12917 { 0xAB70FE17C79AC6CA, -1060, -300 },
12918 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
12919 { 0xBE5691EF416BD60C, -1007, -284 },
12920 { 0x8DD01FAD907FFC3C, -980, -276 },
12921 { 0xD3515C2831559A83, -954, -268 },
12922 { 0x9D71AC8FADA6C9B5, -927, -260 },
12923 { 0xEA9C227723EE8BCB, -901, -252 },
12924 { 0xAECC49914078536D, -874, -244 },
12925 { 0x823C12795DB6CE57, -847, -236 },
12926 { 0xC21094364DFB5637, -821, -228 },
12927 { 0x9096EA6F3848984F, -794, -220 },
12928 { 0xD77485CB25823AC7, -768, -212 },
12929 { 0xA086CFCD97BF97F4, -741, -204 },
12930 { 0xEF340A98172AACE5, -715, -196 },
12931 { 0xB23867FB2A35B28E, -688, -188 },
12932 { 0x84C8D4DFD2C63F3B, -661, -180 },
12933 { 0xC5DD44271AD3CDBA, -635, -172 },
12934 { 0x936B9FCEBB25C996, -608, -164 },
12935 { 0xDBAC6C247D62A584, -582, -156 },
12936 { 0xA3AB66580D5FDAF6, -555, -148 },
12937 { 0xF3E2F893DEC3F126, -529, -140 },
12938 { 0xB5B5ADA8AAFF80B8, -502, -132 },
12939 { 0x87625F056C7C4A8B, -475, -124 },
12940 { 0xC9BCFF6034C13053, -449, -116 },
12941 { 0x964E858C91BA2655, -422, -108 },
12942 { 0xDFF9772470297EBD, -396, -100 },
12943 { 0xA6DFBD9FB8E5B88F, -369, -92 },
12944 { 0xF8A95FCF88747D94, -343, -84 },
12945 { 0xB94470938FA89BCF, -316, -76 },
12946 { 0x8A08F0F8BF0F156B, -289, -68 },
12947 { 0xCDB02555653131B6, -263, -60 },
12948 { 0x993FE2C6D07B7FAC, -236, -52 },
12949 { 0xE45C10C42A2B3B06, -210, -44 },
12950 { 0xAA242499697392D3, -183, -36 },
12951 { 0xFD87B5F28300CA0E, -157, -28 },
12952 { 0xBCE5086492111AEB, -130, -20 },
12953 { 0x8CBCCC096F5088CC, -103, -12 },
12954 { 0xD1B71758E219652C, -77, -4 },
12955 { 0x9C40000000000000, -50, 4 },
12956 { 0xE8D4A51000000000, -24, 12 },
12957 { 0xAD78EBC5AC620000, 3, 20 },
12958 { 0x813F3978F8940984, 30, 28 },
12959 { 0xC097CE7BC90715B3, 56, 36 },
12960 { 0x8F7E32CE7BEA5C70, 83, 44 },
12961 { 0xD5D238A4ABE98068, 109, 52 },
12962 { 0x9F4F2726179A2245, 136, 60 },
12963 { 0xED63A231D4C4FB27, 162, 68 },
12964 { 0xB0DE65388CC8ADA8, 189, 76 },
12965 { 0x83C7088E1AAB65DB, 216, 84 },
12966 { 0xC45D1DF942711D9A, 242, 92 },
12967 { 0x924D692CA61BE758, 269, 100 },
12968 { 0xDA01EE641A708DEA, 295, 108 },
12969 { 0xA26DA3999AEF774A, 322, 116 },
12970 { 0xF209787BB47D6B85, 348, 124 },
12971 { 0xB454E4A179DD1877, 375, 132 },
12972 { 0x865B86925B9BC5C2, 402, 140 },
12973 { 0xC83553C5C8965D3D, 428, 148 },
12974 { 0x952AB45CFA97A0B3, 455, 156 },
12975 { 0xDE469FBD99A05FE3, 481, 164 },
12976 { 0xA59BC234DB398C25, 508, 172 },
12977 { 0xF6C69A72A3989F5C, 534, 180 },
12978 { 0xB7DCBF5354E9BECE, 561, 188 },
12979 { 0x88FCF317F22241E2, 588, 196 },
12980 { 0xCC20CE9BD35C78A5, 614, 204 },
12981 { 0x98165AF37B2153DF, 641, 212 },
12982 { 0xE2A0B5DC971F303A, 667, 220 },
12983 { 0xA8D9D1535CE3B396, 694, 228 },
12984 { 0xFB9B7CD9A4A7443C, 720, 236 },
12985 { 0xBB764C4CA7A44410, 747, 244 },
12986 { 0x8BAB8EEFB6409C1A, 774, 252 },
12987 { 0xD01FEF10A657842C, 800, 260 },
12988 { 0x9B10A4E5E9913129, 827, 268 },
12989 { 0xE7109BFBA19C0C9D, 853, 276 },
12990 { 0xAC2820D9623BF429, 880, 284 },
12991 { 0x80444B5E7AA7CF85, 907, 292 },
12992 { 0xBF21E44003ACDD2D, 933, 300 },
12993 { 0x8E679C2F5E44FF8F, 960, 308 },
12994 { 0xD433179D9C8CB841, 986, 316 },
12995 { 0x9E19DB92B4E31BA9, 1013, 324 },
12996 }
12997 };
12998
12999 // This computation gives exactly the same results for k as
13000 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
13001 // for |e| <= 1500, but doesn't require floating-point operations.
13002 // NB: log_10(2) ~= 78913 / 2^18
13003 assert(e >= -1500);
13004 assert(e <= 1500);
13005 const int f = kAlpha - e - 1;
13006 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
13007
13008 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
13009 assert(index >= 0);
13010 assert(static_cast<std::size_t>(index) < kCachedPowers.size());
13011
13012 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
13013 assert(kAlpha <= cached.e + e + 64);
13014 assert(kGamma >= cached.e + e + 64);
13015
13016 return cached;
13017 }
13018
13019 /*!
13020 For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
13021 For n == 0, returns 1 and sets pow10 := 1.
13022 */
13023 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
13024 {
13025 // LCOV_EXCL_START
13026 if (n >= 1000000000)
13027 {
13028 pow10 = 1000000000;
13029 return 10;
13030 }
13031 // LCOV_EXCL_STOP
13032 else if (n >= 100000000)
13033 {
13034 pow10 = 100000000;
13035 return 9;
13036 }
13037 else if (n >= 10000000)
13038 {
13039 pow10 = 10000000;
13040 return 8;
13041 }
13042 else if (n >= 1000000)
13043 {
13044 pow10 = 1000000;
13045 return 7;
13046 }
13047 else if (n >= 100000)
13048 {
13049 pow10 = 100000;
13050 return 6;
13051 }
13052 else if (n >= 10000)
13053 {
13054 pow10 = 10000;
13055 return 5;
13056 }
13057 else if (n >= 1000)
13058 {
13059 pow10 = 1000;
13060 return 4;
13061 }
13062 else if (n >= 100)
13063 {
13064 pow10 = 100;
13065 return 3;
13066 }
13067 else if (n >= 10)
13068 {
13069 pow10 = 10;
13070 return 2;
13071 }
13072 else
13073 {
13074 pow10 = 1;
13075 return 1;
13076 }
13077 }
13078
13079 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
13080 std::uint64_t rest, std::uint64_t ten_k)
13081 {
13082 assert(len >= 1);
13083 assert(dist <= delta);
13084 assert(rest <= delta);
13085 assert(ten_k > 0);
13086
13087 // <--------------------------- delta ---->
13088 // <---- dist --------->
13089 // --------------[------------------+-------------------]--------------
13090 // M- w M+
13091 //
13092 // ten_k
13093 // <------>
13094 // <---- rest ---->
13095 // --------------[------------------+----+--------------]--------------
13096 // w V
13097 // = buf * 10^k
13098 //
13099 // ten_k represents a unit-in-the-last-place in the decimal representation
13100 // stored in buf.
13101 // Decrement buf by ten_k while this takes buf closer to w.
13102
13103 // The tests are written in this order to avoid overflow in unsigned
13104 // integer arithmetic.
13105
13106 while (rest < dist
13107 and delta - rest >= ten_k
13108 and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
13109 {
13110 assert(buf[len - 1] != '0');
13111 buf[len - 1]--;
13112 rest += ten_k;
13113 }
13114 }
13115
13116 /*!
13117 Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
13118 M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
13119 */
13120 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
13121 diyfp M_minus, diyfp w, diyfp M_plus)
13122 {
13123 static_assert(kAlpha >= -60, "internal error");
13124 static_assert(kGamma <= -32, "internal error");
13125
13126 // Generates the digits (and the exponent) of a decimal floating-point
13127 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
13128 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
13129 //
13130 // <--------------------------- delta ---->
13131 // <---- dist --------->
13132 // --------------[------------------+-------------------]--------------
13133 // M- w M+
13134 //
13135 // Grisu2 generates the digits of M+ from left to right and stops as soon as
13136 // V is in [M-,M+].
13137
13138 assert(M_plus.e >= kAlpha);
13139 assert(M_plus.e <= kGamma);
13140
13141 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
13142 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
13143
13144 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
13145 //
13146 // M+ = f * 2^e
13147 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
13148 // = ((p1 ) * 2^-e + (p2 )) * 2^e
13149 // = p1 + p2 * 2^e
13150
13151 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
13152
13153 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.)
13154 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
13155
13156 // 1)
13157 //
13158 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
13159
13160 assert(p1 > 0);
13161
13162 std::uint32_t pow10;
13163 const int k = find_largest_pow10(p1, pow10);
13164
13165 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
13166 //
13167 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
13168 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
13169 //
13170 // M+ = p1 + p2 * 2^e
13171 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
13172 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
13173 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
13174 //
13175 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
13176 //
13177 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
13178 //
13179 // but stop as soon as
13180 //
13181 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
13182
13183 int n = k;
13184 while (n > 0)
13185 {
13186 // Invariants:
13187 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
13188 // pow10 = 10^(n-1) <= p1 < 10^n
13189 //
13190 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
13191 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
13192 //
13193 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
13194 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
13195 //
13196 assert(d <= 9);
13197 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
13198 //
13199 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
13200 //
13201 p1 = r;
13202 n--;
13203 //
13204 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
13205 // pow10 = 10^n
13206 //
13207
13208 // Now check if enough digits have been generated.
13209 // Compute
13210 //
13211 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
13212 //
13213 // Note:
13214 // Since rest and delta share the same exponent e, it suffices to
13215 // compare the significands.
13216 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
13217 if (rest <= delta)
13218 {
13219 // V = buffer * 10^n, with M- <= V <= M+.
13220
13221 decimal_exponent += n;
13222
13223 // We may now just stop. But instead look if the buffer could be
13224 // decremented to bring V closer to w.
13225 //
13226 // pow10 = 10^n is now 1 ulp in the decimal representation V.
13227 // The rounding procedure works with diyfp's with an implicit
13228 // exponent of e.
13229 //
13230 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
13231 //
13232 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
13233 grisu2_round(buffer, length, dist, delta, rest, ten_n);
13234
13235 return;
13236 }
13237
13238 pow10 /= 10;
13239 //
13240 // pow10 = 10^(n-1) <= p1 < 10^n
13241 // Invariants restored.
13242 }
13243
13244 // 2)
13245 //
13246 // The digits of the integral part have been generated:
13247 //
13248 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
13249 // = buffer + p2 * 2^e
13250 //
13251 // Now generate the digits of the fractional part p2 * 2^e.
13252 //
13253 // Note:
13254 // No decimal point is generated: the exponent is adjusted instead.
13255 //
13256 // p2 actually represents the fraction
13257 //
13258 // p2 * 2^e
13259 // = p2 / 2^-e
13260 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
13261 //
13262 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
13263 //
13264 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
13265 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
13266 //
13267 // using
13268 //
13269 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
13270 // = ( d) * 2^-e + ( r)
13271 //
13272 // or
13273 // 10^m * p2 * 2^e = d + r * 2^e
13274 //
13275 // i.e.
13276 //
13277 // M+ = buffer + p2 * 2^e
13278 // = buffer + 10^-m * (d + r * 2^e)
13279 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
13280 //
13281 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
13282
13283 assert(p2 > delta);
13284
13285 int m = 0;
13286 for (;;)
13287 {
13288 // Invariant:
13289 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
13290 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
13291 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
13292 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
13293 //
13294 assert(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
13295 p2 *= 10;
13296 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
13297 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
13298 //
13299 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
13300 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
13301 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
13302 //
13303 assert(d <= 9);
13304 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
13305 //
13306 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
13307 //
13308 p2 = r;
13309 m++;
13310 //
13311 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
13312 // Invariant restored.
13313
13314 // Check if enough digits have been generated.
13315 //
13316 // 10^-m * p2 * 2^e <= delta * 2^e
13317 // p2 * 2^e <= 10^m * delta * 2^e
13318 // p2 <= 10^m * delta
13319 delta *= 10;
13320 dist *= 10;
13321 if (p2 <= delta)
13322 {
13323 break;
13324 }
13325 }
13326
13327 // V = buffer * 10^-m, with M- <= V <= M+.
13328
13329 decimal_exponent -= m;
13330
13331 // 1 ulp in the decimal representation is now 10^-m.
13332 // Since delta and dist are now scaled by 10^m, we need to do the
13333 // same with ulp in order to keep the units in sync.
13334 //
13335 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
13336 //
13337 const std::uint64_t ten_m = one.f;
13338 grisu2_round(buffer, length, dist, delta, p2, ten_m);
13339
13340 // By construction this algorithm generates the shortest possible decimal
13341 // number (Loitsch, Theorem 6.2) which rounds back to w.
13342 // For an input number of precision p, at least
13343 //
13344 // N = 1 + ceil(p * log_10(2))
13345 //
13346 // decimal digits are sufficient to identify all binary floating-point
13347 // numbers (Matula, "In-and-Out conversions").
13348 // This implies that the algorithm does not produce more than N decimal
13349 // digits.
13350 //
13351 // N = 17 for p = 53 (IEEE double precision)
13352 // N = 9 for p = 24 (IEEE single precision)
13353 }
13354
13355 /*!
13356 v = buf * 10^decimal_exponent
13357 len is the length of the buffer (number of decimal digits)
13358 The buffer must be large enough, i.e. >= max_digits10.
13359 */
13360 JSON_HEDLEY_NON_NULL(1)
13361 inline void grisu2(char* buf, int& len, int& decimal_exponent,
13362 diyfp m_minus, diyfp v, diyfp m_plus)
13363 {
13364 assert(m_plus.e == m_minus.e);
13365 assert(m_plus.e == v.e);
13366
13367 // --------(-----------------------+-----------------------)-------- (A)
13368 // m- v m+
13369 //
13370 // --------------------(-----------+-----------------------)-------- (B)
13371 // m- v m+
13372 //
13373 // First scale v (and m- and m+) such that the exponent is in the range
13374 // [alpha, gamma].
13375
13376 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
13377
13378 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
13379
13380 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
13381 const diyfp w = diyfp::mul(v, c_minus_k);
13382 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
13383 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
13384
13385 // ----(---+---)---------------(---+---)---------------(---+---)----
13386 // w- w w+
13387 // = c*m- = c*v = c*m+
13388 //
13389 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
13390 // w+ are now off by a small amount.
13391 // In fact:
13392 //
13393 // w - v * 10^k < 1 ulp
13394 //
13395 // To account for this inaccuracy, add resp. subtract 1 ulp.
13396 //
13397 // --------+---[---------------(---+---)---------------]---+--------
13398 // w- M- w M+ w+
13399 //
13400 // Now any number in [M-, M+] (bounds included) will round to w when input,
13401 // regardless of how the input rounding algorithm breaks ties.
13402 //
13403 // And digit_gen generates the shortest possible such number in [M-, M+].
13404 // Note that this does not mean that Grisu2 always generates the shortest
13405 // possible number in the interval (m-, m+).
13406 const diyfp M_minus(w_minus.f + 1, w_minus.e);
13407 const diyfp M_plus (w_plus.f - 1, w_plus.e );
13408
13409 decimal_exponent = -cached.k; // = -(-k) = k
13410
13411 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
13412 }
13413
13414 /*!
13415 v = buf * 10^decimal_exponent
13416 len is the length of the buffer (number of decimal digits)
13417 The buffer must be large enough, i.e. >= max_digits10.
13418 */
13419 template <typename FloatType>
13420 JSON_HEDLEY_NON_NULL(1)
13421 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
13422 {
13423 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
13424 "internal error: not enough precision");
13425
13426 assert(std::isfinite(value));
13427 assert(value > 0);
13428
13429 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
13430 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
13431 // decimal representations are not exactly "short".
13432 //
13433 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
13434 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
13435 // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
13436 // does.
13437 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
13438 // representation using the corresponding std::from_chars function recovers value exactly". That
13439 // indicates that single precision floating-point numbers should be recovered using
13440 // 'std::strtof'.
13441 //
13442 // NB: If the neighbors are computed for single-precision numbers, there is a single float
13443 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
13444 // value is off by 1 ulp.
13445 #if 0
13446 const boundaries w = compute_boundaries(static_cast<double>(value));
13447 #else
13448 const boundaries w = compute_boundaries(value);
13449 #endif
13450
13451 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
13452 }
13453
13454 /*!
13455 @brief appends a decimal representation of e to buf
13456 @return a pointer to the element following the exponent.
13457 @pre -1000 < e < 1000
13458 */
13459 JSON_HEDLEY_NON_NULL(1)
13460 JSON_HEDLEY_RETURNS_NON_NULL
13461 inline char* append_exponent(char* buf, int e)
13462 {
13463 assert(e > -1000);
13464 assert(e < 1000);
13465
13466 if (e < 0)
13467 {
13468 e = -e;
13469 *buf++ = '-';
13470 }
13471 else
13472 {
13473 *buf++ = '+';
13474 }
13475
13476 auto k = static_cast<std::uint32_t>(e);
13477 if (k < 10)
13478 {
13479 // Always print at least two digits in the exponent.
13480 // This is for compatibility with printf("%g").
13481 *buf++ = '0';
13482 *buf++ = static_cast<char>('0' + k);
13483 }
13484 else if (k < 100)
13485 {
13486 *buf++ = static_cast<char>('0' + k / 10);
13487 k %= 10;
13488 *buf++ = static_cast<char>('0' + k);
13489 }
13490 else
13491 {
13492 *buf++ = static_cast<char>('0' + k / 100);
13493 k %= 100;
13494 *buf++ = static_cast<char>('0' + k / 10);
13495 k %= 10;
13496 *buf++ = static_cast<char>('0' + k);
13497 }
13498
13499 return buf;
13500 }
13501
13502 /*!
13503 @brief prettify v = buf * 10^decimal_exponent
13504
13505 If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
13506 notation. Otherwise it will be printed in exponential notation.
13507
13508 @pre min_exp < 0
13509 @pre max_exp > 0
13510 */
13511 JSON_HEDLEY_NON_NULL(1)
13512 JSON_HEDLEY_RETURNS_NON_NULL
13513 inline char* format_buffer(char* buf, int len, int decimal_exponent,
13514 int min_exp, int max_exp)
13515 {
13516 assert(min_exp < 0);
13517 assert(max_exp > 0);
13518
13519 const int k = len;
13520 const int n = len + decimal_exponent;
13521
13522 // v = buf * 10^(n-k)
13523 // k is the length of the buffer (number of decimal digits)
13524 // n is the position of the decimal point relative to the start of the buffer.
13525
13526 if (k <= n and n <= max_exp)
13527 {
13528 // digits[000]
13529 // len <= max_exp + 2
13530
13531 std::memset(buf + k, '0', static_cast<size_t>(n - k));
13532 // Make it look like a floating-point number (#362, #378)
13533 buf[n + 0] = '.';
13534 buf[n + 1] = '0';
13535 return buf + (n + 2);
13536 }
13537
13538 if (0 < n and n <= max_exp)
13539 {
13540 // dig.its
13541 // len <= max_digits10 + 1
13542
13543 assert(k > n);
13544
13545 std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
13546 buf[n] = '.';
13547 return buf + (k + 1);
13548 }
13549
13550 if (min_exp < n and n <= 0)
13551 {
13552 // 0.[000]digits
13553 // len <= 2 + (-min_exp - 1) + max_digits10
13554
13555 std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
13556 buf[0] = '0';
13557 buf[1] = '.';
13558 std::memset(buf + 2, '0', static_cast<size_t>(-n));
13559 return buf + (2 + (-n) + k);
13560 }
13561
13562 if (k == 1)
13563 {
13564 // dE+123
13565 // len <= 1 + 5
13566
13567 buf += 1;
13568 }
13569 else
13570 {
13571 // d.igitsE+123
13572 // len <= max_digits10 + 1 + 5
13573
13574 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
13575 buf[1] = '.';
13576 buf += 1 + k;
13577 }
13578
13579 *buf++ = 'e';
13580 return append_exponent(buf, n - 1);
13581 }
13582
13583 } // namespace dtoa_impl
13584
13585 /*!
13586 @brief generates a decimal representation of the floating-point number value in [first, last).
13587
13588 The format of the resulting decimal representation is similar to printf's %g
13589 format. Returns an iterator pointing past-the-end of the decimal representation.
13590
13591 @note The input number must be finite, i.e. NaN's and Inf's are not supported.
13592 @note The buffer must be large enough.
13593 @note The result is NOT null-terminated.
13594 */
13595 template <typename FloatType>
13596 JSON_HEDLEY_NON_NULL(1, 2)
13597 JSON_HEDLEY_RETURNS_NON_NULL
13598 char* to_chars(char* first, const char* last, FloatType value)
13599 {
13600 static_cast<void>(last); // maybe unused - fix warning
13601 assert(std::isfinite(value));
13602
13603 // Use signbit(value) instead of (value < 0) since signbit works for -0.
13604 if (std::signbit(value))
13605 {
13606 value = -value;
13607 *first++ = '-';
13608 }
13609
13610 if (value == 0) // +-0
13611 {
13612 *first++ = '0';
13613 // Make it look like a floating-point number (#362, #378)
13614 *first++ = '.';
13615 *first++ = '0';
13616 return first;
13617 }
13618
13619 assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
13620
13621 // Compute v = buffer * 10^decimal_exponent.
13622 // The decimal digits are stored in the buffer, which needs to be interpreted
13623 // as an unsigned decimal integer.
13624 // len is the length of the buffer, i.e. the number of decimal digits.
13625 int len = 0;
13626 int decimal_exponent = 0;
13627 dtoa_impl::grisu2(first, len, decimal_exponent, value);
13628
13629 assert(len <= std::numeric_limits<FloatType>::max_digits10);
13630
13631 // Format the buffer like printf("%.*g", prec, value)
13632 constexpr int kMinExp = -4;
13633 // Use digits10 here to increase compatibility with version 2.
13634 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
13635
13636 assert(last - first >= kMaxExp + 2);
13637 assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
13638 assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
13639
13640 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
13641 }
13642
13643 } // namespace detail
13644 } // namespace nlohmann
13645
13646 // #include <nlohmann/detail/exceptions.hpp>
13647
13648 // #include <nlohmann/detail/macro_scope.hpp>
13649
13650 // #include <nlohmann/detail/meta/cpp_future.hpp>
13651
13652 // #include <nlohmann/detail/output/binary_writer.hpp>
13653
13654 // #include <nlohmann/detail/output/output_adapters.hpp>
13655
13656 // #include <nlohmann/detail/value_t.hpp>
13657
13658
13659 namespace nlohmann
13660 {
13661 namespace detail
13662 {
13663 ///////////////////
13664 // serialization //
13665 ///////////////////
13666
13667 /// how to treat decoding errors
13668 enum class error_handler_t
13669 {
13670 strict, ///< throw a type_error exception in case of invalid UTF-8
13671 replace, ///< replace invalid UTF-8 sequences with U+FFFD
13672 ignore ///< ignore invalid UTF-8 sequences
13673 };
13674
13675 template<typename BasicJsonType>
13676 class serializer
13677 {
13678 using string_t = typename BasicJsonType::string_t;
13679 using number_float_t = typename BasicJsonType::number_float_t;
13680 using number_integer_t = typename BasicJsonType::number_integer_t;
13681 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
13682 static constexpr std::uint8_t UTF8_ACCEPT = 0;
13683 static constexpr std::uint8_t UTF8_REJECT = 1;
13684
13685 public:
13686 /*!
13687 @param[in] s output stream to serialize to
13688 @param[in] ichar indentation character to use
13689 @param[in] error_handler_ how to react on decoding errors
13690 */
13691 serializer(output_adapter_t<char> s, const char ichar,
13692 error_handler_t error_handler_ = error_handler_t::strict)
13693 : o(std::move(s))
13694 , loc(std::localeconv())
13695 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : * (loc->thousands_sep))
13696 , decimal_point(loc->decimal_point == nullptr ? '\0' : * (loc->decimal_point))
13697 , indent_char(ichar)
13698 , indent_string(512, indent_char)
13699 , error_handler(error_handler_)
13700 {}
13701
13702 // delete because of pointer members
13703 serializer(const serializer&) = delete;
13704 serializer& operator=(const serializer&) = delete;
13705 serializer(serializer&&) = delete;
13706 serializer& operator=(serializer&&) = delete;
13707 ~serializer() = default;
13708
13709 /*!
13710 @brief internal implementation of the serialization function
13711
13712 This function is called by the public member function dump and organizes
13713 the serialization internally. The indentation level is propagated as
13714 additional parameter. In case of arrays and objects, the function is
13715 called recursively.
13716
13717 - strings and object keys are escaped using `escape_string()`
13718 - integer numbers are converted implicitly via `operator<<`
13719 - floating-point numbers are converted to a string using `"%g"` format
13720
13721 @param[in] val value to serialize
13722 @param[in] pretty_print whether the output shall be pretty-printed
13723 @param[in] indent_step the indent level
13724 @param[in] current_indent the current indent level (only used internally)
13725 */
13726 void dump(const BasicJsonType& val, const bool pretty_print,
13727 const bool ensure_ascii,
13728 const unsigned int indent_step,
13729 const unsigned int current_indent = 0)
13730 {
13731 switch (val.m_type)
13732 {
13733 case value_t::object:
13734 {
13735 if (val.m_value.object->empty())
13736 {
13737 o->write_characters("{}", 2);
13738 return;
13739 }
13740
13741 if (pretty_print)
13742 {
13743 o->write_characters("{\n", 2);
13744
13745 // variable to hold indentation for recursive calls
13746 const auto new_indent = current_indent + indent_step;
13747 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
13748 {
13749 indent_string.resize(indent_string.size() * 2, ' ');
13750 }
13751
13752 // first n-1 elements
13753 auto i = val.m_value.object->cbegin();
13754 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
13755 {
13756 o->write_characters(indent_string.c_str(), new_indent);
13757 o->write_character('\"');
13758 dump_escaped(i->first, ensure_ascii);
13759 o->write_characters("\": ", 3);
13760 dump(i->second, true, ensure_ascii, indent_step, new_indent);
13761 o->write_characters(",\n", 2);
13762 }
13763
13764 // last element
13765 assert(i != val.m_value.object->cend());
13766 assert(std::next(i) == val.m_value.object->cend());
13767 o->write_characters(indent_string.c_str(), new_indent);
13768 o->write_character('\"');
13769 dump_escaped(i->first, ensure_ascii);
13770 o->write_characters("\": ", 3);
13771 dump(i->second, true, ensure_ascii, indent_step, new_indent);
13772
13773 o->write_character('\n');
13774 o->write_characters(indent_string.c_str(), current_indent);
13775 o->write_character('}');
13776 }
13777 else
13778 {
13779 o->write_character('{');
13780
13781 // first n-1 elements
13782 auto i = val.m_value.object->cbegin();
13783 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
13784 {
13785 o->write_character('\"');
13786 dump_escaped(i->first, ensure_ascii);
13787 o->write_characters("\":", 2);
13788 dump(i->second, false, ensure_ascii, indent_step, current_indent);
13789 o->write_character(',');
13790 }
13791
13792 // last element
13793 assert(i != val.m_value.object->cend());
13794 assert(std::next(i) == val.m_value.object->cend());
13795 o->write_character('\"');
13796 dump_escaped(i->first, ensure_ascii);
13797 o->write_characters("\":", 2);
13798 dump(i->second, false, ensure_ascii, indent_step, current_indent);
13799
13800 o->write_character('}');
13801 }
13802
13803 return;
13804 }
13805
13806 case value_t::array:
13807 {
13808 if (val.m_value.array->empty())
13809 {
13810 o->write_characters("[]", 2);
13811 return;
13812 }
13813
13814 if (pretty_print)
13815 {
13816 o->write_characters("[\n", 2);
13817
13818 // variable to hold indentation for recursive calls
13819 const auto new_indent = current_indent + indent_step;
13820 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
13821 {
13822 indent_string.resize(indent_string.size() * 2, ' ');
13823 }
13824
13825 // first n-1 elements
13826 for (auto i = val.m_value.array->cbegin();
13827 i != val.m_value.array->cend() - 1; ++i)
13828 {
13829 o->write_characters(indent_string.c_str(), new_indent);
13830 dump(*i, true, ensure_ascii, indent_step, new_indent);
13831 o->write_characters(",\n", 2);
13832 }
13833
13834 // last element
13835 assert(not val.m_value.array->empty());
13836 o->write_characters(indent_string.c_str(), new_indent);
13837 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
13838
13839 o->write_character('\n');
13840 o->write_characters(indent_string.c_str(), current_indent);
13841 o->write_character(']');
13842 }
13843 else
13844 {
13845 o->write_character('[');
13846
13847 // first n-1 elements
13848 for (auto i = val.m_value.array->cbegin();
13849 i != val.m_value.array->cend() - 1; ++i)
13850 {
13851 dump(*i, false, ensure_ascii, indent_step, current_indent);
13852 o->write_character(',');
13853 }
13854
13855 // last element
13856 assert(not val.m_value.array->empty());
13857 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
13858
13859 o->write_character(']');
13860 }
13861
13862 return;
13863 }
13864
13865 case value_t::string:
13866 {
13867 o->write_character('\"');
13868 dump_escaped(*val.m_value.string, ensure_ascii);
13869 o->write_character('\"');
13870 return;
13871 }
13872
13873 case value_t::boolean:
13874 {
13875 if (val.m_value.boolean)
13876 {
13877 o->write_characters("true", 4);
13878 }
13879 else
13880 {
13881 o->write_characters("false", 5);
13882 }
13883 return;
13884 }
13885
13886 case value_t::number_integer:
13887 {
13888 dump_integer(val.m_value.number_integer);
13889 return;
13890 }
13891
13892 case value_t::number_unsigned:
13893 {
13894 dump_integer(val.m_value.number_unsigned);
13895 return;
13896 }
13897
13898 case value_t::number_float:
13899 {
13900 dump_float(val.m_value.number_float);
13901 return;
13902 }
13903
13904 case value_t::discarded:
13905 {
13906 o->write_characters("<discarded>", 11);
13907 return;
13908 }
13909
13910 case value_t::null:
13911 {
13912 o->write_characters("null", 4);
13913 return;
13914 }
13915
13916 default: // LCOV_EXCL_LINE
13917 assert(false); // LCOV_EXCL_LINE
13918 }
13919 }
13920
13921 private:
13922 /*!
13923 @brief dump escaped string
13924
13925 Escape a string by replacing certain special characters by a sequence of an
13926 escape character (backslash) and another character and other control
13927 characters by a sequence of "\u" followed by a four-digit hex
13928 representation. The escaped string is written to output stream @a o.
13929
13930 @param[in] s the string to escape
13931 @param[in] ensure_ascii whether to escape non-ASCII characters with
13932 \uXXXX sequences
13933
13934 @complexity Linear in the length of string @a s.
13935 */
13936 void dump_escaped(const string_t& s, const bool ensure_ascii)
13937 {
13938 std::uint32_t codepoint;
13939 std::uint8_t state = UTF8_ACCEPT;
13940 std::size_t bytes = 0; // number of bytes written to string_buffer
13941
13942 // number of bytes written at the point of the last valid byte
13943 std::size_t bytes_after_last_accept = 0;
13944 std::size_t undumped_chars = 0;
13945
13946 for (std::size_t i = 0; i < s.size(); ++i)
13947 {
13948 const auto byte = static_cast<uint8_t>(s[i]);
13949
13950 switch (decode(state, codepoint, byte))
13951 {
13952 case UTF8_ACCEPT: // decode found a new code point
13953 {
13954 switch (codepoint)
13955 {
13956 case 0x08: // backspace
13957 {
13958 string_buffer[bytes++] = '\\';
13959 string_buffer[bytes++] = 'b';
13960 break;
13961 }
13962
13963 case 0x09: // horizontal tab
13964 {
13965 string_buffer[bytes++] = '\\';
13966 string_buffer[bytes++] = 't';
13967 break;
13968 }
13969
13970 case 0x0A: // newline
13971 {
13972 string_buffer[bytes++] = '\\';
13973 string_buffer[bytes++] = 'n';
13974 break;
13975 }
13976
13977 case 0x0C: // formfeed
13978 {
13979 string_buffer[bytes++] = '\\';
13980 string_buffer[bytes++] = 'f';
13981 break;
13982 }
13983
13984 case 0x0D: // carriage return
13985 {
13986 string_buffer[bytes++] = '\\';
13987 string_buffer[bytes++] = 'r';
13988 break;
13989 }
13990
13991 case 0x22: // quotation mark
13992 {
13993 string_buffer[bytes++] = '\\';
13994 string_buffer[bytes++] = '\"';
13995 break;
13996 }
13997
13998 case 0x5C: // reverse solidus
13999 {
14000 string_buffer[bytes++] = '\\';
14001 string_buffer[bytes++] = '\\';
14002 break;
14003 }
14004
14005 default:
14006 {
14007 // escape control characters (0x00..0x1F) or, if
14008 // ensure_ascii parameter is used, non-ASCII characters
14009 if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
14010 {
14011 if (codepoint <= 0xFFFF)
14012 {
14013 (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
14014 static_cast<std::uint16_t>(codepoint));
14015 bytes += 6;
14016 }
14017 else
14018 {
14019 (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
14020 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
14021 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
14022 bytes += 12;
14023 }
14024 }
14025 else
14026 {
14027 // copy byte to buffer (all previous bytes
14028 // been copied have in default case above)
14029 string_buffer[bytes++] = s[i];
14030 }
14031 break;
14032 }
14033 }
14034
14035 // write buffer and reset index; there must be 13 bytes
14036 // left, as this is the maximal number of bytes to be
14037 // written ("\uxxxx\uxxxx\0") for one code point
14038 if (string_buffer.size() - bytes < 13)
14039 {
14040 o->write_characters(string_buffer.data(), bytes);
14041 bytes = 0;
14042 }
14043
14044 // remember the byte position of this accept
14045 bytes_after_last_accept = bytes;
14046 undumped_chars = 0;
14047 break;
14048 }
14049
14050 case UTF8_REJECT: // decode found invalid UTF-8 byte
14051 {
14052 switch (error_handler)
14053 {
14054 case error_handler_t::strict:
14055 {
14056 std::string sn(3, '\0');
14057 (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
14058 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
14059 }
14060
14061 case error_handler_t::ignore:
14062 case error_handler_t::replace:
14063 {
14064 // in case we saw this character the first time, we
14065 // would like to read it again, because the byte
14066 // may be OK for itself, but just not OK for the
14067 // previous sequence
14068 if (undumped_chars > 0)
14069 {
14070 --i;
14071 }
14072
14073 // reset length buffer to the last accepted index;
14074 // thus removing/ignoring the invalid characters
14075 bytes = bytes_after_last_accept;
14076
14077 if (error_handler == error_handler_t::replace)
14078 {
14079 // add a replacement character
14080 if (ensure_ascii)
14081 {
14082 string_buffer[bytes++] = '\\';
14083 string_buffer[bytes++] = 'u';
14084 string_buffer[bytes++] = 'f';
14085 string_buffer[bytes++] = 'f';
14086 string_buffer[bytes++] = 'f';
14087 string_buffer[bytes++] = 'd';
14088 }
14089 else
14090 {
14091 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
14092 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
14093 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
14094 }
14095
14096 // write buffer and reset index; there must be 13 bytes
14097 // left, as this is the maximal number of bytes to be
14098 // written ("\uxxxx\uxxxx\0") for one code point
14099 if (string_buffer.size() - bytes < 13)
14100 {
14101 o->write_characters(string_buffer.data(), bytes);
14102 bytes = 0;
14103 }
14104
14105 bytes_after_last_accept = bytes;
14106 }
14107
14108 undumped_chars = 0;
14109
14110 // continue processing the string
14111 state = UTF8_ACCEPT;
14112 break;
14113 }
14114
14115 default: // LCOV_EXCL_LINE
14116 assert(false); // LCOV_EXCL_LINE
14117 }
14118 break;
14119 }
14120
14121 default: // decode found yet incomplete multi-byte code point
14122 {
14123 if (not ensure_ascii)
14124 {
14125 // code point will not be escaped - copy byte to buffer
14126 string_buffer[bytes++] = s[i];
14127 }
14128 ++undumped_chars;
14129 break;
14130 }
14131 }
14132 }
14133
14134 // we finished processing the string
14135 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
14136 {
14137 // write buffer
14138 if (bytes > 0)
14139 {
14140 o->write_characters(string_buffer.data(), bytes);
14141 }
14142 }
14143 else
14144 {
14145 // we finish reading, but do not accept: string was incomplete
14146 switch (error_handler)
14147 {
14148 case error_handler_t::strict:
14149 {
14150 std::string sn(3, '\0');
14151 (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
14152 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
14153 }
14154
14155 case error_handler_t::ignore:
14156 {
14157 // write all accepted bytes
14158 o->write_characters(string_buffer.data(), bytes_after_last_accept);
14159 break;
14160 }
14161
14162 case error_handler_t::replace:
14163 {
14164 // write all accepted bytes
14165 o->write_characters(string_buffer.data(), bytes_after_last_accept);
14166 // add a replacement character
14167 if (ensure_ascii)
14168 {
14169 o->write_characters("\\ufffd", 6);
14170 }
14171 else
14172 {
14173 o->write_characters("\xEF\xBF\xBD", 3);
14174 }
14175 break;
14176 }
14177
14178 default: // LCOV_EXCL_LINE
14179 assert(false); // LCOV_EXCL_LINE
14180 }
14181 }
14182 }
14183
14184 /*!
14185 @brief count digits
14186
14187 Count the number of decimal (base 10) digits for an input unsigned integer.
14188
14189 @param[in] x unsigned integer number to count its digits
14190 @return number of decimal digits
14191 */
14192 inline unsigned int count_digits(number_unsigned_t x) noexcept
14193 {
14194 unsigned int n_digits = 1;
14195 for (;;)
14196 {
14197 if (x < 10)
14198 {
14199 return n_digits;
14200 }
14201 if (x < 100)
14202 {
14203 return n_digits + 1;
14204 }
14205 if (x < 1000)
14206 {
14207 return n_digits + 2;
14208 }
14209 if (x < 10000)
14210 {
14211 return n_digits + 3;
14212 }
14213 x = x / 10000u;
14214 n_digits += 4;
14215 }
14216 }
14217
14218 /*!
14219 @brief dump an integer
14220
14221 Dump a given integer to output stream @a o. Works internally with
14222 @a number_buffer.
14223
14224 @param[in] x integer number (signed or unsigned) to dump
14225 @tparam NumberType either @a number_integer_t or @a number_unsigned_t
14226 */
14227 template<typename NumberType, detail::enable_if_t<
14228 std::is_same<NumberType, number_unsigned_t>::value or
14229 std::is_same<NumberType, number_integer_t>::value,
14230 int> = 0>
14231 void dump_integer(NumberType x)
14232 {
14233 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
14234 {
14235 {
14236 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
14237 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
14238 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
14239 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
14240 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
14241 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
14242 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
14243 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
14244 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
14245 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
14246 }
14247 };
14248
14249 // special case for "0"
14250 if (x == 0)
14251 {
14252 o->write_character('0');
14253 return;
14254 }
14255
14256 // use a pointer to fill the buffer
14257 auto buffer_ptr = number_buffer.begin();
14258
14259 const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not(x >= 0); // see issue #755
14260 number_unsigned_t abs_value;
14261
14262 unsigned int n_chars;
14263
14264 if (is_negative)
14265 {
14266 *buffer_ptr = '-';
14267 abs_value = static_cast<number_unsigned_t>(std::abs(static_cast<std::intmax_t>(x)));
14268
14269 // account one more byte for the minus sign
14270 n_chars = 1 + count_digits(abs_value);
14271 }
14272 else
14273 {
14274 abs_value = static_cast<number_unsigned_t>(x);
14275 n_chars = count_digits(abs_value);
14276 }
14277
14278 // spare 1 byte for '\0'
14279 assert(n_chars < number_buffer.size() - 1);
14280
14281 // jump to the end to generate the string from backward
14282 // so we later avoid reversing the result
14283 buffer_ptr += n_chars;
14284
14285 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
14286 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
14287 while (abs_value >= 100)
14288 {
14289 const auto digits_index = static_cast<unsigned>((abs_value % 100));
14290 abs_value /= 100;
14291 *(--buffer_ptr) = digits_to_99[digits_index][1];
14292 *(--buffer_ptr) = digits_to_99[digits_index][0];
14293 }
14294
14295 if (abs_value >= 10)
14296 {
14297 const auto digits_index = static_cast<unsigned>(abs_value);
14298 *(--buffer_ptr) = digits_to_99[digits_index][1];
14299 *(--buffer_ptr) = digits_to_99[digits_index][0];
14300 }
14301 else
14302 {
14303 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
14304 }
14305
14306 o->write_characters(number_buffer.data(), n_chars);
14307 }
14308
14309 /*!
14310 @brief dump a floating-point number
14311
14312 Dump a given floating-point number to output stream @a o. Works internally
14313 with @a number_buffer.
14314
14315 @param[in] x floating-point number to dump
14316 */
14317 void dump_float(number_float_t x)
14318 {
14319 // NaN / inf
14320 if (not std::isfinite(x))
14321 {
14322 o->write_characters("null", 4);
14323 return;
14324 }
14325
14326 // If number_float_t is an IEEE-754 single or double precision number,
14327 // use the Grisu2 algorithm to produce short numbers which are
14328 // guaranteed to round-trip, using strtof and strtod, resp.
14329 //
14330 // NB: The test below works if <long double> == <double>.
14331 static constexpr bool is_ieee_single_or_double
14332 = (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
14333 (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);
14334
14335 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
14336 }
14337
14338 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
14339 {
14340 char* begin = number_buffer.data();
14341 char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
14342
14343 o->write_characters(begin, static_cast<size_t>(end - begin));
14344 }
14345
14346 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
14347 {
14348 // get number of digits for a float -> text -> float round-trip
14349 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
14350
14351 // the actual conversion
14352 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
14353
14354 // negative value indicates an error
14355 assert(len > 0);
14356 // check if buffer was large enough
14357 assert(static_cast<std::size_t>(len) < number_buffer.size());
14358
14359 // erase thousands separator
14360 if (thousands_sep != '\0')
14361 {
14362 const auto end = std::remove(number_buffer.begin(),
14363 number_buffer.begin() + len, thousands_sep);
14364 std::fill(end, number_buffer.end(), '\0');
14365 assert((end - number_buffer.begin()) <= len);
14366 len = (end - number_buffer.begin());
14367 }
14368
14369 // convert decimal point to '.'
14370 if (decimal_point != '\0' and decimal_point != '.')
14371 {
14372 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
14373 if (dec_pos != number_buffer.end())
14374 {
14375 *dec_pos = '.';
14376 }
14377 }
14378
14379 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
14380
14381 // determine if need to append ".0"
14382 const bool value_is_int_like =
14383 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
14384 [](char c)
14385 {
14386 return c == '.' or c == 'e';
14387 });
14388
14389 if (value_is_int_like)
14390 {
14391 o->write_characters(".0", 2);
14392 }
14393 }
14394
14395 /*!
14396 @brief check whether a string is UTF-8 encoded
14397
14398 The function checks each byte of a string whether it is UTF-8 encoded. The
14399 result of the check is stored in the @a state parameter. The function must
14400 be called initially with state 0 (accept). State 1 means the string must
14401 be rejected, because the current byte is not allowed. If the string is
14402 completely processed, but the state is non-zero, the string ended
14403 prematurely; that is, the last byte indicated more bytes should have
14404 followed.
14405
14406 @param[in,out] state the state of the decoding
14407 @param[in,out] codep codepoint (valid only if resulting state is UTF8_ACCEPT)
14408 @param[in] byte next byte to decode
14409 @return new state
14410
14411 @note The function has been edited: a std::array is used.
14412
14413 @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
14414 @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
14415 */
14416 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
14417 {
14418 static const std::array<std::uint8_t, 400> utf8d =
14419 {
14420 {
14421 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
14422 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
14423 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
14424 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
14425 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
14426 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
14427 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
14428 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
14429 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
14430 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
14431 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
14432 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
14433 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
14434 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
14435 }
14436 };
14437
14438 const std::uint8_t type = utf8d[byte];
14439
14440 codep = (state != UTF8_ACCEPT)
14441 ? (byte & 0x3fu) | (codep << 6u)
14442 : (0xFFu >> type) & (byte);
14443
14444 state = utf8d[256u + state * 16u + type];
14445 return state;
14446 }
14447
14448 private:
14449 /// the output of the serializer
14450 output_adapter_t<char> o = nullptr;
14451
14452 /// a (hopefully) large enough character buffer
14453 std::array<char, 64> number_buffer{{}};
14454
14455 /// the locale
14456 const std::lconv* loc = nullptr;
14457 /// the locale's thousand separator character
14458 const char thousands_sep = '\0';
14459 /// the locale's decimal point character
14460 const char decimal_point = '\0';
14461
14462 /// string buffer
14463 std::array<char, 512> string_buffer{{}};
14464
14465 /// the indentation character
14466 const char indent_char;
14467 /// the indentation string
14468 string_t indent_string;
14469
14470 /// error_handler how to react on decoding errors
14471 const error_handler_t error_handler;
14472 };
14473 } // namespace detail
14474 } // namespace nlohmann
14475
14476 // #include <nlohmann/detail/value_t.hpp>
14477
14478 // #include <nlohmann/json_fwd.hpp>
14479
14480
14481 /*!
14482 @brief namespace for Niels Lohmann
14483 @see https://github.com/nlohmann
14484 @since version 1.0.0
14485 */
14486 namespace nlohmann
14487 {
14488
14489 /*!
14490 @brief a class to store JSON values
14491
14492 @tparam ObjectType type for JSON objects (`std::map` by default; will be used
14493 in @ref object_t)
14494 @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
14495 in @ref array_t)
14496 @tparam StringType type for JSON strings and object keys (`std::string` by
14497 default; will be used in @ref string_t)
14498 @tparam BooleanType type for JSON booleans (`bool` by default; will be used
14499 in @ref boolean_t)
14500 @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
14501 default; will be used in @ref number_integer_t)
14502 @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
14503 `uint64_t` by default; will be used in @ref number_unsigned_t)
14504 @tparam NumberFloatType type for JSON floating-point numbers (`double` by
14505 default; will be used in @ref number_float_t)
14506 @tparam AllocatorType type of the allocator to use (`std::allocator` by
14507 default)
14508 @tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
14509 and `from_json()` (@ref adl_serializer by default)
14510
14511 @requirement The class satisfies the following concept requirements:
14512 - Basic
14513 - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
14514 JSON values can be default constructed. The result will be a JSON null
14515 value.
14516 - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
14517 A JSON value can be constructed from an rvalue argument.
14518 - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
14519 A JSON value can be copy-constructed from an lvalue expression.
14520 - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
14521 A JSON value van be assigned from an rvalue argument.
14522 - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
14523 A JSON value can be copy-assigned from an lvalue expression.
14524 - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
14525 JSON values can be destructed.
14526 - Layout
14527 - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
14528 JSON values have
14529 [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
14530 All non-static data members are private and standard layout types, the
14531 class has no virtual functions or (virtual) base classes.
14532 - Library-wide
14533 - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
14534 JSON values can be compared with `==`, see @ref
14535 operator==(const_reference,const_reference).
14536 - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
14537 JSON values can be compared with `<`, see @ref
14538 operator<(const_reference,const_reference).
14539 - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
14540 Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
14541 other compatible types, using unqualified function call @ref swap().
14542 - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
14543 JSON values can be compared against `std::nullptr_t` objects which are used
14544 to model the `null` value.
14545 - Container
14546 - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
14547 JSON values can be used like STL containers and provide iterator access.
14548 - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
14549 JSON values can be used like STL containers and provide reverse iterator
14550 access.
14551
14552 @invariant The member variables @a m_value and @a m_type have the following
14553 relationship:
14554 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
14555 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
14556 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
14557 The invariants are checked by member function assert_invariant().
14558
14559 @internal
14560 @note ObjectType trick from http://stackoverflow.com/a/9860911
14561 @endinternal
14562
14563 @see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
14564 Format](http://rfc7159.net/rfc7159)
14565
14566 @since version 1.0.0
14567
14568 @nosubgrouping
14569 */
14570 NLOHMANN_BASIC_JSON_TPL_DECLARATION
14571 class basic_json
14572 {
14573 private:
14574 template<detail::value_t> friend struct detail::external_constructor;
14575 friend ::nlohmann::json_pointer<basic_json>;
14576 friend ::nlohmann::detail::parser<basic_json>;
14577 friend ::nlohmann::detail::serializer<basic_json>;
14578 template<typename BasicJsonType>
14579 friend class ::nlohmann::detail::iter_impl;
14580 template<typename BasicJsonType, typename CharType>
14581 friend class ::nlohmann::detail::binary_writer;
14582 template<typename BasicJsonType, typename SAX>
14583 friend class ::nlohmann::detail::binary_reader;
14584 template<typename BasicJsonType>
14585 friend class ::nlohmann::detail::json_sax_dom_parser;
14586 template<typename BasicJsonType>
14587 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
14588
14589 /// workaround type for MSVC
14590 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
14591
14592 // convenience aliases for types residing in namespace detail;
14593 using lexer = ::nlohmann::detail::lexer<basic_json>;
14594 using parser = ::nlohmann::detail::parser<basic_json>;
14595
14596 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
14597 template<typename BasicJsonType>
14598 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
14599 template<typename BasicJsonType>
14600 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
14601 template<typename Iterator>
14602 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
14603 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
14604
14605 template<typename CharType>
14606 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
14607
14608 using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
14609 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
14610
14611 using serializer = ::nlohmann::detail::serializer<basic_json>;
14612
14613 public:
14614 using value_t = detail::value_t;
14615 /// JSON Pointer, see @ref nlohmann::json_pointer
14616 using json_pointer = ::nlohmann::json_pointer<basic_json>;
14617 template<typename T, typename SFINAE>
14618 using json_serializer = JSONSerializer<T, SFINAE>;
14619 /// how to treat decoding errors
14620 using error_handler_t = detail::error_handler_t;
14621 /// helper type for initializer lists of basic_json values
14622 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
14623
14624 using input_format_t = detail::input_format_t;
14625 /// SAX interface type, see @ref nlohmann::json_sax
14626 using json_sax_t = json_sax<basic_json>;
14627
14628 ////////////////
14629 // exceptions //
14630 ////////////////
14631
14632 /// @name exceptions
14633 /// Classes to implement user-defined exceptions.
14634 /// @{
14635
14636 /// @copydoc detail::exception
14637 using exception = detail::exception;
14638 /// @copydoc detail::parse_error
14639 using parse_error = detail::parse_error;
14640 /// @copydoc detail::invalid_iterator
14641 using invalid_iterator = detail::invalid_iterator;
14642 /// @copydoc detail::type_error
14643 using type_error = detail::type_error;
14644 /// @copydoc detail::out_of_range
14645 using out_of_range = detail::out_of_range;
14646 /// @copydoc detail::other_error
14647 using other_error = detail::other_error;
14648
14649 /// @}
14650
14651
14652 /////////////////////
14653 // container types //
14654 /////////////////////
14655
14656 /// @name container types
14657 /// The canonic container types to use @ref basic_json like any other STL
14658 /// container.
14659 /// @{
14660
14661 /// the type of elements in a basic_json container
14662 using value_type = basic_json;
14663
14664 /// the type of an element reference
14665 using reference = value_type&;
14666 /// the type of an element const reference
14667 using const_reference = const value_type&;
14668
14669 /// a type to represent differences between iterators
14670 using difference_type = std::ptrdiff_t;
14671 /// a type to represent container sizes
14672 using size_type = std::size_t;
14673
14674 /// the allocator type
14675 using allocator_type = AllocatorType<basic_json>;
14676
14677 /// the type of an element pointer
14678 using pointer = typename std::allocator_traits<allocator_type>::pointer;
14679 /// the type of an element const pointer
14680 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
14681
14682 /// an iterator for a basic_json container
14683 using iterator = iter_impl<basic_json>;
14684 /// a const iterator for a basic_json container
14685 using const_iterator = iter_impl<const basic_json>;
14686 /// a reverse iterator for a basic_json container
14687 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
14688 /// a const reverse iterator for a basic_json container
14689 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
14690
14691 /// @}
14692
14693
14694 /*!
14695 @brief returns the allocator associated with the container
14696 */
14697 static allocator_type get_allocator()
14698 {
14699 return allocator_type();
14700 }
14701
14702 /*!
14703 @brief returns version information on the library
14704
14705 This function returns a JSON object with information about the library,
14706 including the version number and information on the platform and compiler.
14707
14708 @return JSON object holding version information
14709 key | description
14710 ----------- | ---------------
14711 `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).
14712 `copyright` | The copyright line for the library as string.
14713 `name` | The name of the library as string.
14714 `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
14715 `url` | The URL of the project as string.
14716 `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).
14717
14718 @liveexample{The following code shows an example output of the `meta()`
14719 function.,meta}
14720
14721 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14722 changes to any JSON value.
14723
14724 @complexity Constant.
14725
14726 @since 2.1.0
14727 */
14728 JSON_HEDLEY_WARN_UNUSED_RESULT
14729 static basic_json meta()
14730 {
14731 basic_json result;
14732
14733 result["copyright"] = "(C) 2013-2017 Niels Lohmann";
14734 result["name"] = "JSON for Modern C++";
14735 result["url"] = "https://github.com/nlohmann/json";
14736 result["version"]["string"] =
14737 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
14738 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
14739 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
14740 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
14741 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
14742 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
14743
14744 #ifdef _WIN32
14745 result["platform"] = "win32";
14746 #elif defined __linux__
14747 result["platform"] = "linux";
14748 #elif defined __APPLE__
14749 result["platform"] = "apple";
14750 #elif defined __unix__
14751 result["platform"] = "unix";
14752 #else
14753 result["platform"] = "unknown";
14754 #endif
14755
14756 #if defined(__ICC) || defined(__INTEL_COMPILER)
14757 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
14758 #elif defined(__clang__)
14759 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
14760 #elif defined(__GNUC__) || defined(__GNUG__)
14761 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
14762 #elif defined(__HP_cc) || defined(__HP_aCC)
14763 result["compiler"] = "hp"
14764 #elif defined(__IBMCPP__)
14765 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
14766 #elif defined(_MSC_VER)
14767 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
14768 #elif defined(__PGI)
14769 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
14770 #elif defined(__SUNPRO_CC)
14771 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
14772 #else
14773 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
14774 #endif
14775
14776 #ifdef __cplusplus
14777 result["compiler"]["c++"] = std::to_string(__cplusplus);
14778 #else
14779 result["compiler"]["c++"] = "unknown";
14780 #endif
14781 return result;
14782 }
14783
14784
14785 ///////////////////////////
14786 // JSON value data types //
14787 ///////////////////////////
14788
14789 /// @name JSON value data types
14790 /// The data types to store a JSON value. These types are derived from
14791 /// the template arguments passed to class @ref basic_json.
14792 /// @{
14793
14794 #if defined(JSON_HAS_CPP_14)
14795 // Use transparent comparator if possible, combined with perfect forwarding
14796 // on find() and count() calls prevents unnecessary string construction.
14797 using object_comparator_t = std::less<>;
14798 #else
14799 using object_comparator_t = std::less<StringType>;
14800 #endif
14801
14802 /*!
14803 @brief a type for an object
14804
14805 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
14806 > An object is an unordered collection of zero or more name/value pairs,
14807 > where a name is a string and a value is a string, number, boolean, null,
14808 > object, or array.
14809
14810 To store objects in C++, a type is defined by the template parameters
14811 described below.
14812
14813 @tparam ObjectType the container to store objects (e.g., `std::map` or
14814 `std::unordered_map`)
14815 @tparam StringType the type of the keys or names (e.g., `std::string`).
14816 The comparison function `std::less<StringType>` is used to order elements
14817 inside the container.
14818 @tparam AllocatorType the allocator to use for objects (e.g.,
14819 `std::allocator`)
14820
14821 #### Default type
14822
14823 With the default values for @a ObjectType (`std::map`), @a StringType
14824 (`std::string`), and @a AllocatorType (`std::allocator`), the default
14825 value for @a object_t is:
14826
14827 @code {.cpp}
14828 std::map<
14829 std::string, // key_type
14830 basic_json, // value_type
14831 std::less<std::string>, // key_compare
14832 std::allocator<std::pair<const std::string, basic_json>> // allocator_type
14833 >
14834 @endcode
14835
14836 #### Behavior
14837
14838 The choice of @a object_t influences the behavior of the JSON class. With
14839 the default type, objects have the following behavior:
14840
14841 - When all names are unique, objects will be interoperable in the sense
14842 that all software implementations receiving that object will agree on
14843 the name-value mappings.
14844 - When the names within an object are not unique, it is unspecified which
14845 one of the values for a given key will be chosen. For instance,
14846 `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
14847 `{"key": 2}`.
14848 - Internally, name/value pairs are stored in lexicographical order of the
14849 names. Objects will also be serialized (see @ref dump) in this order.
14850 For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
14851 and serialized as `{"a": 2, "b": 1}`.
14852 - When comparing objects, the order of the name/value pairs is irrelevant.
14853 This makes objects interoperable in the sense that they will not be
14854 affected by these differences. For instance, `{"b": 1, "a": 2}` and
14855 `{"a": 2, "b": 1}` will be treated as equal.
14856
14857 #### Limits
14858
14859 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
14860 > An implementation may set limits on the maximum depth of nesting.
14861
14862 In this class, the object's limit of nesting is not explicitly constrained.
14863 However, a maximum depth of nesting may be introduced by the compiler or
14864 runtime environment. A theoretical limit can be queried by calling the
14865 @ref max_size function of a JSON object.
14866
14867 #### Storage
14868
14869 Objects are stored as pointers in a @ref basic_json type. That is, for any
14870 access to object values, a pointer of type `object_t*` must be
14871 dereferenced.
14872
14873 @sa @ref array_t -- type for an array value
14874
14875 @since version 1.0.0
14876
14877 @note The order name/value pairs are added to the object is *not*
14878 preserved by the library. Therefore, iterating an object may return
14879 name/value pairs in a different order than they were originally stored. In
14880 fact, keys will be traversed in alphabetical order as `std::map` with
14881 `std::less` is used by default. Please note this behavior conforms to [RFC
14882 7159](http://rfc7159.net/rfc7159), because any order implements the
14883 specified "unordered" nature of JSON objects.
14884 */
14885 using object_t = ObjectType<StringType,
14886 basic_json,
14887 object_comparator_t,
14888 AllocatorType<std::pair<const StringType,
14889 basic_json>>>;
14890
14891 /*!
14892 @brief a type for an array
14893
14894 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
14895 > An array is an ordered sequence of zero or more values.
14896
14897 To store objects in C++, a type is defined by the template parameters
14898 explained below.
14899
14900 @tparam ArrayType container type to store arrays (e.g., `std::vector` or
14901 `std::list`)
14902 @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
14903
14904 #### Default type
14905
14906 With the default values for @a ArrayType (`std::vector`) and @a
14907 AllocatorType (`std::allocator`), the default value for @a array_t is:
14908
14909 @code {.cpp}
14910 std::vector<
14911 basic_json, // value_type
14912 std::allocator<basic_json> // allocator_type
14913 >
14914 @endcode
14915
14916 #### Limits
14917
14918 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
14919 > An implementation may set limits on the maximum depth of nesting.
14920
14921 In this class, the array's limit of nesting is not explicitly constrained.
14922 However, a maximum depth of nesting may be introduced by the compiler or
14923 runtime environment. A theoretical limit can be queried by calling the
14924 @ref max_size function of a JSON array.
14925
14926 #### Storage
14927
14928 Arrays are stored as pointers in a @ref basic_json type. That is, for any
14929 access to array values, a pointer of type `array_t*` must be dereferenced.
14930
14931 @sa @ref object_t -- type for an object value
14932
14933 @since version 1.0.0
14934 */
14935 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
14936
14937 /*!
14938 @brief a type for a string
14939
14940 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
14941 > A string is a sequence of zero or more Unicode characters.
14942
14943 To store objects in C++, a type is defined by the template parameter
14944 described below. Unicode values are split by the JSON class into
14945 byte-sized characters during deserialization.
14946
14947 @tparam StringType the container to store strings (e.g., `std::string`).
14948 Note this container is used for keys/names in objects, see @ref object_t.
14949
14950 #### Default type
14951
14952 With the default values for @a StringType (`std::string`), the default
14953 value for @a string_t is:
14954
14955 @code {.cpp}
14956 std::string
14957 @endcode
14958
14959 #### Encoding
14960
14961 Strings are stored in UTF-8 encoding. Therefore, functions like
14962 `std::string::size()` or `std::string::length()` return the number of
14963 bytes in the string rather than the number of characters or glyphs.
14964
14965 #### String comparison
14966
14967 [RFC 7159](http://rfc7159.net/rfc7159) states:
14968 > Software implementations are typically required to test names of object
14969 > members for equality. Implementations that transform the textual
14970 > representation into sequences of Unicode code units and then perform the
14971 > comparison numerically, code unit by code unit, are interoperable in the
14972 > sense that implementations will agree in all cases on equality or
14973 > inequality of two strings. For example, implementations that compare
14974 > strings with escaped characters unconverted may incorrectly find that
14975 > `"a\\b"` and `"a\u005Cb"` are not equal.
14976
14977 This implementation is interoperable as it does compare strings code unit
14978 by code unit.
14979
14980 #### Storage
14981
14982 String values are stored as pointers in a @ref basic_json type. That is,
14983 for any access to string values, a pointer of type `string_t*` must be
14984 dereferenced.
14985
14986 @since version 1.0.0
14987 */
14988 using string_t = StringType;
14989
14990 /*!
14991 @brief a type for a boolean
14992
14993 [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
14994 type which differentiates the two literals `true` and `false`.
14995
14996 To store objects in C++, a type is defined by the template parameter @a
14997 BooleanType which chooses the type to use.
14998
14999 #### Default type
15000
15001 With the default values for @a BooleanType (`bool`), the default value for
15002 @a boolean_t is:
15003
15004 @code {.cpp}
15005 bool
15006 @endcode
15007
15008 #### Storage
15009
15010 Boolean values are stored directly inside a @ref basic_json type.
15011
15012 @since version 1.0.0
15013 */
15014 using boolean_t = BooleanType;
15015
15016 /*!
15017 @brief a type for a number (integer)
15018
15019 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
15020 > The representation of numbers is similar to that used in most
15021 > programming languages. A number is represented in base 10 using decimal
15022 > digits. It contains an integer component that may be prefixed with an
15023 > optional minus sign, which may be followed by a fraction part and/or an
15024 > exponent part. Leading zeros are not allowed. (...) Numeric values that
15025 > cannot be represented in the grammar below (such as Infinity and NaN)
15026 > are not permitted.
15027
15028 This description includes both integer and floating-point numbers.
15029 However, C++ allows more precise storage if it is known whether the number
15030 is a signed integer, an unsigned integer or a floating-point number.
15031 Therefore, three different types, @ref number_integer_t, @ref
15032 number_unsigned_t and @ref number_float_t are used.
15033
15034 To store integer numbers in C++, a type is defined by the template
15035 parameter @a NumberIntegerType which chooses the type to use.
15036
15037 #### Default type
15038
15039 With the default values for @a NumberIntegerType (`int64_t`), the default
15040 value for @a number_integer_t is:
15041
15042 @code {.cpp}
15043 int64_t
15044 @endcode
15045
15046 #### Default behavior
15047
15048 - The restrictions about leading zeros is not enforced in C++. Instead,
15049 leading zeros in integer literals lead to an interpretation as octal
15050 number. Internally, the value will be stored as decimal number. For
15051 instance, the C++ integer literal `010` will be serialized to `8`.
15052 During deserialization, leading zeros yield an error.
15053 - Not-a-number (NaN) values will be serialized to `null`.
15054
15055 #### Limits
15056
15057 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
15058 > An implementation may set limits on the range and precision of numbers.
15059
15060 When the default type is used, the maximal integer number that can be
15061 stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
15062 that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
15063 that are out of range will yield over/underflow when used in a
15064 constructor. During deserialization, too large or small integer numbers
15065 will be automatically be stored as @ref number_unsigned_t or @ref
15066 number_float_t.
15067
15068 [RFC 7159](http://rfc7159.net/rfc7159) further states:
15069 > Note that when such software is used, numbers that are integers and are
15070 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
15071 > that implementations will agree exactly on their numeric values.
15072
15073 As this range is a subrange of the exactly supported range [INT64_MIN,
15074 INT64_MAX], this class's integer type is interoperable.
15075
15076 #### Storage
15077
15078 Integer number values are stored directly inside a @ref basic_json type.
15079
15080 @sa @ref number_float_t -- type for number values (floating-point)
15081
15082 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
15083
15084 @since version 1.0.0
15085 */
15086 using number_integer_t = NumberIntegerType;
15087
15088 /*!
15089 @brief a type for a number (unsigned)
15090
15091 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
15092 > The representation of numbers is similar to that used in most
15093 > programming languages. A number is represented in base 10 using decimal
15094 > digits. It contains an integer component that may be prefixed with an
15095 > optional minus sign, which may be followed by a fraction part and/or an
15096 > exponent part. Leading zeros are not allowed. (...) Numeric values that
15097 > cannot be represented in the grammar below (such as Infinity and NaN)
15098 > are not permitted.
15099
15100 This description includes both integer and floating-point numbers.
15101 However, C++ allows more precise storage if it is known whether the number
15102 is a signed integer, an unsigned integer or a floating-point number.
15103 Therefore, three different types, @ref number_integer_t, @ref
15104 number_unsigned_t and @ref number_float_t are used.
15105
15106 To store unsigned integer numbers in C++, a type is defined by the
15107 template parameter @a NumberUnsignedType which chooses the type to use.
15108
15109 #### Default type
15110
15111 With the default values for @a NumberUnsignedType (`uint64_t`), the
15112 default value for @a number_unsigned_t is:
15113
15114 @code {.cpp}
15115 uint64_t
15116 @endcode
15117
15118 #### Default behavior
15119
15120 - The restrictions about leading zeros is not enforced in C++. Instead,
15121 leading zeros in integer literals lead to an interpretation as octal
15122 number. Internally, the value will be stored as decimal number. For
15123 instance, the C++ integer literal `010` will be serialized to `8`.
15124 During deserialization, leading zeros yield an error.
15125 - Not-a-number (NaN) values will be serialized to `null`.
15126
15127 #### Limits
15128
15129 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
15130 > An implementation may set limits on the range and precision of numbers.
15131
15132 When the default type is used, the maximal integer number that can be
15133 stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
15134 number that can be stored is `0`. Integer numbers that are out of range
15135 will yield over/underflow when used in a constructor. During
15136 deserialization, too large or small integer numbers will be automatically
15137 be stored as @ref number_integer_t or @ref number_float_t.
15138
15139 [RFC 7159](http://rfc7159.net/rfc7159) further states:
15140 > Note that when such software is used, numbers that are integers and are
15141 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
15142 > that implementations will agree exactly on their numeric values.
15143
15144 As this range is a subrange (when considered in conjunction with the
15145 number_integer_t type) of the exactly supported range [0, UINT64_MAX],
15146 this class's integer type is interoperable.
15147
15148 #### Storage
15149
15150 Integer number values are stored directly inside a @ref basic_json type.
15151
15152 @sa @ref number_float_t -- type for number values (floating-point)
15153 @sa @ref number_integer_t -- type for number values (integer)
15154
15155 @since version 2.0.0
15156 */
15157 using number_unsigned_t = NumberUnsignedType;
15158
15159 /*!
15160 @brief a type for a number (floating-point)
15161
15162 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
15163 > The representation of numbers is similar to that used in most
15164 > programming languages. A number is represented in base 10 using decimal
15165 > digits. It contains an integer component that may be prefixed with an
15166 > optional minus sign, which may be followed by a fraction part and/or an
15167 > exponent part. Leading zeros are not allowed. (...) Numeric values that
15168 > cannot be represented in the grammar below (such as Infinity and NaN)
15169 > are not permitted.
15170
15171 This description includes both integer and floating-point numbers.
15172 However, C++ allows more precise storage if it is known whether the number
15173 is a signed integer, an unsigned integer or a floating-point number.
15174 Therefore, three different types, @ref number_integer_t, @ref
15175 number_unsigned_t and @ref number_float_t are used.
15176
15177 To store floating-point numbers in C++, a type is defined by the template
15178 parameter @a NumberFloatType which chooses the type to use.
15179
15180 #### Default type
15181
15182 With the default values for @a NumberFloatType (`double`), the default
15183 value for @a number_float_t is:
15184
15185 @code {.cpp}
15186 double
15187 @endcode
15188
15189 #### Default behavior
15190
15191 - The restrictions about leading zeros is not enforced in C++. Instead,
15192 leading zeros in floating-point literals will be ignored. Internally,
15193 the value will be stored as decimal number. For instance, the C++
15194 floating-point literal `01.2` will be serialized to `1.2`. During
15195 deserialization, leading zeros yield an error.
15196 - Not-a-number (NaN) values will be serialized to `null`.
15197
15198 #### Limits
15199
15200 [RFC 7159](http://rfc7159.net/rfc7159) states:
15201 > This specification allows implementations to set limits on the range and
15202 > precision of numbers accepted. Since software that implements IEEE
15203 > 754-2008 binary64 (double precision) numbers is generally available and
15204 > widely used, good interoperability can be achieved by implementations
15205 > that expect no more precision or range than these provide, in the sense
15206 > that implementations will approximate JSON numbers within the expected
15207 > precision.
15208
15209 This implementation does exactly follow this approach, as it uses double
15210 precision floating-point numbers. Note values smaller than
15211 `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
15212 will be stored as NaN internally and be serialized to `null`.
15213
15214 #### Storage
15215
15216 Floating-point number values are stored directly inside a @ref basic_json
15217 type.
15218
15219 @sa @ref number_integer_t -- type for number values (integer)
15220
15221 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
15222
15223 @since version 1.0.0
15224 */
15225 using number_float_t = NumberFloatType;
15226
15227 /// @}
15228
15229 private:
15230
15231 /// helper for exception-safe object creation
15232 template<typename T, typename... Args>
15233 JSON_HEDLEY_RETURNS_NON_NULL
15234 static T* create(Args&& ... args)
15235 {
15236 AllocatorType<T> alloc;
15237 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
15238
15239 auto deleter = [&](T * object)
15240 {
15241 AllocatorTraits::deallocate(alloc, object, 1);
15242 };
15243 std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
15244 AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
15245 assert(object != nullptr);
15246 return object.release();
15247 }
15248
15249 ////////////////////////
15250 // JSON value storage //
15251 ////////////////////////
15252
15253 /*!
15254 @brief a JSON value
15255
15256 The actual storage for a JSON value of the @ref basic_json class. This
15257 union combines the different storage types for the JSON value types
15258 defined in @ref value_t.
15259
15260 JSON type | value_t type | used type
15261 --------- | --------------- | ------------------------
15262 object | object | pointer to @ref object_t
15263 array | array | pointer to @ref array_t
15264 string | string | pointer to @ref string_t
15265 boolean | boolean | @ref boolean_t
15266 number | number_integer | @ref number_integer_t
15267 number | number_unsigned | @ref number_unsigned_t
15268 number | number_float | @ref number_float_t
15269 null | null | *no value is stored*
15270
15271 @note Variable-length types (objects, arrays, and strings) are stored as
15272 pointers. The size of the union should not exceed 64 bits if the default
15273 value types are used.
15274
15275 @since version 1.0.0
15276 */
15277 union json_value
15278 {
15279 /// object (stored with pointer to save storage)
15280 object_t* object;
15281 /// array (stored with pointer to save storage)
15282 array_t* array;
15283 /// string (stored with pointer to save storage)
15284 string_t* string;
15285 /// boolean
15286 boolean_t boolean;
15287 /// number (integer)
15288 number_integer_t number_integer;
15289 /// number (unsigned integer)
15290 number_unsigned_t number_unsigned;
15291 /// number (floating-point)
15292 number_float_t number_float;
15293
15294 /// default constructor (for null values)
15295 json_value() = default;
15296 /// constructor for booleans
15297 json_value(boolean_t v) noexcept : boolean(v) {}
15298 /// constructor for numbers (integer)
15299 json_value(number_integer_t v) noexcept : number_integer(v) {}
15300 /// constructor for numbers (unsigned)
15301 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
15302 /// constructor for numbers (floating-point)
15303 json_value(number_float_t v) noexcept : number_float(v) {}
15304 /// constructor for empty values of a given type
15305 json_value(value_t t)
15306 {
15307 switch (t)
15308 {
15309 case value_t::object:
15310 {
15311 object = create<object_t>();
15312 break;
15313 }
15314
15315 case value_t::array:
15316 {
15317 array = create<array_t>();
15318 break;
15319 }
15320
15321 case value_t::string:
15322 {
15323 string = create<string_t>("");
15324 break;
15325 }
15326
15327 case value_t::boolean:
15328 {
15329 boolean = boolean_t(false);
15330 break;
15331 }
15332
15333 case value_t::number_integer:
15334 {
15335 number_integer = number_integer_t(0);
15336 break;
15337 }
15338
15339 case value_t::number_unsigned:
15340 {
15341 number_unsigned = number_unsigned_t(0);
15342 break;
15343 }
15344
15345 case value_t::number_float:
15346 {
15347 number_float = number_float_t(0.0);
15348 break;
15349 }
15350
15351 case value_t::null:
15352 {
15353 object = nullptr; // silence warning, see #821
15354 break;
15355 }
15356
15357 default:
15358 {
15359 object = nullptr; // silence warning, see #821
15360 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
15361 {
15362 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.7.0")); // LCOV_EXCL_LINE
15363 }
15364 break;
15365 }
15366 }
15367 }
15368
15369 /// constructor for strings
15370 json_value(const string_t& value)
15371 {
15372 string = create<string_t>(value);
15373 }
15374
15375 /// constructor for rvalue strings
15376 json_value(string_t&& value)
15377 {
15378 string = create<string_t>(std::move(value));
15379 }
15380
15381 /// constructor for objects
15382 json_value(const object_t& value)
15383 {
15384 object = create<object_t>(value);
15385 }
15386
15387 /// constructor for rvalue objects
15388 json_value(object_t&& value)
15389 {
15390 object = create<object_t>(std::move(value));
15391 }
15392
15393 /// constructor for arrays
15394 json_value(const array_t& value)
15395 {
15396 array = create<array_t>(value);
15397 }
15398
15399 /// constructor for rvalue arrays
15400 json_value(array_t&& value)
15401 {
15402 array = create<array_t>(std::move(value));
15403 }
15404
15405 void destroy(value_t t) noexcept
15406 {
15407 switch (t)
15408 {
15409 case value_t::object:
15410 {
15411 AllocatorType<object_t> alloc;
15412 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
15413 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
15414 break;
15415 }
15416
15417 case value_t::array:
15418 {
15419 AllocatorType<array_t> alloc;
15420 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
15421 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
15422 break;
15423 }
15424
15425 case value_t::string:
15426 {
15427 AllocatorType<string_t> alloc;
15428 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
15429 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
15430 break;
15431 }
15432
15433 default:
15434 {
15435 break;
15436 }
15437 }
15438 }
15439 };
15440
15441 /*!
15442 @brief checks the class invariants
15443
15444 This function asserts the class invariants. It needs to be called at the
15445 end of every constructor to make sure that created objects respect the
15446 invariant. Furthermore, it has to be called each time the type of a JSON
15447 value is changed, because the invariant expresses a relationship between
15448 @a m_type and @a m_value.
15449 */
15450 void assert_invariant() const noexcept
15451 {
15452 assert(m_type != value_t::object or m_value.object != nullptr);
15453 assert(m_type != value_t::array or m_value.array != nullptr);
15454 assert(m_type != value_t::string or m_value.string != nullptr);
15455 }
15456
15457 public:
15458 //////////////////////////
15459 // JSON parser callback //
15460 //////////////////////////
15461
15462 /*!
15463 @brief parser event types
15464
15465 The parser callback distinguishes the following events:
15466 - `object_start`: the parser read `{` and started to process a JSON object
15467 - `key`: the parser read a key of a value in an object
15468 - `object_end`: the parser read `}` and finished processing a JSON object
15469 - `array_start`: the parser read `[` and started to process a JSON array
15470 - `array_end`: the parser read `]` and finished processing a JSON array
15471 - `value`: the parser finished reading a JSON value
15472
15473 @image html callback_events.png "Example when certain parse events are triggered"
15474
15475 @sa @ref parser_callback_t for more information and examples
15476 */
15477 using parse_event_t = typename parser::parse_event_t;
15478
15479 /*!
15480 @brief per-element parser callback type
15481
15482 With a parser callback function, the result of parsing a JSON text can be
15483 influenced. When passed to @ref parse, it is called on certain events
15484 (passed as @ref parse_event_t via parameter @a event) with a set recursion
15485 depth @a depth and context JSON value @a parsed. The return value of the
15486 callback function is a boolean indicating whether the element that emitted
15487 the callback shall be kept or not.
15488
15489 We distinguish six scenarios (determined by the event type) in which the
15490 callback function can be called. The following table describes the values
15491 of the parameters @a depth, @a event, and @a parsed.
15492
15493 parameter @a event | description | parameter @a depth | parameter @a parsed
15494 ------------------ | ----------- | ------------------ | -------------------
15495 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
15496 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
15497 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
15498 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
15499 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
15500 parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
15501
15502 @image html callback_events.png "Example when certain parse events are triggered"
15503
15504 Discarding a value (i.e., returning `false`) has different effects
15505 depending on the context in which function was called:
15506
15507 - Discarded values in structured types are skipped. That is, the parser
15508 will behave as if the discarded value was never read.
15509 - In case a value outside a structured type is skipped, it is replaced
15510 with `null`. This case happens if the top-level element is skipped.
15511
15512 @param[in] depth the depth of the recursion during parsing
15513
15514 @param[in] event an event of type parse_event_t indicating the context in
15515 the callback function has been called
15516
15517 @param[in,out] parsed the current intermediate parse result; note that
15518 writing to this value has no effect for parse_event_t::key events
15519
15520 @return Whether the JSON value which called the function during parsing
15521 should be kept (`true`) or not (`false`). In the latter case, it is either
15522 skipped completely or replaced by an empty discarded object.
15523
15524 @sa @ref parse for examples
15525
15526 @since version 1.0.0
15527 */
15528 using parser_callback_t = typename parser::parser_callback_t;
15529
15530 //////////////////
15531 // constructors //
15532 //////////////////
15533
15534 /// @name constructors and destructors
15535 /// Constructors of class @ref basic_json, copy/move constructor, copy
15536 /// assignment, static functions creating objects, and the destructor.
15537 /// @{
15538
15539 /*!
15540 @brief create an empty value with a given type
15541
15542 Create an empty JSON value with a given type. The value will be default
15543 initialized with an empty value which depends on the type:
15544
15545 Value type | initial value
15546 ----------- | -------------
15547 null | `null`
15548 boolean | `false`
15549 string | `""`
15550 number | `0`
15551 object | `{}`
15552 array | `[]`
15553
15554 @param[in] v the type of the value to create
15555
15556 @complexity Constant.
15557
15558 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15559 changes to any JSON value.
15560
15561 @liveexample{The following code shows the constructor for different @ref
15562 value_t values,basic_json__value_t}
15563
15564 @sa @ref clear() -- restores the postcondition of this constructor
15565
15566 @since version 1.0.0
15567 */
15568 basic_json(const value_t v)
15569 : m_type(v), m_value(v)
15570 {
15571 assert_invariant();
15572 }
15573
15574 /*!
15575 @brief create a null object
15576
15577 Create a `null` JSON value. It either takes a null pointer as parameter
15578 (explicitly creating `null`) or no parameter (implicitly creating `null`).
15579 The passed null pointer itself is not read -- it is only used to choose
15580 the right constructor.
15581
15582 @complexity Constant.
15583
15584 @exceptionsafety No-throw guarantee: this constructor never throws
15585 exceptions.
15586
15587 @liveexample{The following code shows the constructor with and without a
15588 null pointer parameter.,basic_json__nullptr_t}
15589
15590 @since version 1.0.0
15591 */
15592 basic_json(std::nullptr_t = nullptr) noexcept
15593 : basic_json(value_t::null)
15594 {
15595 assert_invariant();
15596 }
15597
15598 /*!
15599 @brief create a JSON value
15600
15601 This is a "catch all" constructor for all compatible JSON types; that is,
15602 types for which a `to_json()` method exists. The constructor forwards the
15603 parameter @a val to that method (to `json_serializer<U>::to_json` method
15604 with `U = uncvref_t<CompatibleType>`, to be exact).
15605
15606 Template type @a CompatibleType includes, but is not limited to, the
15607 following types:
15608 - **arrays**: @ref array_t and all kinds of compatible containers such as
15609 `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
15610 `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
15611 `std::multiset`, and `std::unordered_multiset` with a `value_type` from
15612 which a @ref basic_json value can be constructed.
15613 - **objects**: @ref object_t and all kinds of compatible associative
15614 containers such as `std::map`, `std::unordered_map`, `std::multimap`,
15615 and `std::unordered_multimap` with a `key_type` compatible to
15616 @ref string_t and a `value_type` from which a @ref basic_json value can
15617 be constructed.
15618 - **strings**: @ref string_t, string literals, and all compatible string
15619 containers can be used.
15620 - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
15621 @ref number_float_t, and all convertible number types such as `int`,
15622 `size_t`, `int64_t`, `float` or `double` can be used.
15623 - **boolean**: @ref boolean_t / `bool` can be used.
15624
15625 See the examples below.
15626
15627 @tparam CompatibleType a type such that:
15628 - @a CompatibleType is not derived from `std::istream`,
15629 - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
15630 constructors),
15631 - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
15632 - @a CompatibleType is not a @ref basic_json nested type (e.g.,
15633 @ref json_pointer, @ref iterator, etc ...)
15634 - @ref @ref json_serializer<U> has a
15635 `to_json(basic_json_t&, CompatibleType&&)` method
15636
15637 @tparam U = `uncvref_t<CompatibleType>`
15638
15639 @param[in] val the value to be forwarded to the respective constructor
15640
15641 @complexity Usually linear in the size of the passed @a val, also
15642 depending on the implementation of the called `to_json()`
15643 method.
15644
15645 @exceptionsafety Depends on the called constructor. For types directly
15646 supported by the library (i.e., all types for which no `to_json()` function
15647 was provided), strong guarantee holds: if an exception is thrown, there are
15648 no changes to any JSON value.
15649
15650 @liveexample{The following code shows the constructor with several
15651 compatible types.,basic_json__CompatibleType}
15652
15653 @since version 2.1.0
15654 */
15655 template <typename CompatibleType,
15656 typename U = detail::uncvref_t<CompatibleType>,
15657 detail::enable_if_t<
15658 not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
15659 basic_json(CompatibleType && val) noexcept(noexcept(
15660 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
15661 std::forward<CompatibleType>(val))))
15662 {
15663 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
15664 assert_invariant();
15665 }
15666
15667 /*!
15668 @brief create a JSON value from an existing one
15669
15670 This is a constructor for existing @ref basic_json types.
15671 It does not hijack copy/move constructors, since the parameter has different
15672 template arguments than the current ones.
15673
15674 The constructor tries to convert the internal @ref m_value of the parameter.
15675
15676 @tparam BasicJsonType a type such that:
15677 - @a BasicJsonType is a @ref basic_json type.
15678 - @a BasicJsonType has different template arguments than @ref basic_json_t.
15679
15680 @param[in] val the @ref basic_json value to be converted.
15681
15682 @complexity Usually linear in the size of the passed @a val, also
15683 depending on the implementation of the called `to_json()`
15684 method.
15685
15686 @exceptionsafety Depends on the called constructor. For types directly
15687 supported by the library (i.e., all types for which no `to_json()` function
15688 was provided), strong guarantee holds: if an exception is thrown, there are
15689 no changes to any JSON value.
15690
15691 @since version 3.2.0
15692 */
15693 template <typename BasicJsonType,
15694 detail::enable_if_t<
15695 detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
15696 basic_json(const BasicJsonType& val)
15697 {
15698 using other_boolean_t = typename BasicJsonType::boolean_t;
15699 using other_number_float_t = typename BasicJsonType::number_float_t;
15700 using other_number_integer_t = typename BasicJsonType::number_integer_t;
15701 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
15702 using other_string_t = typename BasicJsonType::string_t;
15703 using other_object_t = typename BasicJsonType::object_t;
15704 using other_array_t = typename BasicJsonType::array_t;
15705
15706 switch (val.type())
15707 {
15708 case value_t::boolean:
15709 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
15710 break;
15711 case value_t::number_float:
15712 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
15713 break;
15714 case value_t::number_integer:
15715 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
15716 break;
15717 case value_t::number_unsigned:
15718 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
15719 break;
15720 case value_t::string:
15721 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
15722 break;
15723 case value_t::object:
15724 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
15725 break;
15726 case value_t::array:
15727 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
15728 break;
15729 case value_t::null:
15730 *this = nullptr;
15731 break;
15732 case value_t::discarded:
15733 m_type = value_t::discarded;
15734 break;
15735 default: // LCOV_EXCL_LINE
15736 assert(false); // LCOV_EXCL_LINE
15737 }
15738 assert_invariant();
15739 }
15740
15741 /*!
15742 @brief create a container (array or object) from an initializer list
15743
15744 Creates a JSON value of type array or object from the passed initializer
15745 list @a init. In case @a type_deduction is `true` (default), the type of
15746 the JSON value to be created is deducted from the initializer list @a init
15747 according to the following rules:
15748
15749 1. If the list is empty, an empty JSON object value `{}` is created.
15750 2. If the list consists of pairs whose first element is a string, a JSON
15751 object value is created where the first elements of the pairs are
15752 treated as keys and the second elements are as values.
15753 3. In all other cases, an array is created.
15754
15755 The rules aim to create the best fit between a C++ initializer list and
15756 JSON values. The rationale is as follows:
15757
15758 1. The empty initializer list is written as `{}` which is exactly an empty
15759 JSON object.
15760 2. C++ has no way of describing mapped types other than to list a list of
15761 pairs. As JSON requires that keys must be of type string, rule 2 is the
15762 weakest constraint one can pose on initializer lists to interpret them
15763 as an object.
15764 3. In all other cases, the initializer list could not be interpreted as
15765 JSON object type, so interpreting it as JSON array type is safe.
15766
15767 With the rules described above, the following JSON values cannot be
15768 expressed by an initializer list:
15769
15770 - the empty array (`[]`): use @ref array(initializer_list_t)
15771 with an empty initializer list in this case
15772 - arrays whose elements satisfy rule 2: use @ref
15773 array(initializer_list_t) with the same initializer list
15774 in this case
15775
15776 @note When used without parentheses around an empty initializer list, @ref
15777 basic_json() is called instead of this function, yielding the JSON null
15778 value.
15779
15780 @param[in] init initializer list with JSON values
15781
15782 @param[in] type_deduction internal parameter; when set to `true`, the type
15783 of the JSON value is deducted from the initializer list @a init; when set
15784 to `false`, the type provided via @a manual_type is forced. This mode is
15785 used by the functions @ref array(initializer_list_t) and
15786 @ref object(initializer_list_t).
15787
15788 @param[in] manual_type internal parameter; when @a type_deduction is set
15789 to `false`, the created JSON value will use the provided type (only @ref
15790 value_t::array and @ref value_t::object are valid); when @a type_deduction
15791 is set to `true`, this parameter has no effect
15792
15793 @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
15794 `value_t::object`, but @a init contains an element which is not a pair
15795 whose first element is a string. In this case, the constructor could not
15796 create an object. If @a type_deduction would have be `true`, an array
15797 would have been created. See @ref object(initializer_list_t)
15798 for an example.
15799
15800 @complexity Linear in the size of the initializer list @a init.
15801
15802 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15803 changes to any JSON value.
15804
15805 @liveexample{The example below shows how JSON values are created from
15806 initializer lists.,basic_json__list_init_t}
15807
15808 @sa @ref array(initializer_list_t) -- create a JSON array
15809 value from an initializer list
15810 @sa @ref object(initializer_list_t) -- create a JSON object
15811 value from an initializer list
15812
15813 @since version 1.0.0
15814 */
15815 basic_json(initializer_list_t init,
15816 bool type_deduction = true,
15817 value_t manual_type = value_t::array)
15818 {
15819 // check if each element is an array with two elements whose first
15820 // element is a string
15821 bool is_an_object = std::all_of(init.begin(), init.end(),
15822 [](const detail::json_ref<basic_json>& element_ref)
15823 {
15824 return element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string();
15825 });
15826
15827 // adjust type if type deduction is not wanted
15828 if (not type_deduction)
15829 {
15830 // if array is wanted, do not create an object though possible
15831 if (manual_type == value_t::array)
15832 {
15833 is_an_object = false;
15834 }
15835
15836 // if object is wanted but impossible, throw an exception
15837 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object and not is_an_object))
15838 {
15839 JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
15840 }
15841 }
15842
15843 if (is_an_object)
15844 {
15845 // the initializer list is a list of pairs -> create object
15846 m_type = value_t::object;
15847 m_value = value_t::object;
15848
15849 std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
15850 {
15851 auto element = element_ref.moved_or_copied();
15852 m_value.object->emplace(
15853 std::move(*((*element.m_value.array)[0].m_value.string)),
15854 std::move((*element.m_value.array)[1]));
15855 });
15856 }
15857 else
15858 {
15859 // the initializer list describes an array -> create array
15860 m_type = value_t::array;
15861 m_value.array = create<array_t>(init.begin(), init.end());
15862 }
15863
15864 assert_invariant();
15865 }
15866
15867 /*!
15868 @brief explicitly create an array from an initializer list
15869
15870 Creates a JSON array value from a given initializer list. That is, given a
15871 list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
15872 initializer list is empty, the empty array `[]` is created.
15873
15874 @note This function is only needed to express two edge cases that cannot
15875 be realized with the initializer list constructor (@ref
15876 basic_json(initializer_list_t, bool, value_t)). These cases
15877 are:
15878 1. creating an array whose elements are all pairs whose first element is a
15879 string -- in this case, the initializer list constructor would create an
15880 object, taking the first elements as keys
15881 2. creating an empty array -- passing the empty initializer list to the
15882 initializer list constructor yields an empty object
15883
15884 @param[in] init initializer list with JSON values to create an array from
15885 (optional)
15886
15887 @return JSON array value
15888
15889 @complexity Linear in the size of @a init.
15890
15891 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15892 changes to any JSON value.
15893
15894 @liveexample{The following code shows an example for the `array`
15895 function.,array}
15896
15897 @sa @ref basic_json(initializer_list_t, bool, value_t) --
15898 create a JSON value from an initializer list
15899 @sa @ref object(initializer_list_t) -- create a JSON object
15900 value from an initializer list
15901
15902 @since version 1.0.0
15903 */
15904 JSON_HEDLEY_WARN_UNUSED_RESULT
15905 static basic_json array(initializer_list_t init = {})
15906 {
15907 return basic_json(init, false, value_t::array);
15908 }
15909
15910 /*!
15911 @brief explicitly create an object from an initializer list
15912
15913 Creates a JSON object value from a given initializer list. The initializer
15914 lists elements must be pairs, and their first elements must be strings. If
15915 the initializer list is empty, the empty object `{}` is created.
15916
15917 @note This function is only added for symmetry reasons. In contrast to the
15918 related function @ref array(initializer_list_t), there are
15919 no cases which can only be expressed by this function. That is, any
15920 initializer list @a init can also be passed to the initializer list
15921 constructor @ref basic_json(initializer_list_t, bool, value_t).
15922
15923 @param[in] init initializer list to create an object from (optional)
15924
15925 @return JSON object value
15926
15927 @throw type_error.301 if @a init is not a list of pairs whose first
15928 elements are strings. In this case, no object can be created. When such a
15929 value is passed to @ref basic_json(initializer_list_t, bool, value_t),
15930 an array would have been created from the passed initializer list @a init.
15931 See example below.
15932
15933 @complexity Linear in the size of @a init.
15934
15935 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15936 changes to any JSON value.
15937
15938 @liveexample{The following code shows an example for the `object`
15939 function.,object}
15940
15941 @sa @ref basic_json(initializer_list_t, bool, value_t) --
15942 create a JSON value from an initializer list
15943 @sa @ref array(initializer_list_t) -- create a JSON array
15944 value from an initializer list
15945
15946 @since version 1.0.0
15947 */
15948 JSON_HEDLEY_WARN_UNUSED_RESULT
15949 static basic_json object(initializer_list_t init = {})
15950 {
15951 return basic_json(init, false, value_t::object);
15952 }
15953
15954 /*!
15955 @brief construct an array with count copies of given value
15956
15957 Constructs a JSON array value by creating @a cnt copies of a passed value.
15958 In case @a cnt is `0`, an empty array is created.
15959
15960 @param[in] cnt the number of JSON copies of @a val to create
15961 @param[in] val the JSON value to copy
15962
15963 @post `std::distance(begin(),end()) == cnt` holds.
15964
15965 @complexity Linear in @a cnt.
15966
15967 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15968 changes to any JSON value.
15969
15970 @liveexample{The following code shows examples for the @ref
15971 basic_json(size_type\, const basic_json&)
15972 constructor.,basic_json__size_type_basic_json}
15973
15974 @since version 1.0.0
15975 */
15976 basic_json(size_type cnt, const basic_json& val)
15977 : m_type(value_t::array)
15978 {
15979 m_value.array = create<array_t>(cnt, val);
15980 assert_invariant();
15981 }
15982
15983 /*!
15984 @brief construct a JSON container given an iterator range
15985
15986 Constructs the JSON value with the contents of the range `[first, last)`.
15987 The semantics depends on the different types a JSON value can have:
15988 - In case of a null type, invalid_iterator.206 is thrown.
15989 - In case of other primitive types (number, boolean, or string), @a first
15990 must be `begin()` and @a last must be `end()`. In this case, the value is
15991 copied. Otherwise, invalid_iterator.204 is thrown.
15992 - In case of structured types (array, object), the constructor behaves as
15993 similar versions for `std::vector` or `std::map`; that is, a JSON array
15994 or object is constructed from the values in the range.
15995
15996 @tparam InputIT an input iterator type (@ref iterator or @ref
15997 const_iterator)
15998
15999 @param[in] first begin of the range to copy from (included)
16000 @param[in] last end of the range to copy from (excluded)
16001
16002 @pre Iterators @a first and @a last must be initialized. **This
16003 precondition is enforced with an assertion (see warning).** If
16004 assertions are switched off, a violation of this precondition yields
16005 undefined behavior.
16006
16007 @pre Range `[first, last)` is valid. Usually, this precondition cannot be
16008 checked efficiently. Only certain edge cases are detected; see the
16009 description of the exceptions below. A violation of this precondition
16010 yields undefined behavior.
16011
16012 @warning A precondition is enforced with a runtime assertion that will
16013 result in calling `std::abort` if this precondition is not met.
16014 Assertions can be disabled by defining `NDEBUG` at compile time.
16015 See https://en.cppreference.com/w/cpp/error/assert for more
16016 information.
16017
16018 @throw invalid_iterator.201 if iterators @a first and @a last are not
16019 compatible (i.e., do not belong to the same JSON value). In this case,
16020 the range `[first, last)` is undefined.
16021 @throw invalid_iterator.204 if iterators @a first and @a last belong to a
16022 primitive type (number, boolean, or string), but @a first does not point
16023 to the first element any more. In this case, the range `[first, last)` is
16024 undefined. See example code below.
16025 @throw invalid_iterator.206 if iterators @a first and @a last belong to a
16026 null value. In this case, the range `[first, last)` is undefined.
16027
16028 @complexity Linear in distance between @a first and @a last.
16029
16030 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
16031 changes to any JSON value.
16032
16033 @liveexample{The example below shows several ways to create JSON values by
16034 specifying a subrange with iterators.,basic_json__InputIt_InputIt}
16035
16036 @since version 1.0.0
16037 */
16038 template<class InputIT, typename std::enable_if<
16039 std::is_same<InputIT, typename basic_json_t::iterator>::value or
16040 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
16041 basic_json(InputIT first, InputIT last)
16042 {
16043 assert(first.m_object != nullptr);
16044 assert(last.m_object != nullptr);
16045
16046 // make sure iterator fits the current value
16047 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
16048 {
16049 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
16050 }
16051
16052 // copy type from first iterator
16053 m_type = first.m_object->m_type;
16054
16055 // check if iterator range is complete for primitive values
16056 switch (m_type)
16057 {
16058 case value_t::boolean:
16059 case value_t::number_float:
16060 case value_t::number_integer:
16061 case value_t::number_unsigned:
16062 case value_t::string:
16063 {
16064 if (JSON_HEDLEY_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
16065 or not last.m_it.primitive_iterator.is_end()))
16066 {
16067 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
16068 }
16069 break;
16070 }
16071
16072 default:
16073 break;
16074 }
16075
16076 switch (m_type)
16077 {
16078 case value_t::number_integer:
16079 {
16080 m_value.number_integer = first.m_object->m_value.number_integer;
16081 break;
16082 }
16083
16084 case value_t::number_unsigned:
16085 {
16086 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
16087 break;
16088 }
16089
16090 case value_t::number_float:
16091 {
16092 m_value.number_float = first.m_object->m_value.number_float;
16093 break;
16094 }
16095
16096 case value_t::boolean:
16097 {
16098 m_value.boolean = first.m_object->m_value.boolean;
16099 break;
16100 }
16101
16102 case value_t::string:
16103 {
16104 m_value = *first.m_object->m_value.string;
16105 break;
16106 }
16107
16108 case value_t::object:
16109 {
16110 m_value.object = create<object_t>(first.m_it.object_iterator,
16111 last.m_it.object_iterator);
16112 break;
16113 }
16114
16115 case value_t::array:
16116 {
16117 m_value.array = create<array_t>(first.m_it.array_iterator,
16118 last.m_it.array_iterator);
16119 break;
16120 }
16121
16122 default:
16123 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
16124 std::string(first.m_object->type_name())));
16125 }
16126
16127 assert_invariant();
16128 }
16129
16130
16131 ///////////////////////////////////////
16132 // other constructors and destructor //
16133 ///////////////////////////////////////
16134
16135 /// @private
16136 basic_json(const detail::json_ref<basic_json>& ref)
16137 : basic_json(ref.moved_or_copied())
16138 {}
16139
16140 /*!
16141 @brief copy constructor
16142
16143 Creates a copy of a given JSON value.
16144
16145 @param[in] other the JSON value to copy
16146
16147 @post `*this == other`
16148
16149 @complexity Linear in the size of @a other.
16150
16151 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
16152 changes to any JSON value.
16153
16154 @requirement This function helps `basic_json` satisfying the
16155 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
16156 requirements:
16157 - The complexity is linear.
16158 - As postcondition, it holds: `other == basic_json(other)`.
16159
16160 @liveexample{The following code shows an example for the copy
16161 constructor.,basic_json__basic_json}
16162
16163 @since version 1.0.0
16164 */
16165 basic_json(const basic_json& other)
16166 : m_type(other.m_type)
16167 {
16168 // check of passed value is valid
16169 other.assert_invariant();
16170
16171 switch (m_type)
16172 {
16173 case value_t::object:
16174 {
16175 m_value = *other.m_value.object;
16176 break;
16177 }
16178
16179 case value_t::array:
16180 {
16181 m_value = *other.m_value.array;
16182 break;
16183 }
16184
16185 case value_t::string:
16186 {
16187 m_value = *other.m_value.string;
16188 break;
16189 }
16190
16191 case value_t::boolean:
16192 {
16193 m_value = other.m_value.boolean;
16194 break;
16195 }
16196
16197 case value_t::number_integer:
16198 {
16199 m_value = other.m_value.number_integer;
16200 break;
16201 }
16202
16203 case value_t::number_unsigned:
16204 {
16205 m_value = other.m_value.number_unsigned;
16206 break;
16207 }
16208
16209 case value_t::number_float:
16210 {
16211 m_value = other.m_value.number_float;
16212 break;
16213 }
16214
16215 default:
16216 break;
16217 }
16218
16219 assert_invariant();
16220 }
16221
16222 /*!
16223 @brief move constructor
16224
16225 Move constructor. Constructs a JSON value with the contents of the given
16226 value @a other using move semantics. It "steals" the resources from @a
16227 other and leaves it as JSON null value.
16228
16229 @param[in,out] other value to move to this object
16230
16231 @post `*this` has the same value as @a other before the call.
16232 @post @a other is a JSON null value.
16233
16234 @complexity Constant.
16235
16236 @exceptionsafety No-throw guarantee: this constructor never throws
16237 exceptions.
16238
16239 @requirement This function helps `basic_json` satisfying the
16240 [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
16241 requirements.
16242
16243 @liveexample{The code below shows the move constructor explicitly called
16244 via std::move.,basic_json__moveconstructor}
16245
16246 @since version 1.0.0
16247 */
16248 basic_json(basic_json&& other) noexcept
16249 : m_type(std::move(other.m_type)),
16250 m_value(std::move(other.m_value))
16251 {
16252 // check that passed value is valid
16253 other.assert_invariant();
16254
16255 // invalidate payload
16256 other.m_type = value_t::null;
16257 other.m_value = {};
16258
16259 assert_invariant();
16260 }
16261
16262 /*!
16263 @brief copy assignment
16264
16265 Copy assignment operator. Copies a JSON value via the "copy and swap"
16266 strategy: It is expressed in terms of the copy constructor, destructor,
16267 and the `swap()` member function.
16268
16269 @param[in] other value to copy from
16270
16271 @complexity Linear.
16272
16273 @requirement This function helps `basic_json` satisfying the
16274 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
16275 requirements:
16276 - The complexity is linear.
16277
16278 @liveexample{The code below shows and example for the copy assignment. It
16279 creates a copy of value `a` which is then swapped with `b`. Finally\, the
16280 copy of `a` (which is the null value after the swap) is
16281 destroyed.,basic_json__copyassignment}
16282
16283 @since version 1.0.0
16284 */
16285 basic_json& operator=(basic_json other) noexcept (
16286 std::is_nothrow_move_constructible<value_t>::value and
16287 std::is_nothrow_move_assignable<value_t>::value and
16288 std::is_nothrow_move_constructible<json_value>::value and
16289 std::is_nothrow_move_assignable<json_value>::value
16290 )
16291 {
16292 // check that passed value is valid
16293 other.assert_invariant();
16294
16295 using std::swap;
16296 swap(m_type, other.m_type);
16297 swap(m_value, other.m_value);
16298
16299 assert_invariant();
16300 return *this;
16301 }
16302
16303 /*!
16304 @brief destructor
16305
16306 Destroys the JSON value and frees all allocated memory.
16307
16308 @complexity Linear.
16309
16310 @requirement This function helps `basic_json` satisfying the
16311 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
16312 requirements:
16313 - The complexity is linear.
16314 - All stored elements are destroyed and all memory is freed.
16315
16316 @since version 1.0.0
16317 */
16318 ~basic_json() noexcept
16319 {
16320 assert_invariant();
16321 m_value.destroy(m_type);
16322 }
16323
16324 /// @}
16325
16326 public:
16327 ///////////////////////
16328 // object inspection //
16329 ///////////////////////
16330
16331 /// @name object inspection
16332 /// Functions to inspect the type of a JSON value.
16333 /// @{
16334
16335 /*!
16336 @brief serialization
16337
16338 Serialization function for JSON values. The function tries to mimic
16339 Python's `json.dumps()` function, and currently supports its @a indent
16340 and @a ensure_ascii parameters.
16341
16342 @param[in] indent If indent is nonnegative, then array elements and object
16343 members will be pretty-printed with that indent level. An indent level of
16344 `0` will only insert newlines. `-1` (the default) selects the most compact
16345 representation.
16346 @param[in] indent_char The character to use for indentation if @a indent is
16347 greater than `0`. The default is ` ` (space).
16348 @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
16349 in the output are escaped with `\uXXXX` sequences, and the result consists
16350 of ASCII characters only.
16351 @param[in] error_handler how to react on decoding errors; there are three
16352 possible values: `strict` (throws and exception in case a decoding error
16353 occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
16354 and `ignore` (ignore invalid UTF-8 sequences during serialization).
16355
16356 @return string containing the serialization of the JSON value
16357
16358 @throw type_error.316 if a string stored inside the JSON value is not
16359 UTF-8 encoded
16360
16361 @complexity Linear.
16362
16363 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
16364 changes in the JSON value.
16365
16366 @liveexample{The following example shows the effect of different @a indent\,
16367 @a indent_char\, and @a ensure_ascii parameters to the result of the
16368 serialization.,dump}
16369
16370 @see https://docs.python.org/2/library/json.html#json.dump
16371
16372 @since version 1.0.0; indentation character @a indent_char, option
16373 @a ensure_ascii and exceptions added in version 3.0.0; error
16374 handlers added in version 3.4.0.
16375 */
16376 string_t dump(const int indent = -1,
16377 const char indent_char = ' ',
16378 const bool ensure_ascii = false,
16379 const error_handler_t error_handler = error_handler_t::strict) const
16380 {
16381 string_t result;
16382 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
16383
16384 if (indent >= 0)
16385 {
16386 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
16387 }
16388 else
16389 {
16390 s.dump(*this, false, ensure_ascii, 0);
16391 }
16392
16393 return result;
16394 }
16395
16396 /*!
16397 @brief return the type of the JSON value (explicit)
16398
16399 Return the type of the JSON value as a value from the @ref value_t
16400 enumeration.
16401
16402 @return the type of the JSON value
16403 Value type | return value
16404 ------------------------- | -------------------------
16405 null | value_t::null
16406 boolean | value_t::boolean
16407 string | value_t::string
16408 number (integer) | value_t::number_integer
16409 number (unsigned integer) | value_t::number_unsigned
16410 number (floating-point) | value_t::number_float
16411 object | value_t::object
16412 array | value_t::array
16413 discarded | value_t::discarded
16414
16415 @complexity Constant.
16416
16417 @exceptionsafety No-throw guarantee: this member function never throws
16418 exceptions.
16419
16420 @liveexample{The following code exemplifies `type()` for all JSON
16421 types.,type}
16422
16423 @sa @ref operator value_t() -- return the type of the JSON value (implicit)
16424 @sa @ref type_name() -- return the type as string
16425
16426 @since version 1.0.0
16427 */
16428 constexpr value_t type() const noexcept
16429 {
16430 return m_type;
16431 }
16432
16433 /*!
16434 @brief return whether type is primitive
16435
16436 This function returns true if and only if the JSON type is primitive
16437 (string, number, boolean, or null).
16438
16439 @return `true` if type is primitive (string, number, boolean, or null),
16440 `false` otherwise.
16441
16442 @complexity Constant.
16443
16444 @exceptionsafety No-throw guarantee: this member function never throws
16445 exceptions.
16446
16447 @liveexample{The following code exemplifies `is_primitive()` for all JSON
16448 types.,is_primitive}
16449
16450 @sa @ref is_structured() -- returns whether JSON value is structured
16451 @sa @ref is_null() -- returns whether JSON value is `null`
16452 @sa @ref is_string() -- returns whether JSON value is a string
16453 @sa @ref is_boolean() -- returns whether JSON value is a boolean
16454 @sa @ref is_number() -- returns whether JSON value is a number
16455
16456 @since version 1.0.0
16457 */
16458 constexpr bool is_primitive() const noexcept
16459 {
16460 return is_null() or is_string() or is_boolean() or is_number();
16461 }
16462
16463 /*!
16464 @brief return whether type is structured
16465
16466 This function returns true if and only if the JSON type is structured
16467 (array or object).
16468
16469 @return `true` if type is structured (array or object), `false` otherwise.
16470
16471 @complexity Constant.
16472
16473 @exceptionsafety No-throw guarantee: this member function never throws
16474 exceptions.
16475
16476 @liveexample{The following code exemplifies `is_structured()` for all JSON
16477 types.,is_structured}
16478
16479 @sa @ref is_primitive() -- returns whether value is primitive
16480 @sa @ref is_array() -- returns whether value is an array
16481 @sa @ref is_object() -- returns whether value is an object
16482
16483 @since version 1.0.0
16484 */
16485 constexpr bool is_structured() const noexcept
16486 {
16487 return is_array() or is_object();
16488 }
16489
16490 /*!
16491 @brief return whether value is null
16492
16493 This function returns true if and only if the JSON value is null.
16494
16495 @return `true` if type is null, `false` otherwise.
16496
16497 @complexity Constant.
16498
16499 @exceptionsafety No-throw guarantee: this member function never throws
16500 exceptions.
16501
16502 @liveexample{The following code exemplifies `is_null()` for all JSON
16503 types.,is_null}
16504
16505 @since version 1.0.0
16506 */
16507 constexpr bool is_null() const noexcept
16508 {
16509 return m_type == value_t::null;
16510 }
16511
16512 /*!
16513 @brief return whether value is a boolean
16514
16515 This function returns true if and only if the JSON value is a boolean.
16516
16517 @return `true` if type is boolean, `false` otherwise.
16518
16519 @complexity Constant.
16520
16521 @exceptionsafety No-throw guarantee: this member function never throws
16522 exceptions.
16523
16524 @liveexample{The following code exemplifies `is_boolean()` for all JSON
16525 types.,is_boolean}
16526
16527 @since version 1.0.0
16528 */
16529 constexpr bool is_boolean() const noexcept
16530 {
16531 return m_type == value_t::boolean;
16532 }
16533
16534 /*!
16535 @brief return whether value is a number
16536
16537 This function returns true if and only if the JSON value is a number. This
16538 includes both integer (signed and unsigned) and floating-point values.
16539
16540 @return `true` if type is number (regardless whether integer, unsigned
16541 integer or floating-type), `false` otherwise.
16542
16543 @complexity Constant.
16544
16545 @exceptionsafety No-throw guarantee: this member function never throws
16546 exceptions.
16547
16548 @liveexample{The following code exemplifies `is_number()` for all JSON
16549 types.,is_number}
16550
16551 @sa @ref is_number_integer() -- check if value is an integer or unsigned
16552 integer number
16553 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
16554 number
16555 @sa @ref is_number_float() -- check if value is a floating-point number
16556
16557 @since version 1.0.0
16558 */
16559 constexpr bool is_number() const noexcept
16560 {
16561 return is_number_integer() or is_number_float();
16562 }
16563
16564 /*!
16565 @brief return whether value is an integer number
16566
16567 This function returns true if and only if the JSON value is a signed or
16568 unsigned integer number. This excludes floating-point values.
16569
16570 @return `true` if type is an integer or unsigned integer number, `false`
16571 otherwise.
16572
16573 @complexity Constant.
16574
16575 @exceptionsafety No-throw guarantee: this member function never throws
16576 exceptions.
16577
16578 @liveexample{The following code exemplifies `is_number_integer()` for all
16579 JSON types.,is_number_integer}
16580
16581 @sa @ref is_number() -- check if value is a number
16582 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
16583 number
16584 @sa @ref is_number_float() -- check if value is a floating-point number
16585
16586 @since version 1.0.0
16587 */
16588 constexpr bool is_number_integer() const noexcept
16589 {
16590 return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
16591 }
16592
16593 /*!
16594 @brief return whether value is an unsigned integer number
16595
16596 This function returns true if and only if the JSON value is an unsigned
16597 integer number. This excludes floating-point and signed integer values.
16598
16599 @return `true` if type is an unsigned integer number, `false` otherwise.
16600
16601 @complexity Constant.
16602
16603 @exceptionsafety No-throw guarantee: this member function never throws
16604 exceptions.
16605
16606 @liveexample{The following code exemplifies `is_number_unsigned()` for all
16607 JSON types.,is_number_unsigned}
16608
16609 @sa @ref is_number() -- check if value is a number
16610 @sa @ref is_number_integer() -- check if value is an integer or unsigned
16611 integer number
16612 @sa @ref is_number_float() -- check if value is a floating-point number
16613
16614 @since version 2.0.0
16615 */
16616 constexpr bool is_number_unsigned() const noexcept
16617 {
16618 return m_type == value_t::number_unsigned;
16619 }
16620
16621 /*!
16622 @brief return whether value is a floating-point number
16623
16624 This function returns true if and only if the JSON value is a
16625 floating-point number. This excludes signed and unsigned integer values.
16626
16627 @return `true` if type is a floating-point number, `false` otherwise.
16628
16629 @complexity Constant.
16630
16631 @exceptionsafety No-throw guarantee: this member function never throws
16632 exceptions.
16633
16634 @liveexample{The following code exemplifies `is_number_float()` for all
16635 JSON types.,is_number_float}
16636
16637 @sa @ref is_number() -- check if value is number
16638 @sa @ref is_number_integer() -- check if value is an integer number
16639 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
16640 number
16641
16642 @since version 1.0.0
16643 */
16644 constexpr bool is_number_float() const noexcept
16645 {
16646 return m_type == value_t::number_float;
16647 }
16648
16649 /*!
16650 @brief return whether value is an object
16651
16652 This function returns true if and only if the JSON value is an object.
16653
16654 @return `true` if type is object, `false` otherwise.
16655
16656 @complexity Constant.
16657
16658 @exceptionsafety No-throw guarantee: this member function never throws
16659 exceptions.
16660
16661 @liveexample{The following code exemplifies `is_object()` for all JSON
16662 types.,is_object}
16663
16664 @since version 1.0.0
16665 */
16666 constexpr bool is_object() const noexcept
16667 {
16668 return m_type == value_t::object;
16669 }
16670
16671 /*!
16672 @brief return whether value is an array
16673
16674 This function returns true if and only if the JSON value is an array.
16675
16676 @return `true` if type is array, `false` otherwise.
16677
16678 @complexity Constant.
16679
16680 @exceptionsafety No-throw guarantee: this member function never throws
16681 exceptions.
16682
16683 @liveexample{The following code exemplifies `is_array()` for all JSON
16684 types.,is_array}
16685
16686 @since version 1.0.0
16687 */
16688 constexpr bool is_array() const noexcept
16689 {
16690 return m_type == value_t::array;
16691 }
16692
16693 /*!
16694 @brief return whether value is a string
16695
16696 This function returns true if and only if the JSON value is a string.
16697
16698 @return `true` if type is string, `false` otherwise.
16699
16700 @complexity Constant.
16701
16702 @exceptionsafety No-throw guarantee: this member function never throws
16703 exceptions.
16704
16705 @liveexample{The following code exemplifies `is_string()` for all JSON
16706 types.,is_string}
16707
16708 @since version 1.0.0
16709 */
16710 constexpr bool is_string() const noexcept
16711 {
16712 return m_type == value_t::string;
16713 }
16714
16715 /*!
16716 @brief return whether value is discarded
16717
16718 This function returns true if and only if the JSON value was discarded
16719 during parsing with a callback function (see @ref parser_callback_t).
16720
16721 @note This function will always be `false` for JSON values after parsing.
16722 That is, discarded values can only occur during parsing, but will be
16723 removed when inside a structured value or replaced by null in other cases.
16724
16725 @return `true` if type is discarded, `false` otherwise.
16726
16727 @complexity Constant.
16728
16729 @exceptionsafety No-throw guarantee: this member function never throws
16730 exceptions.
16731
16732 @liveexample{The following code exemplifies `is_discarded()` for all JSON
16733 types.,is_discarded}
16734
16735 @since version 1.0.0
16736 */
16737 constexpr bool is_discarded() const noexcept
16738 {
16739 return m_type == value_t::discarded;
16740 }
16741
16742 /*!
16743 @brief return the type of the JSON value (implicit)
16744
16745 Implicitly return the type of the JSON value as a value from the @ref
16746 value_t enumeration.
16747
16748 @return the type of the JSON value
16749
16750 @complexity Constant.
16751
16752 @exceptionsafety No-throw guarantee: this member function never throws
16753 exceptions.
16754
16755 @liveexample{The following code exemplifies the @ref value_t operator for
16756 all JSON types.,operator__value_t}
16757
16758 @sa @ref type() -- return the type of the JSON value (explicit)
16759 @sa @ref type_name() -- return the type as string
16760
16761 @since version 1.0.0
16762 */
16763 constexpr operator value_t() const noexcept
16764 {
16765 return m_type;
16766 }
16767
16768 /// @}
16769
16770 private:
16771 //////////////////
16772 // value access //
16773 //////////////////
16774
16775 /// get a boolean (explicit)
16776 boolean_t get_impl(boolean_t* /*unused*/) const
16777 {
16778 if (JSON_HEDLEY_LIKELY(is_boolean()))
16779 {
16780 return m_value.boolean;
16781 }
16782
16783 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
16784 }
16785
16786 /// get a pointer to the value (object)
16787 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
16788 {
16789 return is_object() ? m_value.object : nullptr;
16790 }
16791
16792 /// get a pointer to the value (object)
16793 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
16794 {
16795 return is_object() ? m_value.object : nullptr;
16796 }
16797
16798 /// get a pointer to the value (array)
16799 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
16800 {
16801 return is_array() ? m_value.array : nullptr;
16802 }
16803
16804 /// get a pointer to the value (array)
16805 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
16806 {
16807 return is_array() ? m_value.array : nullptr;
16808 }
16809
16810 /// get a pointer to the value (string)
16811 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
16812 {
16813 return is_string() ? m_value.string : nullptr;
16814 }
16815
16816 /// get a pointer to the value (string)
16817 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
16818 {
16819 return is_string() ? m_value.string : nullptr;
16820 }
16821
16822 /// get a pointer to the value (boolean)
16823 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
16824 {
16825 return is_boolean() ? &m_value.boolean : nullptr;
16826 }
16827
16828 /// get a pointer to the value (boolean)
16829 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
16830 {
16831 return is_boolean() ? &m_value.boolean : nullptr;
16832 }
16833
16834 /// get a pointer to the value (integer number)
16835 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
16836 {
16837 return is_number_integer() ? &m_value.number_integer : nullptr;
16838 }
16839
16840 /// get a pointer to the value (integer number)
16841 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
16842 {
16843 return is_number_integer() ? &m_value.number_integer : nullptr;
16844 }
16845
16846 /// get a pointer to the value (unsigned number)
16847 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
16848 {
16849 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
16850 }
16851
16852 /// get a pointer to the value (unsigned number)
16853 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
16854 {
16855 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
16856 }
16857
16858 /// get a pointer to the value (floating-point number)
16859 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
16860 {
16861 return is_number_float() ? &m_value.number_float : nullptr;
16862 }
16863
16864 /// get a pointer to the value (floating-point number)
16865 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
16866 {
16867 return is_number_float() ? &m_value.number_float : nullptr;
16868 }
16869
16870 /*!
16871 @brief helper function to implement get_ref()
16872
16873 This function helps to implement get_ref() without code duplication for
16874 const and non-const overloads
16875
16876 @tparam ThisType will be deduced as `basic_json` or `const basic_json`
16877
16878 @throw type_error.303 if ReferenceType does not match underlying value
16879 type of the current JSON
16880 */
16881 template<typename ReferenceType, typename ThisType>
16882 static ReferenceType get_ref_impl(ThisType& obj)
16883 {
16884 // delegate the call to get_ptr<>()
16885 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
16886
16887 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
16888 {
16889 return *ptr;
16890 }
16891
16892 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
16893 }
16894
16895 public:
16896 /// @name value access
16897 /// Direct access to the stored value of a JSON value.
16898 /// @{
16899
16900 /*!
16901 @brief get special-case overload
16902
16903 This overloads avoids a lot of template boilerplate, it can be seen as the
16904 identity method
16905
16906 @tparam BasicJsonType == @ref basic_json
16907
16908 @return a copy of *this
16909
16910 @complexity Constant.
16911
16912 @since version 2.1.0
16913 */
16914 template<typename BasicJsonType, detail::enable_if_t<
16915 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
16916 int> = 0>
16917 basic_json get() const
16918 {
16919 return *this;
16920 }
16921
16922 /*!
16923 @brief get special-case overload
16924
16925 This overloads converts the current @ref basic_json in a different
16926 @ref basic_json type
16927
16928 @tparam BasicJsonType == @ref basic_json
16929
16930 @return a copy of *this, converted into @tparam BasicJsonType
16931
16932 @complexity Depending on the implementation of the called `from_json()`
16933 method.
16934
16935 @since version 3.2.0
16936 */
16937 template<typename BasicJsonType, detail::enable_if_t<
16938 not std::is_same<BasicJsonType, basic_json>::value and
16939 detail::is_basic_json<BasicJsonType>::value, int> = 0>
16940 BasicJsonType get() const
16941 {
16942 return *this;
16943 }
16944
16945 /*!
16946 @brief get a value (explicit)
16947
16948 Explicit type conversion between the JSON value and a compatible value
16949 which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
16950 and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
16951 The value is converted by calling the @ref json_serializer<ValueType>
16952 `from_json()` method.
16953
16954 The function is equivalent to executing
16955 @code {.cpp}
16956 ValueType ret;
16957 JSONSerializer<ValueType>::from_json(*this, ret);
16958 return ret;
16959 @endcode
16960
16961 This overloads is chosen if:
16962 - @a ValueType is not @ref basic_json,
16963 - @ref json_serializer<ValueType> has a `from_json()` method of the form
16964 `void from_json(const basic_json&, ValueType&)`, and
16965 - @ref json_serializer<ValueType> does not have a `from_json()` method of
16966 the form `ValueType from_json(const basic_json&)`
16967
16968 @tparam ValueTypeCV the provided value type
16969 @tparam ValueType the returned value type
16970
16971 @return copy of the JSON value, converted to @a ValueType
16972
16973 @throw what @ref json_serializer<ValueType> `from_json()` method throws
16974
16975 @liveexample{The example below shows several conversions from JSON values
16976 to other types. There a few things to note: (1) Floating-point numbers can
16977 be converted to integers\, (2) A JSON array can be converted to a standard
16978 `std::vector<short>`\, (3) A JSON object can be converted to C++
16979 associative containers such as `std::unordered_map<std::string\,
16980 json>`.,get__ValueType_const}
16981
16982 @since version 2.1.0
16983 */
16984 template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
16985 detail::enable_if_t <
16986 not detail::is_basic_json<ValueType>::value and
16987 detail::has_from_json<basic_json_t, ValueType>::value and
16988 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
16989 int> = 0>
16990 ValueType get() const noexcept(noexcept(
16991 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
16992 {
16993 // we cannot static_assert on ValueTypeCV being non-const, because
16994 // there is support for get<const basic_json_t>(), which is why we
16995 // still need the uncvref
16996 static_assert(not std::is_reference<ValueTypeCV>::value,
16997 "get() cannot be used with reference types, you might want to use get_ref()");
16998 static_assert(std::is_default_constructible<ValueType>::value,
16999 "types must be DefaultConstructible when used with get()");
17000
17001 ValueType ret;
17002 JSONSerializer<ValueType>::from_json(*this, ret);
17003 return ret;
17004 }
17005
17006 /*!
17007 @brief get a value (explicit); special case
17008
17009 Explicit type conversion between the JSON value and a compatible value
17010 which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
17011 and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
17012 The value is converted by calling the @ref json_serializer<ValueType>
17013 `from_json()` method.
17014
17015 The function is equivalent to executing
17016 @code {.cpp}
17017 return JSONSerializer<ValueTypeCV>::from_json(*this);
17018 @endcode
17019
17020 This overloads is chosen if:
17021 - @a ValueType is not @ref basic_json and
17022 - @ref json_serializer<ValueType> has a `from_json()` method of the form
17023 `ValueType from_json(const basic_json&)`
17024
17025 @note If @ref json_serializer<ValueType> has both overloads of
17026 `from_json()`, this one is chosen.
17027
17028 @tparam ValueTypeCV the provided value type
17029 @tparam ValueType the returned value type
17030
17031 @return copy of the JSON value, converted to @a ValueType
17032
17033 @throw what @ref json_serializer<ValueType> `from_json()` method throws
17034
17035 @since version 2.1.0
17036 */
17037 template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
17038 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
17039 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
17040 int> = 0>
17041 ValueType get() const noexcept(noexcept(
17042 JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
17043 {
17044 static_assert(not std::is_reference<ValueTypeCV>::value,
17045 "get() cannot be used with reference types, you might want to use get_ref()");
17046 return JSONSerializer<ValueTypeCV>::from_json(*this);
17047 }
17048
17049 /*!
17050 @brief get a value (explicit)
17051
17052 Explicit type conversion between the JSON value and a compatible value.
17053 The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
17054 `from_json()` method.
17055
17056 The function is equivalent to executing
17057 @code {.cpp}
17058 ValueType v;
17059 JSONSerializer<ValueType>::from_json(*this, v);
17060 @endcode
17061
17062 This overloads is chosen if:
17063 - @a ValueType is not @ref basic_json,
17064 - @ref json_serializer<ValueType> has a `from_json()` method of the form
17065 `void from_json(const basic_json&, ValueType&)`, and
17066
17067 @tparam ValueType the input parameter type.
17068
17069 @return the input parameter, allowing chaining calls.
17070
17071 @throw what @ref json_serializer<ValueType> `from_json()` method throws
17072
17073 @liveexample{The example below shows several conversions from JSON values
17074 to other types. There a few things to note: (1) Floating-point numbers can
17075 be converted to integers\, (2) A JSON array can be converted to a standard
17076 `std::vector<short>`\, (3) A JSON object can be converted to C++
17077 associative containers such as `std::unordered_map<std::string\,
17078 json>`.,get_to}
17079
17080 @since version 3.3.0
17081 */
17082 template<typename ValueType,
17083 detail::enable_if_t <
17084 not detail::is_basic_json<ValueType>::value and
17085 detail::has_from_json<basic_json_t, ValueType>::value,
17086 int> = 0>
17087 ValueType & get_to(ValueType& v) const noexcept(noexcept(
17088 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
17089 {
17090 JSONSerializer<ValueType>::from_json(*this, v);
17091 return v;
17092 }
17093
17094 template <
17095 typename T, std::size_t N,
17096 typename Array = T (&)[N],
17097 detail::enable_if_t <
17098 detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
17099 Array get_to(T (&v)[N]) const
17100 noexcept(noexcept(JSONSerializer<Array>::from_json(
17101 std::declval<const basic_json_t&>(), v)))
17102 {
17103 JSONSerializer<Array>::from_json(*this, v);
17104 return v;
17105 }
17106
17107
17108 /*!
17109 @brief get a pointer value (implicit)
17110
17111 Implicit pointer access to the internally stored JSON value. No copies are
17112 made.
17113
17114 @warning Writing data to the pointee of the result yields an undefined
17115 state.
17116
17117 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
17118 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
17119 @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
17120 assertion.
17121
17122 @return pointer to the internally stored JSON value if the requested
17123 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
17124
17125 @complexity Constant.
17126
17127 @liveexample{The example below shows how pointers to internal values of a
17128 JSON value can be requested. Note that no type conversions are made and a
17129 `nullptr` is returned if the value and the requested pointer type does not
17130 match.,get_ptr}
17131
17132 @since version 1.0.0
17133 */
17134 template<typename PointerType, typename std::enable_if<
17135 std::is_pointer<PointerType>::value, int>::type = 0>
17136 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
17137 {
17138 // delegate the call to get_impl_ptr<>()
17139 return get_impl_ptr(static_cast<PointerType>(nullptr));
17140 }
17141
17142 /*!
17143 @brief get a pointer value (implicit)
17144 @copydoc get_ptr()
17145 */
17146 template<typename PointerType, typename std::enable_if<
17147 std::is_pointer<PointerType>::value and
17148 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
17149 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
17150 {
17151 // delegate the call to get_impl_ptr<>() const
17152 return get_impl_ptr(static_cast<PointerType>(nullptr));
17153 }
17154
17155 /*!
17156 @brief get a pointer value (explicit)
17157
17158 Explicit pointer access to the internally stored JSON value. No copies are
17159 made.
17160
17161 @warning The pointer becomes invalid if the underlying JSON object
17162 changes.
17163
17164 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
17165 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
17166 @ref number_unsigned_t, or @ref number_float_t.
17167
17168 @return pointer to the internally stored JSON value if the requested
17169 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
17170
17171 @complexity Constant.
17172
17173 @liveexample{The example below shows how pointers to internal values of a
17174 JSON value can be requested. Note that no type conversions are made and a
17175 `nullptr` is returned if the value and the requested pointer type does not
17176 match.,get__PointerType}
17177
17178 @sa @ref get_ptr() for explicit pointer-member access
17179
17180 @since version 1.0.0
17181 */
17182 template<typename PointerType, typename std::enable_if<
17183 std::is_pointer<PointerType>::value, int>::type = 0>
17184 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
17185 {
17186 // delegate the call to get_ptr
17187 return get_ptr<PointerType>();
17188 }
17189
17190 /*!
17191 @brief get a pointer value (explicit)
17192 @copydoc get()
17193 */
17194 template<typename PointerType, typename std::enable_if<
17195 std::is_pointer<PointerType>::value, int>::type = 0>
17196 constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
17197 {
17198 // delegate the call to get_ptr
17199 return get_ptr<PointerType>();
17200 }
17201
17202 /*!
17203 @brief get a reference value (implicit)
17204
17205 Implicit reference access to the internally stored JSON value. No copies
17206 are made.
17207
17208 @warning Writing data to the referee of the result yields an undefined
17209 state.
17210
17211 @tparam ReferenceType reference type; must be a reference to @ref array_t,
17212 @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
17213 @ref number_float_t. Enforced by static assertion.
17214
17215 @return reference to the internally stored JSON value if the requested
17216 reference type @a ReferenceType fits to the JSON value; throws
17217 type_error.303 otherwise
17218
17219 @throw type_error.303 in case passed type @a ReferenceType is incompatible
17220 with the stored JSON value; see example below
17221
17222 @complexity Constant.
17223
17224 @liveexample{The example shows several calls to `get_ref()`.,get_ref}
17225
17226 @since version 1.1.0
17227 */
17228 template<typename ReferenceType, typename std::enable_if<
17229 std::is_reference<ReferenceType>::value, int>::type = 0>
17230 ReferenceType get_ref()
17231 {
17232 // delegate call to get_ref_impl
17233 return get_ref_impl<ReferenceType>(*this);
17234 }
17235
17236 /*!
17237 @brief get a reference value (implicit)
17238 @copydoc get_ref()
17239 */
17240 template<typename ReferenceType, typename std::enable_if<
17241 std::is_reference<ReferenceType>::value and
17242 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
17243 ReferenceType get_ref() const
17244 {
17245 // delegate call to get_ref_impl
17246 return get_ref_impl<ReferenceType>(*this);
17247 }
17248
17249 /*!
17250 @brief get a value (implicit)
17251
17252 Implicit type conversion between the JSON value and a compatible value.
17253 The call is realized by calling @ref get() const.
17254
17255 @tparam ValueType non-pointer type compatible to the JSON value, for
17256 instance `int` for JSON integer numbers, `bool` for JSON booleans, or
17257 `std::vector` types for JSON arrays. The character type of @ref string_t
17258 as well as an initializer list of this type is excluded to avoid
17259 ambiguities as these types implicitly convert to `std::string`.
17260
17261 @return copy of the JSON value, converted to type @a ValueType
17262
17263 @throw type_error.302 in case passed type @a ValueType is incompatible
17264 to the JSON value type (e.g., the JSON value is of type boolean, but a
17265 string is requested); see example below
17266
17267 @complexity Linear in the size of the JSON value.
17268
17269 @liveexample{The example below shows several conversions from JSON values
17270 to other types. There a few things to note: (1) Floating-point numbers can
17271 be converted to integers\, (2) A JSON array can be converted to a standard
17272 `std::vector<short>`\, (3) A JSON object can be converted to C++
17273 associative containers such as `std::unordered_map<std::string\,
17274 json>`.,operator__ValueType}
17275
17276 @since version 1.0.0
17277 */
17278 template < typename ValueType, typename std::enable_if <
17279 not std::is_pointer<ValueType>::value and
17280 not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
17281 not std::is_same<ValueType, typename string_t::value_type>::value and
17282 not detail::is_basic_json<ValueType>::value
17283
17284 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
17285 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
17286 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) and _MSC_VER <= 1914))
17287 and not std::is_same<ValueType, typename std::string_view>::value
17288 #endif
17289 #endif
17290 and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
17291 , int >::type = 0 >
17292 operator ValueType() const
17293 {
17294 // delegate the call to get<>() const
17295 return get<ValueType>();
17296 }
17297
17298 /// @}
17299
17300
17301 ////////////////////
17302 // element access //
17303 ////////////////////
17304
17305 /// @name element access
17306 /// Access to the JSON value.
17307 /// @{
17308
17309 /*!
17310 @brief access specified array element with bounds checking
17311
17312 Returns a reference to the element at specified location @a idx, with
17313 bounds checking.
17314
17315 @param[in] idx index of the element to access
17316
17317 @return reference to the element at index @a idx
17318
17319 @throw type_error.304 if the JSON value is not an array; in this case,
17320 calling `at` with an index makes no sense. See example below.
17321 @throw out_of_range.401 if the index @a idx is out of range of the array;
17322 that is, `idx >= size()`. See example below.
17323
17324 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17325 changes in the JSON value.
17326
17327 @complexity Constant.
17328
17329 @since version 1.0.0
17330
17331 @liveexample{The example below shows how array elements can be read and
17332 written using `at()`. It also demonstrates the different exceptions that
17333 can be thrown.,at__size_type}
17334 */
17335 reference at(size_type idx)
17336 {
17337 // at only works for arrays
17338 if (JSON_HEDLEY_LIKELY(is_array()))
17339 {
17340 JSON_TRY
17341 {
17342 return m_value.array->at(idx);
17343 }
17344 JSON_CATCH (std::out_of_range&)
17345 {
17346 // create better exception explanation
17347 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
17348 }
17349 }
17350 else
17351 {
17352 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
17353 }
17354 }
17355
17356 /*!
17357 @brief access specified array element with bounds checking
17358
17359 Returns a const reference to the element at specified location @a idx,
17360 with bounds checking.
17361
17362 @param[in] idx index of the element to access
17363
17364 @return const reference to the element at index @a idx
17365
17366 @throw type_error.304 if the JSON value is not an array; in this case,
17367 calling `at` with an index makes no sense. See example below.
17368 @throw out_of_range.401 if the index @a idx is out of range of the array;
17369 that is, `idx >= size()`. See example below.
17370
17371 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17372 changes in the JSON value.
17373
17374 @complexity Constant.
17375
17376 @since version 1.0.0
17377
17378 @liveexample{The example below shows how array elements can be read using
17379 `at()`. It also demonstrates the different exceptions that can be thrown.,
17380 at__size_type_const}
17381 */
17382 const_reference at(size_type idx) const
17383 {
17384 // at only works for arrays
17385 if (JSON_HEDLEY_LIKELY(is_array()))
17386 {
17387 JSON_TRY
17388 {
17389 return m_value.array->at(idx);
17390 }
17391 JSON_CATCH (std::out_of_range&)
17392 {
17393 // create better exception explanation
17394 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
17395 }
17396 }
17397 else
17398 {
17399 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
17400 }
17401 }
17402
17403 /*!
17404 @brief access specified object element with bounds checking
17405
17406 Returns a reference to the element at with specified key @a key, with
17407 bounds checking.
17408
17409 @param[in] key key of the element to access
17410
17411 @return reference to the element at key @a key
17412
17413 @throw type_error.304 if the JSON value is not an object; in this case,
17414 calling `at` with a key makes no sense. See example below.
17415 @throw out_of_range.403 if the key @a key is is not stored in the object;
17416 that is, `find(key) == end()`. See example below.
17417
17418 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17419 changes in the JSON value.
17420
17421 @complexity Logarithmic in the size of the container.
17422
17423 @sa @ref operator[](const typename object_t::key_type&) for unchecked
17424 access by reference
17425 @sa @ref value() for access by value with a default value
17426
17427 @since version 1.0.0
17428
17429 @liveexample{The example below shows how object elements can be read and
17430 written using `at()`. It also demonstrates the different exceptions that
17431 can be thrown.,at__object_t_key_type}
17432 */
17433 reference at(const typename object_t::key_type& key)
17434 {
17435 // at only works for objects
17436 if (JSON_HEDLEY_LIKELY(is_object()))
17437 {
17438 JSON_TRY
17439 {
17440 return m_value.object->at(key);
17441 }
17442 JSON_CATCH (std::out_of_range&)
17443 {
17444 // create better exception explanation
17445 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
17446 }
17447 }
17448 else
17449 {
17450 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
17451 }
17452 }
17453
17454 /*!
17455 @brief access specified object element with bounds checking
17456
17457 Returns a const reference to the element at with specified key @a key,
17458 with bounds checking.
17459
17460 @param[in] key key of the element to access
17461
17462 @return const reference to the element at key @a key
17463
17464 @throw type_error.304 if the JSON value is not an object; in this case,
17465 calling `at` with a key makes no sense. See example below.
17466 @throw out_of_range.403 if the key @a key is is not stored in the object;
17467 that is, `find(key) == end()`. See example below.
17468
17469 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17470 changes in the JSON value.
17471
17472 @complexity Logarithmic in the size of the container.
17473
17474 @sa @ref operator[](const typename object_t::key_type&) for unchecked
17475 access by reference
17476 @sa @ref value() for access by value with a default value
17477
17478 @since version 1.0.0
17479
17480 @liveexample{The example below shows how object elements can be read using
17481 `at()`. It also demonstrates the different exceptions that can be thrown.,
17482 at__object_t_key_type_const}
17483 */
17484 const_reference at(const typename object_t::key_type& key) const
17485 {
17486 // at only works for objects
17487 if (JSON_HEDLEY_LIKELY(is_object()))
17488 {
17489 JSON_TRY
17490 {
17491 return m_value.object->at(key);
17492 }
17493 JSON_CATCH (std::out_of_range&)
17494 {
17495 // create better exception explanation
17496 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
17497 }
17498 }
17499 else
17500 {
17501 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
17502 }
17503 }
17504
17505 /*!
17506 @brief access specified array element
17507
17508 Returns a reference to the element at specified location @a idx.
17509
17510 @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
17511 then the array is silently filled up with `null` values to make `idx` a
17512 valid reference to the last stored element.
17513
17514 @param[in] idx index of the element to access
17515
17516 @return reference to the element at index @a idx
17517
17518 @throw type_error.305 if the JSON value is not an array or null; in that
17519 cases, using the [] operator with an index makes no sense.
17520
17521 @complexity Constant if @a idx is in the range of the array. Otherwise
17522 linear in `idx - size()`.
17523
17524 @liveexample{The example below shows how array elements can be read and
17525 written using `[]` operator. Note the addition of `null`
17526 values.,operatorarray__size_type}
17527
17528 @since version 1.0.0
17529 */
17530 reference operator[](size_type idx)
17531 {
17532 // implicitly convert null value to an empty array
17533 if (is_null())
17534 {
17535 m_type = value_t::array;
17536 m_value.array = create<array_t>();
17537 assert_invariant();
17538 }
17539
17540 // operator[] only works for arrays
17541 if (JSON_HEDLEY_LIKELY(is_array()))
17542 {
17543 // fill up array with null values if given idx is outside range
17544 if (idx >= m_value.array->size())
17545 {
17546 m_value.array->insert(m_value.array->end(),
17547 idx - m_value.array->size() + 1,
17548 basic_json());
17549 }
17550
17551 return m_value.array->operator[](idx);
17552 }
17553
17554 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
17555 }
17556
17557 /*!
17558 @brief access specified array element
17559
17560 Returns a const reference to the element at specified location @a idx.
17561
17562 @param[in] idx index of the element to access
17563
17564 @return const reference to the element at index @a idx
17565
17566 @throw type_error.305 if the JSON value is not an array; in that case,
17567 using the [] operator with an index makes no sense.
17568
17569 @complexity Constant.
17570
17571 @liveexample{The example below shows how array elements can be read using
17572 the `[]` operator.,operatorarray__size_type_const}
17573
17574 @since version 1.0.0
17575 */
17576 const_reference operator[](size_type idx) const
17577 {
17578 // const operator[] only works for arrays
17579 if (JSON_HEDLEY_LIKELY(is_array()))
17580 {
17581 return m_value.array->operator[](idx);
17582 }
17583
17584 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
17585 }
17586
17587 /*!
17588 @brief access specified object element
17589
17590 Returns a reference to the element at with specified key @a key.
17591
17592 @note If @a key is not found in the object, then it is silently added to
17593 the object and filled with a `null` value to make `key` a valid reference.
17594 In case the value was `null` before, it is converted to an object.
17595
17596 @param[in] key key of the element to access
17597
17598 @return reference to the element at key @a key
17599
17600 @throw type_error.305 if the JSON value is not an object or null; in that
17601 cases, using the [] operator with a key makes no sense.
17602
17603 @complexity Logarithmic in the size of the container.
17604
17605 @liveexample{The example below shows how object elements can be read and
17606 written using the `[]` operator.,operatorarray__key_type}
17607
17608 @sa @ref at(const typename object_t::key_type&) for access by reference
17609 with range checking
17610 @sa @ref value() for access by value with a default value
17611
17612 @since version 1.0.0
17613 */
17614 reference operator[](const typename object_t::key_type& key)
17615 {
17616 // implicitly convert null value to an empty object
17617 if (is_null())
17618 {
17619 m_type = value_t::object;
17620 m_value.object = create<object_t>();
17621 assert_invariant();
17622 }
17623
17624 // operator[] only works for objects
17625 if (JSON_HEDLEY_LIKELY(is_object()))
17626 {
17627 return m_value.object->operator[](key);
17628 }
17629
17630 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
17631 }
17632
17633 /*!
17634 @brief read-only access specified object element
17635
17636 Returns a const reference to the element at with specified key @a key. No
17637 bounds checking is performed.
17638
17639 @warning If the element with key @a key does not exist, the behavior is
17640 undefined.
17641
17642 @param[in] key key of the element to access
17643
17644 @return const reference to the element at key @a key
17645
17646 @pre The element with key @a key must exist. **This precondition is
17647 enforced with an assertion.**
17648
17649 @throw type_error.305 if the JSON value is not an object; in that case,
17650 using the [] operator with a key makes no sense.
17651
17652 @complexity Logarithmic in the size of the container.
17653
17654 @liveexample{The example below shows how object elements can be read using
17655 the `[]` operator.,operatorarray__key_type_const}
17656
17657 @sa @ref at(const typename object_t::key_type&) for access by reference
17658 with range checking
17659 @sa @ref value() for access by value with a default value
17660
17661 @since version 1.0.0
17662 */
17663 const_reference operator[](const typename object_t::key_type& key) const
17664 {
17665 // const operator[] only works for objects
17666 if (JSON_HEDLEY_LIKELY(is_object()))
17667 {
17668 assert(m_value.object->find(key) != m_value.object->end());
17669 return m_value.object->find(key)->second;
17670 }
17671
17672 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
17673 }
17674
17675 /*!
17676 @brief access specified object element
17677
17678 Returns a reference to the element at with specified key @a key.
17679
17680 @note If @a key is not found in the object, then it is silently added to
17681 the object and filled with a `null` value to make `key` a valid reference.
17682 In case the value was `null` before, it is converted to an object.
17683
17684 @param[in] key key of the element to access
17685
17686 @return reference to the element at key @a key
17687
17688 @throw type_error.305 if the JSON value is not an object or null; in that
17689 cases, using the [] operator with a key makes no sense.
17690
17691 @complexity Logarithmic in the size of the container.
17692
17693 @liveexample{The example below shows how object elements can be read and
17694 written using the `[]` operator.,operatorarray__key_type}
17695
17696 @sa @ref at(const typename object_t::key_type&) for access by reference
17697 with range checking
17698 @sa @ref value() for access by value with a default value
17699
17700 @since version 1.1.0
17701 */
17702 template<typename T>
17703 JSON_HEDLEY_NON_NULL(2)
17704 reference operator[](T* key)
17705 {
17706 // implicitly convert null to object
17707 if (is_null())
17708 {
17709 m_type = value_t::object;
17710 m_value = value_t::object;
17711 assert_invariant();
17712 }
17713
17714 // at only works for objects
17715 if (JSON_HEDLEY_LIKELY(is_object()))
17716 {
17717 return m_value.object->operator[](key);
17718 }
17719
17720 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
17721 }
17722
17723 /*!
17724 @brief read-only access specified object element
17725
17726 Returns a const reference to the element at with specified key @a key. No
17727 bounds checking is performed.
17728
17729 @warning If the element with key @a key does not exist, the behavior is
17730 undefined.
17731
17732 @param[in] key key of the element to access
17733
17734 @return const reference to the element at key @a key
17735
17736 @pre The element with key @a key must exist. **This precondition is
17737 enforced with an assertion.**
17738
17739 @throw type_error.305 if the JSON value is not an object; in that case,
17740 using the [] operator with a key makes no sense.
17741
17742 @complexity Logarithmic in the size of the container.
17743
17744 @liveexample{The example below shows how object elements can be read using
17745 the `[]` operator.,operatorarray__key_type_const}
17746
17747 @sa @ref at(const typename object_t::key_type&) for access by reference
17748 with range checking
17749 @sa @ref value() for access by value with a default value
17750
17751 @since version 1.1.0
17752 */
17753 template<typename T>
17754 JSON_HEDLEY_NON_NULL(2)
17755 const_reference operator[](T* key) const
17756 {
17757 // at only works for objects
17758 if (JSON_HEDLEY_LIKELY(is_object()))
17759 {
17760 assert(m_value.object->find(key) != m_value.object->end());
17761 return m_value.object->find(key)->second;
17762 }
17763
17764 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
17765 }
17766
17767 /*!
17768 @brief access specified object element with default value
17769
17770 Returns either a copy of an object's element at the specified key @a key
17771 or a given default value if no element with key @a key exists.
17772
17773 The function is basically equivalent to executing
17774 @code {.cpp}
17775 try {
17776 return at(key);
17777 } catch(out_of_range) {
17778 return default_value;
17779 }
17780 @endcode
17781
17782 @note Unlike @ref at(const typename object_t::key_type&), this function
17783 does not throw if the given key @a key was not found.
17784
17785 @note Unlike @ref operator[](const typename object_t::key_type& key), this
17786 function does not implicitly add an element to the position defined by @a
17787 key. This function is furthermore also applicable to const objects.
17788
17789 @param[in] key key of the element to access
17790 @param[in] default_value the value to return if @a key is not found
17791
17792 @tparam ValueType type compatible to JSON values, for instance `int` for
17793 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
17794 JSON arrays. Note the type of the expected value at @a key and the default
17795 value @a default_value must be compatible.
17796
17797 @return copy of the element at key @a key or @a default_value if @a key
17798 is not found
17799
17800 @throw type_error.302 if @a default_value does not match the type of the
17801 value at @a key
17802 @throw type_error.306 if the JSON value is not an object; in that case,
17803 using `value()` with a key makes no sense.
17804
17805 @complexity Logarithmic in the size of the container.
17806
17807 @liveexample{The example below shows how object elements can be queried
17808 with a default value.,basic_json__value}
17809
17810 @sa @ref at(const typename object_t::key_type&) for access by reference
17811 with range checking
17812 @sa @ref operator[](const typename object_t::key_type&) for unchecked
17813 access by reference
17814
17815 @since version 1.0.0
17816 */
17817 template<class ValueType, typename std::enable_if<
17818 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
17819 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
17820 {
17821 // at only works for objects
17822 if (JSON_HEDLEY_LIKELY(is_object()))
17823 {
17824 // if key is found, return value and given default value otherwise
17825 const auto it = find(key);
17826 if (it != end())
17827 {
17828 return *it;
17829 }
17830
17831 return default_value;
17832 }
17833
17834 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
17835 }
17836
17837 /*!
17838 @brief overload for a default value of type const char*
17839 @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const
17840 */
17841 string_t value(const typename object_t::key_type& key, const char* default_value) const
17842 {
17843 return value(key, string_t(default_value));
17844 }
17845
17846 /*!
17847 @brief access specified object element via JSON Pointer with default value
17848
17849 Returns either a copy of an object's element at the specified key @a key
17850 or a given default value if no element with key @a key exists.
17851
17852 The function is basically equivalent to executing
17853 @code {.cpp}
17854 try {
17855 return at(ptr);
17856 } catch(out_of_range) {
17857 return default_value;
17858 }
17859 @endcode
17860
17861 @note Unlike @ref at(const json_pointer&), this function does not throw
17862 if the given key @a key was not found.
17863
17864 @param[in] ptr a JSON pointer to the element to access
17865 @param[in] default_value the value to return if @a ptr found no value
17866
17867 @tparam ValueType type compatible to JSON values, for instance `int` for
17868 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
17869 JSON arrays. Note the type of the expected value at @a key and the default
17870 value @a default_value must be compatible.
17871
17872 @return copy of the element at key @a key or @a default_value if @a key
17873 is not found
17874
17875 @throw type_error.302 if @a default_value does not match the type of the
17876 value at @a ptr
17877 @throw type_error.306 if the JSON value is not an object; in that case,
17878 using `value()` with a key makes no sense.
17879
17880 @complexity Logarithmic in the size of the container.
17881
17882 @liveexample{The example below shows how object elements can be queried
17883 with a default value.,basic_json__value_ptr}
17884
17885 @sa @ref operator[](const json_pointer&) for unchecked access by reference
17886
17887 @since version 2.0.2
17888 */
17889 template<class ValueType, typename std::enable_if<
17890 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
17891 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
17892 {
17893 // at only works for objects
17894 if (JSON_HEDLEY_LIKELY(is_object()))
17895 {
17896 // if pointer resolves a value, return it or use default value
17897 JSON_TRY
17898 {
17899 return ptr.get_checked(this);
17900 }
17901 JSON_INTERNAL_CATCH (out_of_range&)
17902 {
17903 return default_value;
17904 }
17905 }
17906
17907 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
17908 }
17909
17910 /*!
17911 @brief overload for a default value of type const char*
17912 @copydoc basic_json::value(const json_pointer&, ValueType) const
17913 */
17914 JSON_HEDLEY_NON_NULL(3)
17915 string_t value(const json_pointer& ptr, const char* default_value) const
17916 {
17917 return value(ptr, string_t(default_value));
17918 }
17919
17920 /*!
17921 @brief access the first element
17922
17923 Returns a reference to the first element in the container. For a JSON
17924 container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
17925
17926 @return In case of a structured type (array or object), a reference to the
17927 first element is returned. In case of number, string, or boolean values, a
17928 reference to the value is returned.
17929
17930 @complexity Constant.
17931
17932 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
17933 or an empty array or object (undefined behavior, **guarded by
17934 assertions**).
17935 @post The JSON value remains unchanged.
17936
17937 @throw invalid_iterator.214 when called on `null` value
17938
17939 @liveexample{The following code shows an example for `front()`.,front}
17940
17941 @sa @ref back() -- access the last element
17942
17943 @since version 1.0.0
17944 */
17945 reference front()
17946 {
17947 return *begin();
17948 }
17949
17950 /*!
17951 @copydoc basic_json::front()
17952 */
17953 const_reference front() const
17954 {
17955 return *cbegin();
17956 }
17957
17958 /*!
17959 @brief access the last element
17960
17961 Returns a reference to the last element in the container. For a JSON
17962 container `c`, the expression `c.back()` is equivalent to
17963 @code {.cpp}
17964 auto tmp = c.end();
17965 --tmp;
17966 return *tmp;
17967 @endcode
17968
17969 @return In case of a structured type (array or object), a reference to the
17970 last element is returned. In case of number, string, or boolean values, a
17971 reference to the value is returned.
17972
17973 @complexity Constant.
17974
17975 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
17976 or an empty array or object (undefined behavior, **guarded by
17977 assertions**).
17978 @post The JSON value remains unchanged.
17979
17980 @throw invalid_iterator.214 when called on a `null` value. See example
17981 below.
17982
17983 @liveexample{The following code shows an example for `back()`.,back}
17984
17985 @sa @ref front() -- access the first element
17986
17987 @since version 1.0.0
17988 */
17989 reference back()
17990 {
17991 auto tmp = end();
17992 --tmp;
17993 return *tmp;
17994 }
17995
17996 /*!
17997 @copydoc basic_json::back()
17998 */
17999 const_reference back() const
18000 {
18001 auto tmp = cend();
18002 --tmp;
18003 return *tmp;
18004 }
18005
18006 /*!
18007 @brief remove element given an iterator
18008
18009 Removes the element specified by iterator @a pos. The iterator @a pos must
18010 be valid and dereferenceable. Thus the `end()` iterator (which is valid,
18011 but is not dereferenceable) cannot be used as a value for @a pos.
18012
18013 If called on a primitive type other than `null`, the resulting JSON value
18014 will be `null`.
18015
18016 @param[in] pos iterator to the element to remove
18017 @return Iterator following the last removed element. If the iterator @a
18018 pos refers to the last element, the `end()` iterator is returned.
18019
18020 @tparam IteratorType an @ref iterator or @ref const_iterator
18021
18022 @post Invalidates iterators and references at or after the point of the
18023 erase, including the `end()` iterator.
18024
18025 @throw type_error.307 if called on a `null` value; example: `"cannot use
18026 erase() with null"`
18027 @throw invalid_iterator.202 if called on an iterator which does not belong
18028 to the current JSON value; example: `"iterator does not fit current
18029 value"`
18030 @throw invalid_iterator.205 if called on a primitive type with invalid
18031 iterator (i.e., any iterator which is not `begin()`); example: `"iterator
18032 out of range"`
18033
18034 @complexity The complexity depends on the type:
18035 - objects: amortized constant
18036 - arrays: linear in distance between @a pos and the end of the container
18037 - strings: linear in the length of the string
18038 - other types: constant
18039
18040 @liveexample{The example shows the result of `erase()` for different JSON
18041 types.,erase__IteratorType}
18042
18043 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
18044 the given range
18045 @sa @ref erase(const typename object_t::key_type&) -- removes the element
18046 from an object at the given key
18047 @sa @ref erase(const size_type) -- removes the element from an array at
18048 the given index
18049
18050 @since version 1.0.0
18051 */
18052 template<class IteratorType, typename std::enable_if<
18053 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
18054 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
18055 = 0>
18056 IteratorType erase(IteratorType pos)
18057 {
18058 // make sure iterator fits the current value
18059 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
18060 {
18061 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
18062 }
18063
18064 IteratorType result = end();
18065
18066 switch (m_type)
18067 {
18068 case value_t::boolean:
18069 case value_t::number_float:
18070 case value_t::number_integer:
18071 case value_t::number_unsigned:
18072 case value_t::string:
18073 {
18074 if (JSON_HEDLEY_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
18075 {
18076 JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
18077 }
18078
18079 if (is_string())
18080 {
18081 AllocatorType<string_t> alloc;
18082 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
18083 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
18084 m_value.string = nullptr;
18085 }
18086
18087 m_type = value_t::null;
18088 assert_invariant();
18089 break;
18090 }
18091
18092 case value_t::object:
18093 {
18094 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
18095 break;
18096 }
18097
18098 case value_t::array:
18099 {
18100 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
18101 break;
18102 }
18103
18104 default:
18105 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
18106 }
18107
18108 return result;
18109 }
18110
18111 /*!
18112 @brief remove elements given an iterator range
18113
18114 Removes the element specified by the range `[first; last)`. The iterator
18115 @a first does not need to be dereferenceable if `first == last`: erasing
18116 an empty range is a no-op.
18117
18118 If called on a primitive type other than `null`, the resulting JSON value
18119 will be `null`.
18120
18121 @param[in] first iterator to the beginning of the range to remove
18122 @param[in] last iterator past the end of the range to remove
18123 @return Iterator following the last removed element. If the iterator @a
18124 second refers to the last element, the `end()` iterator is returned.
18125
18126 @tparam IteratorType an @ref iterator or @ref const_iterator
18127
18128 @post Invalidates iterators and references at or after the point of the
18129 erase, including the `end()` iterator.
18130
18131 @throw type_error.307 if called on a `null` value; example: `"cannot use
18132 erase() with null"`
18133 @throw invalid_iterator.203 if called on iterators which does not belong
18134 to the current JSON value; example: `"iterators do not fit current value"`
18135 @throw invalid_iterator.204 if called on a primitive type with invalid
18136 iterators (i.e., if `first != begin()` and `last != end()`); example:
18137 `"iterators out of range"`
18138
18139 @complexity The complexity depends on the type:
18140 - objects: `log(size()) + std::distance(first, last)`
18141 - arrays: linear in the distance between @a first and @a last, plus linear
18142 in the distance between @a last and end of the container
18143 - strings: linear in the length of the string
18144 - other types: constant
18145
18146 @liveexample{The example shows the result of `erase()` for different JSON
18147 types.,erase__IteratorType_IteratorType}
18148
18149 @sa @ref erase(IteratorType) -- removes the element at a given position
18150 @sa @ref erase(const typename object_t::key_type&) -- removes the element
18151 from an object at the given key
18152 @sa @ref erase(const size_type) -- removes the element from an array at
18153 the given index
18154
18155 @since version 1.0.0
18156 */
18157 template<class IteratorType, typename std::enable_if<
18158 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
18159 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
18160 = 0>
18161 IteratorType erase(IteratorType first, IteratorType last)
18162 {
18163 // make sure iterator fits the current value
18164 if (JSON_HEDLEY_UNLIKELY(this != first.m_object or this != last.m_object))
18165 {
18166 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
18167 }
18168
18169 IteratorType result = end();
18170
18171 switch (m_type)
18172 {
18173 case value_t::boolean:
18174 case value_t::number_float:
18175 case value_t::number_integer:
18176 case value_t::number_unsigned:
18177 case value_t::string:
18178 {
18179 if (JSON_HEDLEY_LIKELY(not first.m_it.primitive_iterator.is_begin()
18180 or not last.m_it.primitive_iterator.is_end()))
18181 {
18182 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
18183 }
18184
18185 if (is_string())
18186 {
18187 AllocatorType<string_t> alloc;
18188 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
18189 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
18190 m_value.string = nullptr;
18191 }
18192
18193 m_type = value_t::null;
18194 assert_invariant();
18195 break;
18196 }
18197
18198 case value_t::object:
18199 {
18200 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
18201 last.m_it.object_iterator);
18202 break;
18203 }
18204
18205 case value_t::array:
18206 {
18207 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
18208 last.m_it.array_iterator);
18209 break;
18210 }
18211
18212 default:
18213 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
18214 }
18215
18216 return result;
18217 }
18218
18219 /*!
18220 @brief remove element from a JSON object given a key
18221
18222 Removes elements from a JSON object with the key value @a key.
18223
18224 @param[in] key value of the elements to remove
18225
18226 @return Number of elements removed. If @a ObjectType is the default
18227 `std::map` type, the return value will always be `0` (@a key was not
18228 found) or `1` (@a key was found).
18229
18230 @post References and iterators to the erased elements are invalidated.
18231 Other references and iterators are not affected.
18232
18233 @throw type_error.307 when called on a type other than JSON object;
18234 example: `"cannot use erase() with null"`
18235
18236 @complexity `log(size()) + count(key)`
18237
18238 @liveexample{The example shows the effect of `erase()`.,erase__key_type}
18239
18240 @sa @ref erase(IteratorType) -- removes the element at a given position
18241 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
18242 the given range
18243 @sa @ref erase(const size_type) -- removes the element from an array at
18244 the given index
18245
18246 @since version 1.0.0
18247 */
18248 size_type erase(const typename object_t::key_type& key)
18249 {
18250 // this erase only works for objects
18251 if (JSON_HEDLEY_LIKELY(is_object()))
18252 {
18253 return m_value.object->erase(key);
18254 }
18255
18256 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
18257 }
18258
18259 /*!
18260 @brief remove element from a JSON array given an index
18261
18262 Removes element from a JSON array at the index @a idx.
18263
18264 @param[in] idx index of the element to remove
18265
18266 @throw type_error.307 when called on a type other than JSON object;
18267 example: `"cannot use erase() with null"`
18268 @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
18269 is out of range"`
18270
18271 @complexity Linear in distance between @a idx and the end of the container.
18272
18273 @liveexample{The example shows the effect of `erase()`.,erase__size_type}
18274
18275 @sa @ref erase(IteratorType) -- removes the element at a given position
18276 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
18277 the given range
18278 @sa @ref erase(const typename object_t::key_type&) -- removes the element
18279 from an object at the given key
18280
18281 @since version 1.0.0
18282 */
18283 void erase(const size_type idx)
18284 {
18285 // this erase only works for arrays
18286 if (JSON_HEDLEY_LIKELY(is_array()))
18287 {
18288 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
18289 {
18290 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
18291 }
18292
18293 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
18294 }
18295 else
18296 {
18297 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
18298 }
18299 }
18300
18301 /// @}
18302
18303
18304 ////////////
18305 // lookup //
18306 ////////////
18307
18308 /// @name lookup
18309 /// @{
18310
18311 /*!
18312 @brief find an element in a JSON object
18313
18314 Finds an element in a JSON object with key equivalent to @a key. If the
18315 element is not found or the JSON value is not an object, end() is
18316 returned.
18317
18318 @note This method always returns @ref end() when executed on a JSON type
18319 that is not an object.
18320
18321 @param[in] key key value of the element to search for.
18322
18323 @return Iterator to an element with key equivalent to @a key. If no such
18324 element is found or the JSON value is not an object, past-the-end (see
18325 @ref end()) iterator is returned.
18326
18327 @complexity Logarithmic in the size of the JSON object.
18328
18329 @liveexample{The example shows how `find()` is used.,find__key_type}
18330
18331 @sa @ref contains(KeyT&&) const -- checks whether a key exists
18332
18333 @since version 1.0.0
18334 */
18335 template<typename KeyT>
18336 iterator find(KeyT&& key)
18337 {
18338 auto result = end();
18339
18340 if (is_object())
18341 {
18342 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
18343 }
18344
18345 return result;
18346 }
18347
18348 /*!
18349 @brief find an element in a JSON object
18350 @copydoc find(KeyT&&)
18351 */
18352 template<typename KeyT>
18353 const_iterator find(KeyT&& key) const
18354 {
18355 auto result = cend();
18356
18357 if (is_object())
18358 {
18359 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
18360 }
18361
18362 return result;
18363 }
18364
18365 /*!
18366 @brief returns the number of occurrences of a key in a JSON object
18367
18368 Returns the number of elements with key @a key. If ObjectType is the
18369 default `std::map` type, the return value will always be `0` (@a key was
18370 not found) or `1` (@a key was found).
18371
18372 @note This method always returns `0` when executed on a JSON type that is
18373 not an object.
18374
18375 @param[in] key key value of the element to count
18376
18377 @return Number of elements with key @a key. If the JSON value is not an
18378 object, the return value will be `0`.
18379
18380 @complexity Logarithmic in the size of the JSON object.
18381
18382 @liveexample{The example shows how `count()` is used.,count}
18383
18384 @since version 1.0.0
18385 */
18386 template<typename KeyT>
18387 size_type count(KeyT&& key) const
18388 {
18389 // return 0 for all nonobject types
18390 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
18391 }
18392
18393 /*!
18394 @brief check the existence of an element in a JSON object
18395
18396 Check whether an element exists in a JSON object with key equivalent to
18397 @a key. If the element is not found or the JSON value is not an object,
18398 false is returned.
18399
18400 @note This method always returns false when executed on a JSON type
18401 that is not an object.
18402
18403 @param[in] key key value to check its existence.
18404
18405 @return true if an element with specified @a key exists. If no such
18406 element with such key is found or the JSON value is not an object,
18407 false is returned.
18408
18409 @complexity Logarithmic in the size of the JSON object.
18410
18411 @liveexample{The following code shows an example for `contains()`.,contains}
18412
18413 @sa @ref find(KeyT&&) -- returns an iterator to an object element
18414 @sa @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer
18415
18416 @since version 3.6.0
18417 */
18418 template<typename KeyT, typename std::enable_if<
18419 not std::is_same<KeyT, json_pointer>::value, int>::type = 0>
18420 bool contains(KeyT && key) const
18421 {
18422 return is_object() and m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
18423 }
18424
18425 /*!
18426 @brief check the existence of an element in a JSON object given a JSON pointer
18427
18428 Check wehther the given JSON pointer @a ptr can be resolved in the current
18429 JSON value.
18430
18431 @note This method can be executed on any JSON value type.
18432
18433 @param[in] ptr JSON pointer to check its existence.
18434
18435 @return true if the JSON pointer can be resolved to a stored value, false
18436 otherwise.
18437
18438 @post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`.
18439
18440 @throw parse_error.106 if an array index begins with '0'
18441 @throw parse_error.109 if an array index was not a number
18442
18443 @complexity Logarithmic in the size of the JSON object.
18444
18445 @liveexample{The following code shows an example for `contains()`.,contains_json_pointer}
18446
18447 @sa @ref contains(KeyT &&) const -- checks the existence of a key
18448
18449 @since version 3.7.0
18450 */
18451 bool contains(const json_pointer& ptr) const
18452 {
18453 return ptr.contains(this);
18454 }
18455
18456 /// @}
18457
18458
18459 ///////////////
18460 // iterators //
18461 ///////////////
18462
18463 /// @name iterators
18464 /// @{
18465
18466 /*!
18467 @brief returns an iterator to the first element
18468
18469 Returns an iterator to the first element.
18470
18471 @image html range-begin-end.svg "Illustration from cppreference.com"
18472
18473 @return iterator to the first element
18474
18475 @complexity Constant.
18476
18477 @requirement This function helps `basic_json` satisfying the
18478 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18479 requirements:
18480 - The complexity is constant.
18481
18482 @liveexample{The following code shows an example for `begin()`.,begin}
18483
18484 @sa @ref cbegin() -- returns a const iterator to the beginning
18485 @sa @ref end() -- returns an iterator to the end
18486 @sa @ref cend() -- returns a const iterator to the end
18487
18488 @since version 1.0.0
18489 */
18490 iterator begin() noexcept
18491 {
18492 iterator result(this);
18493 result.set_begin();
18494 return result;
18495 }
18496
18497 /*!
18498 @copydoc basic_json::cbegin()
18499 */
18500 const_iterator begin() const noexcept
18501 {
18502 return cbegin();
18503 }
18504
18505 /*!
18506 @brief returns a const iterator to the first element
18507
18508 Returns a const iterator to the first element.
18509
18510 @image html range-begin-end.svg "Illustration from cppreference.com"
18511
18512 @return const iterator to the first element
18513
18514 @complexity Constant.
18515
18516 @requirement This function helps `basic_json` satisfying the
18517 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18518 requirements:
18519 - The complexity is constant.
18520 - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
18521
18522 @liveexample{The following code shows an example for `cbegin()`.,cbegin}
18523
18524 @sa @ref begin() -- returns an iterator to the beginning
18525 @sa @ref end() -- returns an iterator to the end
18526 @sa @ref cend() -- returns a const iterator to the end
18527
18528 @since version 1.0.0
18529 */
18530 const_iterator cbegin() const noexcept
18531 {
18532 const_iterator result(this);
18533 result.set_begin();
18534 return result;
18535 }
18536
18537 /*!
18538 @brief returns an iterator to one past the last element
18539
18540 Returns an iterator to one past the last element.
18541
18542 @image html range-begin-end.svg "Illustration from cppreference.com"
18543
18544 @return iterator one past the last element
18545
18546 @complexity Constant.
18547
18548 @requirement This function helps `basic_json` satisfying the
18549 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18550 requirements:
18551 - The complexity is constant.
18552
18553 @liveexample{The following code shows an example for `end()`.,end}
18554
18555 @sa @ref cend() -- returns a const iterator to the end
18556 @sa @ref begin() -- returns an iterator to the beginning
18557 @sa @ref cbegin() -- returns a const iterator to the beginning
18558
18559 @since version 1.0.0
18560 */
18561 iterator end() noexcept
18562 {
18563 iterator result(this);
18564 result.set_end();
18565 return result;
18566 }
18567
18568 /*!
18569 @copydoc basic_json::cend()
18570 */
18571 const_iterator end() const noexcept
18572 {
18573 return cend();
18574 }
18575
18576 /*!
18577 @brief returns a const iterator to one past the last element
18578
18579 Returns a const iterator to one past the last element.
18580
18581 @image html range-begin-end.svg "Illustration from cppreference.com"
18582
18583 @return const iterator one past the last element
18584
18585 @complexity Constant.
18586
18587 @requirement This function helps `basic_json` satisfying the
18588 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18589 requirements:
18590 - The complexity is constant.
18591 - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
18592
18593 @liveexample{The following code shows an example for `cend()`.,cend}
18594
18595 @sa @ref end() -- returns an iterator to the end
18596 @sa @ref begin() -- returns an iterator to the beginning
18597 @sa @ref cbegin() -- returns a const iterator to the beginning
18598
18599 @since version 1.0.0
18600 */
18601 const_iterator cend() const noexcept
18602 {
18603 const_iterator result(this);
18604 result.set_end();
18605 return result;
18606 }
18607
18608 /*!
18609 @brief returns an iterator to the reverse-beginning
18610
18611 Returns an iterator to the reverse-beginning; that is, the last element.
18612
18613 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
18614
18615 @complexity Constant.
18616
18617 @requirement This function helps `basic_json` satisfying the
18618 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
18619 requirements:
18620 - The complexity is constant.
18621 - Has the semantics of `reverse_iterator(end())`.
18622
18623 @liveexample{The following code shows an example for `rbegin()`.,rbegin}
18624
18625 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
18626 @sa @ref rend() -- returns a reverse iterator to the end
18627 @sa @ref crend() -- returns a const reverse iterator to the end
18628
18629 @since version 1.0.0
18630 */
18631 reverse_iterator rbegin() noexcept
18632 {
18633 return reverse_iterator(end());
18634 }
18635
18636 /*!
18637 @copydoc basic_json::crbegin()
18638 */
18639 const_reverse_iterator rbegin() const noexcept
18640 {
18641 return crbegin();
18642 }
18643
18644 /*!
18645 @brief returns an iterator to the reverse-end
18646
18647 Returns an iterator to the reverse-end; that is, one before the first
18648 element.
18649
18650 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
18651
18652 @complexity Constant.
18653
18654 @requirement This function helps `basic_json` satisfying the
18655 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
18656 requirements:
18657 - The complexity is constant.
18658 - Has the semantics of `reverse_iterator(begin())`.
18659
18660 @liveexample{The following code shows an example for `rend()`.,rend}
18661
18662 @sa @ref crend() -- returns a const reverse iterator to the end
18663 @sa @ref rbegin() -- returns a reverse iterator to the beginning
18664 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
18665
18666 @since version 1.0.0
18667 */
18668 reverse_iterator rend() noexcept
18669 {
18670 return reverse_iterator(begin());
18671 }
18672
18673 /*!
18674 @copydoc basic_json::crend()
18675 */
18676 const_reverse_iterator rend() const noexcept
18677 {
18678 return crend();
18679 }
18680
18681 /*!
18682 @brief returns a const reverse iterator to the last element
18683
18684 Returns a const iterator to the reverse-beginning; that is, the last
18685 element.
18686
18687 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
18688
18689 @complexity Constant.
18690
18691 @requirement This function helps `basic_json` satisfying the
18692 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
18693 requirements:
18694 - The complexity is constant.
18695 - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
18696
18697 @liveexample{The following code shows an example for `crbegin()`.,crbegin}
18698
18699 @sa @ref rbegin() -- returns a reverse iterator to the beginning
18700 @sa @ref rend() -- returns a reverse iterator to the end
18701 @sa @ref crend() -- returns a const reverse iterator to the end
18702
18703 @since version 1.0.0
18704 */
18705 const_reverse_iterator crbegin() const noexcept
18706 {
18707 return const_reverse_iterator(cend());
18708 }
18709
18710 /*!
18711 @brief returns a const reverse iterator to one before the first
18712
18713 Returns a const reverse iterator to the reverse-end; that is, one before
18714 the first element.
18715
18716 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
18717
18718 @complexity Constant.
18719
18720 @requirement This function helps `basic_json` satisfying the
18721 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
18722 requirements:
18723 - The complexity is constant.
18724 - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
18725
18726 @liveexample{The following code shows an example for `crend()`.,crend}
18727
18728 @sa @ref rend() -- returns a reverse iterator to the end
18729 @sa @ref rbegin() -- returns a reverse iterator to the beginning
18730 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
18731
18732 @since version 1.0.0
18733 */
18734 const_reverse_iterator crend() const noexcept
18735 {
18736 return const_reverse_iterator(cbegin());
18737 }
18738
18739 public:
18740 /*!
18741 @brief wrapper to access iterator member functions in range-based for
18742
18743 This function allows to access @ref iterator::key() and @ref
18744 iterator::value() during range-based for loops. In these loops, a
18745 reference to the JSON values is returned, so there is no access to the
18746 underlying iterator.
18747
18748 For loop without iterator_wrapper:
18749
18750 @code{cpp}
18751 for (auto it = j_object.begin(); it != j_object.end(); ++it)
18752 {
18753 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
18754 }
18755 @endcode
18756
18757 Range-based for loop without iterator proxy:
18758
18759 @code{cpp}
18760 for (auto it : j_object)
18761 {
18762 // "it" is of type json::reference and has no key() member
18763 std::cout << "value: " << it << '\n';
18764 }
18765 @endcode
18766
18767 Range-based for loop with iterator proxy:
18768
18769 @code{cpp}
18770 for (auto it : json::iterator_wrapper(j_object))
18771 {
18772 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
18773 }
18774 @endcode
18775
18776 @note When iterating over an array, `key()` will return the index of the
18777 element as string (see example).
18778
18779 @param[in] ref reference to a JSON value
18780 @return iteration proxy object wrapping @a ref with an interface to use in
18781 range-based for loops
18782
18783 @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
18784
18785 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18786 changes in the JSON value.
18787
18788 @complexity Constant.
18789
18790 @note The name of this function is not yet final and may change in the
18791 future.
18792
18793 @deprecated This stream operator is deprecated and will be removed in
18794 future 4.0.0 of the library. Please use @ref items() instead;
18795 that is, replace `json::iterator_wrapper(j)` with `j.items()`.
18796 */
18797 JSON_HEDLEY_DEPRECATED(3.1.0)
18798 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
18799 {
18800 return ref.items();
18801 }
18802
18803 /*!
18804 @copydoc iterator_wrapper(reference)
18805 */
18806 JSON_HEDLEY_DEPRECATED(3.1.0)
18807 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
18808 {
18809 return ref.items();
18810 }
18811
18812 /*!
18813 @brief helper to access iterator member functions in range-based for
18814
18815 This function allows to access @ref iterator::key() and @ref
18816 iterator::value() during range-based for loops. In these loops, a
18817 reference to the JSON values is returned, so there is no access to the
18818 underlying iterator.
18819
18820 For loop without `items()` function:
18821
18822 @code{cpp}
18823 for (auto it = j_object.begin(); it != j_object.end(); ++it)
18824 {
18825 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
18826 }
18827 @endcode
18828
18829 Range-based for loop without `items()` function:
18830
18831 @code{cpp}
18832 for (auto it : j_object)
18833 {
18834 // "it" is of type json::reference and has no key() member
18835 std::cout << "value: " << it << '\n';
18836 }
18837 @endcode
18838
18839 Range-based for loop with `items()` function:
18840
18841 @code{cpp}
18842 for (auto& el : j_object.items())
18843 {
18844 std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
18845 }
18846 @endcode
18847
18848 The `items()` function also allows to use
18849 [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
18850 (C++17):
18851
18852 @code{cpp}
18853 for (auto& [key, val] : j_object.items())
18854 {
18855 std::cout << "key: " << key << ", value:" << val << '\n';
18856 }
18857 @endcode
18858
18859 @note When iterating over an array, `key()` will return the index of the
18860 element as string (see example). For primitive types (e.g., numbers),
18861 `key()` returns an empty string.
18862
18863 @return iteration proxy object wrapping @a ref with an interface to use in
18864 range-based for loops
18865
18866 @liveexample{The following code shows how the function is used.,items}
18867
18868 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18869 changes in the JSON value.
18870
18871 @complexity Constant.
18872
18873 @since version 3.1.0, structured bindings support since 3.5.0.
18874 */
18875 iteration_proxy<iterator> items() noexcept
18876 {
18877 return iteration_proxy<iterator>(*this);
18878 }
18879
18880 /*!
18881 @copydoc items()
18882 */
18883 iteration_proxy<const_iterator> items() const noexcept
18884 {
18885 return iteration_proxy<const_iterator>(*this);
18886 }
18887
18888 /// @}
18889
18890
18891 //////////////
18892 // capacity //
18893 //////////////
18894
18895 /// @name capacity
18896 /// @{
18897
18898 /*!
18899 @brief checks whether the container is empty.
18900
18901 Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
18902
18903 @return The return value depends on the different types and is
18904 defined as follows:
18905 Value type | return value
18906 ----------- | -------------
18907 null | `true`
18908 boolean | `false`
18909 string | `false`
18910 number | `false`
18911 object | result of function `object_t::empty()`
18912 array | result of function `array_t::empty()`
18913
18914 @liveexample{The following code uses `empty()` to check if a JSON
18915 object contains any elements.,empty}
18916
18917 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
18918 the Container concept; that is, their `empty()` functions have constant
18919 complexity.
18920
18921 @iterators No changes.
18922
18923 @exceptionsafety No-throw guarantee: this function never throws exceptions.
18924
18925 @note This function does not return whether a string stored as JSON value
18926 is empty - it returns whether the JSON container itself is empty which is
18927 false in the case of a string.
18928
18929 @requirement This function helps `basic_json` satisfying the
18930 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18931 requirements:
18932 - The complexity is constant.
18933 - Has the semantics of `begin() == end()`.
18934
18935 @sa @ref size() -- returns the number of elements
18936
18937 @since version 1.0.0
18938 */
18939 bool empty() const noexcept
18940 {
18941 switch (m_type)
18942 {
18943 case value_t::null:
18944 {
18945 // null values are empty
18946 return true;
18947 }
18948
18949 case value_t::array:
18950 {
18951 // delegate call to array_t::empty()
18952 return m_value.array->empty();
18953 }
18954
18955 case value_t::object:
18956 {
18957 // delegate call to object_t::empty()
18958 return m_value.object->empty();
18959 }
18960
18961 default:
18962 {
18963 // all other types are nonempty
18964 return false;
18965 }
18966 }
18967 }
18968
18969 /*!
18970 @brief returns the number of elements
18971
18972 Returns the number of elements in a JSON value.
18973
18974 @return The return value depends on the different types and is
18975 defined as follows:
18976 Value type | return value
18977 ----------- | -------------
18978 null | `0`
18979 boolean | `1`
18980 string | `1`
18981 number | `1`
18982 object | result of function object_t::size()
18983 array | result of function array_t::size()
18984
18985 @liveexample{The following code calls `size()` on the different value
18986 types.,size}
18987
18988 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
18989 the Container concept; that is, their size() functions have constant
18990 complexity.
18991
18992 @iterators No changes.
18993
18994 @exceptionsafety No-throw guarantee: this function never throws exceptions.
18995
18996 @note This function does not return the length of a string stored as JSON
18997 value - it returns the number of elements in the JSON value which is 1 in
18998 the case of a string.
18999
19000 @requirement This function helps `basic_json` satisfying the
19001 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
19002 requirements:
19003 - The complexity is constant.
19004 - Has the semantics of `std::distance(begin(), end())`.
19005
19006 @sa @ref empty() -- checks whether the container is empty
19007 @sa @ref max_size() -- returns the maximal number of elements
19008
19009 @since version 1.0.0
19010 */
19011 size_type size() const noexcept
19012 {
19013 switch (m_type)
19014 {
19015 case value_t::null:
19016 {
19017 // null values are empty
19018 return 0;
19019 }
19020
19021 case value_t::array:
19022 {
19023 // delegate call to array_t::size()
19024 return m_value.array->size();
19025 }
19026
19027 case value_t::object:
19028 {
19029 // delegate call to object_t::size()
19030 return m_value.object->size();
19031 }
19032
19033 default:
19034 {
19035 // all other types have size 1
19036 return 1;
19037 }
19038 }
19039 }
19040
19041 /*!
19042 @brief returns the maximum possible number of elements
19043
19044 Returns the maximum number of elements a JSON value is able to hold due to
19045 system or library implementation limitations, i.e. `std::distance(begin(),
19046 end())` for the JSON value.
19047
19048 @return The return value depends on the different types and is
19049 defined as follows:
19050 Value type | return value
19051 ----------- | -------------
19052 null | `0` (same as `size()`)
19053 boolean | `1` (same as `size()`)
19054 string | `1` (same as `size()`)
19055 number | `1` (same as `size()`)
19056 object | result of function `object_t::max_size()`
19057 array | result of function `array_t::max_size()`
19058
19059 @liveexample{The following code calls `max_size()` on the different value
19060 types. Note the output is implementation specific.,max_size}
19061
19062 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
19063 the Container concept; that is, their `max_size()` functions have constant
19064 complexity.
19065
19066 @iterators No changes.
19067
19068 @exceptionsafety No-throw guarantee: this function never throws exceptions.
19069
19070 @requirement This function helps `basic_json` satisfying the
19071 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
19072 requirements:
19073 - The complexity is constant.
19074 - Has the semantics of returning `b.size()` where `b` is the largest
19075 possible JSON value.
19076
19077 @sa @ref size() -- returns the number of elements
19078
19079 @since version 1.0.0
19080 */
19081 size_type max_size() const noexcept
19082 {
19083 switch (m_type)
19084 {
19085 case value_t::array:
19086 {
19087 // delegate call to array_t::max_size()
19088 return m_value.array->max_size();
19089 }
19090
19091 case value_t::object:
19092 {
19093 // delegate call to object_t::max_size()
19094 return m_value.object->max_size();
19095 }
19096
19097 default:
19098 {
19099 // all other types have max_size() == size()
19100 return size();
19101 }
19102 }
19103 }
19104
19105 /// @}
19106
19107
19108 ///////////////
19109 // modifiers //
19110 ///////////////
19111
19112 /// @name modifiers
19113 /// @{
19114
19115 /*!
19116 @brief clears the contents
19117
19118 Clears the content of a JSON value and resets it to the default value as
19119 if @ref basic_json(value_t) would have been called with the current value
19120 type from @ref type():
19121
19122 Value type | initial value
19123 ----------- | -------------
19124 null | `null`
19125 boolean | `false`
19126 string | `""`
19127 number | `0`
19128 object | `{}`
19129 array | `[]`
19130
19131 @post Has the same effect as calling
19132 @code {.cpp}
19133 *this = basic_json(type());
19134 @endcode
19135
19136 @liveexample{The example below shows the effect of `clear()` to different
19137 JSON types.,clear}
19138
19139 @complexity Linear in the size of the JSON value.
19140
19141 @iterators All iterators, pointers and references related to this container
19142 are invalidated.
19143
19144 @exceptionsafety No-throw guarantee: this function never throws exceptions.
19145
19146 @sa @ref basic_json(value_t) -- constructor that creates an object with the
19147 same value than calling `clear()`
19148
19149 @since version 1.0.0
19150 */
19151 void clear() noexcept
19152 {
19153 switch (m_type)
19154 {
19155 case value_t::number_integer:
19156 {
19157 m_value.number_integer = 0;
19158 break;
19159 }
19160
19161 case value_t::number_unsigned:
19162 {
19163 m_value.number_unsigned = 0;
19164 break;
19165 }
19166
19167 case value_t::number_float:
19168 {
19169 m_value.number_float = 0.0;
19170 break;
19171 }
19172
19173 case value_t::boolean:
19174 {
19175 m_value.boolean = false;
19176 break;
19177 }
19178
19179 case value_t::string:
19180 {
19181 m_value.string->clear();
19182 break;
19183 }
19184
19185 case value_t::array:
19186 {
19187 m_value.array->clear();
19188 break;
19189 }
19190
19191 case value_t::object:
19192 {
19193 m_value.object->clear();
19194 break;
19195 }
19196
19197 default:
19198 break;
19199 }
19200 }
19201
19202 /*!
19203 @brief add an object to an array
19204
19205 Appends the given element @a val to the end of the JSON value. If the
19206 function is called on a JSON null value, an empty array is created before
19207 appending @a val.
19208
19209 @param[in] val the value to add to the JSON array
19210
19211 @throw type_error.308 when called on a type other than JSON array or
19212 null; example: `"cannot use push_back() with number"`
19213
19214 @complexity Amortized constant.
19215
19216 @liveexample{The example shows how `push_back()` and `+=` can be used to
19217 add elements to a JSON array. Note how the `null` value was silently
19218 converted to a JSON array.,push_back}
19219
19220 @since version 1.0.0
19221 */
19222 void push_back(basic_json&& val)
19223 {
19224 // push_back only works for null objects or arrays
19225 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
19226 {
19227 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
19228 }
19229
19230 // transform null object into an array
19231 if (is_null())
19232 {
19233 m_type = value_t::array;
19234 m_value = value_t::array;
19235 assert_invariant();
19236 }
19237
19238 // add element to array (move semantics)
19239 m_value.array->push_back(std::move(val));
19240 // invalidate object: mark it null so we do not call the destructor
19241 // cppcheck-suppress accessMoved
19242 val.m_type = value_t::null;
19243 }
19244
19245 /*!
19246 @brief add an object to an array
19247 @copydoc push_back(basic_json&&)
19248 */
19249 reference operator+=(basic_json&& val)
19250 {
19251 push_back(std::move(val));
19252 return *this;
19253 }
19254
19255 /*!
19256 @brief add an object to an array
19257 @copydoc push_back(basic_json&&)
19258 */
19259 void push_back(const basic_json& val)
19260 {
19261 // push_back only works for null objects or arrays
19262 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
19263 {
19264 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
19265 }
19266
19267 // transform null object into an array
19268 if (is_null())
19269 {
19270 m_type = value_t::array;
19271 m_value = value_t::array;
19272 assert_invariant();
19273 }
19274
19275 // add element to array
19276 m_value.array->push_back(val);
19277 }
19278
19279 /*!
19280 @brief add an object to an array
19281 @copydoc push_back(basic_json&&)
19282 */
19283 reference operator+=(const basic_json& val)
19284 {
19285 push_back(val);
19286 return *this;
19287 }
19288
19289 /*!
19290 @brief add an object to an object
19291
19292 Inserts the given element @a val to the JSON object. If the function is
19293 called on a JSON null value, an empty object is created before inserting
19294 @a val.
19295
19296 @param[in] val the value to add to the JSON object
19297
19298 @throw type_error.308 when called on a type other than JSON object or
19299 null; example: `"cannot use push_back() with number"`
19300
19301 @complexity Logarithmic in the size of the container, O(log(`size()`)).
19302
19303 @liveexample{The example shows how `push_back()` and `+=` can be used to
19304 add elements to a JSON object. Note how the `null` value was silently
19305 converted to a JSON object.,push_back__object_t__value}
19306
19307 @since version 1.0.0
19308 */
19309 void push_back(const typename object_t::value_type& val)
19310 {
19311 // push_back only works for null objects or objects
19312 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_object())))
19313 {
19314 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
19315 }
19316
19317 // transform null object into an object
19318 if (is_null())
19319 {
19320 m_type = value_t::object;
19321 m_value = value_t::object;
19322 assert_invariant();
19323 }
19324
19325 // add element to array
19326 m_value.object->insert(val);
19327 }
19328
19329 /*!
19330 @brief add an object to an object
19331 @copydoc push_back(const typename object_t::value_type&)
19332 */
19333 reference operator+=(const typename object_t::value_type& val)
19334 {
19335 push_back(val);
19336 return *this;
19337 }
19338
19339 /*!
19340 @brief add an object to an object
19341
19342 This function allows to use `push_back` with an initializer list. In case
19343
19344 1. the current value is an object,
19345 2. the initializer list @a init contains only two elements, and
19346 3. the first element of @a init is a string,
19347
19348 @a init is converted into an object element and added using
19349 @ref push_back(const typename object_t::value_type&). Otherwise, @a init
19350 is converted to a JSON value and added using @ref push_back(basic_json&&).
19351
19352 @param[in] init an initializer list
19353
19354 @complexity Linear in the size of the initializer list @a init.
19355
19356 @note This function is required to resolve an ambiguous overload error,
19357 because pairs like `{"key", "value"}` can be both interpreted as
19358 `object_t::value_type` or `std::initializer_list<basic_json>`, see
19359 https://github.com/nlohmann/json/issues/235 for more information.
19360
19361 @liveexample{The example shows how initializer lists are treated as
19362 objects when possible.,push_back__initializer_list}
19363 */
19364 void push_back(initializer_list_t init)
19365 {
19366 if (is_object() and init.size() == 2 and (*init.begin())->is_string())
19367 {
19368 basic_json&& key = init.begin()->moved_or_copied();
19369 push_back(typename object_t::value_type(
19370 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
19371 }
19372 else
19373 {
19374 push_back(basic_json(init));
19375 }
19376 }
19377
19378 /*!
19379 @brief add an object to an object
19380 @copydoc push_back(initializer_list_t)
19381 */
19382 reference operator+=(initializer_list_t init)
19383 {
19384 push_back(init);
19385 return *this;
19386 }
19387
19388 /*!
19389 @brief add an object to an array
19390
19391 Creates a JSON value from the passed parameters @a args to the end of the
19392 JSON value. If the function is called on a JSON null value, an empty array
19393 is created before appending the value created from @a args.
19394
19395 @param[in] args arguments to forward to a constructor of @ref basic_json
19396 @tparam Args compatible types to create a @ref basic_json object
19397
19398 @return reference to the inserted element
19399
19400 @throw type_error.311 when called on a type other than JSON array or
19401 null; example: `"cannot use emplace_back() with number"`
19402
19403 @complexity Amortized constant.
19404
19405 @liveexample{The example shows how `push_back()` can be used to add
19406 elements to a JSON array. Note how the `null` value was silently converted
19407 to a JSON array.,emplace_back}
19408
19409 @since version 2.0.8, returns reference since 3.7.0
19410 */
19411 template<class... Args>
19412 reference emplace_back(Args&& ... args)
19413 {
19414 // emplace_back only works for null objects or arrays
19415 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
19416 {
19417 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
19418 }
19419
19420 // transform null object into an array
19421 if (is_null())
19422 {
19423 m_type = value_t::array;
19424 m_value = value_t::array;
19425 assert_invariant();
19426 }
19427
19428 // add element to array (perfect forwarding)
19429 #ifdef JSON_HAS_CPP_17
19430 return m_value.array->emplace_back(std::forward<Args>(args)...);
19431 #else
19432 m_value.array->emplace_back(std::forward<Args>(args)...);
19433 return m_value.array->back();
19434 #endif
19435 }
19436
19437 /*!
19438 @brief add an object to an object if key does not exist
19439
19440 Inserts a new element into a JSON object constructed in-place with the
19441 given @a args if there is no element with the key in the container. If the
19442 function is called on a JSON null value, an empty object is created before
19443 appending the value created from @a args.
19444
19445 @param[in] args arguments to forward to a constructor of @ref basic_json
19446 @tparam Args compatible types to create a @ref basic_json object
19447
19448 @return a pair consisting of an iterator to the inserted element, or the
19449 already-existing element if no insertion happened, and a bool
19450 denoting whether the insertion took place.
19451
19452 @throw type_error.311 when called on a type other than JSON object or
19453 null; example: `"cannot use emplace() with number"`
19454
19455 @complexity Logarithmic in the size of the container, O(log(`size()`)).
19456
19457 @liveexample{The example shows how `emplace()` can be used to add elements
19458 to a JSON object. Note how the `null` value was silently converted to a
19459 JSON object. Further note how no value is added if there was already one
19460 value stored with the same key.,emplace}
19461
19462 @since version 2.0.8
19463 */
19464 template<class... Args>
19465 std::pair<iterator, bool> emplace(Args&& ... args)
19466 {
19467 // emplace only works for null objects or arrays
19468 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_object())))
19469 {
19470 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
19471 }
19472
19473 // transform null object into an object
19474 if (is_null())
19475 {
19476 m_type = value_t::object;
19477 m_value = value_t::object;
19478 assert_invariant();
19479 }
19480
19481 // add element to array (perfect forwarding)
19482 auto res = m_value.object->emplace(std::forward<Args>(args)...);
19483 // create result iterator and set iterator to the result of emplace
19484 auto it = begin();
19485 it.m_it.object_iterator = res.first;
19486
19487 // return pair of iterator and boolean
19488 return {it, res.second};
19489 }
19490
19491 /// Helper for insertion of an iterator
19492 /// @note: This uses std::distance to support GCC 4.8,
19493 /// see https://github.com/nlohmann/json/pull/1257
19494 template<typename... Args>
19495 iterator insert_iterator(const_iterator pos, Args&& ... args)
19496 {
19497 iterator result(this);
19498 assert(m_value.array != nullptr);
19499
19500 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
19501 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
19502 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
19503
19504 // This could have been written as:
19505 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
19506 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
19507
19508 return result;
19509 }
19510
19511 /*!
19512 @brief inserts element
19513
19514 Inserts element @a val before iterator @a pos.
19515
19516 @param[in] pos iterator before which the content will be inserted; may be
19517 the end() iterator
19518 @param[in] val element to insert
19519 @return iterator pointing to the inserted @a val.
19520
19521 @throw type_error.309 if called on JSON values other than arrays;
19522 example: `"cannot use insert() with string"`
19523 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
19524 example: `"iterator does not fit current value"`
19525
19526 @complexity Constant plus linear in the distance between @a pos and end of
19527 the container.
19528
19529 @liveexample{The example shows how `insert()` is used.,insert}
19530
19531 @since version 1.0.0
19532 */
19533 iterator insert(const_iterator pos, const basic_json& val)
19534 {
19535 // insert only works for arrays
19536 if (JSON_HEDLEY_LIKELY(is_array()))
19537 {
19538 // check if iterator pos fits to this JSON value
19539 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
19540 {
19541 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
19542 }
19543
19544 // insert to array and return iterator
19545 return insert_iterator(pos, val);
19546 }
19547
19548 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
19549 }
19550
19551 /*!
19552 @brief inserts element
19553 @copydoc insert(const_iterator, const basic_json&)
19554 */
19555 iterator insert(const_iterator pos, basic_json&& val)
19556 {
19557 return insert(pos, val);
19558 }
19559
19560 /*!
19561 @brief inserts elements
19562
19563 Inserts @a cnt copies of @a val before iterator @a pos.
19564
19565 @param[in] pos iterator before which the content will be inserted; may be
19566 the end() iterator
19567 @param[in] cnt number of copies of @a val to insert
19568 @param[in] val element to insert
19569 @return iterator pointing to the first element inserted, or @a pos if
19570 `cnt==0`
19571
19572 @throw type_error.309 if called on JSON values other than arrays; example:
19573 `"cannot use insert() with string"`
19574 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
19575 example: `"iterator does not fit current value"`
19576
19577 @complexity Linear in @a cnt plus linear in the distance between @a pos
19578 and end of the container.
19579
19580 @liveexample{The example shows how `insert()` is used.,insert__count}
19581
19582 @since version 1.0.0
19583 */
19584 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
19585 {
19586 // insert only works for arrays
19587 if (JSON_HEDLEY_LIKELY(is_array()))
19588 {
19589 // check if iterator pos fits to this JSON value
19590 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
19591 {
19592 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
19593 }
19594
19595 // insert to array and return iterator
19596 return insert_iterator(pos, cnt, val);
19597 }
19598
19599 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
19600 }
19601
19602 /*!
19603 @brief inserts elements
19604
19605 Inserts elements from range `[first, last)` before iterator @a pos.
19606
19607 @param[in] pos iterator before which the content will be inserted; may be
19608 the end() iterator
19609 @param[in] first begin of the range of elements to insert
19610 @param[in] last end of the range of elements to insert
19611
19612 @throw type_error.309 if called on JSON values other than arrays; example:
19613 `"cannot use insert() with string"`
19614 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
19615 example: `"iterator does not fit current value"`
19616 @throw invalid_iterator.210 if @a first and @a last do not belong to the
19617 same JSON value; example: `"iterators do not fit"`
19618 @throw invalid_iterator.211 if @a first or @a last are iterators into
19619 container for which insert is called; example: `"passed iterators may not
19620 belong to container"`
19621
19622 @return iterator pointing to the first element inserted, or @a pos if
19623 `first==last`
19624
19625 @complexity Linear in `std::distance(first, last)` plus linear in the
19626 distance between @a pos and end of the container.
19627
19628 @liveexample{The example shows how `insert()` is used.,insert__range}
19629
19630 @since version 1.0.0
19631 */
19632 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
19633 {
19634 // insert only works for arrays
19635 if (JSON_HEDLEY_UNLIKELY(not is_array()))
19636 {
19637 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
19638 }
19639
19640 // check if iterator pos fits to this JSON value
19641 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
19642 {
19643 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
19644 }
19645
19646 // check if range iterators belong to the same JSON object
19647 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19648 {
19649 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
19650 }
19651
19652 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
19653 {
19654 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
19655 }
19656
19657 // insert to array and return iterator
19658 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
19659 }
19660
19661 /*!
19662 @brief inserts elements
19663
19664 Inserts elements from initializer list @a ilist before iterator @a pos.
19665
19666 @param[in] pos iterator before which the content will be inserted; may be
19667 the end() iterator
19668 @param[in] ilist initializer list to insert the values from
19669
19670 @throw type_error.309 if called on JSON values other than arrays; example:
19671 `"cannot use insert() with string"`
19672 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
19673 example: `"iterator does not fit current value"`
19674
19675 @return iterator pointing to the first element inserted, or @a pos if
19676 `ilist` is empty
19677
19678 @complexity Linear in `ilist.size()` plus linear in the distance between
19679 @a pos and end of the container.
19680
19681 @liveexample{The example shows how `insert()` is used.,insert__ilist}
19682
19683 @since version 1.0.0
19684 */
19685 iterator insert(const_iterator pos, initializer_list_t ilist)
19686 {
19687 // insert only works for arrays
19688 if (JSON_HEDLEY_UNLIKELY(not is_array()))
19689 {
19690 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
19691 }
19692
19693 // check if iterator pos fits to this JSON value
19694 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
19695 {
19696 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
19697 }
19698
19699 // insert to array and return iterator
19700 return insert_iterator(pos, ilist.begin(), ilist.end());
19701 }
19702
19703 /*!
19704 @brief inserts elements
19705
19706 Inserts elements from range `[first, last)`.
19707
19708 @param[in] first begin of the range of elements to insert
19709 @param[in] last end of the range of elements to insert
19710
19711 @throw type_error.309 if called on JSON values other than objects; example:
19712 `"cannot use insert() with string"`
19713 @throw invalid_iterator.202 if iterator @a first or @a last does does not
19714 point to an object; example: `"iterators first and last must point to
19715 objects"`
19716 @throw invalid_iterator.210 if @a first and @a last do not belong to the
19717 same JSON value; example: `"iterators do not fit"`
19718
19719 @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
19720 of elements to insert.
19721
19722 @liveexample{The example shows how `insert()` is used.,insert__range_object}
19723
19724 @since version 3.0.0
19725 */
19726 void insert(const_iterator first, const_iterator last)
19727 {
19728 // insert only works for objects
19729 if (JSON_HEDLEY_UNLIKELY(not is_object()))
19730 {
19731 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
19732 }
19733
19734 // check if range iterators belong to the same JSON object
19735 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19736 {
19737 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
19738 }
19739
19740 // passed iterators must belong to objects
19741 if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object()))
19742 {
19743 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
19744 }
19745
19746 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
19747 }
19748
19749 /*!
19750 @brief updates a JSON object from another object, overwriting existing keys
19751
19752 Inserts all values from JSON object @a j and overwrites existing keys.
19753
19754 @param[in] j JSON object to read values from
19755
19756 @throw type_error.312 if called on JSON values other than objects; example:
19757 `"cannot use update() with string"`
19758
19759 @complexity O(N*log(size() + N)), where N is the number of elements to
19760 insert.
19761
19762 @liveexample{The example shows how `update()` is used.,update}
19763
19764 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
19765
19766 @since version 3.0.0
19767 */
19768 void update(const_reference j)
19769 {
19770 // implicitly convert null value to an empty object
19771 if (is_null())
19772 {
19773 m_type = value_t::object;
19774 m_value.object = create<object_t>();
19775 assert_invariant();
19776 }
19777
19778 if (JSON_HEDLEY_UNLIKELY(not is_object()))
19779 {
19780 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
19781 }
19782 if (JSON_HEDLEY_UNLIKELY(not j.is_object()))
19783 {
19784 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
19785 }
19786
19787 for (auto it = j.cbegin(); it != j.cend(); ++it)
19788 {
19789 m_value.object->operator[](it.key()) = it.value();
19790 }
19791 }
19792
19793 /*!
19794 @brief updates a JSON object from another object, overwriting existing keys
19795
19796 Inserts all values from from range `[first, last)` and overwrites existing
19797 keys.
19798
19799 @param[in] first begin of the range of elements to insert
19800 @param[in] last end of the range of elements to insert
19801
19802 @throw type_error.312 if called on JSON values other than objects; example:
19803 `"cannot use update() with string"`
19804 @throw invalid_iterator.202 if iterator @a first or @a last does does not
19805 point to an object; example: `"iterators first and last must point to
19806 objects"`
19807 @throw invalid_iterator.210 if @a first and @a last do not belong to the
19808 same JSON value; example: `"iterators do not fit"`
19809
19810 @complexity O(N*log(size() + N)), where N is the number of elements to
19811 insert.
19812
19813 @liveexample{The example shows how `update()` is used__range.,update}
19814
19815 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
19816
19817 @since version 3.0.0
19818 */
19819 void update(const_iterator first, const_iterator last)
19820 {
19821 // implicitly convert null value to an empty object
19822 if (is_null())
19823 {
19824 m_type = value_t::object;
19825 m_value.object = create<object_t>();
19826 assert_invariant();
19827 }
19828
19829 if (JSON_HEDLEY_UNLIKELY(not is_object()))
19830 {
19831 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
19832 }
19833
19834 // check if range iterators belong to the same JSON object
19835 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19836 {
19837 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
19838 }
19839
19840 // passed iterators must belong to objects
19841 if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object()
19842 or not last.m_object->is_object()))
19843 {
19844 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
19845 }
19846
19847 for (auto it = first; it != last; ++it)
19848 {
19849 m_value.object->operator[](it.key()) = it.value();
19850 }
19851 }
19852
19853 /*!
19854 @brief exchanges the values
19855
19856 Exchanges the contents of the JSON value with those of @a other. Does not
19857 invoke any move, copy, or swap operations on individual elements. All
19858 iterators and references remain valid. The past-the-end iterator is
19859 invalidated.
19860
19861 @param[in,out] other JSON value to exchange the contents with
19862
19863 @complexity Constant.
19864
19865 @liveexample{The example below shows how JSON values can be swapped with
19866 `swap()`.,swap__reference}
19867
19868 @since version 1.0.0
19869 */
19870 void swap(reference other) noexcept (
19871 std::is_nothrow_move_constructible<value_t>::value and
19872 std::is_nothrow_move_assignable<value_t>::value and
19873 std::is_nothrow_move_constructible<json_value>::value and
19874 std::is_nothrow_move_assignable<json_value>::value
19875 )
19876 {
19877 std::swap(m_type, other.m_type);
19878 std::swap(m_value, other.m_value);
19879 assert_invariant();
19880 }
19881
19882 /*!
19883 @brief exchanges the values
19884
19885 Exchanges the contents of a JSON array with those of @a other. Does not
19886 invoke any move, copy, or swap operations on individual elements. All
19887 iterators and references remain valid. The past-the-end iterator is
19888 invalidated.
19889
19890 @param[in,out] other array to exchange the contents with
19891
19892 @throw type_error.310 when JSON value is not an array; example: `"cannot
19893 use swap() with string"`
19894
19895 @complexity Constant.
19896
19897 @liveexample{The example below shows how arrays can be swapped with
19898 `swap()`.,swap__array_t}
19899
19900 @since version 1.0.0
19901 */
19902 void swap(array_t& other)
19903 {
19904 // swap only works for arrays
19905 if (JSON_HEDLEY_LIKELY(is_array()))
19906 {
19907 std::swap(*(m_value.array), other);
19908 }
19909 else
19910 {
19911 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
19912 }
19913 }
19914
19915 /*!
19916 @brief exchanges the values
19917
19918 Exchanges the contents of a JSON object with those of @a other. Does not
19919 invoke any move, copy, or swap operations on individual elements. All
19920 iterators and references remain valid. The past-the-end iterator is
19921 invalidated.
19922
19923 @param[in,out] other object to exchange the contents with
19924
19925 @throw type_error.310 when JSON value is not an object; example:
19926 `"cannot use swap() with string"`
19927
19928 @complexity Constant.
19929
19930 @liveexample{The example below shows how objects can be swapped with
19931 `swap()`.,swap__object_t}
19932
19933 @since version 1.0.0
19934 */
19935 void swap(object_t& other)
19936 {
19937 // swap only works for objects
19938 if (JSON_HEDLEY_LIKELY(is_object()))
19939 {
19940 std::swap(*(m_value.object), other);
19941 }
19942 else
19943 {
19944 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
19945 }
19946 }
19947
19948 /*!
19949 @brief exchanges the values
19950
19951 Exchanges the contents of a JSON string with those of @a other. Does not
19952 invoke any move, copy, or swap operations on individual elements. All
19953 iterators and references remain valid. The past-the-end iterator is
19954 invalidated.
19955
19956 @param[in,out] other string to exchange the contents with
19957
19958 @throw type_error.310 when JSON value is not a string; example: `"cannot
19959 use swap() with boolean"`
19960
19961 @complexity Constant.
19962
19963 @liveexample{The example below shows how strings can be swapped with
19964 `swap()`.,swap__string_t}
19965
19966 @since version 1.0.0
19967 */
19968 void swap(string_t& other)
19969 {
19970 // swap only works for strings
19971 if (JSON_HEDLEY_LIKELY(is_string()))
19972 {
19973 std::swap(*(m_value.string), other);
19974 }
19975 else
19976 {
19977 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
19978 }
19979 }
19980
19981 /// @}
19982
19983 public:
19984 //////////////////////////////////////////
19985 // lexicographical comparison operators //
19986 //////////////////////////////////////////
19987
19988 /// @name lexicographical comparison operators
19989 /// @{
19990
19991 /*!
19992 @brief comparison: equal
19993
19994 Compares two JSON values for equality according to the following rules:
19995 - Two JSON values are equal if (1) they are from the same type and (2)
19996 their stored values are the same according to their respective
19997 `operator==`.
19998 - Integer and floating-point numbers are automatically converted before
19999 comparison. Note than two NaN values are always treated as unequal.
20000 - Two JSON null values are equal.
20001
20002 @note Floating-point inside JSON values numbers are compared with
20003 `json::number_float_t::operator==` which is `double::operator==` by
20004 default. To compare floating-point while respecting an epsilon, an alternative
20005 [comparison function](https://github.com/mariokonrad/marnav/blob/master/src/marnav/math/floatingpoint.hpp#L34-#L39)
20006 could be used, for instance
20007 @code {.cpp}
20008 template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
20009 inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
20010 {
20011 return std::abs(a - b) <= epsilon;
20012 }
20013 @endcode
20014
20015 @note NaN values never compare equal to themselves or to other NaN values.
20016
20017 @param[in] lhs first JSON value to consider
20018 @param[in] rhs second JSON value to consider
20019 @return whether the values @a lhs and @a rhs are equal
20020
20021 @exceptionsafety No-throw guarantee: this function never throws exceptions.
20022
20023 @complexity Linear.
20024
20025 @liveexample{The example demonstrates comparing several JSON
20026 types.,operator__equal}
20027
20028 @since version 1.0.0
20029 */
20030 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
20031 {
20032 const auto lhs_type = lhs.type();
20033 const auto rhs_type = rhs.type();
20034
20035 if (lhs_type == rhs_type)
20036 {
20037 switch (lhs_type)
20038 {
20039 case value_t::array:
20040 return *lhs.m_value.array == *rhs.m_value.array;
20041
20042 case value_t::object:
20043 return *lhs.m_value.object == *rhs.m_value.object;
20044
20045 case value_t::null:
20046 return true;
20047
20048 case value_t::string:
20049 return *lhs.m_value.string == *rhs.m_value.string;
20050
20051 case value_t::boolean:
20052 return lhs.m_value.boolean == rhs.m_value.boolean;
20053
20054 case value_t::number_integer:
20055 return lhs.m_value.number_integer == rhs.m_value.number_integer;
20056
20057 case value_t::number_unsigned:
20058 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
20059
20060 case value_t::number_float:
20061 return lhs.m_value.number_float == rhs.m_value.number_float;
20062
20063 default:
20064 return false;
20065 }
20066 }
20067 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
20068 {
20069 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
20070 }
20071 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
20072 {
20073 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
20074 }
20075 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
20076 {
20077 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
20078 }
20079 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
20080 {
20081 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
20082 }
20083 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
20084 {
20085 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
20086 }
20087 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
20088 {
20089 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
20090 }
20091
20092 return false;
20093 }
20094
20095 /*!
20096 @brief comparison: equal
20097 @copydoc operator==(const_reference, const_reference)
20098 */
20099 template<typename ScalarType, typename std::enable_if<
20100 std::is_scalar<ScalarType>::value, int>::type = 0>
20101 friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
20102 {
20103 return lhs == basic_json(rhs);
20104 }
20105
20106 /*!
20107 @brief comparison: equal
20108 @copydoc operator==(const_reference, const_reference)
20109 */
20110 template<typename ScalarType, typename std::enable_if<
20111 std::is_scalar<ScalarType>::value, int>::type = 0>
20112 friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
20113 {
20114 return basic_json(lhs) == rhs;
20115 }
20116
20117 /*!
20118 @brief comparison: not equal
20119
20120 Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
20121
20122 @param[in] lhs first JSON value to consider
20123 @param[in] rhs second JSON value to consider
20124 @return whether the values @a lhs and @a rhs are not equal
20125
20126 @complexity Linear.
20127
20128 @exceptionsafety No-throw guarantee: this function never throws exceptions.
20129
20130 @liveexample{The example demonstrates comparing several JSON
20131 types.,operator__notequal}
20132
20133 @since version 1.0.0
20134 */
20135 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
20136 {
20137 return not (lhs == rhs);
20138 }
20139
20140 /*!
20141 @brief comparison: not equal
20142 @copydoc operator!=(const_reference, const_reference)
20143 */
20144 template<typename ScalarType, typename std::enable_if<
20145 std::is_scalar<ScalarType>::value, int>::type = 0>
20146 friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
20147 {
20148 return lhs != basic_json(rhs);
20149 }
20150
20151 /*!
20152 @brief comparison: not equal
20153 @copydoc operator!=(const_reference, const_reference)
20154 */
20155 template<typename ScalarType, typename std::enable_if<
20156 std::is_scalar<ScalarType>::value, int>::type = 0>
20157 friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
20158 {
20159 return basic_json(lhs) != rhs;
20160 }
20161
20162 /*!
20163 @brief comparison: less than
20164
20165 Compares whether one JSON value @a lhs is less than another JSON value @a
20166 rhs according to the following rules:
20167 - If @a lhs and @a rhs have the same type, the values are compared using
20168 the default `<` operator.
20169 - Integer and floating-point numbers are automatically converted before
20170 comparison
20171 - In case @a lhs and @a rhs have different types, the values are ignored
20172 and the order of the types is considered, see
20173 @ref operator<(const value_t, const value_t).
20174
20175 @param[in] lhs first JSON value to consider
20176 @param[in] rhs second JSON value to consider
20177 @return whether @a lhs is less than @a rhs
20178
20179 @complexity Linear.
20180
20181 @exceptionsafety No-throw guarantee: this function never throws exceptions.
20182
20183 @liveexample{The example demonstrates comparing several JSON
20184 types.,operator__less}
20185
20186 @since version 1.0.0
20187 */
20188 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
20189 {
20190 const auto lhs_type = lhs.type();
20191 const auto rhs_type = rhs.type();
20192
20193 if (lhs_type == rhs_type)
20194 {
20195 switch (lhs_type)
20196 {
20197 case value_t::array:
20198 // note parentheses are necessary, see
20199 // https://github.com/nlohmann/json/issues/1530
20200 return (*lhs.m_value.array) < (*rhs.m_value.array);
20201
20202 case value_t::object:
20203 return (*lhs.m_value.object) < (*rhs.m_value.object);
20204
20205 case value_t::null:
20206 return false;
20207
20208 case value_t::string:
20209 return (*lhs.m_value.string) < (*rhs.m_value.string);
20210
20211 case value_t::boolean:
20212 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
20213
20214 case value_t::number_integer:
20215 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
20216
20217 case value_t::number_unsigned:
20218 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
20219
20220 case value_t::number_float:
20221 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
20222
20223 default:
20224 return false;
20225 }
20226 }
20227 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
20228 {
20229 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
20230 }
20231 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
20232 {
20233 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
20234 }
20235 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
20236 {
20237 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
20238 }
20239 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
20240 {
20241 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
20242 }
20243 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
20244 {
20245 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
20246 }
20247 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
20248 {
20249 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
20250 }
20251
20252 // We only reach this line if we cannot compare values. In that case,
20253 // we compare types. Note we have to call the operator explicitly,
20254 // because MSVC has problems otherwise.
20255 return operator<(lhs_type, rhs_type);
20256 }
20257
20258 /*!
20259 @brief comparison: less than
20260 @copydoc operator<(const_reference, const_reference)
20261 */
20262 template<typename ScalarType, typename std::enable_if<
20263 std::is_scalar<ScalarType>::value, int>::type = 0>
20264 friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
20265 {
20266 return lhs < basic_json(rhs);
20267 }
20268
20269 /*!
20270 @brief comparison: less than
20271 @copydoc operator<(const_reference, const_reference)
20272 */
20273 template<typename ScalarType, typename std::enable_if<
20274 std::is_scalar<ScalarType>::value, int>::type = 0>
20275 friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
20276 {
20277 return basic_json(lhs) < rhs;
20278 }
20279
20280 /*!
20281 @brief comparison: less than or equal
20282
20283 Compares whether one JSON value @a lhs is less than or equal to another
20284 JSON value by calculating `not (rhs < lhs)`.
20285
20286 @param[in] lhs first JSON value to consider
20287 @param[in] rhs second JSON value to consider
20288 @return whether @a lhs is less than or equal to @a rhs
20289
20290 @complexity Linear.
20291
20292 @exceptionsafety No-throw guarantee: this function never throws exceptions.
20293
20294 @liveexample{The example demonstrates comparing several JSON
20295 types.,operator__greater}
20296
20297 @since version 1.0.0
20298 */
20299 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
20300 {
20301 return not (rhs < lhs);
20302 }
20303
20304 /*!
20305 @brief comparison: less than or equal
20306 @copydoc operator<=(const_reference, const_reference)
20307 */
20308 template<typename ScalarType, typename std::enable_if<
20309 std::is_scalar<ScalarType>::value, int>::type = 0>
20310 friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
20311 {
20312 return lhs <= basic_json(rhs);
20313 }
20314
20315 /*!
20316 @brief comparison: less than or equal
20317 @copydoc operator<=(const_reference, const_reference)
20318 */
20319 template<typename ScalarType, typename std::enable_if<
20320 std::is_scalar<ScalarType>::value, int>::type = 0>
20321 friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
20322 {
20323 return basic_json(lhs) <= rhs;
20324 }
20325
20326 /*!
20327 @brief comparison: greater than
20328
20329 Compares whether one JSON value @a lhs is greater than another
20330 JSON value by calculating `not (lhs <= rhs)`.
20331
20332 @param[in] lhs first JSON value to consider
20333 @param[in] rhs second JSON value to consider
20334 @return whether @a lhs is greater than to @a rhs
20335
20336 @complexity Linear.
20337
20338 @exceptionsafety No-throw guarantee: this function never throws exceptions.
20339
20340 @liveexample{The example demonstrates comparing several JSON
20341 types.,operator__lessequal}
20342
20343 @since version 1.0.0
20344 */
20345 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
20346 {
20347 return not (lhs <= rhs);
20348 }
20349
20350 /*!
20351 @brief comparison: greater than
20352 @copydoc operator>(const_reference, const_reference)
20353 */
20354 template<typename ScalarType, typename std::enable_if<
20355 std::is_scalar<ScalarType>::value, int>::type = 0>
20356 friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
20357 {
20358 return lhs > basic_json(rhs);
20359 }
20360
20361 /*!
20362 @brief comparison: greater than
20363 @copydoc operator>(const_reference, const_reference)
20364 */
20365 template<typename ScalarType, typename std::enable_if<
20366 std::is_scalar<ScalarType>::value, int>::type = 0>
20367 friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
20368 {
20369 return basic_json(lhs) > rhs;
20370 }
20371
20372 /*!
20373 @brief comparison: greater than or equal
20374
20375 Compares whether one JSON value @a lhs is greater than or equal to another
20376 JSON value by calculating `not (lhs < rhs)`.
20377
20378 @param[in] lhs first JSON value to consider
20379 @param[in] rhs second JSON value to consider
20380 @return whether @a lhs is greater than or equal to @a rhs
20381
20382 @complexity Linear.
20383
20384 @exceptionsafety No-throw guarantee: this function never throws exceptions.
20385
20386 @liveexample{The example demonstrates comparing several JSON
20387 types.,operator__greaterequal}
20388
20389 @since version 1.0.0
20390 */
20391 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
20392 {
20393 return not (lhs < rhs);
20394 }
20395
20396 /*!
20397 @brief comparison: greater than or equal
20398 @copydoc operator>=(const_reference, const_reference)
20399 */
20400 template<typename ScalarType, typename std::enable_if<
20401 std::is_scalar<ScalarType>::value, int>::type = 0>
20402 friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
20403 {
20404 return lhs >= basic_json(rhs);
20405 }
20406
20407 /*!
20408 @brief comparison: greater than or equal
20409 @copydoc operator>=(const_reference, const_reference)
20410 */
20411 template<typename ScalarType, typename std::enable_if<
20412 std::is_scalar<ScalarType>::value, int>::type = 0>
20413 friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
20414 {
20415 return basic_json(lhs) >= rhs;
20416 }
20417
20418 /// @}
20419
20420 ///////////////////
20421 // serialization //
20422 ///////////////////
20423
20424 /// @name serialization
20425 /// @{
20426
20427 /*!
20428 @brief serialize to stream
20429
20430 Serialize the given JSON value @a j to the output stream @a o. The JSON
20431 value will be serialized using the @ref dump member function.
20432
20433 - The indentation of the output can be controlled with the member variable
20434 `width` of the output stream @a o. For instance, using the manipulator
20435 `std::setw(4)` on @a o sets the indentation level to `4` and the
20436 serialization result is the same as calling `dump(4)`.
20437
20438 - The indentation character can be controlled with the member variable
20439 `fill` of the output stream @a o. For instance, the manipulator
20440 `std::setfill('\\t')` sets indentation to use a tab character rather than
20441 the default space character.
20442
20443 @param[in,out] o stream to serialize to
20444 @param[in] j JSON value to serialize
20445
20446 @return the stream @a o
20447
20448 @throw type_error.316 if a string stored inside the JSON value is not
20449 UTF-8 encoded
20450
20451 @complexity Linear.
20452
20453 @liveexample{The example below shows the serialization with different
20454 parameters to `width` to adjust the indentation level.,operator_serialize}
20455
20456 @since version 1.0.0; indentation character added in version 3.0.0
20457 */
20458 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
20459 {
20460 // read width member and use it as indentation parameter if nonzero
20461 const bool pretty_print = o.width() > 0;
20462 const auto indentation = pretty_print ? o.width() : 0;
20463
20464 // reset width to 0 for subsequent calls to this stream
20465 o.width(0);
20466
20467 // do the actual serialization
20468 serializer s(detail::output_adapter<char>(o), o.fill());
20469 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
20470 return o;
20471 }
20472
20473 /*!
20474 @brief serialize to stream
20475 @deprecated This stream operator is deprecated and will be removed in
20476 future 4.0.0 of the library. Please use
20477 @ref operator<<(std::ostream&, const basic_json&)
20478 instead; that is, replace calls like `j >> o;` with `o << j;`.
20479 @since version 1.0.0; deprecated since version 3.0.0
20480 */
20481 JSON_HEDLEY_DEPRECATED(3.0.0)
20482 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
20483 {
20484 return o << j;
20485 }
20486
20487 /// @}
20488
20489
20490 /////////////////////
20491 // deserialization //
20492 /////////////////////
20493
20494 /// @name deserialization
20495 /// @{
20496
20497 /*!
20498 @brief deserialize from a compatible input
20499
20500 This function reads from a compatible input. Examples are:
20501 - an array of 1-byte values
20502 - strings with character/literal type with size of 1 byte
20503 - input streams
20504 - container with contiguous storage of 1-byte values. Compatible container
20505 types include `std::vector`, `std::string`, `std::array`,
20506 `std::valarray`, and `std::initializer_list`. Furthermore, C-style
20507 arrays can be used with `std::begin()`/`std::end()`. User-defined
20508 containers can be used as long as they implement random-access iterators
20509 and a contiguous storage.
20510
20511 @pre Each element of the container has a size of 1 byte. Violating this
20512 precondition yields undefined behavior. **This precondition is enforced
20513 with a static assertion.**
20514
20515 @pre The container storage is contiguous. Violating this precondition
20516 yields undefined behavior. **This precondition is enforced with an
20517 assertion.**
20518
20519 @warning There is no way to enforce all preconditions at compile-time. If
20520 the function is called with a noncompliant container and with
20521 assertions switched off, the behavior is undefined and will most
20522 likely yield segmentation violation.
20523
20524 @param[in] i input to read from
20525 @param[in] cb a parser callback function of type @ref parser_callback_t
20526 which is used to control the deserialization by filtering unwanted values
20527 (optional)
20528 @param[in] allow_exceptions whether to throw exceptions in case of a
20529 parse error (optional, true by default)
20530
20531 @return deserialized JSON value; in case of a parse error and
20532 @a allow_exceptions set to `false`, the return value will be
20533 value_t::discarded.
20534
20535 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
20536 of input; expected string literal""`
20537 @throw parse_error.102 if to_unicode fails or surrogate error
20538 @throw parse_error.103 if to_unicode fails
20539
20540 @complexity Linear in the length of the input. The parser is a predictive
20541 LL(1) parser. The complexity can be higher if the parser callback function
20542 @a cb has a super-linear complexity.
20543
20544 @note A UTF-8 byte order mark is silently ignored.
20545
20546 @liveexample{The example below demonstrates the `parse()` function reading
20547 from an array.,parse__array__parser_callback_t}
20548
20549 @liveexample{The example below demonstrates the `parse()` function with
20550 and without callback function.,parse__string__parser_callback_t}
20551
20552 @liveexample{The example below demonstrates the `parse()` function with
20553 and without callback function.,parse__istream__parser_callback_t}
20554
20555 @liveexample{The example below demonstrates the `parse()` function reading
20556 from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
20557
20558 @since version 2.0.3 (contiguous containers)
20559 */
20560 JSON_HEDLEY_WARN_UNUSED_RESULT
20561 static basic_json parse(detail::input_adapter&& i,
20562 const parser_callback_t cb = nullptr,
20563 const bool allow_exceptions = true)
20564 {
20565 basic_json result;
20566 parser(i, cb, allow_exceptions).parse(true, result);
20567 return result;
20568 }
20569
20570 static bool accept(detail::input_adapter&& i)
20571 {
20572 return parser(i).accept(true);
20573 }
20574
20575 /*!
20576 @brief generate SAX events
20577
20578 The SAX event lister must follow the interface of @ref json_sax.
20579
20580 This function reads from a compatible input. Examples are:
20581 - an array of 1-byte values
20582 - strings with character/literal type with size of 1 byte
20583 - input streams
20584 - container with contiguous storage of 1-byte values. Compatible container
20585 types include `std::vector`, `std::string`, `std::array`,
20586 `std::valarray`, and `std::initializer_list`. Furthermore, C-style
20587 arrays can be used with `std::begin()`/`std::end()`. User-defined
20588 containers can be used as long as they implement random-access iterators
20589 and a contiguous storage.
20590
20591 @pre Each element of the container has a size of 1 byte. Violating this
20592 precondition yields undefined behavior. **This precondition is enforced
20593 with a static assertion.**
20594
20595 @pre The container storage is contiguous. Violating this precondition
20596 yields undefined behavior. **This precondition is enforced with an
20597 assertion.**
20598
20599 @warning There is no way to enforce all preconditions at compile-time. If
20600 the function is called with a noncompliant container and with
20601 assertions switched off, the behavior is undefined and will most
20602 likely yield segmentation violation.
20603
20604 @param[in] i input to read from
20605 @param[in,out] sax SAX event listener
20606 @param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON)
20607 @param[in] strict whether the input has to be consumed completely
20608
20609 @return return value of the last processed SAX event
20610
20611 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
20612 of input; expected string literal""`
20613 @throw parse_error.102 if to_unicode fails or surrogate error
20614 @throw parse_error.103 if to_unicode fails
20615
20616 @complexity Linear in the length of the input. The parser is a predictive
20617 LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
20618 a super-linear complexity.
20619
20620 @note A UTF-8 byte order mark is silently ignored.
20621
20622 @liveexample{The example below demonstrates the `sax_parse()` function
20623 reading from string and processing the events with a user-defined SAX
20624 event consumer.,sax_parse}
20625
20626 @since version 3.2.0
20627 */
20628 template <typename SAX>
20629 JSON_HEDLEY_NON_NULL(2)
20630 static bool sax_parse(detail::input_adapter&& i, SAX* sax,
20631 input_format_t format = input_format_t::json,
20632 const bool strict = true)
20633 {
20634 assert(sax);
20635 return format == input_format_t::json
20636 ? parser(std::move(i)).sax_parse(sax, strict)
20637 : detail::binary_reader<basic_json, SAX>(std::move(i)).sax_parse(format, sax, strict);
20638 }
20639
20640 /*!
20641 @brief deserialize from an iterator range with contiguous storage
20642
20643 This function reads from an iterator range of a container with contiguous
20644 storage of 1-byte values. Compatible container types include
20645 `std::vector`, `std::string`, `std::array`, `std::valarray`, and
20646 `std::initializer_list`. Furthermore, C-style arrays can be used with
20647 `std::begin()`/`std::end()`. User-defined containers can be used as long
20648 as they implement random-access iterators and a contiguous storage.
20649
20650 @pre The iterator range is contiguous. Violating this precondition yields
20651 undefined behavior. **This precondition is enforced with an assertion.**
20652 @pre Each element in the range has a size of 1 byte. Violating this
20653 precondition yields undefined behavior. **This precondition is enforced
20654 with a static assertion.**
20655
20656 @warning There is no way to enforce all preconditions at compile-time. If
20657 the function is called with noncompliant iterators and with
20658 assertions switched off, the behavior is undefined and will most
20659 likely yield segmentation violation.
20660
20661 @tparam IteratorType iterator of container with contiguous storage
20662 @param[in] first begin of the range to parse (included)
20663 @param[in] last end of the range to parse (excluded)
20664 @param[in] cb a parser callback function of type @ref parser_callback_t
20665 which is used to control the deserialization by filtering unwanted values
20666 (optional)
20667 @param[in] allow_exceptions whether to throw exceptions in case of a
20668 parse error (optional, true by default)
20669
20670 @return deserialized JSON value; in case of a parse error and
20671 @a allow_exceptions set to `false`, the return value will be
20672 value_t::discarded.
20673
20674 @throw parse_error.101 in case of an unexpected token
20675 @throw parse_error.102 if to_unicode fails or surrogate error
20676 @throw parse_error.103 if to_unicode fails
20677
20678 @complexity Linear in the length of the input. The parser is a predictive
20679 LL(1) parser. The complexity can be higher if the parser callback function
20680 @a cb has a super-linear complexity.
20681
20682 @note A UTF-8 byte order mark is silently ignored.
20683
20684 @liveexample{The example below demonstrates the `parse()` function reading
20685 from an iterator range.,parse__iteratortype__parser_callback_t}
20686
20687 @since version 2.0.3
20688 */
20689 template<class IteratorType, typename std::enable_if<
20690 std::is_base_of<
20691 std::random_access_iterator_tag,
20692 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
20693 static basic_json parse(IteratorType first, IteratorType last,
20694 const parser_callback_t cb = nullptr,
20695 const bool allow_exceptions = true)
20696 {
20697 basic_json result;
20698 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
20699 return result;
20700 }
20701
20702 template<class IteratorType, typename std::enable_if<
20703 std::is_base_of<
20704 std::random_access_iterator_tag,
20705 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
20706 static bool accept(IteratorType first, IteratorType last)
20707 {
20708 return parser(detail::input_adapter(first, last)).accept(true);
20709 }
20710
20711 template<class IteratorType, class SAX, typename std::enable_if<
20712 std::is_base_of<
20713 std::random_access_iterator_tag,
20714 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
20715 JSON_HEDLEY_NON_NULL(3)
20716 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
20717 {
20718 return parser(detail::input_adapter(first, last)).sax_parse(sax);
20719 }
20720
20721 /*!
20722 @brief deserialize from stream
20723 @deprecated This stream operator is deprecated and will be removed in
20724 version 4.0.0 of the library. Please use
20725 @ref operator>>(std::istream&, basic_json&)
20726 instead; that is, replace calls like `j << i;` with `i >> j;`.
20727 @since version 1.0.0; deprecated since version 3.0.0
20728 */
20729 JSON_HEDLEY_DEPRECATED(3.0.0)
20730 friend std::istream& operator<<(basic_json& j, std::istream& i)
20731 {
20732 return operator>>(i, j);
20733 }
20734
20735 /*!
20736 @brief deserialize from stream
20737
20738 Deserializes an input stream to a JSON value.
20739
20740 @param[in,out] i input stream to read a serialized JSON value from
20741 @param[in,out] j JSON value to write the deserialized input to
20742
20743 @throw parse_error.101 in case of an unexpected token
20744 @throw parse_error.102 if to_unicode fails or surrogate error
20745 @throw parse_error.103 if to_unicode fails
20746
20747 @complexity Linear in the length of the input. The parser is a predictive
20748 LL(1) parser.
20749
20750 @note A UTF-8 byte order mark is silently ignored.
20751
20752 @liveexample{The example below shows how a JSON value is constructed by
20753 reading a serialization from a stream.,operator_deserialize}
20754
20755 @sa parse(std::istream&, const parser_callback_t) for a variant with a
20756 parser callback function to filter values while parsing
20757
20758 @since version 1.0.0
20759 */
20760 friend std::istream& operator>>(std::istream& i, basic_json& j)
20761 {
20762 parser(detail::input_adapter(i)).parse(false, j);
20763 return i;
20764 }
20765
20766 /// @}
20767
20768 ///////////////////////////
20769 // convenience functions //
20770 ///////////////////////////
20771
20772 /*!
20773 @brief return the type as string
20774
20775 Returns the type name as string to be used in error messages - usually to
20776 indicate that a function was called on a wrong JSON type.
20777
20778 @return a string representation of a the @a m_type member:
20779 Value type | return value
20780 ----------- | -------------
20781 null | `"null"`
20782 boolean | `"boolean"`
20783 string | `"string"`
20784 number | `"number"` (for all number types)
20785 object | `"object"`
20786 array | `"array"`
20787 discarded | `"discarded"`
20788
20789 @exceptionsafety No-throw guarantee: this function never throws exceptions.
20790
20791 @complexity Constant.
20792
20793 @liveexample{The following code exemplifies `type_name()` for all JSON
20794 types.,type_name}
20795
20796 @sa @ref type() -- return the type of the JSON value
20797 @sa @ref operator value_t() -- return the type of the JSON value (implicit)
20798
20799 @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
20800 since 3.0.0
20801 */
20802 JSON_HEDLEY_RETURNS_NON_NULL
20803 const char* type_name() const noexcept
20804 {
20805 {
20806 switch (m_type)
20807 {
20808 case value_t::null:
20809 return "null";
20810 case value_t::object:
20811 return "object";
20812 case value_t::array:
20813 return "array";
20814 case value_t::string:
20815 return "string";
20816 case value_t::boolean:
20817 return "boolean";
20818 case value_t::discarded:
20819 return "discarded";
20820 default:
20821 return "number";
20822 }
20823 }
20824 }
20825
20826
20827 private:
20828 //////////////////////
20829 // member variables //
20830 //////////////////////
20831
20832 /// the type of the current element
20833 value_t m_type = value_t::null;
20834
20835 /// the value of the current element
20836 json_value m_value = {};
20837
20838 //////////////////////////////////////////
20839 // binary serialization/deserialization //
20840 //////////////////////////////////////////
20841
20842 /// @name binary serialization/deserialization support
20843 /// @{
20844
20845 public:
20846 /*!
20847 @brief create a CBOR serialization of a given JSON value
20848
20849 Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
20850 Binary Object Representation) serialization format. CBOR is a binary
20851 serialization format which aims to be more compact than JSON itself, yet
20852 more efficient to parse.
20853
20854 The library uses the following mapping from JSON values types to
20855 CBOR types according to the CBOR specification (RFC 7049):
20856
20857 JSON value type | value/range | CBOR type | first byte
20858 --------------- | ------------------------------------------ | ---------------------------------- | ---------------
20859 null | `null` | Null | 0xF6
20860 boolean | `true` | True | 0xF5
20861 boolean | `false` | False | 0xF4
20862 number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B
20863 number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A
20864 number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39
20865 number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38
20866 number_integer | -24..-1 | Negative integer | 0x20..0x37
20867 number_integer | 0..23 | Integer | 0x00..0x17
20868 number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18
20869 number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
20870 number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
20871 number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
20872 number_unsigned | 0..23 | Integer | 0x00..0x17
20873 number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18
20874 number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
20875 number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
20876 number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
20877 number_float | *any value* | Double-Precision Float | 0xFB
20878 string | *length*: 0..23 | UTF-8 string | 0x60..0x77
20879 string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78
20880 string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79
20881 string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A
20882 string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B
20883 array | *size*: 0..23 | array | 0x80..0x97
20884 array | *size*: 23..255 | array (1 byte follow) | 0x98
20885 array | *size*: 256..65535 | array (2 bytes follow) | 0x99
20886 array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A
20887 array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B
20888 object | *size*: 0..23 | map | 0xA0..0xB7
20889 object | *size*: 23..255 | map (1 byte follow) | 0xB8
20890 object | *size*: 256..65535 | map (2 bytes follow) | 0xB9
20891 object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA
20892 object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB
20893
20894 @note The mapping is **complete** in the sense that any JSON value type
20895 can be converted to a CBOR value.
20896
20897 @note If NaN or Infinity are stored inside a JSON number, they are
20898 serialized properly. This behavior differs from the @ref dump()
20899 function which serializes NaN or Infinity to `null`.
20900
20901 @note The following CBOR types are not used in the conversion:
20902 - byte strings (0x40..0x5F)
20903 - UTF-8 strings terminated by "break" (0x7F)
20904 - arrays terminated by "break" (0x9F)
20905 - maps terminated by "break" (0xBF)
20906 - date/time (0xC0..0xC1)
20907 - bignum (0xC2..0xC3)
20908 - decimal fraction (0xC4)
20909 - bigfloat (0xC5)
20910 - tagged items (0xC6..0xD4, 0xD8..0xDB)
20911 - expected conversions (0xD5..0xD7)
20912 - simple values (0xE0..0xF3, 0xF8)
20913 - undefined (0xF7)
20914 - half and single-precision floats (0xF9-0xFA)
20915 - break (0xFF)
20916
20917 @param[in] j JSON value to serialize
20918 @return MessagePack serialization as byte vector
20919
20920 @complexity Linear in the size of the JSON value @a j.
20921
20922 @liveexample{The example shows the serialization of a JSON value to a byte
20923 vector in CBOR format.,to_cbor}
20924
20925 @sa http://cbor.io
20926 @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
20927 analogous deserialization
20928 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
20929 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
20930 related UBJSON format
20931
20932 @since version 2.0.9
20933 */
20934 static std::vector<uint8_t> to_cbor(const basic_json& j)
20935 {
20936 std::vector<uint8_t> result;
20937 to_cbor(j, result);
20938 return result;
20939 }
20940
20941 static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
20942 {
20943 binary_writer<uint8_t>(o).write_cbor(j);
20944 }
20945
20946 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
20947 {
20948 binary_writer<char>(o).write_cbor(j);
20949 }
20950
20951 /*!
20952 @brief create a MessagePack serialization of a given JSON value
20953
20954 Serializes a given JSON value @a j to a byte vector using the MessagePack
20955 serialization format. MessagePack is a binary serialization format which
20956 aims to be more compact than JSON itself, yet more efficient to parse.
20957
20958 The library uses the following mapping from JSON values types to
20959 MessagePack types according to the MessagePack specification:
20960
20961 JSON value type | value/range | MessagePack type | first byte
20962 --------------- | --------------------------------- | ---------------- | ----------
20963 null | `null` | nil | 0xC0
20964 boolean | `true` | true | 0xC3
20965 boolean | `false` | false | 0xC2
20966 number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3
20967 number_integer | -2147483648..-32769 | int32 | 0xD2
20968 number_integer | -32768..-129 | int16 | 0xD1
20969 number_integer | -128..-33 | int8 | 0xD0
20970 number_integer | -32..-1 | negative fixint | 0xE0..0xFF
20971 number_integer | 0..127 | positive fixint | 0x00..0x7F
20972 number_integer | 128..255 | uint 8 | 0xCC
20973 number_integer | 256..65535 | uint 16 | 0xCD
20974 number_integer | 65536..4294967295 | uint 32 | 0xCE
20975 number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF
20976 number_unsigned | 0..127 | positive fixint | 0x00..0x7F
20977 number_unsigned | 128..255 | uint 8 | 0xCC
20978 number_unsigned | 256..65535 | uint 16 | 0xCD
20979 number_unsigned | 65536..4294967295 | uint 32 | 0xCE
20980 number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF
20981 number_float | *any value* | float 64 | 0xCB
20982 string | *length*: 0..31 | fixstr | 0xA0..0xBF
20983 string | *length*: 32..255 | str 8 | 0xD9
20984 string | *length*: 256..65535 | str 16 | 0xDA
20985 string | *length*: 65536..4294967295 | str 32 | 0xDB
20986 array | *size*: 0..15 | fixarray | 0x90..0x9F
20987 array | *size*: 16..65535 | array 16 | 0xDC
20988 array | *size*: 65536..4294967295 | array 32 | 0xDD
20989 object | *size*: 0..15 | fix map | 0x80..0x8F
20990 object | *size*: 16..65535 | map 16 | 0xDE
20991 object | *size*: 65536..4294967295 | map 32 | 0xDF
20992
20993 @note The mapping is **complete** in the sense that any JSON value type
20994 can be converted to a MessagePack value.
20995
20996 @note The following values can **not** be converted to a MessagePack value:
20997 - strings with more than 4294967295 bytes
20998 - arrays with more than 4294967295 elements
20999 - objects with more than 4294967295 elements
21000
21001 @note The following MessagePack types are not used in the conversion:
21002 - bin 8 - bin 32 (0xC4..0xC6)
21003 - ext 8 - ext 32 (0xC7..0xC9)
21004 - float 32 (0xCA)
21005 - fixext 1 - fixext 16 (0xD4..0xD8)
21006
21007 @note Any MessagePack output created @ref to_msgpack can be successfully
21008 parsed by @ref from_msgpack.
21009
21010 @note If NaN or Infinity are stored inside a JSON number, they are
21011 serialized properly. This behavior differs from the @ref dump()
21012 function which serializes NaN or Infinity to `null`.
21013
21014 @param[in] j JSON value to serialize
21015 @return MessagePack serialization as byte vector
21016
21017 @complexity Linear in the size of the JSON value @a j.
21018
21019 @liveexample{The example shows the serialization of a JSON value to a byte
21020 vector in MessagePack format.,to_msgpack}
21021
21022 @sa http://msgpack.org
21023 @sa @ref from_msgpack for the analogous deserialization
21024 @sa @ref to_cbor(const basic_json& for the related CBOR format
21025 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
21026 related UBJSON format
21027
21028 @since version 2.0.9
21029 */
21030 static std::vector<uint8_t> to_msgpack(const basic_json& j)
21031 {
21032 std::vector<uint8_t> result;
21033 to_msgpack(j, result);
21034 return result;
21035 }
21036
21037 static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
21038 {
21039 binary_writer<uint8_t>(o).write_msgpack(j);
21040 }
21041
21042 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
21043 {
21044 binary_writer<char>(o).write_msgpack(j);
21045 }
21046
21047 /*!
21048 @brief create a UBJSON serialization of a given JSON value
21049
21050 Serializes a given JSON value @a j to a byte vector using the UBJSON
21051 (Universal Binary JSON) serialization format. UBJSON aims to be more compact
21052 than JSON itself, yet more efficient to parse.
21053
21054 The library uses the following mapping from JSON values types to
21055 UBJSON types according to the UBJSON specification:
21056
21057 JSON value type | value/range | UBJSON type | marker
21058 --------------- | --------------------------------- | ----------- | ------
21059 null | `null` | null | `Z`
21060 boolean | `true` | true | `T`
21061 boolean | `false` | false | `F`
21062 number_integer | -9223372036854775808..-2147483649 | int64 | `L`
21063 number_integer | -2147483648..-32769 | int32 | `l`
21064 number_integer | -32768..-129 | int16 | `I`
21065 number_integer | -128..127 | int8 | `i`
21066 number_integer | 128..255 | uint8 | `U`
21067 number_integer | 256..32767 | int16 | `I`
21068 number_integer | 32768..2147483647 | int32 | `l`
21069 number_integer | 2147483648..9223372036854775807 | int64 | `L`
21070 number_unsigned | 0..127 | int8 | `i`
21071 number_unsigned | 128..255 | uint8 | `U`
21072 number_unsigned | 256..32767 | int16 | `I`
21073 number_unsigned | 32768..2147483647 | int32 | `l`
21074 number_unsigned | 2147483648..9223372036854775807 | int64 | `L`
21075 number_float | *any value* | float64 | `D`
21076 string | *with shortest length indicator* | string | `S`
21077 array | *see notes on optimized format* | array | `[`
21078 object | *see notes on optimized format* | map | `{`
21079
21080 @note The mapping is **complete** in the sense that any JSON value type
21081 can be converted to a UBJSON value.
21082
21083 @note The following values can **not** be converted to a UBJSON value:
21084 - strings with more than 9223372036854775807 bytes (theoretical)
21085 - unsigned integer numbers above 9223372036854775807
21086
21087 @note The following markers are not used in the conversion:
21088 - `Z`: no-op values are not created.
21089 - `C`: single-byte strings are serialized with `S` markers.
21090
21091 @note Any UBJSON output created @ref to_ubjson can be successfully parsed
21092 by @ref from_ubjson.
21093
21094 @note If NaN or Infinity are stored inside a JSON number, they are
21095 serialized properly. This behavior differs from the @ref dump()
21096 function which serializes NaN or Infinity to `null`.
21097
21098 @note The optimized formats for containers are supported: Parameter
21099 @a use_size adds size information to the beginning of a container and
21100 removes the closing marker. Parameter @a use_type further checks
21101 whether all elements of a container have the same type and adds the
21102 type marker to the beginning of the container. The @a use_type
21103 parameter must only be used together with @a use_size = true. Note
21104 that @a use_size = true alone may result in larger representations -
21105 the benefit of this parameter is that the receiving side is
21106 immediately informed on the number of elements of the container.
21107
21108 @param[in] j JSON value to serialize
21109 @param[in] use_size whether to add size annotations to container types
21110 @param[in] use_type whether to add type annotations to container types
21111 (must be combined with @a use_size = true)
21112 @return UBJSON serialization as byte vector
21113
21114 @complexity Linear in the size of the JSON value @a j.
21115
21116 @liveexample{The example shows the serialization of a JSON value to a byte
21117 vector in UBJSON format.,to_ubjson}
21118
21119 @sa http://ubjson.org
21120 @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
21121 analogous deserialization
21122 @sa @ref to_cbor(const basic_json& for the related CBOR format
21123 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
21124
21125 @since version 3.1.0
21126 */
21127 static std::vector<uint8_t> to_ubjson(const basic_json& j,
21128 const bool use_size = false,
21129 const bool use_type = false)
21130 {
21131 std::vector<uint8_t> result;
21132 to_ubjson(j, result, use_size, use_type);
21133 return result;
21134 }
21135
21136 static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
21137 const bool use_size = false, const bool use_type = false)
21138 {
21139 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
21140 }
21141
21142 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
21143 const bool use_size = false, const bool use_type = false)
21144 {
21145 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
21146 }
21147
21148
21149 /*!
21150 @brief Serializes the given JSON object `j` to BSON and returns a vector
21151 containing the corresponding BSON-representation.
21152
21153 BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are
21154 stored as a single entity (a so-called document).
21155
21156 The library uses the following mapping from JSON values types to BSON types:
21157
21158 JSON value type | value/range | BSON type | marker
21159 --------------- | --------------------------------- | ----------- | ------
21160 null | `null` | null | 0x0A
21161 boolean | `true`, `false` | boolean | 0x08
21162 number_integer | -9223372036854775808..-2147483649 | int64 | 0x12
21163 number_integer | -2147483648..2147483647 | int32 | 0x10
21164 number_integer | 2147483648..9223372036854775807 | int64 | 0x12
21165 number_unsigned | 0..2147483647 | int32 | 0x10
21166 number_unsigned | 2147483648..9223372036854775807 | int64 | 0x12
21167 number_unsigned | 9223372036854775808..18446744073709551615| -- | --
21168 number_float | *any value* | double | 0x01
21169 string | *any value* | string | 0x02
21170 array | *any value* | document | 0x04
21171 object | *any value* | document | 0x03
21172
21173 @warning The mapping is **incomplete**, since only JSON-objects (and things
21174 contained therein) can be serialized to BSON.
21175 Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
21176 and the keys may not contain U+0000, since they are serialized a
21177 zero-terminated c-strings.
21178
21179 @throw out_of_range.407 if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`
21180 @throw out_of_range.409 if a key in `j` contains a NULL (U+0000)
21181 @throw type_error.317 if `!j.is_object()`
21182
21183 @pre The input `j` is required to be an object: `j.is_object() == true`.
21184
21185 @note Any BSON output created via @ref to_bson can be successfully parsed
21186 by @ref from_bson.
21187
21188 @param[in] j JSON value to serialize
21189 @return BSON serialization as byte vector
21190
21191 @complexity Linear in the size of the JSON value @a j.
21192
21193 @liveexample{The example shows the serialization of a JSON value to a byte
21194 vector in BSON format.,to_bson}
21195
21196 @sa http://bsonspec.org/spec.html
21197 @sa @ref from_bson(detail::input_adapter&&, const bool strict) for the
21198 analogous deserialization
21199 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
21200 related UBJSON format
21201 @sa @ref to_cbor(const basic_json&) for the related CBOR format
21202 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
21203 */
21204 static std::vector<uint8_t> to_bson(const basic_json& j)
21205 {
21206 std::vector<uint8_t> result;
21207 to_bson(j, result);
21208 return result;
21209 }
21210
21211 /*!
21212 @brief Serializes the given JSON object `j` to BSON and forwards the
21213 corresponding BSON-representation to the given output_adapter `o`.
21214 @param j The JSON object to convert to BSON.
21215 @param o The output adapter that receives the binary BSON representation.
21216 @pre The input `j` shall be an object: `j.is_object() == true`
21217 @sa @ref to_bson(const basic_json&)
21218 */
21219 static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
21220 {
21221 binary_writer<uint8_t>(o).write_bson(j);
21222 }
21223
21224 /*!
21225 @copydoc to_bson(const basic_json&, detail::output_adapter<uint8_t>)
21226 */
21227 static void to_bson(const basic_json& j, detail::output_adapter<char> o)
21228 {
21229 binary_writer<char>(o).write_bson(j);
21230 }
21231
21232
21233 /*!
21234 @brief create a JSON value from an input in CBOR format
21235
21236 Deserializes a given input @a i to a JSON value using the CBOR (Concise
21237 Binary Object Representation) serialization format.
21238
21239 The library maps CBOR types to JSON value types as follows:
21240
21241 CBOR type | JSON value type | first byte
21242 ---------------------- | --------------- | ----------
21243 Integer | number_unsigned | 0x00..0x17
21244 Unsigned integer | number_unsigned | 0x18
21245 Unsigned integer | number_unsigned | 0x19
21246 Unsigned integer | number_unsigned | 0x1A
21247 Unsigned integer | number_unsigned | 0x1B
21248 Negative integer | number_integer | 0x20..0x37
21249 Negative integer | number_integer | 0x38
21250 Negative integer | number_integer | 0x39
21251 Negative integer | number_integer | 0x3A
21252 Negative integer | number_integer | 0x3B
21253 Negative integer | number_integer | 0x40..0x57
21254 UTF-8 string | string | 0x60..0x77
21255 UTF-8 string | string | 0x78
21256 UTF-8 string | string | 0x79
21257 UTF-8 string | string | 0x7A
21258 UTF-8 string | string | 0x7B
21259 UTF-8 string | string | 0x7F
21260 array | array | 0x80..0x97
21261 array | array | 0x98
21262 array | array | 0x99
21263 array | array | 0x9A
21264 array | array | 0x9B
21265 array | array | 0x9F
21266 map | object | 0xA0..0xB7
21267 map | object | 0xB8
21268 map | object | 0xB9
21269 map | object | 0xBA
21270 map | object | 0xBB
21271 map | object | 0xBF
21272 False | `false` | 0xF4
21273 True | `true` | 0xF5
21274 Null | `null` | 0xF6
21275 Half-Precision Float | number_float | 0xF9
21276 Single-Precision Float | number_float | 0xFA
21277 Double-Precision Float | number_float | 0xFB
21278
21279 @warning The mapping is **incomplete** in the sense that not all CBOR
21280 types can be converted to a JSON value. The following CBOR types
21281 are not supported and will yield parse errors (parse_error.112):
21282 - byte strings (0x40..0x5F)
21283 - date/time (0xC0..0xC1)
21284 - bignum (0xC2..0xC3)
21285 - decimal fraction (0xC4)
21286 - bigfloat (0xC5)
21287 - tagged items (0xC6..0xD4, 0xD8..0xDB)
21288 - expected conversions (0xD5..0xD7)
21289 - simple values (0xE0..0xF3, 0xF8)
21290 - undefined (0xF7)
21291
21292 @warning CBOR allows map keys of any type, whereas JSON only allows
21293 strings as keys in object values. Therefore, CBOR maps with keys
21294 other than UTF-8 strings are rejected (parse_error.113).
21295
21296 @note Any CBOR output created @ref to_cbor can be successfully parsed by
21297 @ref from_cbor.
21298
21299 @param[in] i an input in CBOR format convertible to an input adapter
21300 @param[in] strict whether to expect the input to be consumed until EOF
21301 (true by default)
21302 @param[in] allow_exceptions whether to throw exceptions in case of a
21303 parse error (optional, true by default)
21304
21305 @return deserialized JSON value; in case of a parse error and
21306 @a allow_exceptions set to `false`, the return value will be
21307 value_t::discarded.
21308
21309 @throw parse_error.110 if the given input ends prematurely or the end of
21310 file was not reached when @a strict was set to true
21311 @throw parse_error.112 if unsupported features from CBOR were
21312 used in the given input @a v or if the input is not valid CBOR
21313 @throw parse_error.113 if a string was expected as map key, but not found
21314
21315 @complexity Linear in the size of the input @a i.
21316
21317 @liveexample{The example shows the deserialization of a byte vector in CBOR
21318 format to a JSON value.,from_cbor}
21319
21320 @sa http://cbor.io
21321 @sa @ref to_cbor(const basic_json&) for the analogous serialization
21322 @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for the
21323 related MessagePack format
21324 @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
21325 related UBJSON format
21326
21327 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
21328 consume input adapters, removed start_index parameter, and added
21329 @a strict parameter since 3.0.0; added @a allow_exceptions parameter
21330 since 3.2.0
21331 */
21332 JSON_HEDLEY_WARN_UNUSED_RESULT
21333 static basic_json from_cbor(detail::input_adapter&& i,
21334 const bool strict = true,
21335 const bool allow_exceptions = true)
21336 {
21337 basic_json result;
21338 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21339 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::cbor, &sdp, strict);
21340 return res ? result : basic_json(value_t::discarded);
21341 }
21342
21343 /*!
21344 @copydoc from_cbor(detail::input_adapter&&, const bool, const bool)
21345 */
21346 template<typename A1, typename A2,
21347 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
21348 JSON_HEDLEY_WARN_UNUSED_RESULT
21349 static basic_json from_cbor(A1 && a1, A2 && a2,
21350 const bool strict = true,
21351 const bool allow_exceptions = true)
21352 {
21353 basic_json result;
21354 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21355 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::cbor, &sdp, strict);
21356 return res ? result : basic_json(value_t::discarded);
21357 }
21358
21359 /*!
21360 @brief create a JSON value from an input in MessagePack format
21361
21362 Deserializes a given input @a i to a JSON value using the MessagePack
21363 serialization format.
21364
21365 The library maps MessagePack types to JSON value types as follows:
21366
21367 MessagePack type | JSON value type | first byte
21368 ---------------- | --------------- | ----------
21369 positive fixint | number_unsigned | 0x00..0x7F
21370 fixmap | object | 0x80..0x8F
21371 fixarray | array | 0x90..0x9F
21372 fixstr | string | 0xA0..0xBF
21373 nil | `null` | 0xC0
21374 false | `false` | 0xC2
21375 true | `true` | 0xC3
21376 float 32 | number_float | 0xCA
21377 float 64 | number_float | 0xCB
21378 uint 8 | number_unsigned | 0xCC
21379 uint 16 | number_unsigned | 0xCD
21380 uint 32 | number_unsigned | 0xCE
21381 uint 64 | number_unsigned | 0xCF
21382 int 8 | number_integer | 0xD0
21383 int 16 | number_integer | 0xD1
21384 int 32 | number_integer | 0xD2
21385 int 64 | number_integer | 0xD3
21386 str 8 | string | 0xD9
21387 str 16 | string | 0xDA
21388 str 32 | string | 0xDB
21389 array 16 | array | 0xDC
21390 array 32 | array | 0xDD
21391 map 16 | object | 0xDE
21392 map 32 | object | 0xDF
21393 negative fixint | number_integer | 0xE0-0xFF
21394
21395 @warning The mapping is **incomplete** in the sense that not all
21396 MessagePack types can be converted to a JSON value. The following
21397 MessagePack types are not supported and will yield parse errors:
21398 - bin 8 - bin 32 (0xC4..0xC6)
21399 - ext 8 - ext 32 (0xC7..0xC9)
21400 - fixext 1 - fixext 16 (0xD4..0xD8)
21401
21402 @note Any MessagePack output created @ref to_msgpack can be successfully
21403 parsed by @ref from_msgpack.
21404
21405 @param[in] i an input in MessagePack format convertible to an input
21406 adapter
21407 @param[in] strict whether to expect the input to be consumed until EOF
21408 (true by default)
21409 @param[in] allow_exceptions whether to throw exceptions in case of a
21410 parse error (optional, true by default)
21411
21412 @return deserialized JSON value; in case of a parse error and
21413 @a allow_exceptions set to `false`, the return value will be
21414 value_t::discarded.
21415
21416 @throw parse_error.110 if the given input ends prematurely or the end of
21417 file was not reached when @a strict was set to true
21418 @throw parse_error.112 if unsupported features from MessagePack were
21419 used in the given input @a i or if the input is not valid MessagePack
21420 @throw parse_error.113 if a string was expected as map key, but not found
21421
21422 @complexity Linear in the size of the input @a i.
21423
21424 @liveexample{The example shows the deserialization of a byte vector in
21425 MessagePack format to a JSON value.,from_msgpack}
21426
21427 @sa http://msgpack.org
21428 @sa @ref to_msgpack(const basic_json&) for the analogous serialization
21429 @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
21430 related CBOR format
21431 @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for
21432 the related UBJSON format
21433 @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
21434 the related BSON format
21435
21436 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
21437 consume input adapters, removed start_index parameter, and added
21438 @a strict parameter since 3.0.0; added @a allow_exceptions parameter
21439 since 3.2.0
21440 */
21441 JSON_HEDLEY_WARN_UNUSED_RESULT
21442 static basic_json from_msgpack(detail::input_adapter&& i,
21443 const bool strict = true,
21444 const bool allow_exceptions = true)
21445 {
21446 basic_json result;
21447 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21448 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::msgpack, &sdp, strict);
21449 return res ? result : basic_json(value_t::discarded);
21450 }
21451
21452 /*!
21453 @copydoc from_msgpack(detail::input_adapter&&, const bool, const bool)
21454 */
21455 template<typename A1, typename A2,
21456 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
21457 JSON_HEDLEY_WARN_UNUSED_RESULT
21458 static basic_json from_msgpack(A1 && a1, A2 && a2,
21459 const bool strict = true,
21460 const bool allow_exceptions = true)
21461 {
21462 basic_json result;
21463 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21464 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::msgpack, &sdp, strict);
21465 return res ? result : basic_json(value_t::discarded);
21466 }
21467
21468 /*!
21469 @brief create a JSON value from an input in UBJSON format
21470
21471 Deserializes a given input @a i to a JSON value using the UBJSON (Universal
21472 Binary JSON) serialization format.
21473
21474 The library maps UBJSON types to JSON value types as follows:
21475
21476 UBJSON type | JSON value type | marker
21477 ----------- | --------------------------------------- | ------
21478 no-op | *no value, next value is read* | `N`
21479 null | `null` | `Z`
21480 false | `false` | `F`
21481 true | `true` | `T`
21482 float32 | number_float | `d`
21483 float64 | number_float | `D`
21484 uint8 | number_unsigned | `U`
21485 int8 | number_integer | `i`
21486 int16 | number_integer | `I`
21487 int32 | number_integer | `l`
21488 int64 | number_integer | `L`
21489 string | string | `S`
21490 char | string | `C`
21491 array | array (optimized values are supported) | `[`
21492 object | object (optimized values are supported) | `{`
21493
21494 @note The mapping is **complete** in the sense that any UBJSON value can
21495 be converted to a JSON value.
21496
21497 @param[in] i an input in UBJSON format convertible to an input adapter
21498 @param[in] strict whether to expect the input to be consumed until EOF
21499 (true by default)
21500 @param[in] allow_exceptions whether to throw exceptions in case of a
21501 parse error (optional, true by default)
21502
21503 @return deserialized JSON value; in case of a parse error and
21504 @a allow_exceptions set to `false`, the return value will be
21505 value_t::discarded.
21506
21507 @throw parse_error.110 if the given input ends prematurely or the end of
21508 file was not reached when @a strict was set to true
21509 @throw parse_error.112 if a parse error occurs
21510 @throw parse_error.113 if a string could not be parsed successfully
21511
21512 @complexity Linear in the size of the input @a i.
21513
21514 @liveexample{The example shows the deserialization of a byte vector in
21515 UBJSON format to a JSON value.,from_ubjson}
21516
21517 @sa http://ubjson.org
21518 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
21519 analogous serialization
21520 @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
21521 related CBOR format
21522 @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
21523 the related MessagePack format
21524 @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
21525 the related BSON format
21526
21527 @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
21528 */
21529 JSON_HEDLEY_WARN_UNUSED_RESULT
21530 static basic_json from_ubjson(detail::input_adapter&& i,
21531 const bool strict = true,
21532 const bool allow_exceptions = true)
21533 {
21534 basic_json result;
21535 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21536 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::ubjson, &sdp, strict);
21537 return res ? result : basic_json(value_t::discarded);
21538 }
21539
21540 /*!
21541 @copydoc from_ubjson(detail::input_adapter&&, const bool, const bool)
21542 */
21543 template<typename A1, typename A2,
21544 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
21545 JSON_HEDLEY_WARN_UNUSED_RESULT
21546 static basic_json from_ubjson(A1 && a1, A2 && a2,
21547 const bool strict = true,
21548 const bool allow_exceptions = true)
21549 {
21550 basic_json result;
21551 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21552 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::ubjson, &sdp, strict);
21553 return res ? result : basic_json(value_t::discarded);
21554 }
21555
21556 /*!
21557 @brief Create a JSON value from an input in BSON format
21558
21559 Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)
21560 serialization format.
21561
21562 The library maps BSON record types to JSON value types as follows:
21563
21564 BSON type | BSON marker byte | JSON value type
21565 --------------- | ---------------- | ---------------------------
21566 double | 0x01 | number_float
21567 string | 0x02 | string
21568 document | 0x03 | object
21569 array | 0x04 | array
21570 binary | 0x05 | still unsupported
21571 undefined | 0x06 | still unsupported
21572 ObjectId | 0x07 | still unsupported
21573 boolean | 0x08 | boolean
21574 UTC Date-Time | 0x09 | still unsupported
21575 null | 0x0A | null
21576 Regular Expr. | 0x0B | still unsupported
21577 DB Pointer | 0x0C | still unsupported
21578 JavaScript Code | 0x0D | still unsupported
21579 Symbol | 0x0E | still unsupported
21580 JavaScript Code | 0x0F | still unsupported
21581 int32 | 0x10 | number_integer
21582 Timestamp | 0x11 | still unsupported
21583 128-bit decimal float | 0x13 | still unsupported
21584 Max Key | 0x7F | still unsupported
21585 Min Key | 0xFF | still unsupported
21586
21587 @warning The mapping is **incomplete**. The unsupported mappings
21588 are indicated in the table above.
21589
21590 @param[in] i an input in BSON format convertible to an input adapter
21591 @param[in] strict whether to expect the input to be consumed until EOF
21592 (true by default)
21593 @param[in] allow_exceptions whether to throw exceptions in case of a
21594 parse error (optional, true by default)
21595
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.
21599
21600 @throw parse_error.114 if an unsupported BSON record type is encountered
21601
21602 @complexity Linear in the size of the input @a i.
21603
21604 @liveexample{The example shows the deserialization of a byte vector in
21605 BSON format to a JSON value.,from_bson}
21606
21607 @sa http://bsonspec.org/spec.html
21608 @sa @ref to_bson(const basic_json&) for the analogous serialization
21609 @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
21610 related CBOR format
21611 @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
21612 the related MessagePack format
21613 @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
21614 related UBJSON format
21615 */
21616 JSON_HEDLEY_WARN_UNUSED_RESULT
21617 static basic_json from_bson(detail::input_adapter&& i,
21618 const bool strict = true,
21619 const bool allow_exceptions = true)
21620 {
21621 basic_json result;
21622 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21623 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::bson, &sdp, strict);
21624 return res ? result : basic_json(value_t::discarded);
21625 }
21626
21627 /*!
21628 @copydoc from_bson(detail::input_adapter&&, const bool, const bool)
21629 */
21630 template<typename A1, typename A2,
21631 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
21632 JSON_HEDLEY_WARN_UNUSED_RESULT
21633 static basic_json from_bson(A1 && a1, A2 && a2,
21634 const bool strict = true,
21635 const bool allow_exceptions = true)
21636 {
21637 basic_json result;
21638 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21639 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::bson, &sdp, strict);
21640 return res ? result : basic_json(value_t::discarded);
21641 }
21642
21643
21644
21645 /// @}
21646
21647 //////////////////////////
21648 // JSON Pointer support //
21649 //////////////////////////
21650
21651 /// @name JSON Pointer functions
21652 /// @{
21653
21654 /*!
21655 @brief access specified element via JSON Pointer
21656
21657 Uses a JSON pointer to retrieve a reference to the respective JSON value.
21658 No bound checking is performed. Similar to @ref operator[](const typename
21659 object_t::key_type&), `null` values are created in arrays and objects if
21660 necessary.
21661
21662 In particular:
21663 - If the JSON pointer points to an object key that does not exist, it
21664 is created an filled with a `null` value before a reference to it
21665 is returned.
21666 - If the JSON pointer points to an array index that does not exist, it
21667 is created an filled with a `null` value before a reference to it
21668 is returned. All indices between the current maximum and the given
21669 index are also filled with `null`.
21670 - The special value `-` is treated as a synonym for the index past the
21671 end.
21672
21673 @param[in] ptr a JSON pointer
21674
21675 @return reference to the element pointed to by @a ptr
21676
21677 @complexity Constant.
21678
21679 @throw parse_error.106 if an array index begins with '0'
21680 @throw parse_error.109 if an array index was not a number
21681 @throw out_of_range.404 if the JSON pointer can not be resolved
21682
21683 @liveexample{The behavior is shown in the example.,operatorjson_pointer}
21684
21685 @since version 2.0.0
21686 */
21687 reference operator[](const json_pointer& ptr)
21688 {
21689 return ptr.get_unchecked(this);
21690 }
21691
21692 /*!
21693 @brief access specified element via JSON Pointer
21694
21695 Uses a JSON pointer to retrieve a reference to the respective JSON value.
21696 No bound checking is performed. The function does not change the JSON
21697 value; no `null` values are created. In particular, the the special value
21698 `-` yields an exception.
21699
21700 @param[in] ptr JSON pointer to the desired element
21701
21702 @return const reference to the element pointed to by @a ptr
21703
21704 @complexity Constant.
21705
21706 @throw parse_error.106 if an array index begins with '0'
21707 @throw parse_error.109 if an array index was not a number
21708 @throw out_of_range.402 if the array index '-' is used
21709 @throw out_of_range.404 if the JSON pointer can not be resolved
21710
21711 @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
21712
21713 @since version 2.0.0
21714 */
21715 const_reference operator[](const json_pointer& ptr) const
21716 {
21717 return ptr.get_unchecked(this);
21718 }
21719
21720 /*!
21721 @brief access specified element via JSON Pointer
21722
21723 Returns a reference to the element at with specified JSON pointer @a ptr,
21724 with bounds checking.
21725
21726 @param[in] ptr JSON pointer to the desired element
21727
21728 @return reference to the element pointed to by @a ptr
21729
21730 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
21731 begins with '0'. See example below.
21732
21733 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
21734 is not a number. See example below.
21735
21736 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
21737 is out of range. See example below.
21738
21739 @throw out_of_range.402 if the array index '-' is used in the passed JSON
21740 pointer @a ptr. As `at` provides checked access (and no elements are
21741 implicitly inserted), the index '-' is always invalid. See example below.
21742
21743 @throw out_of_range.403 if the JSON pointer describes a key of an object
21744 which cannot be found. See example below.
21745
21746 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
21747 See example below.
21748
21749 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21750 changes in the JSON value.
21751
21752 @complexity Constant.
21753
21754 @since version 2.0.0
21755
21756 @liveexample{The behavior is shown in the example.,at_json_pointer}
21757 */
21758 reference at(const json_pointer& ptr)
21759 {
21760 return ptr.get_checked(this);
21761 }
21762
21763 /*!
21764 @brief access specified element via JSON Pointer
21765
21766 Returns a const reference to the element at with specified JSON pointer @a
21767 ptr, with bounds checking.
21768
21769 @param[in] ptr JSON pointer to the desired element
21770
21771 @return reference to the element pointed to by @a ptr
21772
21773 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
21774 begins with '0'. See example below.
21775
21776 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
21777 is not a number. See example below.
21778
21779 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
21780 is out of range. See example below.
21781
21782 @throw out_of_range.402 if the array index '-' is used in the passed JSON
21783 pointer @a ptr. As `at` provides checked access (and no elements are
21784 implicitly inserted), the index '-' is always invalid. See example below.
21785
21786 @throw out_of_range.403 if the JSON pointer describes a key of an object
21787 which cannot be found. See example below.
21788
21789 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
21790 See example below.
21791
21792 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21793 changes in the JSON value.
21794
21795 @complexity Constant.
21796
21797 @since version 2.0.0
21798
21799 @liveexample{The behavior is shown in the example.,at_json_pointer_const}
21800 */
21801 const_reference at(const json_pointer& ptr) const
21802 {
21803 return ptr.get_checked(this);
21804 }
21805
21806 /*!
21807 @brief return flattened JSON value
21808
21809 The function creates a JSON object whose keys are JSON pointers (see [RFC
21810 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
21811 primitive. The original JSON value can be restored using the @ref
21812 unflatten() function.
21813
21814 @return an object that maps JSON pointers to primitive values
21815
21816 @note Empty objects and arrays are flattened to `null` and will not be
21817 reconstructed correctly by the @ref unflatten() function.
21818
21819 @complexity Linear in the size the JSON value.
21820
21821 @liveexample{The following code shows how a JSON object is flattened to an
21822 object whose keys consist of JSON pointers.,flatten}
21823
21824 @sa @ref unflatten() for the reverse function
21825
21826 @since version 2.0.0
21827 */
21828 basic_json flatten() const
21829 {
21830 basic_json result(value_t::object);
21831 json_pointer::flatten("", *this, result);
21832 return result;
21833 }
21834
21835 /*!
21836 @brief unflatten a previously flattened JSON value
21837
21838 The function restores the arbitrary nesting of a JSON value that has been
21839 flattened before using the @ref flatten() function. The JSON value must
21840 meet certain constraints:
21841 1. The value must be an object.
21842 2. The keys must be JSON pointers (see
21843 [RFC 6901](https://tools.ietf.org/html/rfc6901))
21844 3. The mapped values must be primitive JSON types.
21845
21846 @return the original JSON from a flattened version
21847
21848 @note Empty objects and arrays are flattened by @ref flatten() to `null`
21849 values and can not unflattened to their original type. Apart from
21850 this example, for a JSON value `j`, the following is always true:
21851 `j == j.flatten().unflatten()`.
21852
21853 @complexity Linear in the size the JSON value.
21854
21855 @throw type_error.314 if value is not an object
21856 @throw type_error.315 if object values are not primitive
21857
21858 @liveexample{The following code shows how a flattened JSON object is
21859 unflattened into the original nested JSON object.,unflatten}
21860
21861 @sa @ref flatten() for the reverse function
21862
21863 @since version 2.0.0
21864 */
21865 basic_json unflatten() const
21866 {
21867 return json_pointer::unflatten(*this);
21868 }
21869
21870 /// @}
21871
21872 //////////////////////////
21873 // JSON Patch functions //
21874 //////////////////////////
21875
21876 /// @name JSON Patch functions
21877 /// @{
21878
21879 /*!
21880 @brief applies a JSON patch
21881
21882 [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
21883 expressing a sequence of operations to apply to a JSON) document. With
21884 this function, a JSON Patch is applied to the current JSON value by
21885 executing all operations from the patch.
21886
21887 @param[in] json_patch JSON patch document
21888 @return patched document
21889
21890 @note The application of a patch is atomic: Either all operations succeed
21891 and the patched document is returned or an exception is thrown. In
21892 any case, the original value is not changed: the patch is applied
21893 to a copy of the value.
21894
21895 @throw parse_error.104 if the JSON patch does not consist of an array of
21896 objects
21897
21898 @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
21899 attributes are missing); example: `"operation add must have member path"`
21900
21901 @throw out_of_range.401 if an array index is out of range.
21902
21903 @throw out_of_range.403 if a JSON pointer inside the patch could not be
21904 resolved successfully in the current JSON value; example: `"key baz not
21905 found"`
21906
21907 @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
21908 "move")
21909
21910 @throw other_error.501 if "test" operation was unsuccessful
21911
21912 @complexity Linear in the size of the JSON value and the length of the
21913 JSON patch. As usually only a fraction of the JSON value is affected by
21914 the patch, the complexity can usually be neglected.
21915
21916 @liveexample{The following code shows how a JSON patch is applied to a
21917 value.,patch}
21918
21919 @sa @ref diff -- create a JSON patch by comparing two JSON values
21920
21921 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
21922 @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
21923
21924 @since version 2.0.0
21925 */
21926 basic_json patch(const basic_json& json_patch) const
21927 {
21928 // make a working copy to apply the patch to
21929 basic_json result = *this;
21930
21931 // the valid JSON Patch operations
21932 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
21933
21934 const auto get_op = [](const std::string & op)
21935 {
21936 if (op == "add")
21937 {
21938 return patch_operations::add;
21939 }
21940 if (op == "remove")
21941 {
21942 return patch_operations::remove;
21943 }
21944 if (op == "replace")
21945 {
21946 return patch_operations::replace;
21947 }
21948 if (op == "move")
21949 {
21950 return patch_operations::move;
21951 }
21952 if (op == "copy")
21953 {
21954 return patch_operations::copy;
21955 }
21956 if (op == "test")
21957 {
21958 return patch_operations::test;
21959 }
21960
21961 return patch_operations::invalid;
21962 };
21963
21964 // wrapper for "add" operation; add value at ptr
21965 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
21966 {
21967 // adding to the root of the target document means replacing it
21968 if (ptr.empty())
21969 {
21970 result = val;
21971 return;
21972 }
21973
21974 // make sure the top element of the pointer exists
21975 json_pointer top_pointer = ptr.top();
21976 if (top_pointer != ptr)
21977 {
21978 result.at(top_pointer);
21979 }
21980
21981 // get reference to parent of JSON pointer ptr
21982 const auto last_path = ptr.back();
21983 ptr.pop_back();
21984 basic_json& parent = result[ptr];
21985
21986 switch (parent.m_type)
21987 {
21988 case value_t::null:
21989 case value_t::object:
21990 {
21991 // use operator[] to add value
21992 parent[last_path] = val;
21993 break;
21994 }
21995
21996 case value_t::array:
21997 {
21998 if (last_path == "-")
21999 {
22000 // special case: append to back
22001 parent.push_back(val);
22002 }
22003 else
22004 {
22005 const auto idx = json_pointer::array_index(last_path);
22006 if (JSON_HEDLEY_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
22007 {
22008 // avoid undefined behavior
22009 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
22010 }
22011
22012 // default case: insert add offset
22013 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
22014 }
22015 break;
22016 }
22017
22018 // if there exists a parent it cannot be primitive
22019 default: // LCOV_EXCL_LINE
22020 assert(false); // LCOV_EXCL_LINE
22021 }
22022 };
22023
22024 // wrapper for "remove" operation; remove value at ptr
22025 const auto operation_remove = [&result](json_pointer & ptr)
22026 {
22027 // get reference to parent of JSON pointer ptr
22028 const auto last_path = ptr.back();
22029 ptr.pop_back();
22030 basic_json& parent = result.at(ptr);
22031
22032 // remove child
22033 if (parent.is_object())
22034 {
22035 // perform range check
22036 auto it = parent.find(last_path);
22037 if (JSON_HEDLEY_LIKELY(it != parent.end()))
22038 {
22039 parent.erase(it);
22040 }
22041 else
22042 {
22043 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
22044 }
22045 }
22046 else if (parent.is_array())
22047 {
22048 // note erase performs range check
22049 parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
22050 }
22051 };
22052
22053 // type check: top level value must be an array
22054 if (JSON_HEDLEY_UNLIKELY(not json_patch.is_array()))
22055 {
22056 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
22057 }
22058
22059 // iterate and apply the operations
22060 for (const auto& val : json_patch)
22061 {
22062 // wrapper to get a value for an operation
22063 const auto get_value = [&val](const std::string & op,
22064 const std::string & member,
22065 bool string_type) -> basic_json &
22066 {
22067 // find value
22068 auto it = val.m_value.object->find(member);
22069
22070 // context-sensitive error message
22071 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
22072
22073 // check if desired value is present
22074 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
22075 {
22076 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
22077 }
22078
22079 // check if result is of type string
22080 if (JSON_HEDLEY_UNLIKELY(string_type and not it->second.is_string()))
22081 {
22082 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
22083 }
22084
22085 // no error: return value
22086 return it->second;
22087 };
22088
22089 // type check: every element of the array must be an object
22090 if (JSON_HEDLEY_UNLIKELY(not val.is_object()))
22091 {
22092 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
22093 }
22094
22095 // collect mandatory members
22096 const std::string op = get_value("op", "op", true);
22097 const std::string path = get_value(op, "path", true);
22098 json_pointer ptr(path);
22099
22100 switch (get_op(op))
22101 {
22102 case patch_operations::add:
22103 {
22104 operation_add(ptr, get_value("add", "value", false));
22105 break;
22106 }
22107
22108 case patch_operations::remove:
22109 {
22110 operation_remove(ptr);
22111 break;
22112 }
22113
22114 case patch_operations::replace:
22115 {
22116 // the "path" location must exist - use at()
22117 result.at(ptr) = get_value("replace", "value", false);
22118 break;
22119 }
22120
22121 case patch_operations::move:
22122 {
22123 const std::string from_path = get_value("move", "from", true);
22124 json_pointer from_ptr(from_path);
22125
22126 // the "from" location must exist - use at()
22127 basic_json v = result.at(from_ptr);
22128
22129 // The move operation is functionally identical to a
22130 // "remove" operation on the "from" location, followed
22131 // immediately by an "add" operation at the target
22132 // location with the value that was just removed.
22133 operation_remove(from_ptr);
22134 operation_add(ptr, v);
22135 break;
22136 }
22137
22138 case patch_operations::copy:
22139 {
22140 const std::string from_path = get_value("copy", "from", true);
22141 const json_pointer from_ptr(from_path);
22142
22143 // the "from" location must exist - use at()
22144 basic_json v = result.at(from_ptr);
22145
22146 // The copy is functionally identical to an "add"
22147 // operation at the target location using the value
22148 // specified in the "from" member.
22149 operation_add(ptr, v);
22150 break;
22151 }
22152
22153 case patch_operations::test:
22154 {
22155 bool success = false;
22156 JSON_TRY
22157 {
22158 // check if "value" matches the one at "path"
22159 // the "path" location must exist - use at()
22160 success = (result.at(ptr) == get_value("test", "value", false));
22161 }
22162 JSON_INTERNAL_CATCH (out_of_range&)
22163 {
22164 // ignore out of range errors: success remains false
22165 }
22166
22167 // throw an exception if test fails
22168 if (JSON_HEDLEY_UNLIKELY(not success))
22169 {
22170 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
22171 }
22172
22173 break;
22174 }
22175
22176 default:
22177 {
22178 // op must be "add", "remove", "replace", "move", "copy", or
22179 // "test"
22180 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
22181 }
22182 }
22183 }
22184
22185 return result;
22186 }
22187
22188 /*!
22189 @brief creates a diff as a JSON patch
22190
22191 Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
22192 be changed into the value @a target by calling @ref patch function.
22193
22194 @invariant For two JSON values @a source and @a target, the following code
22195 yields always `true`:
22196 @code {.cpp}
22197 source.patch(diff(source, target)) == target;
22198 @endcode
22199
22200 @note Currently, only `remove`, `add`, and `replace` operations are
22201 generated.
22202
22203 @param[in] source JSON value to compare from
22204 @param[in] target JSON value to compare against
22205 @param[in] path helper value to create JSON pointers
22206
22207 @return a JSON patch to convert the @a source to @a target
22208
22209 @complexity Linear in the lengths of @a source and @a target.
22210
22211 @liveexample{The following code shows how a JSON patch is created as a
22212 diff for two JSON values.,diff}
22213
22214 @sa @ref patch -- apply a JSON patch
22215 @sa @ref merge_patch -- apply a JSON Merge Patch
22216
22217 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
22218
22219 @since version 2.0.0
22220 */
22221 JSON_HEDLEY_WARN_UNUSED_RESULT
22222 static basic_json diff(const basic_json& source, const basic_json& target,
22223 const std::string& path = "")
22224 {
22225 // the patch
22226 basic_json result(value_t::array);
22227
22228 // if the values are the same, return empty patch
22229 if (source == target)
22230 {
22231 return result;
22232 }
22233
22234 if (source.type() != target.type())
22235 {
22236 // different types: replace value
22237 result.push_back(
22238 {
22239 {"op", "replace"}, {"path", path}, {"value", target}
22240 });
22241 return result;
22242 }
22243
22244 switch (source.type())
22245 {
22246 case value_t::array:
22247 {
22248 // first pass: traverse common elements
22249 std::size_t i = 0;
22250 while (i < source.size() and i < target.size())
22251 {
22252 // recursive call to compare array values at index i
22253 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
22254 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
22255 ++i;
22256 }
22257
22258 // i now reached the end of at least one array
22259 // in a second pass, traverse the remaining elements
22260
22261 // remove my remaining elements
22262 const auto end_index = static_cast<difference_type>(result.size());
22263 while (i < source.size())
22264 {
22265 // add operations in reverse order to avoid invalid
22266 // indices
22267 result.insert(result.begin() + end_index, object(
22268 {
22269 {"op", "remove"},
22270 {"path", path + "/" + std::to_string(i)}
22271 }));
22272 ++i;
22273 }
22274
22275 // add other remaining elements
22276 while (i < target.size())
22277 {
22278 result.push_back(
22279 {
22280 {"op", "add"},
22281 {"path", path + "/" + std::to_string(i)},
22282 {"value", target[i]}
22283 });
22284 ++i;
22285 }
22286
22287 break;
22288 }
22289
22290 case value_t::object:
22291 {
22292 // first pass: traverse this object's elements
22293 for (auto it = source.cbegin(); it != source.cend(); ++it)
22294 {
22295 // escape the key name to be used in a JSON patch
22296 const auto key = json_pointer::escape(it.key());
22297
22298 if (target.find(it.key()) != target.end())
22299 {
22300 // recursive call to compare object values at key it
22301 auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
22302 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
22303 }
22304 else
22305 {
22306 // found a key that is not in o -> remove it
22307 result.push_back(object(
22308 {
22309 {"op", "remove"}, {"path", path + "/" + key}
22310 }));
22311 }
22312 }
22313
22314 // second pass: traverse other object's elements
22315 for (auto it = target.cbegin(); it != target.cend(); ++it)
22316 {
22317 if (source.find(it.key()) == source.end())
22318 {
22319 // found a key that is not in this -> add it
22320 const auto key = json_pointer::escape(it.key());
22321 result.push_back(
22322 {
22323 {"op", "add"}, {"path", path + "/" + key},
22324 {"value", it.value()}
22325 });
22326 }
22327 }
22328
22329 break;
22330 }
22331
22332 default:
22333 {
22334 // both primitive type: replace value
22335 result.push_back(
22336 {
22337 {"op", "replace"}, {"path", path}, {"value", target}
22338 });
22339 break;
22340 }
22341 }
22342
22343 return result;
22344 }
22345
22346 /// @}
22347
22348 ////////////////////////////////
22349 // JSON Merge Patch functions //
22350 ////////////////////////////////
22351
22352 /// @name JSON Merge Patch functions
22353 /// @{
22354
22355 /*!
22356 @brief applies a JSON Merge Patch
22357
22358 The merge patch format is primarily intended for use with the HTTP PATCH
22359 method as a means of describing a set of modifications to a target
22360 resource's content. This function applies a merge patch to the current
22361 JSON value.
22362
22363 The function implements the following algorithm from Section 2 of
22364 [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
22365
22366 ```
22367 define MergePatch(Target, Patch):
22368 if Patch is an Object:
22369 if Target is not an Object:
22370 Target = {} // Ignore the contents and set it to an empty Object
22371 for each Name/Value pair in Patch:
22372 if Value is null:
22373 if Name exists in Target:
22374 remove the Name/Value pair from Target
22375 else:
22376 Target[Name] = MergePatch(Target[Name], Value)
22377 return Target
22378 else:
22379 return Patch
22380 ```
22381
22382 Thereby, `Target` is the current object; that is, the patch is applied to
22383 the current value.
22384
22385 @param[in] apply_patch the patch to apply
22386
22387 @complexity Linear in the lengths of @a patch.
22388
22389 @liveexample{The following code shows how a JSON Merge Patch is applied to
22390 a JSON document.,merge_patch}
22391
22392 @sa @ref patch -- apply a JSON patch
22393 @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
22394
22395 @since version 3.0.0
22396 */
22397 void merge_patch(const basic_json& apply_patch)
22398 {
22399 if (apply_patch.is_object())
22400 {
22401 if (not is_object())
22402 {
22403 *this = object();
22404 }
22405 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
22406 {
22407 if (it.value().is_null())
22408 {
22409 erase(it.key());
22410 }
22411 else
22412 {
22413 operator[](it.key()).merge_patch(it.value());
22414 }
22415 }
22416 }
22417 else
22418 {
22419 *this = apply_patch;
22420 }
22421 }
22422
22423 /// @}
22424 };
22425
22426 /*!
22427 @brief user-defined to_string function for JSON values
22428
22429 This function implements a user-defined to_string for JSON objects.
22430
22431 @param[in] j a JSON object
22432 @return a std::string object
22433 */
22434
22435 NLOHMANN_BASIC_JSON_TPL_DECLARATION
22436 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
22437 {
22438 return j.dump();
22439 }
22440 } // namespace nlohmann
22441
22442 ///////////////////////
22443 // nonmember support //
22444 ///////////////////////
22445
22446 // specialization of std::swap, and std::hash
22447 namespace std
22448 {
22449
22450 /// hash value for JSON objects
22451 template<>
22452 struct hash<nlohmann::json>
22453 {
22454 /*!
22455 @brief return a hash value for a JSON object
22456
22457 @since version 1.0.0
22458 */
22459 std::size_t operator()(const nlohmann::json& j) const
22460 {
22461 // a naive hashing via the string representation
22462 const auto& h = hash<nlohmann::json::string_t>();
22463 return h(j.dump());
22464 }
22465 };
22466
22467 /// specialization for std::less<value_t>
22468 /// @note: do not remove the space after '<',
22469 /// see https://github.com/nlohmann/json/pull/679
22470 template<>
22471 struct less< ::nlohmann::detail::value_t>
22472 {
22473 /*!
22474 @brief compare two value_t enum values
22475 @since version 3.0.0
22476 */
22477 bool operator()(nlohmann::detail::value_t lhs,
22478 nlohmann::detail::value_t rhs) const noexcept
22479 {
22480 return nlohmann::detail::operator<(lhs, rhs);
22481 }
22482 };
22483
22484 /*!
22485 @brief exchanges the values of two JSON objects
22486
22487 @since version 1.0.0
22488 */
22489 template<>
22490 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
22491 is_nothrow_move_constructible<nlohmann::json>::value and
22492 is_nothrow_move_assignable<nlohmann::json>::value
22493 )
22494 {
22495 j1.swap(j2);
22496 }
22497
22498 } // namespace std
22499
22500 /*!
22501 @brief user-defined string literal for JSON values
22502
22503 This operator implements a user-defined string literal for JSON objects. It
22504 can be used by adding `"_json"` to a string literal and returns a JSON object
22505 if no parse error occurred.
22506
22507 @param[in] s a string representation of a JSON object
22508 @param[in] n the length of string @a s
22509 @return a JSON object
22510
22511 @since version 1.0.0
22512 */
22513 JSON_HEDLEY_NON_NULL(1)
22514 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
22515 {
22516 return nlohmann::json::parse(s, s + n);
22517 }
22518
22519 /*!
22520 @brief user-defined string literal for JSON pointer
22521
22522 This operator implements a user-defined string literal for JSON Pointers. It
22523 can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
22524 object if no parse error occurred.
22525
22526 @param[in] s a string representation of a JSON Pointer
22527 @param[in] n the length of string @a s
22528 @return a JSON pointer object
22529
22530 @since version 2.0.0
22531 */
22532 JSON_HEDLEY_NON_NULL(1)
22533 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
22534 {
22535 return nlohmann::json::json_pointer(std::string(s, n));
22536 }
22537
22538 // #include <nlohmann/detail/macro_unscope.hpp>
22539
22540
22541 // restore GCC/clang diagnostic settings
22542 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
22543 #pragma GCC diagnostic pop
22544 #endif
22545 #if defined(__clang__)
22546 #pragma GCC diagnostic pop
22547 #endif
22548
22549 // clean up
22550 #undef JSON_INTERNAL_CATCH
22551 #undef JSON_CATCH
22552 #undef JSON_THROW
22553 #undef JSON_TRY
22554 #undef JSON_HAS_CPP_14
22555 #undef JSON_HAS_CPP_17
22556 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
22557 #undef NLOHMANN_BASIC_JSON_TPL
22558
22559 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
22560 #undef JSON_HEDLEY_ALWAYS_INLINE
22561 #undef JSON_HEDLEY_ARM_VERSION
22562 #undef JSON_HEDLEY_ARM_VERSION_CHECK
22563 #undef JSON_HEDLEY_ARRAY_PARAM
22564 #undef JSON_HEDLEY_ASSUME
22565 #undef JSON_HEDLEY_BEGIN_C_DECLS
22566 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
22567 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
22568 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
22569 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
22570 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
22571 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
22572 #undef JSON_HEDLEY_CLANG_HAS_WARNING
22573 #undef JSON_HEDLEY_COMPCERT_VERSION
22574 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
22575 #undef JSON_HEDLEY_CONCAT
22576 #undef JSON_HEDLEY_CONCAT_EX
22577 #undef JSON_HEDLEY_CONST
22578 #undef JSON_HEDLEY_CONSTEXPR
22579 #undef JSON_HEDLEY_CONST_CAST
22580 #undef JSON_HEDLEY_CPP_CAST
22581 #undef JSON_HEDLEY_CRAY_VERSION
22582 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
22583 #undef JSON_HEDLEY_C_DECL
22584 #undef JSON_HEDLEY_DEPRECATED
22585 #undef JSON_HEDLEY_DEPRECATED_FOR
22586 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
22587 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
22588 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
22589 #undef JSON_HEDLEY_DIAGNOSTIC_POP
22590 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
22591 #undef JSON_HEDLEY_DMC_VERSION
22592 #undef JSON_HEDLEY_DMC_VERSION_CHECK
22593 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
22594 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
22595 #undef JSON_HEDLEY_END_C_DECLS
22596 #undef JSON_HEDLEY_FALL_THROUGH
22597 #undef JSON_HEDLEY_FLAGS
22598 #undef JSON_HEDLEY_FLAGS_CAST
22599 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
22600 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
22601 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
22602 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
22603 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
22604 #undef JSON_HEDLEY_GCC_HAS_FEATURE
22605 #undef JSON_HEDLEY_GCC_HAS_WARNING
22606 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
22607 #undef JSON_HEDLEY_GCC_VERSION
22608 #undef JSON_HEDLEY_GCC_VERSION_CHECK
22609 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
22610 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
22611 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
22612 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
22613 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
22614 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
22615 #undef JSON_HEDLEY_GNUC_HAS_WARNING
22616 #undef JSON_HEDLEY_GNUC_VERSION
22617 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
22618 #undef JSON_HEDLEY_HAS_ATTRIBUTE
22619 #undef JSON_HEDLEY_HAS_BUILTIN
22620 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
22621 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
22622 #undef JSON_HEDLEY_HAS_EXTENSION
22623 #undef JSON_HEDLEY_HAS_FEATURE
22624 #undef JSON_HEDLEY_HAS_WARNING
22625 #undef JSON_HEDLEY_IAR_VERSION
22626 #undef JSON_HEDLEY_IAR_VERSION_CHECK
22627 #undef JSON_HEDLEY_IBM_VERSION
22628 #undef JSON_HEDLEY_IBM_VERSION_CHECK
22629 #undef JSON_HEDLEY_IMPORT
22630 #undef JSON_HEDLEY_INLINE
22631 #undef JSON_HEDLEY_INTEL_VERSION
22632 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
22633 #undef JSON_HEDLEY_IS_CONSTANT
22634 #undef JSON_HEDLEY_LIKELY
22635 #undef JSON_HEDLEY_MALLOC
22636 #undef JSON_HEDLEY_MESSAGE
22637 #undef JSON_HEDLEY_MSVC_VERSION
22638 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
22639 #undef JSON_HEDLEY_NEVER_INLINE
22640 #undef JSON_HEDLEY_NON_NULL
22641 #undef JSON_HEDLEY_NO_RETURN
22642 #undef JSON_HEDLEY_NO_THROW
22643 #undef JSON_HEDLEY_PELLES_VERSION
22644 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
22645 #undef JSON_HEDLEY_PGI_VERSION
22646 #undef JSON_HEDLEY_PGI_VERSION_CHECK
22647 #undef JSON_HEDLEY_PREDICT
22648 #undef JSON_HEDLEY_PRINTF_FORMAT
22649 #undef JSON_HEDLEY_PRIVATE
22650 #undef JSON_HEDLEY_PUBLIC
22651 #undef JSON_HEDLEY_PURE
22652 #undef JSON_HEDLEY_REINTERPRET_CAST
22653 #undef JSON_HEDLEY_REQUIRE
22654 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
22655 #undef JSON_HEDLEY_REQUIRE_MSG
22656 #undef JSON_HEDLEY_RESTRICT
22657 #undef JSON_HEDLEY_RETURNS_NON_NULL
22658 #undef JSON_HEDLEY_SENTINEL
22659 #undef JSON_HEDLEY_STATIC_ASSERT
22660 #undef JSON_HEDLEY_STATIC_CAST
22661 #undef JSON_HEDLEY_STRINGIFY
22662 #undef JSON_HEDLEY_STRINGIFY_EX
22663 #undef JSON_HEDLEY_SUNPRO_VERSION
22664 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
22665 #undef JSON_HEDLEY_TINYC_VERSION
22666 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
22667 #undef JSON_HEDLEY_TI_VERSION
22668 #undef JSON_HEDLEY_TI_VERSION_CHECK
22669 #undef JSON_HEDLEY_UNAVAILABLE
22670 #undef JSON_HEDLEY_UNLIKELY
22671 #undef JSON_HEDLEY_UNPREDICTABLE
22672 #undef JSON_HEDLEY_UNREACHABLE
22673 #undef JSON_HEDLEY_UNREACHABLE_RETURN
22674 #undef JSON_HEDLEY_VERSION
22675 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
22676 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
22677 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
22678 #undef JSON_HEDLEY_VERSION_ENCODE
22679 #undef JSON_HEDLEY_WARNING
22680 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
22681
22682
22683
22684 #endif // INCLUDE_NLOHMANN_JSON_HPP_