JSON for Modern C++ 3.8.0

json.hpp
1 /*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.8.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 8
35 #define NLOHMANN_JSON_VERSION_PATCH 0
36
37 #include <algorithm> // all_of, find, for_each
38 #include <cassert> // assert
39 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
40 #include <functional> // hash, less
41 #include <initializer_list> // initializer_list
42 #include <iosfwd> // istream, ostream
43 #include <iterator> // random_access_iterator_tag
44 #include <memory> // unique_ptr
45 #include <numeric> // accumulate
46 #include <string> // string, stoi, to_string
47 #include <utility> // declval, forward, move, pair, swap
48 #include <vector> // vector
49
50 // #include <nlohmann/adl_serializer.hpp>
51
52
53 #include <utility>
54
55 // #include <nlohmann/detail/conversions/from_json.hpp>
56
57
58 #include <algorithm> // transform
59 #include <array> // array
60 #include <forward_list> // forward_list
61 #include <iterator> // inserter, front_inserter, end
62 #include <map> // map
63 #include <string> // string
64 #include <tuple> // tuple, make_tuple
65 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
66 #include <unordered_map> // unordered_map
67 #include <utility> // pair, declval
68 #include <valarray> // valarray
69
70 // #include <nlohmann/detail/boolean_operators.hpp>
71
72
73 // Header <ciso646> is removed in C++20.
74 // See <https://github.com/nlohmann/json/issues/2089> for more information.
75
76 #if __cplusplus <= 201703L
77 #include <ciso646> // and, not, or
78 #endif
79
80 // #include <nlohmann/detail/exceptions.hpp>
81
82
83 #include <exception> // exception
84 #include <stdexcept> // runtime_error
85 #include <string> // to_string
86
87 // #include <nlohmann/detail/input/position_t.hpp>
88
89
90 #include <cstddef> // size_t
91
92 namespace nlohmann
93 {
94 namespace detail
95 {
97 struct position_t
98 {
100 std::size_t chars_read_total = 0;
102 std::size_t chars_read_current_line = 0;
104 std::size_t lines_read = 0;
105
107 constexpr operator size_t() const
108 {
109 return chars_read_total;
110 }
111 };
112
113 } // namespace detail
114 } // namespace nlohmann
115
116 // #include <nlohmann/detail/macro_scope.hpp>
117
118
119 #include <utility> // pair
120 // #include <nlohmann/thirdparty/hedley/hedley.hpp>
121 /* Hedley - https://nemequ.github.io/hedley
122 * Created by Evan Nemerson <evan@nemerson.com>
123 *
124 * To the extent possible under law, the author(s) have dedicated all
125 * copyright and related and neighboring rights to this software to
126 * the public domain worldwide. This software is distributed without
127 * any warranty.
128 *
129 * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
130 * SPDX-License-Identifier: CC0-1.0
131 */
132
133 #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 13)
134 #if defined(JSON_HEDLEY_VERSION)
135 #undef JSON_HEDLEY_VERSION
136 #endif
137 #define JSON_HEDLEY_VERSION 13
138
139 #if defined(JSON_HEDLEY_STRINGIFY_EX)
140 #undef JSON_HEDLEY_STRINGIFY_EX
141 #endif
142 #define JSON_HEDLEY_STRINGIFY_EX(x) #x
143
144 #if defined(JSON_HEDLEY_STRINGIFY)
145 #undef JSON_HEDLEY_STRINGIFY
146 #endif
147 #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
148
149 #if defined(JSON_HEDLEY_CONCAT_EX)
150 #undef JSON_HEDLEY_CONCAT_EX
151 #endif
152 #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
153
154 #if defined(JSON_HEDLEY_CONCAT)
155 #undef JSON_HEDLEY_CONCAT
156 #endif
157 #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
158
159 #if defined(JSON_HEDLEY_CONCAT3_EX)
160 #undef JSON_HEDLEY_CONCAT3_EX
161 #endif
162 #define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
163
164 #if defined(JSON_HEDLEY_CONCAT3)
165 #undef JSON_HEDLEY_CONCAT3
166 #endif
167 #define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
168
169 #if defined(JSON_HEDLEY_VERSION_ENCODE)
170 #undef JSON_HEDLEY_VERSION_ENCODE
171 #endif
172 #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
173
174 #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
175 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
176 #endif
177 #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
178
179 #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
180 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
181 #endif
182 #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
183
184 #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
185 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
186 #endif
187 #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
188
189 #if defined(JSON_HEDLEY_GNUC_VERSION)
190 #undef JSON_HEDLEY_GNUC_VERSION
191 #endif
192 #if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
193 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
194 #elif defined(__GNUC__)
195 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
196 #endif
197
198 #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
199 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
200 #endif
201 #if defined(JSON_HEDLEY_GNUC_VERSION)
202 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
203 #else
204 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
205 #endif
206
207 #if defined(JSON_HEDLEY_MSVC_VERSION)
208 #undef JSON_HEDLEY_MSVC_VERSION
209 #endif
210 #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000)
211 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
212 #elif defined(_MSC_FULL_VER)
213 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
214 #elif defined(_MSC_VER)
215 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
216 #endif
217
218 #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
219 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
220 #endif
221 #if !defined(_MSC_VER)
222 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
223 #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
224 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
225 #elif defined(_MSC_VER) && (_MSC_VER >= 1200)
226 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
227 #else
228 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
229 #endif
230
231 #if defined(JSON_HEDLEY_INTEL_VERSION)
232 #undef JSON_HEDLEY_INTEL_VERSION
233 #endif
234 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE)
235 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
236 #elif defined(__INTEL_COMPILER)
237 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
238 #endif
239
240 #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
241 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
242 #endif
243 #if defined(JSON_HEDLEY_INTEL_VERSION)
244 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
245 #else
246 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
247 #endif
248
249 #if defined(JSON_HEDLEY_PGI_VERSION)
250 #undef JSON_HEDLEY_PGI_VERSION
251 #endif
252 #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
253 #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
254 #endif
255
256 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
257 #undef JSON_HEDLEY_PGI_VERSION_CHECK
258 #endif
259 #if defined(JSON_HEDLEY_PGI_VERSION)
260 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
261 #else
262 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
263 #endif
264
265 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
266 #undef JSON_HEDLEY_SUNPRO_VERSION
267 #endif
268 #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
269 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)
270 #elif defined(__SUNPRO_C)
271 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
272 #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
273 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)
274 #elif defined(__SUNPRO_CC)
275 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
276 #endif
277
278 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
279 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
280 #endif
281 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
282 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
283 #else
284 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
285 #endif
286
287 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
288 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
289 #endif
290 #if defined(__EMSCRIPTEN__)
291 #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
292 #endif
293
294 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
295 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
296 #endif
297 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
298 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
299 #else
300 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
301 #endif
302
303 #if defined(JSON_HEDLEY_ARM_VERSION)
304 #undef JSON_HEDLEY_ARM_VERSION
305 #endif
306 #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
307 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
308 #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
309 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
310 #endif
311
312 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
313 #undef JSON_HEDLEY_ARM_VERSION_CHECK
314 #endif
315 #if defined(JSON_HEDLEY_ARM_VERSION)
316 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
317 #else
318 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
319 #endif
320
321 #if defined(JSON_HEDLEY_IBM_VERSION)
322 #undef JSON_HEDLEY_IBM_VERSION
323 #endif
324 #if defined(__ibmxl__)
325 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
326 #elif defined(__xlC__) && defined(__xlC_ver__)
327 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
328 #elif defined(__xlC__)
329 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
330 #endif
331
332 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
333 #undef JSON_HEDLEY_IBM_VERSION_CHECK
334 #endif
335 #if defined(JSON_HEDLEY_IBM_VERSION)
336 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
337 #else
338 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
339 #endif
340
341 #if defined(JSON_HEDLEY_TI_VERSION)
342 #undef JSON_HEDLEY_TI_VERSION
343 #endif
344 #if \
345 defined(__TI_COMPILER_VERSION__) && \
346 ( \
347 defined(__TMS470__) || defined(__TI_ARM__) || \
348 defined(__MSP430__) || \
349 defined(__TMS320C2000__) \
350 )
351 #if (__TI_COMPILER_VERSION__ >= 16000000)
352 #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
353 #endif
354 #endif
355
356 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
357 #undef JSON_HEDLEY_TI_VERSION_CHECK
358 #endif
359 #if defined(JSON_HEDLEY_TI_VERSION)
360 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
361 #else
362 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
363 #endif
364
365 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
366 #undef JSON_HEDLEY_TI_CL2000_VERSION
367 #endif
368 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
369 #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
370 #endif
371
372 #if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
373 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
374 #endif
375 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
376 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
377 #else
378 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
379 #endif
380
381 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
382 #undef JSON_HEDLEY_TI_CL430_VERSION
383 #endif
384 #if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
385 #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
386 #endif
387
388 #if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
389 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
390 #endif
391 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
392 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
393 #else
394 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
395 #endif
396
397 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
398 #undef JSON_HEDLEY_TI_ARMCL_VERSION
399 #endif
400 #if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
401 #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
402 #endif
403
404 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
405 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
406 #endif
407 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
408 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
409 #else
410 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
411 #endif
412
413 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
414 #undef JSON_HEDLEY_TI_CL6X_VERSION
415 #endif
416 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
417 #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
418 #endif
419
420 #if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
421 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
422 #endif
423 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
424 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
425 #else
426 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
427 #endif
428
429 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
430 #undef JSON_HEDLEY_TI_CL7X_VERSION
431 #endif
432 #if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
433 #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
434 #endif
435
436 #if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
437 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
438 #endif
439 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
440 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
441 #else
442 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
443 #endif
444
445 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
446 #undef JSON_HEDLEY_TI_CLPRU_VERSION
447 #endif
448 #if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
449 #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
450 #endif
451
452 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
453 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
454 #endif
455 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
456 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
457 #else
458 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
459 #endif
460
461 #if defined(JSON_HEDLEY_CRAY_VERSION)
462 #undef JSON_HEDLEY_CRAY_VERSION
463 #endif
464 #if defined(_CRAYC)
465 #if defined(_RELEASE_PATCHLEVEL)
466 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
467 #else
468 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
469 #endif
470 #endif
471
472 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
473 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
474 #endif
475 #if defined(JSON_HEDLEY_CRAY_VERSION)
476 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
477 #else
478 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
479 #endif
480
481 #if defined(JSON_HEDLEY_IAR_VERSION)
482 #undef JSON_HEDLEY_IAR_VERSION
483 #endif
484 #if defined(__IAR_SYSTEMS_ICC__)
485 #if __VER__ > 1000
486 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
487 #else
488 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(VER / 100, __VER__ % 100, 0)
489 #endif
490 #endif
491
492 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
493 #undef JSON_HEDLEY_IAR_VERSION_CHECK
494 #endif
495 #if defined(JSON_HEDLEY_IAR_VERSION)
496 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
497 #else
498 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
499 #endif
500
501 #if defined(JSON_HEDLEY_TINYC_VERSION)
502 #undef JSON_HEDLEY_TINYC_VERSION
503 #endif
504 #if defined(__TINYC__)
505 #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
506 #endif
507
508 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
509 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
510 #endif
511 #if defined(JSON_HEDLEY_TINYC_VERSION)
512 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
513 #else
514 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
515 #endif
516
517 #if defined(JSON_HEDLEY_DMC_VERSION)
518 #undef JSON_HEDLEY_DMC_VERSION
519 #endif
520 #if defined(__DMC__)
521 #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
522 #endif
523
524 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
525 #undef JSON_HEDLEY_DMC_VERSION_CHECK
526 #endif
527 #if defined(JSON_HEDLEY_DMC_VERSION)
528 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
529 #else
530 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
531 #endif
532
533 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
534 #undef JSON_HEDLEY_COMPCERT_VERSION
535 #endif
536 #if defined(__COMPCERT_VERSION__)
537 #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
538 #endif
539
540 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
541 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
542 #endif
543 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
544 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
545 #else
546 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
547 #endif
548
549 #if defined(JSON_HEDLEY_PELLES_VERSION)
550 #undef JSON_HEDLEY_PELLES_VERSION
551 #endif
552 #if defined(__POCC__)
553 #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
554 #endif
555
556 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
557 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
558 #endif
559 #if defined(JSON_HEDLEY_PELLES_VERSION)
560 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
561 #else
562 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
563 #endif
564
565 #if defined(JSON_HEDLEY_GCC_VERSION)
566 #undef JSON_HEDLEY_GCC_VERSION
567 #endif
568 #if \
569 defined(JSON_HEDLEY_GNUC_VERSION) && \
570 !defined(__clang__) && \
571 !defined(JSON_HEDLEY_INTEL_VERSION) && \
572 !defined(JSON_HEDLEY_PGI_VERSION) && \
573 !defined(JSON_HEDLEY_ARM_VERSION) && \
574 !defined(JSON_HEDLEY_TI_VERSION) && \
575 !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
576 !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
577 !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
578 !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
579 !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
580 !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
581 !defined(__COMPCERT__)
582 #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
583 #endif
584
585 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
586 #undef JSON_HEDLEY_GCC_VERSION_CHECK
587 #endif
588 #if defined(JSON_HEDLEY_GCC_VERSION)
589 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
590 #else
591 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
592 #endif
593
594 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
595 #undef JSON_HEDLEY_HAS_ATTRIBUTE
596 #endif
597 #if defined(__has_attribute)
598 #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
599 #else
600 #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
601 #endif
602
603 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
604 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
605 #endif
606 #if defined(__has_attribute)
607 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
608 #else
609 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
610 #endif
611
612 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
613 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
614 #endif
615 #if defined(__has_attribute)
616 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
617 #else
618 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
619 #endif
620
621 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
622 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
623 #endif
624 #if \
625 defined(__has_cpp_attribute) && \
626 defined(__cplusplus) && \
627 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
628 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
629 #else
630 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
631 #endif
632
633 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
634 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
635 #endif
636 #if !defined(__cplusplus) || !defined(__has_cpp_attribute)
637 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
638 #elif \
639 !defined(JSON_HEDLEY_PGI_VERSION) && \
640 !defined(JSON_HEDLEY_IAR_VERSION) && \
641 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
642 (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
643 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
644 #else
645 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
646 #endif
647
648 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
649 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
650 #endif
651 #if defined(__has_cpp_attribute) && defined(__cplusplus)
652 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
653 #else
654 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
655 #endif
656
657 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
658 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
659 #endif
660 #if defined(__has_cpp_attribute) && defined(__cplusplus)
661 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
662 #else
663 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
664 #endif
665
666 #if defined(JSON_HEDLEY_HAS_BUILTIN)
667 #undef JSON_HEDLEY_HAS_BUILTIN
668 #endif
669 #if defined(__has_builtin)
670 #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
671 #else
672 #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
673 #endif
674
675 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
676 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
677 #endif
678 #if defined(__has_builtin)
679 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
680 #else
681 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
682 #endif
683
684 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
685 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
686 #endif
687 #if defined(__has_builtin)
688 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
689 #else
690 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
691 #endif
692
693 #if defined(JSON_HEDLEY_HAS_FEATURE)
694 #undef JSON_HEDLEY_HAS_FEATURE
695 #endif
696 #if defined(__has_feature)
697 #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
698 #else
699 #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
700 #endif
701
702 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
703 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
704 #endif
705 #if defined(__has_feature)
706 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
707 #else
708 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
709 #endif
710
711 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
712 #undef JSON_HEDLEY_GCC_HAS_FEATURE
713 #endif
714 #if defined(__has_feature)
715 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
716 #else
717 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
718 #endif
719
720 #if defined(JSON_HEDLEY_HAS_EXTENSION)
721 #undef JSON_HEDLEY_HAS_EXTENSION
722 #endif
723 #if defined(__has_extension)
724 #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
725 #else
726 #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
727 #endif
728
729 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
730 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
731 #endif
732 #if defined(__has_extension)
733 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
734 #else
735 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
736 #endif
737
738 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
739 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
740 #endif
741 #if defined(__has_extension)
742 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
743 #else
744 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
745 #endif
746
747 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
748 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
749 #endif
750 #if defined(__has_declspec_attribute)
751 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
752 #else
753 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
754 #endif
755
756 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
757 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
758 #endif
759 #if defined(__has_declspec_attribute)
760 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
761 #else
762 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
763 #endif
764
765 #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
766 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
767 #endif
768 #if defined(__has_declspec_attribute)
769 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
770 #else
771 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
772 #endif
773
774 #if defined(JSON_HEDLEY_HAS_WARNING)
775 #undef JSON_HEDLEY_HAS_WARNING
776 #endif
777 #if defined(__has_warning)
778 #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
779 #else
780 #define JSON_HEDLEY_HAS_WARNING(warning) (0)
781 #endif
782
783 #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
784 #undef JSON_HEDLEY_GNUC_HAS_WARNING
785 #endif
786 #if defined(__has_warning)
787 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
788 #else
789 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
790 #endif
791
792 #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
793 #undef JSON_HEDLEY_GCC_HAS_WARNING
794 #endif
795 #if defined(__has_warning)
796 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
797 #else
798 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
799 #endif
800
801 /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
802 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
803 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
804 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
805 #endif
806 #if defined(__cplusplus)
807 # if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
808 # if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
809 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
810 JSON_HEDLEY_DIAGNOSTIC_PUSH \
811 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
812 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
813 xpr \
814 JSON_HEDLEY_DIAGNOSTIC_POP
815 # else
816 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
817 JSON_HEDLEY_DIAGNOSTIC_PUSH \
818 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
819 xpr \
820 JSON_HEDLEY_DIAGNOSTIC_POP
821 # endif
822 # endif
823 #endif
824 #if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
825 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
826 #endif
827
828 #if defined(JSON_HEDLEY_CONST_CAST)
829 #undef JSON_HEDLEY_CONST_CAST
830 #endif
831 #if defined(__cplusplus)
832 # define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
833 #elif \
834 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
835 JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
836 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
837 # define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
838 JSON_HEDLEY_DIAGNOSTIC_PUSH \
839 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
840 ((T) (expr)); \
841 JSON_HEDLEY_DIAGNOSTIC_POP \
842 }))
843 #else
844 # define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
845 #endif
846
847 #if defined(JSON_HEDLEY_REINTERPRET_CAST)
848 #undef JSON_HEDLEY_REINTERPRET_CAST
849 #endif
850 #if defined(__cplusplus)
851 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
852 #else
853 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
854 #endif
855
856 #if defined(JSON_HEDLEY_STATIC_CAST)
857 #undef JSON_HEDLEY_STATIC_CAST
858 #endif
859 #if defined(__cplusplus)
860 #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
861 #else
862 #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
863 #endif
864
865 #if defined(JSON_HEDLEY_CPP_CAST)
866 #undef JSON_HEDLEY_CPP_CAST
867 #endif
868 #if defined(__cplusplus)
869 # if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
870 # define JSON_HEDLEY_CPP_CAST(T, expr) \
871 JSON_HEDLEY_DIAGNOSTIC_PUSH \
872 _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
873 ((T) (expr)) \
874 JSON_HEDLEY_DIAGNOSTIC_POP
875 # elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
876 # define JSON_HEDLEY_CPP_CAST(T, expr) \
877 JSON_HEDLEY_DIAGNOSTIC_PUSH \
878 _Pragma("diag_suppress=Pe137") \
879 JSON_HEDLEY_DIAGNOSTIC_POP \
880 # else
881 # define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
882 # endif
883 #else
884 # define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
885 #endif
886
887 #if \
888 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
889 defined(__clang__) || \
890 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
891 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
892 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
893 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
894 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
895 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
896 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
897 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
898 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
899 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
900 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
901 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
902 JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
903 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
904 JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
905 (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
906 #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
907 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
908 #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
909 #else
910 #define JSON_HEDLEY_PRAGMA(value)
911 #endif
912
913 #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
914 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
915 #endif
916 #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
917 #undef JSON_HEDLEY_DIAGNOSTIC_POP
918 #endif
919 #if defined(__clang__)
920 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
921 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
922 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
923 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
924 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
925 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
926 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
927 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
928 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
929 #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
930 #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
931 #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
932 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
933 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
934 #elif \
935 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
936 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
937 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
938 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
939 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
940 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
941 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
942 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
943 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
944 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
945 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
946 #else
947 #define JSON_HEDLEY_DIAGNOSTIC_PUSH
948 #define JSON_HEDLEY_DIAGNOSTIC_POP
949 #endif
950
951 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
952 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
953 #endif
954 #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
955 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
956 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
957 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
958 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
959 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
960 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
961 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
962 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
963 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
964 #elif \
965 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
966 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
967 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
968 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
969 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
970 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
971 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
972 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
973 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
974 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
975 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
976 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
977 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
978 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
979 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
980 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
981 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
982 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
983 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
984 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
985 #else
986 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
987 #endif
988
989 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
990 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
991 #endif
992 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
993 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
994 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
995 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
996 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
997 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
998 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
999 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1000 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1001 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1002 #elif \
1003 JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1004 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1005 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1006 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1007 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1008 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1009 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1010 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1011 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1012 #else
1013 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1014 #endif
1015
1016 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1017 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1018 #endif
1019 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1020 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1021 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1022 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1023 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1024 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1025 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1026 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1027 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1028 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1029 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1030 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1031 #elif \
1032 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1033 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1034 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1035 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1036 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1037 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1038 #else
1039 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1040 #endif
1041
1042 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1043 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1044 #endif
1045 #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1046 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1047 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1048 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1049 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1050 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1051 #else
1052 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1053 #endif
1054
1055 #if defined(JSON_HEDLEY_DEPRECATED)
1056 #undef JSON_HEDLEY_DEPRECATED
1057 #endif
1058 #if defined(JSON_HEDLEY_DEPRECATED_FOR)
1059 #undef JSON_HEDLEY_DEPRECATED_FOR
1060 #endif
1061 #if JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0)
1062 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1063 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1064 #elif defined(__cplusplus) && (__cplusplus >= 201402L)
1065 #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1066 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1067 #elif \
1068 JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) || \
1069 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1070 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1071 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1072 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1073 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1074 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1075 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1076 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1077 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1078 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1079 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1080 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1081 #elif \
1082 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1083 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1084 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1085 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1086 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1087 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1088 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1089 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1090 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1091 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1092 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1093 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1094 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1095 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1096 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1097 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1098 #elif \
1099 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1100 JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0)
1101 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1102 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1103 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1104 #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1105 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1106 #else
1107 #define JSON_HEDLEY_DEPRECATED(since)
1108 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1109 #endif
1110
1111 #if defined(JSON_HEDLEY_UNAVAILABLE)
1112 #undef JSON_HEDLEY_UNAVAILABLE
1113 #endif
1114 #if \
1115 JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1116 JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1117 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1118 #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1119 #else
1120 #define JSON_HEDLEY_UNAVAILABLE(available_since)
1121 #endif
1122
1123 #if defined()
1124 #undef
1125 #endif
1126 #if defined(_MSG)
1127 #undef _MSG
1128 #endif
1129 #if (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1130 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1131 #define _MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1132 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1133 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1134 #define _MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1135 #elif \
1136 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1137 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1138 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1139 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1140 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1141 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1142 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1143 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1144 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1145 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1146 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1147 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1148 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1149 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1150 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1151 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1152 #define __attribute__((__warn_unused_result__))
1153 #define _MSG(msg) __attribute__((__warn_unused_result__))
1154 #elif defined(_Check_return_) /* SAL */
1155 #define _Check_return_
1156 #define _MSG(msg) _Check_return_
1157 #else
1158 #define
1159 #define _MSG(msg)
1160 #endif
1161
1162 #if defined(JSON_HEDLEY_SENTINEL)
1163 #undef JSON_HEDLEY_SENTINEL
1164 #endif
1165 #if \
1166 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1167 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1168 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1169 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0)
1170 #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1171 #else
1172 #define JSON_HEDLEY_SENTINEL(position)
1173 #endif
1174
1175 #if defined(JSON_HEDLEY_NO_RETURN)
1176 #undef JSON_HEDLEY_NO_RETURN
1177 #endif
1178 #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1179 #define JSON_HEDLEY_NO_RETURN __noreturn
1180 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1181 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1182 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1183 #define JSON_HEDLEY_NO_RETURN _Noreturn
1184 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
1185 #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1186 #elif \
1187 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1188 JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1189 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1190 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1191 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1192 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1193 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1194 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1195 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1196 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1197 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1198 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1199 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1200 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1201 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1202 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1203 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1204 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1205 #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1206 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
1207 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1208 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1209 #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1210 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1211 #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1212 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1213 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1214 #else
1215 #define JSON_HEDLEY_NO_RETURN
1216 #endif
1217
1218 #if defined(JSON_HEDLEY_NO_ESCAPE)
1219 #undef JSON_HEDLEY_NO_ESCAPE
1220 #endif
1221 #if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1222 #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1223 #else
1224 #define JSON_HEDLEY_NO_ESCAPE
1225 #endif
1226
1227 #if defined(JSON_HEDLEY_UNREACHABLE)
1228 #undef JSON_HEDLEY_UNREACHABLE
1229 #endif
1230 #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1231 #undef JSON_HEDLEY_UNREACHABLE_RETURN
1232 #endif
1233 #if defined(JSON_HEDLEY_ASSUME)
1234 #undef JSON_HEDLEY_ASSUME
1235 #endif
1236 #if \
1237 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1238 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1239 #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1240 #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1241 #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1242 #elif \
1243 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1244 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1245 #if defined(__cplusplus)
1246 #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1247 #else
1248 #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1249 #endif
1250 #endif
1251 #if \
1252 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1253 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1254 JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1255 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1256 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5)
1257 #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1258 #elif defined(JSON_HEDLEY_ASSUME)
1259 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1260 #endif
1261 #if !defined(JSON_HEDLEY_ASSUME)
1262 #if defined(JSON_HEDLEY_UNREACHABLE)
1263 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1264 #else
1265 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1266 #endif
1267 #endif
1268 #if defined(JSON_HEDLEY_UNREACHABLE)
1269 #if \
1270 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1271 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1272 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1273 #else
1274 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1275 #endif
1276 #else
1277 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1278 #endif
1279 #if !defined(JSON_HEDLEY_UNREACHABLE)
1280 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1281 #endif
1282
1283 JSON_HEDLEY_DIAGNOSTIC_PUSH
1284 #if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1285 #pragma clang diagnostic ignored "-Wpedantic"
1286 #endif
1287 #if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1288 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1289 #endif
1290 #if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1291 #if defined(__clang__)
1292 #pragma clang diagnostic ignored "-Wvariadic-macros"
1293 #elif defined(JSON_HEDLEY_GCC_VERSION)
1294 #pragma GCC diagnostic ignored "-Wvariadic-macros"
1295 #endif
1296 #endif
1297 #if defined(JSON_HEDLEY_NON_NULL)
1298 #undef JSON_HEDLEY_NON_NULL
1299 #endif
1300 #if \
1301 JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1302 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1303 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1304 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1305 #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1306 #else
1307 #define JSON_HEDLEY_NON_NULL(...)
1308 #endif
1309 JSON_HEDLEY_DIAGNOSTIC_POP
1310
1311 #if defined(JSON_HEDLEY_PRINTF_FORMAT)
1312 #undef JSON_HEDLEY_PRINTF_FORMAT
1313 #endif
1314 #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1315 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1316 #elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1317 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1318 #elif \
1319 JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1320 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1321 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1322 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1323 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1324 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1325 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1326 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1327 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1328 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1329 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1330 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1331 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1332 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1333 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1334 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1335 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1336 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1337 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1338 #else
1339 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1340 #endif
1341
1342 #if defined(JSON_HEDLEY_CONSTEXPR)
1343 #undef JSON_HEDLEY_CONSTEXPR
1344 #endif
1345 #if defined(__cplusplus)
1346 #if __cplusplus >= 201103L
1347 #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1348 #endif
1349 #endif
1350 #if !defined(JSON_HEDLEY_CONSTEXPR)
1351 #define JSON_HEDLEY_CONSTEXPR
1352 #endif
1353
1354 #if defined(JSON_HEDLEY_PREDICT)
1355 #undef JSON_HEDLEY_PREDICT
1356 #endif
1357 #if defined(JSON_HEDLEY_LIKELY)
1358 #undef JSON_HEDLEY_LIKELY
1359 #endif
1360 #if defined(JSON_HEDLEY_UNLIKELY)
1361 #undef JSON_HEDLEY_UNLIKELY
1362 #endif
1363 #if defined(JSON_HEDLEY_UNPREDICTABLE)
1364 #undef JSON_HEDLEY_UNPREDICTABLE
1365 #endif
1366 #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1367 #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1368 #endif
1369 #if \
1370 JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) || \
1371 JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0)
1372 # define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1373 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1374 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1375 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1376 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1377 #elif \
1378 JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) || \
1379 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1380 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1381 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1382 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1383 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1384 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1385 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1386 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1387 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1388 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1389 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1390 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1391 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1392 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
1393 # define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1394 (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1395 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1396 (__extension__ ({ \
1397 double hedley_probability_ = (probability); \
1398 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1399 }))
1400 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1401 (__extension__ ({ \
1402 double hedley_probability_ = (probability); \
1403 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1404 }))
1405 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1406 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1407 #else
1408 # define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1409 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1410 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1411 # define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1412 # define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1413 #endif
1414 #if !defined(JSON_HEDLEY_UNPREDICTABLE)
1415 #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1416 #endif
1417
1418 #if defined(JSON_HEDLEY_MALLOC)
1419 #undef JSON_HEDLEY_MALLOC
1420 #endif
1421 #if \
1422 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1423 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1424 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1425 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1426 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1427 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1428 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1429 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1430 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1431 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1432 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1433 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1434 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1435 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1436 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1437 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1438 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1439 #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1440 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1441 #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1442 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(14, 0, 0)
1443 #define JSON_HEDLEY_MALLOC __declspec(restrict)
1444 #else
1445 #define JSON_HEDLEY_MALLOC
1446 #endif
1447
1448 #if defined(JSON_HEDLEY_PURE)
1449 #undef JSON_HEDLEY_PURE
1450 #endif
1451 #if \
1452 JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1453 JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1454 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1455 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1456 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1457 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1458 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1459 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1460 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1461 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1462 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1463 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1464 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1465 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1466 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1467 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1468 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1469 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1470 # define JSON_HEDLEY_PURE __attribute__((__pure__))
1471 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1472 # define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1473 #elif defined(__cplusplus) && \
1474 ( \
1475 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1476 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1477 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1478 )
1479 # define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1480 #else
1481 # define JSON_HEDLEY_PURE
1482 #endif
1483
1484 #if defined(JSON_HEDLEY_CONST)
1485 #undef JSON_HEDLEY_CONST
1486 #endif
1487 #if \
1488 JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1489 JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1490 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1491 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1492 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1493 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1494 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1495 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1496 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1497 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1498 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1499 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1500 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1501 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1502 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1503 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1504 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1505 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1506 #define JSON_HEDLEY_CONST __attribute__((__const__))
1507 #elif \
1508 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1509 #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1510 #else
1511 #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1512 #endif
1513
1514 #if defined(JSON_HEDLEY_RESTRICT)
1515 #undef JSON_HEDLEY_RESTRICT
1516 #endif
1517 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1518 #define JSON_HEDLEY_RESTRICT restrict
1519 #elif \
1520 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1521 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1522 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1523 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1524 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1525 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1526 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1527 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1528 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1529 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1530 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1531 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1532 defined(__clang__)
1533 #define JSON_HEDLEY_RESTRICT __restrict
1534 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1535 #define JSON_HEDLEY_RESTRICT _Restrict
1536 #else
1537 #define JSON_HEDLEY_RESTRICT
1538 #endif
1539
1540 #if defined(JSON_HEDLEY_INLINE)
1541 #undef JSON_HEDLEY_INLINE
1542 #endif
1543 #if \
1544 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1545 (defined(__cplusplus) && (__cplusplus >= 199711L))
1546 #define JSON_HEDLEY_INLINE inline
1547 #elif \
1548 defined(JSON_HEDLEY_GCC_VERSION) || \
1549 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1550 #define JSON_HEDLEY_INLINE __inline__
1551 #elif \
1552 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1553 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1554 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1555 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1556 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1557 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1558 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1559 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1560 #define JSON_HEDLEY_INLINE __inline
1561 #else
1562 #define JSON_HEDLEY_INLINE
1563 #endif
1564
1565 #if defined(JSON_HEDLEY_ALWAYS_INLINE)
1566 #undef JSON_HEDLEY_ALWAYS_INLINE
1567 #endif
1568 #if \
1569 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1570 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1571 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1572 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1573 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1574 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1575 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1576 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1577 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1578 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1579 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1580 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1581 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1582 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1583 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1584 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1585 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1586 # define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1587 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0)
1588 # define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1589 #elif defined(__cplusplus) && \
1590 ( \
1591 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1592 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1593 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1594 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1595 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1596 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1597 )
1598 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1599 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1600 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1601 #else
1602 # define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1603 #endif
1604
1605 #if defined(JSON_HEDLEY_NEVER_INLINE)
1606 #undef JSON_HEDLEY_NEVER_INLINE
1607 #endif
1608 #if \
1609 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1610 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1611 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1612 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1613 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1614 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1615 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1616 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1617 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1618 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1619 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1620 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1621 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1622 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1623 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1624 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1625 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1626 #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1627 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
1628 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1629 #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1630 #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1631 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1632 #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1633 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1634 #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1635 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1636 #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1637 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1638 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1639 #else
1640 #define JSON_HEDLEY_NEVER_INLINE
1641 #endif
1642
1643 #if defined(JSON_HEDLEY_PRIVATE)
1644 #undef JSON_HEDLEY_PRIVATE
1645 #endif
1646 #if defined(JSON_HEDLEY_PUBLIC)
1647 #undef JSON_HEDLEY_PUBLIC
1648 #endif
1649 #if defined(JSON_HEDLEY_IMPORT)
1650 #undef JSON_HEDLEY_IMPORT
1651 #endif
1652 #if defined(_WIN32) || defined(__CYGWIN__)
1653 # define JSON_HEDLEY_PRIVATE
1654 # define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1655 # define JSON_HEDLEY_IMPORT __declspec(dllimport)
1656 #else
1657 # if \
1658 JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1659 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1660 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1661 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1662 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1663 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1664 ( \
1665 defined(__TI_EABI__) && \
1666 ( \
1667 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1668 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1669 ) \
1670 )
1671 # define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1672 # define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1673 # else
1674 # define JSON_HEDLEY_PRIVATE
1675 # define JSON_HEDLEY_PUBLIC
1676 # endif
1677 # define JSON_HEDLEY_IMPORT extern
1678 #endif
1679
1680 #if defined(JSON_HEDLEY_NO_THROW)
1681 #undef JSON_HEDLEY_NO_THROW
1682 #endif
1683 #if \
1684 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1685 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1686 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1687 #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1688 #elif \
1689 JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1690 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1691 #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1692 #else
1693 #define JSON_HEDLEY_NO_THROW
1694 #endif
1695
1696 #if defined(JSON_HEDLEY_FALL_THROUGH)
1697 #undef JSON_HEDLEY_FALL_THROUGH
1698 #endif
1699 #if \
1700 JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1701 JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0)
1702 #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1703 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1704 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1705 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1706 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1707 #elif defined(__fallthrough) /* SAL */
1708 #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1709 #else
1710 #define JSON_HEDLEY_FALL_THROUGH
1711 #endif
1712
1713 #if defined()
1714 #undef
1715 #endif
1716 #if \
1717 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1718 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
1719 #define __attribute__((__returns_nonnull__))
1720 #elif defined(_Ret_notnull_) /* SAL */
1721 #define _Ret_notnull_
1722 #else
1723 #define
1724 #endif
1725
1726 #if defined(JSON_HEDLEY_ARRAY_PARAM)
1727 #undef JSON_HEDLEY_ARRAY_PARAM
1728 #endif
1729 #if \
1730 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1731 !defined(__STDC_NO_VLA__) && \
1732 !defined(__cplusplus) && \
1733 !defined(JSON_HEDLEY_PGI_VERSION) && \
1734 !defined(JSON_HEDLEY_TINYC_VERSION)
1735 #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1736 #else
1737 #define JSON_HEDLEY_ARRAY_PARAM(name)
1738 #endif
1739
1740 #if defined(JSON_HEDLEY_IS_CONSTANT)
1741 #undef JSON_HEDLEY_IS_CONSTANT
1742 #endif
1743 #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1744 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1745 #endif
1746 /* JSON_HEDLEY_IS_CONSTEXPR_ is for
1747 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1748 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1749 #undef JSON_HEDLEY_IS_CONSTEXPR_
1750 #endif
1751 #if \
1752 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1753 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1754 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1755 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1756 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1757 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1758 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1759 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1760 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
1761 #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1762 #endif
1763 #if !defined(__cplusplus)
1764 # if \
1765 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1766 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1767 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1768 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1769 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1770 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1771 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1772 #if defined(__INTPTR_TYPE__)
1773 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1774 #else
1775 #include <stdint.h>
1776 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1777 #endif
1778 # elif \
1779 ( \
1780 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1781 !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1782 !defined(JSON_HEDLEY_PGI_VERSION) && \
1783 !defined(JSON_HEDLEY_IAR_VERSION)) || \
1784 JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) || \
1785 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1786 JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1787 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1788 JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1789 #if defined(__INTPTR_TYPE__)
1790 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1791 #else
1792 #include <stdint.h>
1793 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1794 #endif
1795 # elif \
1796 defined(JSON_HEDLEY_GCC_VERSION) || \
1797 defined(JSON_HEDLEY_INTEL_VERSION) || \
1798 defined(JSON_HEDLEY_TINYC_VERSION) || \
1799 defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1800 JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1801 defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1802 defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1803 defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1804 defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1805 defined(__clang__)
1806 # define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1807 sizeof(void) != \
1808 sizeof(*( \
1809 1 ? \
1810 ((void*) ((expr) * 0L) ) : \
1811 ((struct { char v[sizeof(void) * 2]; } *) 1) \
1812 ) \
1813 ) \
1814 )
1815 # endif
1816 #endif
1817 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1818 #if !defined(JSON_HEDLEY_IS_CONSTANT)
1819 #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1820 #endif
1821 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
1822 #else
1823 #if !defined(JSON_HEDLEY_IS_CONSTANT)
1824 #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
1825 #endif
1826 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
1827 #endif
1828
1829 #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
1830 #undef JSON_HEDLEY_BEGIN_C_DECLS
1831 #endif
1832 #if defined(JSON_HEDLEY_END_C_DECLS)
1833 #undef JSON_HEDLEY_END_C_DECLS
1834 #endif
1835 #if defined(JSON_HEDLEY_C_DECL)
1836 #undef JSON_HEDLEY_C_DECL
1837 #endif
1838 #if defined(__cplusplus)
1839 #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
1840 #define JSON_HEDLEY_END_C_DECLS }
1841 #define JSON_HEDLEY_C_DECL extern "C"
1842 #else
1843 #define JSON_HEDLEY_BEGIN_C_DECLS
1844 #define JSON_HEDLEY_END_C_DECLS
1845 #define JSON_HEDLEY_C_DECL
1846 #endif
1847
1848 #if defined(JSON_HEDLEY_STATIC_ASSERT)
1849 #undef JSON_HEDLEY_STATIC_ASSERT
1850 #endif
1851 #if \
1852 !defined(__cplusplus) && ( \
1853 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
1854 JSON_HEDLEY_HAS_FEATURE(c_static_assert) || \
1855 JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
1856 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1857 defined(_Static_assert) \
1858 )
1859 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
1860 #elif \
1861 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
1862 JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0)
1863 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
1864 #else
1865 # define JSON_HEDLEY_STATIC_ASSERT(expr, message)
1866 #endif
1867
1868 #if defined(JSON_HEDLEY_NULL)
1869 #undef JSON_HEDLEY_NULL
1870 #endif
1871 #if defined(__cplusplus)
1872 #if __cplusplus >= 201103L
1873 #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
1874 #elif defined(NULL)
1875 #define JSON_HEDLEY_NULL NULL
1876 #else
1877 #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
1878 #endif
1879 #elif defined(NULL)
1880 #define JSON_HEDLEY_NULL NULL
1881 #else
1882 #define JSON_HEDLEY_NULL ((void*) 0)
1883 #endif
1884
1885 #if defined(JSON_HEDLEY_MESSAGE)
1886 #undef JSON_HEDLEY_MESSAGE
1887 #endif
1888 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1889 # define JSON_HEDLEY_MESSAGE(msg) \
1890 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1891 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1892 JSON_HEDLEY_PRAGMA(message msg) \
1893 JSON_HEDLEY_DIAGNOSTIC_POP
1894 #elif \
1895 JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
1896 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1897 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
1898 #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
1899 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
1900 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1901 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1902 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
1903 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1904 #else
1905 # define JSON_HEDLEY_MESSAGE(msg)
1906 #endif
1907
1908 #if defined(JSON_HEDLEY_WARNING)
1909 #undef JSON_HEDLEY_WARNING
1910 #endif
1911 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1912 # define JSON_HEDLEY_WARNING(msg) \
1913 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1914 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1915 JSON_HEDLEY_PRAGMA(clang warning msg) \
1916 JSON_HEDLEY_DIAGNOSTIC_POP
1917 #elif \
1918 JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
1919 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
1920 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1921 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
1922 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1923 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
1924 #else
1925 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
1926 #endif
1927
1928 #if defined(JSON_HEDLEY_REQUIRE)
1929 #undef JSON_HEDLEY_REQUIRE
1930 #endif
1931 #if defined(JSON_HEDLEY_REQUIRE_MSG)
1932 #undef JSON_HEDLEY_REQUIRE_MSG
1933 #endif
1934 #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
1935 # if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
1936 # define JSON_HEDLEY_REQUIRE(expr) \
1937 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1938 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1939 __attribute__((diagnose_if(!(expr), #expr, "error"))) \
1940 JSON_HEDLEY_DIAGNOSTIC_POP
1941 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
1942 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1943 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1944 __attribute__((diagnose_if(!(expr), msg, "error"))) \
1945 JSON_HEDLEY_DIAGNOSTIC_POP
1946 # else
1947 # define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
1948 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
1949 # endif
1950 #else
1951 # define JSON_HEDLEY_REQUIRE(expr)
1952 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
1953 #endif
1954
1955 #if defined(JSON_HEDLEY_FLAGS)
1956 #undef JSON_HEDLEY_FLAGS
1957 #endif
1958 #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum)
1959 #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
1960 #endif
1961
1962 #if defined(JSON_HEDLEY_FLAGS_CAST)
1963 #undef JSON_HEDLEY_FLAGS_CAST
1964 #endif
1965 #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
1966 # define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
1967 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1968 _Pragma("warning(disable:188)") \
1969 ((T) (expr)); \
1970 JSON_HEDLEY_DIAGNOSTIC_POP \
1971 }))
1972 #else
1973 # define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
1974 #endif
1975
1976 #if defined(JSON_HEDLEY_EMPTY_BASES)
1977 #undef JSON_HEDLEY_EMPTY_BASES
1978 #endif
1979 #if JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)
1980 #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
1981 #else
1982 #define JSON_HEDLEY_EMPTY_BASES
1983 #endif
1984
1985 /* Remaining macros are deprecated. */
1986
1987 #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
1988 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
1989 #endif
1990 #if defined(__clang__)
1991 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
1992 #else
1993 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1994 #endif
1995
1996 #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
1997 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
1998 #endif
1999 #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2000
2001 #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2002 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2003 #endif
2004 #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2005
2006 #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2007 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2008 #endif
2009 #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2010
2011 #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2012 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2013 #endif
2014 #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2015
2016 #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2017 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2018 #endif
2019 #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2020
2021 #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2022 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2023 #endif
2024 #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2025
2026 #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2027 #undef JSON_HEDLEY_CLANG_HAS_WARNING
2028 #endif
2029 #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2030
2031 #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2032
2033
2034 // This file contains all internal macro definitions
2035 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2036
2037 // exclude unsupported compilers
2038 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2039 #if defined(__clang__)
2040 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2041 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2042 #endif
2043 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2044 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2045 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2046 #endif
2047 #endif
2048 #endif
2049
2050 // C++ language standard detection
2051 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2052 #define JSON_HAS_CPP_17
2053 #define JSON_HAS_CPP_14
2054 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2055 #define JSON_HAS_CPP_14
2056 #endif
2057
2058 // disable float-equal warnings on GCC/clang
2059 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
2060 #pragma GCC diagnostic push
2061 #pragma GCC diagnostic ignored "-Wfloat-equal"
2062 #endif
2063
2064 // disable documentation warnings on clang
2065 #if defined(__clang__)
2066 #pragma GCC diagnostic push
2067 #pragma GCC diagnostic ignored "-Wdocumentation"
2068 #endif
2069
2070 // allow to disable exceptions
2071 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2072 #define JSON_THROW(exception) throw exception
2073 #define JSON_TRY try
2074 #define JSON_CATCH(exception) catch(exception)
2075 #define JSON_INTERNAL_CATCH(exception) catch(exception)
2076 #else
2077 #include <cstdlib>
2078 #define JSON_THROW(exception) std::abort()
2079 #define JSON_TRY if(true)
2080 #define JSON_CATCH(exception) if(false)
2081 #define JSON_INTERNAL_CATCH(exception) if(false)
2082 #endif
2083
2084 // override exception macros
2085 #if defined(JSON_THROW_USER)
2086 #undef JSON_THROW
2087 #define JSON_THROW JSON_THROW_USER
2088 #endif
2089 #if defined(JSON_TRY_USER)
2090 #undef JSON_TRY
2091 #define JSON_TRY JSON_TRY_USER
2092 #endif
2093 #if defined(JSON_CATCH_USER)
2094 #undef JSON_CATCH
2095 #define JSON_CATCH JSON_CATCH_USER
2096 #undef JSON_INTERNAL_CATCH
2097 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2098 #endif
2099 #if defined(JSON_INTERNAL_CATCH_USER)
2100 #undef JSON_INTERNAL_CATCH
2101 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2102 #endif
2103
2109 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2110 template<typename BasicJsonType> \
2111 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2112 { \
2113 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2114 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2115 auto it = std::find_if(std::begin(m), std::end(m), \
2116 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2117 { \
2118 return ej_pair.first == e; \
2119 }); \
2120 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2121 } \
2122 template<typename BasicJsonType> \
2123 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2124 { \
2125 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2126 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2127 auto it = std::find_if(std::begin(m), std::end(m), \
2128 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2129 { \
2130 return ej_pair.second == j; \
2131 }); \
2132 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2133 }
2134
2135 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2136 // may be removed in the future once the class is split.
2137
2138 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2139 template<template<typename, typename, typename...> class ObjectType, \
2140 template<typename, typename...> class ArrayType, \
2141 class StringType, class BooleanType, class NumberIntegerType, \
2142 class NumberUnsignedType, class NumberFloatType, \
2143 template<typename> class AllocatorType, \
2144 template<typename, typename = void> class JSONSerializer, \
2145 class BinaryType>
2146
2147 #define NLOHMANN_BASIC_JSON_TPL \
2148 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2149 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2150 AllocatorType, JSONSerializer, BinaryType>
2151
2152
2153 namespace nlohmann
2154 {
2155 namespace detail
2156 {
2158 // exceptions //
2160
2189 class exception : public std::exception
2190 {
2191 public:
2193
2194 const char* what() const noexcept override
2195 {
2196 return m.what();
2197 }
2198
2200 const int id;
2201
2202 protected:
2203 JSON_HEDLEY_NON_NULL(3)
2204 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
2205
2206 static std::string name(const std::string& ename, int id_)
2207 {
2208 return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2209 }
2210
2211 private:
2213 std::runtime_error m;
2214 };
2215
2260 class parse_error : public exception
2261 {
2262 public:
2272 static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
2273 {
2274 std::string w = exception::name("parse_error", id_) + "parse error" +
2275 position_string(pos) + ": " + what_arg;
2276 return parse_error(id_, pos.chars_read_total, w.c_str());
2277 }
2278
2279 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
2280 {
2281 std::string w = exception::name("parse_error", id_) + "parse error" +
2282 (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2283 ": " + what_arg;
2284 return parse_error(id_, byte_, w.c_str());
2285 }
2286
2296 const std::size_t byte;
2297
2298 private:
2299 parse_error(int id_, std::size_t byte_, const char* what_arg)
2300 : exception(id_, what_arg), byte(byte_) {}
2301
2302 static std::string position_string(const position_t& pos)
2303 {
2304 return " at line " + std::to_string(pos.lines_read + 1) +
2305 ", column " + std::to_string(pos.chars_read_current_line);
2306 }
2307 };
2308
2346 class invalid_iterator : public exception
2347 {
2348 public:
2349 static invalid_iterator create(int id_, const std::string& what_arg)
2350 {
2351 std::string w = exception::name("invalid_iterator", id_) + what_arg;
2352 return invalid_iterator(id_, w.c_str());
2353 }
2354
2355 private:
2356 JSON_HEDLEY_NON_NULL(3)
2357 invalid_iterator(int id_, const char* what_arg)
2358 : exception(id_, what_arg) {}
2359 };
2360
2400 class type_error : public exception
2401 {
2402 public:
2403 static type_error create(int id_, const std::string& what_arg)
2404 {
2405 std::string w = exception::name("type_error", id_) + what_arg;
2406 return type_error(id_, w.c_str());
2407 }
2408
2409 private:
2410 JSON_HEDLEY_NON_NULL(3)
2411 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2412 };
2413
2447 class out_of_range : public exception
2448 {
2449 public:
2450 static out_of_range create(int id_, const std::string& what_arg)
2451 {
2452 std::string w = exception::name("out_of_range", id_) + what_arg;
2453 return out_of_range(id_, w.c_str());
2454 }
2455
2456 private:
2457 JSON_HEDLEY_NON_NULL(3)
2458 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
2459 };
2460
2485 class other_error : public exception
2486 {
2487 public:
2488 static other_error create(int id_, const std::string& what_arg)
2489 {
2490 std::string w = exception::name("other_error", id_) + what_arg;
2491 return other_error(id_, w.c_str());
2492 }
2493
2494 private:
2495 JSON_HEDLEY_NON_NULL(3)
2496 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2497 };
2498 } // namespace detail
2499 } // namespace nlohmann
2500
2501 // #include <nlohmann/detail/macro_scope.hpp>
2502
2503 // #include <nlohmann/detail/meta/cpp_future.hpp>
2504
2505
2506 #include <cstddef> // size_t
2507 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
2508
2509 // #include <nlohmann/detail/boolean_operators.hpp>
2510
2511
2512 namespace nlohmann
2513 {
2514 namespace detail
2515 {
2516 // alias templates to reduce boilerplate
2517 template<bool B, typename T = void>
2518 using enable_if_t = typename std::enable_if<B, T>::type;
2519
2520 template<typename T>
2521 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
2522
2523 // implementation of C++14 index_sequence and affiliates
2524 // source: https://stackoverflow.com/a/32223343
2525 template<std::size_t... Ints>
2526 struct index_sequence
2527 {
2528 using type = index_sequence;
2529 using value_type = std::size_t;
2530 static constexpr std::size_t size() noexcept
2531 {
2532 return sizeof...(Ints);
2533 }
2534 };
2535
2536 template<class Sequence1, class Sequence2>
2537 struct merge_and_renumber;
2538
2539 template<std::size_t... I1, std::size_t... I2>
2540 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
2541 : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
2542
2543 template<std::size_t N>
2544 struct make_index_sequence
2545 : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
2546 typename make_index_sequence < N - N / 2 >::type > {};
2547
2548 template<> struct make_index_sequence<0> : index_sequence<> {};
2549 template<> struct make_index_sequence<1> : index_sequence<0> {};
2550
2551 template<typename... Ts>
2552 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
2553
2554 // dispatch utility (taken from ranges-v3)
2555 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
2556 template<> struct priority_tag<0> {};
2557
2558 // taken from ranges-v3
2559 template<typename T>
2560 struct static_const
2561 {
2562 static constexpr T value{};
2563 };
2564
2565 template<typename T>
2566 constexpr T static_const<T>::value;
2567 } // namespace detail
2568 } // namespace nlohmann
2569
2570 // #include <nlohmann/detail/meta/type_traits.hpp>
2571
2572
2573 #include <limits> // numeric_limits
2574 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
2575 #include <utility> // declval
2576
2577 // #include <nlohmann/detail/boolean_operators.hpp>
2578
2579 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
2580
2581
2582 #include <iterator> // random_access_iterator_tag
2583
2584 // #include <nlohmann/detail/meta/void_t.hpp>
2585
2586
2587 namespace nlohmann
2588 {
2589 namespace detail
2590 {
2591 template <typename ...Ts> struct make_void
2592 {
2593 using type = void;
2594 };
2595 template <typename ...Ts> using void_t = typename make_void<Ts...>::type;
2596 } // namespace detail
2597 } // namespace nlohmann
2598
2599 // #include <nlohmann/detail/meta/cpp_future.hpp>
2600
2601
2602 namespace nlohmann
2603 {
2604 namespace detail
2605 {
2606 template <typename It, typename = void>
2607 struct iterator_types {};
2608
2609 template <typename It>
2610 struct iterator_types <
2611 It,
2612 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
2613 typename It::reference, typename It::iterator_category >>
2614 {
2615 using difference_type = typename It::difference_type;
2616 using value_type = typename It::value_type;
2617 using pointer = typename It::pointer;
2618 using reference = typename It::reference;
2619 using iterator_category = typename It::iterator_category;
2620 };
2621
2622 // This is required as some compilers implement std::iterator_traits in a way that
2623 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
2624 template <typename T, typename = void>
2625 struct iterator_traits
2626 {
2627 };
2628
2629 template <typename T>
2630 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
2631 : iterator_types<T>
2632 {
2633 };
2634
2635 template <typename T>
2636 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
2637 {
2638 using iterator_category = std::random_access_iterator_tag;
2639 using value_type = T;
2640 using difference_type = ptrdiff_t;
2641 using pointer = T*;
2642 using reference = T&;
2643 };
2644 } // namespace detail
2645 } // namespace nlohmann
2646
2647 // #include <nlohmann/detail/macro_scope.hpp>
2648
2649 // #include <nlohmann/detail/meta/cpp_future.hpp>
2650
2651 // #include <nlohmann/detail/meta/detected.hpp>
2652
2653
2654 #include <type_traits>
2655
2656 // #include <nlohmann/detail/meta/void_t.hpp>
2657
2658
2659 // https://en.cppreference.com/w/cpp/experimental/is_detected
2660 namespace nlohmann
2661 {
2662 namespace detail
2663 {
2664 struct nonesuch
2665 {
2666 nonesuch() = delete;
2667 ~nonesuch() = delete;
2668 nonesuch(nonesuch const&) = delete;
2669 nonesuch(nonesuch const&&) = delete;
2670 void operator=(nonesuch const&) = delete;
2671 void operator=(nonesuch&&) = delete;
2672 };
2673
2674 template <class Default,
2675 class AlwaysVoid,
2676 template <class...> class Op,
2677 class... Args>
2678 struct detector
2679 {
2680 using value_t = std::false_type;
2681 using type = Default;
2682 };
2683
2684 template <class Default, template <class...> class Op, class... Args>
2685 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2686 {
2687 using value_t = std::true_type;
2688 using type = Op<Args...>;
2689 };
2690
2691 template <template <class...> class Op, class... Args>
2692 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2693
2694 template <template <class...> class Op, class... Args>
2695 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2696
2697 template <class Default, template <class...> class Op, class... Args>
2698 using detected_or = detector<Default, void, Op, Args...>;
2699
2700 template <class Default, template <class...> class Op, class... Args>
2701 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2702
2703 template <class Expected, template <class...> class Op, class... Args>
2704 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2705
2706 template <class To, template <class...> class Op, class... Args>
2707 using is_detected_convertible =
2708 std::is_convertible<detected_t<Op, Args...>, To>;
2709 } // namespace detail
2710 } // namespace nlohmann
2711
2712 // #include <nlohmann/json_fwd.hpp>
2713 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
2714 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
2715
2716 #include <cstdint> // int64_t, uint64_t
2717 #include <map> // map
2718 #include <memory> // allocator
2719 #include <string> // string
2720 #include <vector> // vector
2721
2727 namespace nlohmann
2728 {
2736 template<typename T = void, typename SFINAE = void>
2737 struct adl_serializer;
2738
2739 template<template<typename U, typename V, typename... Args> class ObjectType =
2740 std::map,
2741 template<typename U, typename... Args> class ArrayType = std::vector,
2742 class StringType = std::string, class BooleanType = bool,
2743 class NumberIntegerType = std::int64_t,
2744 class NumberUnsignedType = std::uint64_t,
2745 class NumberFloatType = double,
2746 template<typename U> class AllocatorType = std::allocator,
2747 template<typename T, typename SFINAE = void> class JSONSerializer =
2748 adl_serializer,
2749 class BinaryType = std::vector<std::uint8_t>>
2750 class basic_json;
2751
2763 template<typename BasicJsonType>
2764 class json_pointer;
2765
2774 using json = basic_json<>;
2775 } // namespace nlohmann
2776
2777 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
2778
2779
2780 namespace nlohmann
2781 {
2790 namespace detail
2791 {
2793 // helpers //
2795
2796 // Note to maintainers:
2797 //
2798 // Every trait in this file expects a non CV-qualified type.
2799 // The only exceptions are in the 'aliases for detected' section
2800 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
2801 //
2802 // In this case, T has to be properly CV-qualified to constraint the function arguments
2803 // (e.g. to_json(BasicJsonType&, const T&))
2804
2805 template<typename> struct is_basic_json : std::false_type {};
2806
2807 NLOHMANN_BASIC_JSON_TPL_DECLARATION
2808 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
2809
2811 // json_ref helpers //
2813
2814 template <typename>
2815 class json_ref;
2816
2817 template<typename>
2818 struct is_json_ref : std::false_type {};
2819
2820 template <typename T>
2821 struct is_json_ref<json_ref<T>> : std::true_type {};
2822
2824 // aliases for detected //
2826
2827 template <typename T>
2828 using mapped_type_t = typename T::mapped_type;
2829
2830 template <typename T>
2831 using key_type_t = typename T::key_type;
2832
2833 template <typename T>
2834 using value_type_t = typename T::value_type;
2835
2836 template <typename T>
2837 using difference_type_t = typename T::difference_type;
2838
2839 template <typename T>
2840 using pointer_t = typename T::pointer;
2841
2842 template <typename T>
2843 using reference_t = typename T::reference;
2844
2845 template <typename T>
2846 using iterator_category_t = typename T::iterator_category;
2847
2848 template <typename T>
2849 using iterator_t = typename T::iterator;
2850
2851 template <typename T, typename... Args>
2852 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
2853
2854 template <typename T, typename... Args>
2855 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
2856
2857 template <typename T, typename U>
2858 using get_template_function = decltype(std::declval<T>().template get<U>());
2859
2860 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
2861 template <typename BasicJsonType, typename T, typename = void>
2862 struct has_from_json : std::false_type {};
2863
2864 template <typename BasicJsonType, typename T>
2865 struct has_from_json<BasicJsonType, T,
2866 enable_if_t<not is_basic_json<T>::value>>
2867 {
2868 using serializer = typename BasicJsonType::template json_serializer<T, void>;
2869
2870 static constexpr bool value =
2871 is_detected_exact<void, from_json_function, serializer,
2872 const BasicJsonType&, T&>::value;
2873 };
2874
2875 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
2876 // this overload is used for non-default-constructible user-defined-types
2877 template <typename BasicJsonType, typename T, typename = void>
2878 struct has_non_default_from_json : std::false_type {};
2879
2880 template<typename BasicJsonType, typename T>
2881 struct has_non_default_from_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
2882 {
2883 using serializer = typename BasicJsonType::template json_serializer<T, void>;
2884
2885 static constexpr bool value =
2886 is_detected_exact<T, from_json_function, serializer,
2887 const BasicJsonType&>::value;
2888 };
2889
2890 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
2891 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
2892 template <typename BasicJsonType, typename T, typename = void>
2893 struct has_to_json : std::false_type {};
2894
2895 template <typename BasicJsonType, typename T>
2896 struct has_to_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
2897 {
2898 using serializer = typename BasicJsonType::template json_serializer<T, void>;
2899
2900 static constexpr bool value =
2901 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
2902 T>::value;
2903 };
2904
2905
2907 // is_ functions //
2909
2910 template <typename T, typename = void>
2911 struct is_iterator_traits : std::false_type {};
2912
2913 template <typename T>
2914 struct is_iterator_traits<iterator_traits<T>>
2915 {
2916 private:
2917 using traits = iterator_traits<T>;
2918
2919 public:
2920 static constexpr auto value =
2921 is_detected<value_type_t, traits>::value &&
2922 is_detected<difference_type_t, traits>::value &&
2923 is_detected<pointer_t, traits>::value &&
2924 is_detected<iterator_category_t, traits>::value &&
2925 is_detected<reference_t, traits>::value;
2926 };
2927
2928 // source: https://stackoverflow.com/a/37193089/4116453
2929
2930 template <typename T, typename = void>
2931 struct is_complete_type : std::false_type {};
2932
2933 template <typename T>
2934 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
2935
2936 template <typename BasicJsonType, typename CompatibleObjectType,
2937 typename = void>
2938 struct is_compatible_object_type_impl : std::false_type {};
2939
2940 template <typename BasicJsonType, typename CompatibleObjectType>
2941 struct is_compatible_object_type_impl <
2942 BasicJsonType, CompatibleObjectType,
2943 enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value and
2944 is_detected<key_type_t, CompatibleObjectType>::value >>
2945 {
2946
2947 using object_t = typename BasicJsonType::object_t;
2948
2949 // macOS's is_constructible does not play well with nonesuch...
2950 static constexpr bool value =
2951 std::is_constructible<typename object_t::key_type,
2952 typename CompatibleObjectType::key_type>::value and
2953 std::is_constructible<typename object_t::mapped_type,
2954 typename CompatibleObjectType::mapped_type>::value;
2955 };
2956
2957 template <typename BasicJsonType, typename CompatibleObjectType>
2958 struct is_compatible_object_type
2959 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
2960
2961 template <typename BasicJsonType, typename ConstructibleObjectType,
2962 typename = void>
2963 struct is_constructible_object_type_impl : std::false_type {};
2964
2965 template <typename BasicJsonType, typename ConstructibleObjectType>
2966 struct is_constructible_object_type_impl <
2967 BasicJsonType, ConstructibleObjectType,
2968 enable_if_t<is_detected<mapped_type_t, ConstructibleObjectType>::value and
2969 is_detected<key_type_t, ConstructibleObjectType>::value >>
2970 {
2971 using object_t = typename BasicJsonType::object_t;
2972
2973 static constexpr bool value =
2974 (std::is_default_constructible<ConstructibleObjectType>::value and
2975 (std::is_move_assignable<ConstructibleObjectType>::value or
2976 std::is_copy_assignable<ConstructibleObjectType>::value) and
2977 (std::is_constructible<typename ConstructibleObjectType::key_type,
2978 typename object_t::key_type>::value and
2979 std::is_same <
2980 typename object_t::mapped_type,
2981 typename ConstructibleObjectType::mapped_type >::value)) or
2982 (has_from_json<BasicJsonType,
2983 typename ConstructibleObjectType::mapped_type>::value or
2984 has_non_default_from_json <
2985 BasicJsonType,
2986 typename ConstructibleObjectType::mapped_type >::value);
2987 };
2988
2989 template <typename BasicJsonType, typename ConstructibleObjectType>
2990 struct is_constructible_object_type
2991 : is_constructible_object_type_impl<BasicJsonType,
2992 ConstructibleObjectType> {};
2993
2994 template <typename BasicJsonType, typename CompatibleStringType,
2995 typename = void>
2996 struct is_compatible_string_type_impl : std::false_type {};
2997
2998 template <typename BasicJsonType, typename CompatibleStringType>
2999 struct is_compatible_string_type_impl <
3000 BasicJsonType, CompatibleStringType,
3001 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3002 value_type_t, CompatibleStringType>::value >>
3003 {
3004 static constexpr auto value =
3005 std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
3006 };
3007
3008 template <typename BasicJsonType, typename ConstructibleStringType>
3009 struct is_compatible_string_type
3010 : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3011
3012 template <typename BasicJsonType, typename ConstructibleStringType,
3013 typename = void>
3014 struct is_constructible_string_type_impl : std::false_type {};
3015
3016 template <typename BasicJsonType, typename ConstructibleStringType>
3017 struct is_constructible_string_type_impl <
3018 BasicJsonType, ConstructibleStringType,
3019 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3020 value_type_t, ConstructibleStringType>::value >>
3021 {
3022 static constexpr auto value =
3023 std::is_constructible<ConstructibleStringType,
3024 typename BasicJsonType::string_t>::value;
3025 };
3026
3027 template <typename BasicJsonType, typename ConstructibleStringType>
3028 struct is_constructible_string_type
3029 : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3030
3031 template <typename BasicJsonType, typename CompatibleArrayType, typename = void>
3032 struct is_compatible_array_type_impl : std::false_type {};
3033
3034 template <typename BasicJsonType, typename CompatibleArrayType>
3035 struct is_compatible_array_type_impl <
3036 BasicJsonType, CompatibleArrayType,
3037 enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value and
3038 is_detected<iterator_t, CompatibleArrayType>::value and
3039 // This is needed because json_reverse_iterator has a ::iterator type...
3040 // Therefore it is detected as a CompatibleArrayType.
3041 // The real fix would be to have an Iterable concept.
3042 not is_iterator_traits<
3043 iterator_traits<CompatibleArrayType>>::value >>
3044 {
3045 static constexpr bool value =
3046 std::is_constructible<BasicJsonType,
3047 typename CompatibleArrayType::value_type>::value;
3048 };
3049
3050 template <typename BasicJsonType, typename CompatibleArrayType>
3051 struct is_compatible_array_type
3052 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3053
3054 template <typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3055 struct is_constructible_array_type_impl : std::false_type {};
3056
3057 template <typename BasicJsonType, typename ConstructibleArrayType>
3058 struct is_constructible_array_type_impl <
3059 BasicJsonType, ConstructibleArrayType,
3060 enable_if_t<std::is_same<ConstructibleArrayType,
3061 typename BasicJsonType::value_type>::value >>
3062 : std::true_type {};
3063
3064 template <typename BasicJsonType, typename ConstructibleArrayType>
3065 struct is_constructible_array_type_impl <
3066 BasicJsonType, ConstructibleArrayType,
3067 enable_if_t<not std::is_same<ConstructibleArrayType,
3068 typename BasicJsonType::value_type>::value and
3069 std::is_default_constructible<ConstructibleArrayType>::value and
3070 (std::is_move_assignable<ConstructibleArrayType>::value or
3071 std::is_copy_assignable<ConstructibleArrayType>::value) and
3072 is_detected<value_type_t, ConstructibleArrayType>::value and
3073 is_detected<iterator_t, ConstructibleArrayType>::value and
3074 is_complete_type<
3075 detected_t<value_type_t, ConstructibleArrayType>>::value >>
3076 {
3077 static constexpr bool value =
3078 // This is needed because json_reverse_iterator has a ::iterator type,
3079 // furthermore, std::back_insert_iterator (and other iterators) have a
3080 // base class `iterator`... Therefore it is detected as a
3081 // ConstructibleArrayType. The real fix would be to have an Iterable
3082 // concept.
3083 not is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value and
3084
3085 (std::is_same<typename ConstructibleArrayType::value_type,
3086 typename BasicJsonType::array_t::value_type>::value or
3087 has_from_json<BasicJsonType,
3088 typename ConstructibleArrayType::value_type>::value or
3089 has_non_default_from_json <
3090 BasicJsonType, typename ConstructibleArrayType::value_type >::value);
3091 };
3092
3093 template <typename BasicJsonType, typename ConstructibleArrayType>
3094 struct is_constructible_array_type
3095 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3096
3097 template <typename RealIntegerType, typename CompatibleNumberIntegerType,
3098 typename = void>
3099 struct is_compatible_integer_type_impl : std::false_type {};
3100
3101 template <typename RealIntegerType, typename CompatibleNumberIntegerType>
3102 struct is_compatible_integer_type_impl <
3103 RealIntegerType, CompatibleNumberIntegerType,
3104 enable_if_t<std::is_integral<RealIntegerType>::value and
3105 std::is_integral<CompatibleNumberIntegerType>::value and
3106 not std::is_same<bool, CompatibleNumberIntegerType>::value >>
3107 {
3108 // is there an assert somewhere on overflows?
3109 using RealLimits = std::numeric_limits<RealIntegerType>;
3110 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3111
3112 static constexpr auto value =
3113 std::is_constructible<RealIntegerType,
3114 CompatibleNumberIntegerType>::value and
3115 CompatibleLimits::is_integer and
3116 RealLimits::is_signed == CompatibleLimits::is_signed;
3117 };
3118
3119 template <typename RealIntegerType, typename CompatibleNumberIntegerType>
3120 struct is_compatible_integer_type
3121 : is_compatible_integer_type_impl<RealIntegerType,
3122 CompatibleNumberIntegerType> {};
3123
3124 template <typename BasicJsonType, typename CompatibleType, typename = void>
3125 struct is_compatible_type_impl: std::false_type {};
3126
3127 template <typename BasicJsonType, typename CompatibleType>
3128 struct is_compatible_type_impl <
3129 BasicJsonType, CompatibleType,
3130 enable_if_t<is_complete_type<CompatibleType>::value >>
3131 {
3132 static constexpr bool value =
3133 has_to_json<BasicJsonType, CompatibleType>::value;
3134 };
3135
3136 template <typename BasicJsonType, typename CompatibleType>
3137 struct is_compatible_type
3138 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3139
3140 // https://en.cppreference.com/w/cpp/types/conjunction
3141 template<class...> struct conjunction : std::true_type { };
3142 template<class B1> struct conjunction<B1> : B1 { };
3143 template<class B1, class... Bn>
3144 struct conjunction<B1, Bn...>
3145 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3146
3147 template <typename T1, typename T2>
3148 struct is_constructible_tuple : std::false_type {};
3149
3150 template <typename T1, typename... Args>
3151 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<std::is_constructible<T1, Args>...> {};
3152 } // namespace detail
3153 } // namespace nlohmann
3154
3155 // #include <nlohmann/detail/value_t.hpp>
3156
3157
3158 #include <array> // array
3159 #include <cstddef> // size_t
3160 #include <cstdint> // uint8_t
3161 #include <string> // string
3162
3163 // #include <nlohmann/detail/boolean_operators.hpp>
3164
3165
3166 namespace nlohmann
3167 {
3168 namespace detail
3169 {
3171 // JSON type enumeration //
3173
3198 enum class value_t : std::uint8_t
3199 {
3200 null,
3201 object,
3202 array,
3203 string,
3204 boolean,
3205 number_integer,
3206 number_unsigned,
3207 number_float,
3208 binary,
3209 discarded
3210 };
3211
3225 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
3226 {
3227 static constexpr std::array<std::uint8_t, 9> order = {{
3228 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
3229 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
3230 6 /* binary */
3231 }
3232 };
3233
3234 const auto l_index = static_cast<std::size_t>(lhs);
3235 const auto r_index = static_cast<std::size_t>(rhs);
3236 return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
3237 }
3238 } // namespace detail
3239 } // namespace nlohmann
3240
3241
3242 namespace nlohmann
3243 {
3244 namespace detail
3245 {
3246 template<typename BasicJsonType>
3247 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3248 {
3249 if (JSON_HEDLEY_UNLIKELY(not j.is_null()))
3250 {
3251 JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
3252 }
3253 n = nullptr;
3254 }
3255
3256 // overloads for basic_json template parameters
3257 template<typename BasicJsonType, typename ArithmeticType,
3258 enable_if_t<std::is_arithmetic<ArithmeticType>::value and
3259 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3260 int> = 0>
3261 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3262 {
3263 switch (static_cast<value_t>(j))
3264 {
3265 case value_t::number_unsigned:
3266 {
3267 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3268 break;
3269 }
3270 case value_t::number_integer:
3271 {
3272 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3273 break;
3274 }
3275 case value_t::number_float:
3276 {
3277 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3278 break;
3279 }
3280
3281 default:
3282 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
3283 }
3284 }
3285
3286 template<typename BasicJsonType>
3287 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
3288 {
3289 if (JSON_HEDLEY_UNLIKELY(not j.is_boolean()))
3290 {
3291 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
3292 }
3293 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
3294 }
3295
3296 template<typename BasicJsonType>
3297 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
3298 {
3299 if (JSON_HEDLEY_UNLIKELY(not j.is_string()))
3300 {
3301 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
3302 }
3303 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3304 }
3305
3306 template <
3307 typename BasicJsonType, typename ConstructibleStringType,
3308 enable_if_t <
3309 is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value and
3310 not std::is_same<typename BasicJsonType::string_t,
3311 ConstructibleStringType>::value,
3312 int > = 0 >
3313 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
3314 {
3315 if (JSON_HEDLEY_UNLIKELY(not j.is_string()))
3316 {
3317 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
3318 }
3319
3320 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3321 }
3322
3323 template<typename BasicJsonType>
3324 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
3325 {
3326 get_arithmetic_value(j, val);
3327 }
3328
3329 template<typename BasicJsonType>
3330 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
3331 {
3332 get_arithmetic_value(j, val);
3333 }
3334
3335 template<typename BasicJsonType>
3336 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
3337 {
3338 get_arithmetic_value(j, val);
3339 }
3340
3341 template<typename BasicJsonType, typename EnumType,
3342 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
3343 void from_json(const BasicJsonType& j, EnumType& e)
3344 {
3345 typename std::underlying_type<EnumType>::type val;
3346 get_arithmetic_value(j, val);
3347 e = static_cast<EnumType>(val);
3348 }
3349
3350 // forward_list doesn't have an insert method
3351 template<typename BasicJsonType, typename T, typename Allocator,
3352 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
3353 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
3354 {
3355 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3356 {
3357 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3358 }
3359 l.clear();
3360 std::transform(j.rbegin(), j.rend(),
3361 std::front_inserter(l), [](const BasicJsonType & i)
3362 {
3363 return i.template get<T>();
3364 });
3365 }
3366
3367 // valarray doesn't have an insert method
3368 template<typename BasicJsonType, typename T,
3369 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
3370 void from_json(const BasicJsonType& j, std::valarray<T>& l)
3371 {
3372 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3373 {
3374 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3375 }
3376 l.resize(j.size());
3377 std::copy(j.begin(), j.end(), std::begin(l));
3378 }
3379
3380 template <typename BasicJsonType, typename T, std::size_t N>
3381 auto from_json(const BasicJsonType& j, T (&arr)[N])
3382 -> decltype(j.template get<T>(), void())
3383 {
3384 for (std::size_t i = 0; i < N; ++i)
3385 {
3386 arr[i] = j.at(i).template get<T>();
3387 }
3388 }
3389
3390 template<typename BasicJsonType>
3391 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
3392 {
3393 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
3394 }
3395
3396 template <typename BasicJsonType, typename T, std::size_t N>
3397 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
3398 priority_tag<2> /*unused*/)
3399 -> decltype(j.template get<T>(), void())
3400 {
3401 for (std::size_t i = 0; i < N; ++i)
3402 {
3403 arr[i] = j.at(i).template get<T>();
3404 }
3405 }
3406
3407 template<typename BasicJsonType, typename ConstructibleArrayType>
3408 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
3409 -> decltype(
3410 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
3411 j.template get<typename ConstructibleArrayType::value_type>(),
3412 void())
3413 {
3414 using std::end;
3415
3416 ConstructibleArrayType ret;
3417 ret.reserve(j.size());
3418 std::transform(j.begin(), j.end(),
3419 std::inserter(ret, end(ret)), [](const BasicJsonType & i)
3420 {
3421 // get<BasicJsonType>() returns *this, this won't call a from_json
3422 // method when value_type is BasicJsonType
3423 return i.template get<typename ConstructibleArrayType::value_type>();
3424 });
3425 arr = std::move(ret);
3426 }
3427
3428 template <typename BasicJsonType, typename ConstructibleArrayType>
3429 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
3430 priority_tag<0> /*unused*/)
3431 {
3432 using std::end;
3433
3434 ConstructibleArrayType ret;
3435 std::transform(
3436 j.begin(), j.end(), std::inserter(ret, end(ret)),
3437 [](const BasicJsonType & i)
3438 {
3439 // get<BasicJsonType>() returns *this, this won't call a from_json
3440 // method when value_type is BasicJsonType
3441 return i.template get<typename ConstructibleArrayType::value_type>();
3442 });
3443 arr = std::move(ret);
3444 }
3445
3446 template <typename BasicJsonType, typename ConstructibleArrayType,
3447 enable_if_t <
3448 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value and
3449 not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value and
3450 not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value and
3451 not std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value and
3452 not is_basic_json<ConstructibleArrayType>::value,
3453 int > = 0 >
3454 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
3455 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
3456 j.template get<typename ConstructibleArrayType::value_type>(),
3457 void())
3458 {
3459 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3460 {
3461 JSON_THROW(type_error::create(302, "type must be array, but is " +
3462 std::string(j.type_name())));
3463 }
3464
3465 from_json_array_impl(j, arr, priority_tag<3> {});
3466 }
3467
3468 template <typename BasicJsonType>
3469 void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
3470 {
3471 if (JSON_HEDLEY_UNLIKELY(not j.is_binary()))
3472 {
3473 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name())));
3474 }
3475
3476 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
3477 }
3478
3479 template<typename BasicJsonType, typename ConstructibleObjectType,
3480 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
3481 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
3482 {
3483 if (JSON_HEDLEY_UNLIKELY(not j.is_object()))
3484 {
3485 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
3486 }
3487
3488 ConstructibleObjectType ret;
3489 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
3490 using value_type = typename ConstructibleObjectType::value_type;
3491 std::transform(
3492 inner_object->begin(), inner_object->end(),
3493 std::inserter(ret, ret.begin()),
3494 [](typename BasicJsonType::object_t::value_type const & p)
3495 {
3496 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
3497 });
3498 obj = std::move(ret);
3499 }
3500
3501 // overload for arithmetic types, not chosen for basic_json template arguments
3502 // (BooleanType, etc..); note: Is it really necessary to provide explicit
3503 // overloads for boolean_t etc. in case of a custom BooleanType which is not
3504 // an arithmetic type?
3505 template<typename BasicJsonType, typename ArithmeticType,
3506 enable_if_t <
3507 std::is_arithmetic<ArithmeticType>::value and
3508 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
3509 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
3510 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
3511 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3512 int> = 0>
3513 void from_json(const BasicJsonType& j, ArithmeticType& val)
3514 {
3515 switch (static_cast<value_t>(j))
3516 {
3517 case value_t::number_unsigned:
3518 {
3519 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3520 break;
3521 }
3522 case value_t::number_integer:
3523 {
3524 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3525 break;
3526 }
3527 case value_t::number_float:
3528 {
3529 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3530 break;
3531 }
3532 case value_t::boolean:
3533 {
3534 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
3535 break;
3536 }
3537
3538 default:
3539 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
3540 }
3541 }
3542
3543 template<typename BasicJsonType, typename A1, typename A2>
3544 void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
3545 {
3546 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
3547 }
3548
3549 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
3550 void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
3551 {
3552 t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
3553 }
3554
3555 template<typename BasicJsonType, typename... Args>
3556 void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
3557 {
3558 from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
3559 }
3560
3561 template <typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
3562 typename = enable_if_t<not std::is_constructible<
3563 typename BasicJsonType::string_t, Key>::value>>
3564 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
3565 {
3566 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3567 {
3568 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3569 }
3570 m.clear();
3571 for (const auto& p : j)
3572 {
3573 if (JSON_HEDLEY_UNLIKELY(not p.is_array()))
3574 {
3575 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3576 }
3577 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3578 }
3579 }
3580
3581 template <typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
3582 typename = enable_if_t<not std::is_constructible<
3583 typename BasicJsonType::string_t, Key>::value>>
3584 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
3585 {
3586 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3587 {
3588 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3589 }
3590 m.clear();
3591 for (const auto& p : j)
3592 {
3593 if (JSON_HEDLEY_UNLIKELY(not p.is_array()))
3594 {
3595 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3596 }
3597 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3598 }
3599 }
3600
3601 struct from_json_fn
3602 {
3603 template<typename BasicJsonType, typename T>
3604 auto operator()(const BasicJsonType& j, T& val) const
3605 noexcept(noexcept(from_json(j, val)))
3606 -> decltype(from_json(j, val), void())
3607 {
3608 return from_json(j, val);
3609 }
3610 };
3611 } // namespace detail
3612
3616 namespace
3617 {
3618 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
3619 } // namespace
3620 } // namespace nlohmann
3621
3622 // #include <nlohmann/detail/conversions/to_json.hpp>
3623
3624
3625 #include <algorithm> // copy
3626 #include <iterator> // begin, end
3627 #include <string> // string
3628 #include <tuple> // tuple, get
3629 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
3630 #include <utility> // move, forward, declval, pair
3631 #include <valarray> // valarray
3632 #include <vector> // vector
3633
3634 // #include <nlohmann/detail/boolean_operators.hpp>
3635
3636 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
3637
3638
3639 #include <cstddef> // size_t
3640 #include <iterator> // input_iterator_tag
3641 #include <string> // string, to_string
3642 #include <tuple> // tuple_size, get, tuple_element
3643
3644 // #include <nlohmann/detail/meta/type_traits.hpp>
3645
3646 // #include <nlohmann/detail/value_t.hpp>
3647
3648
3649 namespace nlohmann
3650 {
3651 namespace detail
3652 {
3653 template<typename string_type>
3654 void int_to_string( string_type& target, std::size_t value )
3655 {
3656 target = std::to_string(value);
3657 }
3658 template <typename IteratorType> class iteration_proxy_value
3659 {
3660 public:
3661 using difference_type = std::ptrdiff_t;
3662 using value_type = iteration_proxy_value;
3663 using pointer = value_type * ;
3664 using reference = value_type & ;
3665 using iterator_category = std::input_iterator_tag;
3666 using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
3667
3668 private:
3670 IteratorType anchor;
3672 std::size_t array_index = 0;
3674 mutable std::size_t array_index_last = 0;
3676 mutable string_type array_index_str = "0";
3678 const string_type empty_str = "";
3679
3680 public:
3681 explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
3682
3684 iteration_proxy_value& operator*()
3685 {
3686 return *this;
3687 }
3688
3690 iteration_proxy_value& operator++()
3691 {
3692 ++anchor;
3693 ++array_index;
3694
3695 return *this;
3696 }
3697
3699 bool operator==(const iteration_proxy_value& o) const
3700 {
3701 return anchor == o.anchor;
3702 }
3703
3705 bool operator!=(const iteration_proxy_value& o) const
3706 {
3707 return anchor != o.anchor;
3708 }
3709
3711 const string_type& key() const
3712 {
3713 assert(anchor.m_object != nullptr);
3714
3715 switch (anchor.m_object->type())
3716 {
3717 // use integer array index as key
3718 case value_t::array:
3719 {
3720 if (array_index != array_index_last)
3721 {
3722 int_to_string( array_index_str, array_index );
3723 array_index_last = array_index;
3724 }
3725 return array_index_str;
3726 }
3727
3728 // use key from the object
3729 case value_t::object:
3730 return anchor.key();
3731
3732 // use an empty key for all primitive types
3733 default:
3734 return empty_str;
3735 }
3736 }
3737
3739 typename IteratorType::reference value() const
3740 {
3741 return anchor.value();
3742 }
3743 };
3744
3746 template<typename IteratorType> class iteration_proxy
3747 {
3748 private:
3750 typename IteratorType::reference container;
3751
3752 public:
3754 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
3755 : container(cont) {}
3756
3758 iteration_proxy_value<IteratorType> begin() noexcept
3759 {
3760 return iteration_proxy_value<IteratorType>(container.begin());
3761 }
3762
3764 iteration_proxy_value<IteratorType> end() noexcept
3765 {
3766 return iteration_proxy_value<IteratorType>(container.end());
3767 }
3768 };
3769 // Structured Bindings Support
3770 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3771 // And see https://github.com/nlohmann/json/pull/1391
3772 template <std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
3773 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
3774 {
3775 return i.key();
3776 }
3777 // Structured Bindings Support
3778 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3779 // And see https://github.com/nlohmann/json/pull/1391
3780 template <std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
3781 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
3782 {
3783 return i.value();
3784 }
3785 } // namespace detail
3786 } // namespace nlohmann
3787
3788 // The Addition to the STD Namespace is required to add
3789 // Structured Bindings Support to the iteration_proxy_value class
3790 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3791 // And see https://github.com/nlohmann/json/pull/1391
3792 namespace std
3793 {
3794 #if defined(__clang__)
3795 // Fix: https://github.com/nlohmann/json/issues/1401
3796 #pragma clang diagnostic push
3797 #pragma clang diagnostic ignored "-Wmismatched-tags"
3798 #endif
3799 template <typename IteratorType>
3800 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
3801 : public std::integral_constant<std::size_t, 2> {};
3802
3803 template <std::size_t N, typename IteratorType>
3804 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
3805 {
3806 public:
3807 using type = decltype(
3808 get<N>(std::declval <
3809 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
3810 };
3811 #if defined(__clang__)
3812 #pragma clang diagnostic pop
3813 #endif
3814 } // namespace std
3815
3816 // #include <nlohmann/detail/meta/cpp_future.hpp>
3817
3818 // #include <nlohmann/detail/meta/type_traits.hpp>
3819
3820 // #include <nlohmann/detail/value_t.hpp>
3821
3822
3823 namespace nlohmann
3824 {
3825 namespace detail
3826 {
3828 // constructors //
3830
3831 template<value_t> struct external_constructor;
3832
3833 template<>
3834 struct external_constructor<value_t::boolean>
3835 {
3836 template<typename BasicJsonType>
3837 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
3838 {
3839 j.m_type = value_t::boolean;
3840 j.m_value = b;
3841 j.assert_invariant();
3842 }
3843 };
3844
3845 template<>
3846 struct external_constructor<value_t::string>
3847 {
3848 template<typename BasicJsonType>
3849 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
3850 {
3851 j.m_type = value_t::string;
3852 j.m_value = s;
3853 j.assert_invariant();
3854 }
3855
3856 template<typename BasicJsonType>
3857 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
3858 {
3859 j.m_type = value_t::string;
3860 j.m_value = std::move(s);
3861 j.assert_invariant();
3862 }
3863
3864 template<typename BasicJsonType, typename CompatibleStringType,
3865 enable_if_t<not std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
3866 int> = 0>
3867 static void construct(BasicJsonType& j, const CompatibleStringType& str)
3868 {
3869 j.m_type = value_t::string;
3870 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
3871 j.assert_invariant();
3872 }
3873 };
3874
3875 template<>
3876 struct external_constructor<value_t::binary>
3877 {
3878 template<typename BasicJsonType>
3879 static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
3880 {
3881 j.m_type = value_t::binary;
3882 typename BasicJsonType::binary_t value{b};
3883 j.m_value = value;
3884 j.assert_invariant();
3885 }
3886
3887 template<typename BasicJsonType>
3888 static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
3889 {
3890 j.m_type = value_t::binary;
3891 typename BasicJsonType::binary_t value{std::move(b)};
3892 j.m_value = value;
3893 j.assert_invariant();
3894 }
3895 };
3896
3897 template<>
3898 struct external_constructor<value_t::number_float>
3899 {
3900 template<typename BasicJsonType>
3901 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
3902 {
3903 j.m_type = value_t::number_float;
3904 j.m_value = val;
3905 j.assert_invariant();
3906 }
3907 };
3908
3909 template<>
3910 struct external_constructor<value_t::number_unsigned>
3911 {
3912 template<typename BasicJsonType>
3913 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
3914 {
3915 j.m_type = value_t::number_unsigned;
3916 j.m_value = val;
3917 j.assert_invariant();
3918 }
3919 };
3920
3921 template<>
3922 struct external_constructor<value_t::number_integer>
3923 {
3924 template<typename BasicJsonType>
3925 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
3926 {
3927 j.m_type = value_t::number_integer;
3928 j.m_value = val;
3929 j.assert_invariant();
3930 }
3931 };
3932
3933 template<>
3934 struct external_constructor<value_t::array>
3935 {
3936 template<typename BasicJsonType>
3937 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
3938 {
3939 j.m_type = value_t::array;
3940 j.m_value = arr;
3941 j.assert_invariant();
3942 }
3943
3944 template<typename BasicJsonType>
3945 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
3946 {
3947 j.m_type = value_t::array;
3948 j.m_value = std::move(arr);
3949 j.assert_invariant();
3950 }
3951
3952 template<typename BasicJsonType, typename CompatibleArrayType,
3953 enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
3954 int> = 0>
3955 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
3956 {
3957 using std::begin;
3958 using std::end;
3959 j.m_type = value_t::array;
3960 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
3961 j.assert_invariant();
3962 }
3963
3964 template<typename BasicJsonType>
3965 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
3966 {
3967 j.m_type = value_t::array;
3968 j.m_value = value_t::array;
3969 j.m_value.array->reserve(arr.size());
3970 for (const bool x : arr)
3971 {
3972 j.m_value.array->push_back(x);
3973 }
3974 j.assert_invariant();
3975 }
3976
3977 template<typename BasicJsonType, typename T,
3978 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
3979 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
3980 {
3981 j.m_type = value_t::array;
3982 j.m_value = value_t::array;
3983 j.m_value.array->resize(arr.size());
3984 if (arr.size() > 0)
3985 {
3986 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
3987 }
3988 j.assert_invariant();
3989 }
3990 };
3991
3992 template<>
3993 struct external_constructor<value_t::object>
3994 {
3995 template<typename BasicJsonType>
3996 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
3997 {
3998 j.m_type = value_t::object;
3999 j.m_value = obj;
4000 j.assert_invariant();
4001 }
4002
4003 template<typename BasicJsonType>
4004 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4005 {
4006 j.m_type = value_t::object;
4007 j.m_value = std::move(obj);
4008 j.assert_invariant();
4009 }
4010
4011 template<typename BasicJsonType, typename CompatibleObjectType,
4012 enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0>
4013 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4014 {
4015 using std::begin;
4016 using std::end;
4017
4018 j.m_type = value_t::object;
4019 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4020 j.assert_invariant();
4021 }
4022 };
4023
4025 // to_json //
4027
4028 template<typename BasicJsonType, typename T,
4029 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
4030 void to_json(BasicJsonType& j, T b) noexcept
4031 {
4032 external_constructor<value_t::boolean>::construct(j, b);
4033 }
4034
4035 template<typename BasicJsonType, typename CompatibleString,
4036 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
4037 void to_json(BasicJsonType& j, const CompatibleString& s)
4038 {
4039 external_constructor<value_t::string>::construct(j, s);
4040 }
4041
4042 template<typename BasicJsonType>
4043 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4044 {
4045 external_constructor<value_t::string>::construct(j, std::move(s));
4046 }
4047
4048 template<typename BasicJsonType, typename FloatType,
4049 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
4050 void to_json(BasicJsonType& j, FloatType val) noexcept
4051 {
4052 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4053 }
4054
4055 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4056 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
4057 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4058 {
4059 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4060 }
4061
4062 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4063 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
4064 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4065 {
4066 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4067 }
4068
4069 template<typename BasicJsonType, typename EnumType,
4070 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4071 void to_json(BasicJsonType& j, EnumType e) noexcept
4072 {
4073 using underlying_type = typename std::underlying_type<EnumType>::type;
4074 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4075 }
4076
4077 template<typename BasicJsonType>
4078 void to_json(BasicJsonType& j, const std::vector<bool>& e)
4079 {
4080 external_constructor<value_t::array>::construct(j, e);
4081 }
4082
4083 template <typename BasicJsonType, typename CompatibleArrayType,
4084 enable_if_t<is_compatible_array_type<BasicJsonType,
4085 CompatibleArrayType>::value and
4086 not is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value and
4087 not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
4088 not std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value and
4089 not is_basic_json<CompatibleArrayType>::value,
4090 int> = 0>
4091 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4092 {
4093 external_constructor<value_t::array>::construct(j, arr);
4094 }
4095
4096 template <typename BasicJsonType>
4097 void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4098 {
4099 external_constructor<value_t::binary>::construct(j, bin);
4100 }
4101
4102 template<typename BasicJsonType, typename T,
4103 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4104 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4105 {
4106 external_constructor<value_t::array>::construct(j, std::move(arr));
4107 }
4108
4109 template<typename BasicJsonType>
4110 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4111 {
4112 external_constructor<value_t::array>::construct(j, std::move(arr));
4113 }
4114
4115 template<typename BasicJsonType, typename CompatibleObjectType,
4116 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value and not is_basic_json<CompatibleObjectType>::value, int> = 0>
4117 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4118 {
4119 external_constructor<value_t::object>::construct(j, obj);
4120 }
4121
4122 template<typename BasicJsonType>
4123 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4124 {
4125 external_constructor<value_t::object>::construct(j, std::move(obj));
4126 }
4127
4128 template <
4129 typename BasicJsonType, typename T, std::size_t N,
4130 enable_if_t<not std::is_constructible<typename BasicJsonType::string_t,
4131 const T(&)[N]>::value,
4132 int> = 0 >
4133 void to_json(BasicJsonType& j, const T(&arr)[N])
4134 {
4135 external_constructor<value_t::array>::construct(j, arr);
4136 }
4137
4138 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
4139 void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4140 {
4141 j = { p.first, p.second };
4142 }
4143
4144 // for https://github.com/nlohmann/json/pull/1134
4145 template < typename BasicJsonType, typename T,
4146 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
4147 void to_json(BasicJsonType& j, const T& b)
4148 {
4149 j = { {b.key(), b.value()} };
4150 }
4151
4152 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
4153 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4154 {
4155 j = { std::get<Idx>(t)... };
4156 }
4157
4158 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
4159 void to_json(BasicJsonType& j, const T& t)
4160 {
4161 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
4162 }
4163
4164 struct to_json_fn
4165 {
4166 template<typename BasicJsonType, typename T>
4167 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
4168 -> decltype(to_json(j, std::forward<T>(val)), void())
4169 {
4170 return to_json(j, std::forward<T>(val));
4171 }
4172 };
4173 } // namespace detail
4174
4176 namespace
4177 {
4178 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
4179 } // namespace
4180 } // namespace nlohmann
4181
4182
4183 namespace nlohmann
4184 {
4185
4186 template<typename, typename>
4187 struct adl_serializer
4188 {
4198 template<typename BasicJsonType, typename ValueType>
4199 static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
4200 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
4201 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
4202 {
4203 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
4204 }
4205
4215 template <typename BasicJsonType, typename ValueType>
4216 static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
4217 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
4218 -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void())
4219 {
4220 ::nlohmann::to_json(j, std::forward<ValueType>(val));
4221 }
4222 };
4223
4224 } // namespace nlohmann
4225
4226 // #include <nlohmann/byte_container_with_subtype.hpp>
4227
4228
4229 #include <cstdint> // uint8_t
4230 #include <tuple> // tie
4231 #include <utility> // move
4232
4233 namespace nlohmann
4234 {
4235
4249 template<typename BinaryType>
4250 class byte_container_with_subtype : public BinaryType
4251 {
4252 public:
4254 using container_type = BinaryType;
4255
4256 byte_container_with_subtype() noexcept(noexcept(container_type()))
4257 : container_type()
4258 {}
4259
4260 byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))
4261 : container_type(b)
4262 {}
4263
4264 byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
4265 : container_type(std::move(b))
4266 {}
4267
4268 byte_container_with_subtype(const container_type& b, std::uint8_t subtype) noexcept(noexcept(container_type(b)))
4269 : container_type(b)
4270 , m_subtype(subtype)
4271 , m_has_subtype(true)
4272 {}
4273
4274 byte_container_with_subtype(container_type&& b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b))))
4275 : container_type(std::move(b))
4276 , m_subtype(subtype)
4277 , m_has_subtype(true)
4278 {}
4279
4280 bool operator==(const byte_container_with_subtype& rhs) const
4281 {
4282 return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
4283 std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
4284 }
4285
4286 bool operator!=(const byte_container_with_subtype& rhs) const
4287 {
4288 return !(rhs == *this);
4289 }
4290
4309 void set_subtype(std::uint8_t subtype) noexcept
4310 {
4311 m_subtype = subtype;
4312 m_has_subtype = true;
4313 }
4314
4336 constexpr std::uint8_t subtype() const noexcept
4337 {
4338 return m_subtype;
4339 }
4340
4357 constexpr bool has_subtype() const noexcept
4358 {
4359 return m_has_subtype;
4360 }
4361
4381 void clear_subtype() noexcept
4382 {
4383 m_subtype = 0;
4384 m_has_subtype = false;
4385 }
4386
4387 private:
4388 std::uint8_t m_subtype = 0;
4389 bool m_has_subtype = false;
4390 };
4391
4392 } // namespace nlohmann
4393
4394 // #include <nlohmann/detail/boolean_operators.hpp>
4395
4396 // #include <nlohmann/detail/conversions/from_json.hpp>
4397
4398 // #include <nlohmann/detail/conversions/to_json.hpp>
4399
4400 // #include <nlohmann/detail/exceptions.hpp>
4401
4402 // #include <nlohmann/detail/input/binary_reader.hpp>
4403
4404
4405 #include <algorithm> // generate_n
4406 #include <array> // array
4407 #include <cassert> // assert
4408 #include <cmath> // ldexp
4409 #include <cstddef> // size_t
4410 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
4411 #include <cstdio> // snprintf
4412 #include <cstring> // memcpy
4413 #include <iterator> // back_inserter
4414 #include <limits> // numeric_limits
4415 #include <string> // char_traits, string
4416 #include <utility> // make_pair, move
4417
4418 // #include <nlohmann/detail/exceptions.hpp>
4419
4420 // #include <nlohmann/detail/input/input_adapters.hpp>
4421
4422
4423 #include <array> // array
4424 #include <cassert> // assert
4425 #include <cstddef> // size_t
4426 #include <cstdio> //FILE *
4427 #include <cstring> // strlen
4428 #include <istream> // istream
4429 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
4430 #include <memory> // shared_ptr, make_shared, addressof
4431 #include <numeric> // accumulate
4432 #include <string> // string, char_traits
4433 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
4434 #include <utility> // pair, declval
4435
4436 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
4437
4438 // #include <nlohmann/detail/macro_scope.hpp>
4439
4440
4441 namespace nlohmann
4442 {
4443 namespace detail
4444 {
4446 enum class input_format_t { json, cbor, msgpack, ubjson, bson };
4447
4449 // input adapters //
4451
4456 class file_input_adapter
4457 {
4458 public:
4459 using char_type = char;
4460
4461 JSON_HEDLEY_NON_NULL(2)
4462 explicit file_input_adapter(std::FILE* f) noexcept
4463 : m_file(f)
4464 {}
4465
4466 // make class move-only
4467 file_input_adapter(const file_input_adapter&) = delete;
4468 file_input_adapter(file_input_adapter&&) = default;
4469 file_input_adapter& operator=(const file_input_adapter&) = delete;
4470 file_input_adapter& operator=(file_input_adapter&&) = delete;
4471
4472 std::char_traits<char>::int_type get_character() noexcept
4473 {
4474 return std::fgetc(m_file);
4475 }
4476
4477 private:
4479 std::FILE* m_file;
4480 };
4481
4482
4492 class input_stream_adapter
4493 {
4494 public:
4495 using char_type = char;
4496
4497 ~input_stream_adapter()
4498 {
4499 // clear stream flags; we use underlying streambuf I/O, do not
4500 // maintain ifstream flags, except eof
4501 if (is)
4502 {
4503 is->clear(is->rdstate() & std::ios::eofbit);
4504 }
4505 }
4506
4507 explicit input_stream_adapter(std::istream& i)
4508 : is(&i), sb(i.rdbuf())
4509 {}
4510
4511 // delete because of pointer members
4512 input_stream_adapter(const input_stream_adapter&) = delete;
4513 input_stream_adapter& operator=(input_stream_adapter&) = delete;
4514 input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
4515
4516 input_stream_adapter(input_stream_adapter&& rhs) : is(rhs.is), sb(rhs.sb)
4517 {
4518 rhs.is = nullptr;
4519 rhs.sb = nullptr;
4520 }
4521
4522 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
4523 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
4524 // end up as the same value, eg. 0xFFFFFFFF.
4525 std::char_traits<char>::int_type get_character()
4526 {
4527 auto res = sb->sbumpc();
4528 // set eof manually, as we don't use the istream interface.
4529 if (JSON_HEDLEY_UNLIKELY(res == EOF))
4530 {
4531 is->clear(is->rdstate() | std::ios::eofbit);
4532 }
4533 return res;
4534 }
4535
4536 private:
4538 std::istream* is = nullptr;
4539 std::streambuf* sb = nullptr;
4540 };
4541
4542 // General-purpose iterator-based adapter. It might not be as fast as
4543 // theoretically possible for some containers, but it is extremely versatile.
4544 template<typename IteratorType>
4545 class iterator_input_adapter
4546 {
4547 public:
4548 using char_type = typename std::iterator_traits<IteratorType>::value_type;
4549
4550 iterator_input_adapter(IteratorType first, IteratorType last)
4551 : current(std::move(first)), end(std::move(last)) {}
4552
4553 typename std::char_traits<char_type>::int_type get_character()
4554 {
4555 if (JSON_HEDLEY_LIKELY(current != end))
4556 {
4557 auto result = std::char_traits<char_type>::to_int_type(*current);
4558 std::advance(current, 1);
4559 return result;
4560 }
4561 else
4562 {
4563 return std::char_traits<char_type>::eof();
4564 }
4565 }
4566
4567 private:
4568 IteratorType current;
4569 IteratorType end;
4570
4571 template<typename BaseInputAdapter, size_t T>
4572 friend struct wide_string_input_helper;
4573
4574 bool empty() const
4575 {
4576 return current == end;
4577 }
4578
4579 };
4580
4581
4582 template<typename BaseInputAdapter, size_t T>
4583 struct wide_string_input_helper;
4584
4585 template<typename BaseInputAdapter>
4586 struct wide_string_input_helper<BaseInputAdapter, 4>
4587 {
4588 // UTF-32
4589 static void fill_buffer(BaseInputAdapter& input,
4590 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4591 size_t& utf8_bytes_index,
4592 size_t& utf8_bytes_filled)
4593 {
4594 utf8_bytes_index = 0;
4595
4596 if (JSON_HEDLEY_UNLIKELY(input.empty()))
4597 {
4598 utf8_bytes[0] = std::char_traits<char>::eof();
4599 utf8_bytes_filled = 1;
4600 }
4601 else
4602 {
4603 // get the current character
4604 const auto wc = input.get_character();
4605
4606 // UTF-32 to UTF-8 encoding
4607 if (wc < 0x80)
4608 {
4609 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4610 utf8_bytes_filled = 1;
4611 }
4612 else if (wc <= 0x7FF)
4613 {
4614 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
4615 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4616 utf8_bytes_filled = 2;
4617 }
4618 else if (wc <= 0xFFFF)
4619 {
4620 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
4621 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4622 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4623 utf8_bytes_filled = 3;
4624 }
4625 else if (wc <= 0x10FFFF)
4626 {
4627 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
4628 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
4629 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4630 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4631 utf8_bytes_filled = 4;
4632 }
4633 else
4634 {
4635 // unknown character
4636 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4637 utf8_bytes_filled = 1;
4638 }
4639 }
4640 }
4641 };
4642
4643 template<typename BaseInputAdapter>
4644 struct wide_string_input_helper<BaseInputAdapter, 2>
4645 {
4646 // UTF-16
4647 static void fill_buffer(BaseInputAdapter& input,
4648 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4649 size_t& utf8_bytes_index,
4650 size_t& utf8_bytes_filled)
4651 {
4652 utf8_bytes_index = 0;
4653
4654 if (JSON_HEDLEY_UNLIKELY(input.empty()))
4655 {
4656 utf8_bytes[0] = std::char_traits<char>::eof();
4657 utf8_bytes_filled = 1;
4658 }
4659 else
4660 {
4661 // get the current character
4662 const auto wc = input.get_character();
4663
4664 // UTF-16 to UTF-8 encoding
4665 if (wc < 0x80)
4666 {
4667 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4668 utf8_bytes_filled = 1;
4669 }
4670 else if (wc <= 0x7FF)
4671 {
4672 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
4673 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4674 utf8_bytes_filled = 2;
4675 }
4676 else if (0xD800 > wc or wc >= 0xE000)
4677 {
4678 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
4679 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4680 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4681 utf8_bytes_filled = 3;
4682 }
4683 else
4684 {
4685 if (JSON_HEDLEY_UNLIKELY(not input.empty()))
4686 {
4687 const auto wc2 = static_cast<unsigned int>(input.get_character());
4688 const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
4689 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
4690 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
4691 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
4692 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
4693 utf8_bytes_filled = 4;
4694 }
4695 else
4696 {
4697 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4698 utf8_bytes_filled = 1;
4699 }
4700 }
4701 }
4702 }
4703 };
4704
4705 // Wraps another input apdater to convert wide character types into individual bytes.
4706 template<typename BaseInputAdapter, typename WideCharType>
4707 class wide_string_input_adapter
4708 {
4709 public:
4710 using char_type = char;
4711
4712 wide_string_input_adapter(BaseInputAdapter base)
4713 : base_adapter(base) {}
4714
4715 typename std::char_traits<char>::int_type get_character() noexcept
4716 {
4717 // check if buffer needs to be filled
4718 if (utf8_bytes_index == utf8_bytes_filled)
4719 {
4720 fill_buffer<sizeof(WideCharType)>();
4721
4722 assert(utf8_bytes_filled > 0);
4723 assert(utf8_bytes_index == 0);
4724 }
4725
4726 // use buffer
4727 assert(utf8_bytes_filled > 0);
4728 assert(utf8_bytes_index < utf8_bytes_filled);
4729 return utf8_bytes[utf8_bytes_index++];
4730 }
4731
4732 private:
4733 BaseInputAdapter base_adapter;
4734
4735 template<size_t T>
4736 void fill_buffer()
4737 {
4738 wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
4739 }
4740
4742 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
4743
4745 std::size_t utf8_bytes_index = 0;
4747 std::size_t utf8_bytes_filled = 0;
4748 };
4749
4750
4751 template<typename IteratorType, typename Enable = void>
4752 struct iterator_input_adapter_factory
4753 {
4754 using iterator_type = IteratorType;
4755 using char_type = typename std::iterator_traits<iterator_type>::value_type;
4756 using adapter_type = iterator_input_adapter<iterator_type>;
4757
4758 static adapter_type create(IteratorType first, IteratorType last)
4759 {
4760 return adapter_type(std::move(first), std::move(last));
4761 }
4762 };
4763
4764 template<typename T>
4765 struct is_iterator_of_multibyte
4766 {
4767 using value_type = typename std::iterator_traits<T>::value_type;
4768 enum
4769 {
4770 value = sizeof(value_type) > 1
4771 };
4772 };
4773
4774 template<typename IteratorType>
4775 struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
4776 {
4777 using iterator_type = IteratorType;
4778 using char_type = typename std::iterator_traits<iterator_type>::value_type;
4779 using base_adapter_type = iterator_input_adapter<iterator_type>;
4780 using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
4781
4782 static adapter_type create(IteratorType first, IteratorType last)
4783 {
4784 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
4785 }
4786 };
4787
4788 // General purpose iterator-based input
4789 template<typename IteratorType>
4790 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
4791 {
4792 using factory_type = iterator_input_adapter_factory<IteratorType>;
4793 return factory_type::create(first, last);
4794 }
4795
4796 // Convenience shorthand from container to iterator
4797 template<typename ContainerType>
4798 auto input_adapter(const ContainerType& container) -> decltype(input_adapter(begin(container), end(container)))
4799 {
4800 // Enable ADL
4801 using std::begin;
4802 using std::end;
4803
4804 return input_adapter(begin(container), end(container));
4805 }
4806
4807 // Special cases with fast paths
4808 inline file_input_adapter input_adapter(std::FILE* file)
4809 {
4810 return file_input_adapter(file);
4811 }
4812
4813 inline input_stream_adapter input_adapter(std::istream& stream)
4814 {
4815 return input_stream_adapter(stream);
4816 }
4817
4818 inline input_stream_adapter input_adapter(std::istream&& stream)
4819 {
4820 return input_stream_adapter(stream);
4821 }
4822
4823 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
4824
4825 // Null-delimited strings, and the like.
4826 template < typename CharT,
4827 typename std::enable_if <
4828 std::is_pointer<CharT>::value and
4829 not std::is_array<CharT>::value and
4830 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
4831 sizeof(typename std::remove_pointer<CharT>::type) == 1,
4832 int >::type = 0 >
4833 contiguous_bytes_input_adapter input_adapter(CharT b)
4834 {
4835 auto length = std::strlen(reinterpret_cast<const char*>(b));
4836 auto ptr = reinterpret_cast<const char*>(b);
4837 return input_adapter(ptr, ptr + length);
4838 }
4839
4840 template<typename T, std::size_t N>
4841 auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N))
4842 {
4843 return input_adapter(array, array + N);
4844 }
4845
4846 // This class only handles inputs of input_buffer_adapter type.
4847 // It's required so that expressions like {ptr, len} can be implicitely casted
4848 // to the correct adapter.
4849 class span_input_adapter
4850 {
4851 public:
4852 template<typename CharT,
4853 typename std::enable_if<
4854 std::is_pointer<CharT>::value and
4855 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
4856 sizeof(typename std::remove_pointer<CharT>::type) == 1,
4857 int>::type = 0>
4858 span_input_adapter(CharT b, std::size_t l)
4859 : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
4860
4861 template<class IteratorType,
4862 typename std::enable_if<
4863 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
4864 int>::type = 0>
4865 span_input_adapter(IteratorType first, IteratorType last)
4866 : ia(input_adapter(first, last)) {}
4867
4868 contiguous_bytes_input_adapter&& get()
4869 {
4870 return std::move(ia);
4871 }
4872
4873 private:
4874 contiguous_bytes_input_adapter ia;
4875 };
4876 } // namespace detail
4877 } // namespace nlohmann
4878
4879 // #include <nlohmann/detail/input/json_sax.hpp>
4880
4881
4882 #include <cassert> // assert
4883 #include <cstddef>
4884 #include <string> // string
4885 #include <utility> // move
4886 #include <vector> // vector
4887
4888 // #include <nlohmann/detail/exceptions.hpp>
4889
4890 // #include <nlohmann/detail/macro_scope.hpp>
4891
4892
4893 namespace nlohmann
4894 {
4895
4904 template<typename BasicJsonType>
4905 struct json_sax
4906 {
4907 using number_integer_t = typename BasicJsonType::number_integer_t;
4908 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4909 using number_float_t = typename BasicJsonType::number_float_t;
4910 using string_t = typename BasicJsonType::string_t;
4911 using binary_t = typename BasicJsonType::binary_t;
4912
4917 virtual bool null() = 0;
4918
4924 virtual bool boolean(bool val) = 0;
4925
4931 virtual bool number_integer(number_integer_t val) = 0;
4932
4938 virtual bool number_unsigned(number_unsigned_t val) = 0;
4939
4946 virtual bool number_float(number_float_t val, const string_t& s) = 0;
4947
4954 virtual bool string(string_t& val) = 0;
4955
4962 virtual bool binary(binary_t& val) = 0;
4963
4970 virtual bool start_object(std::size_t elements) = 0;
4971
4978 virtual bool key(string_t& val) = 0;
4979
4984 virtual bool end_object() = 0;
4985
4992 virtual bool start_array(std::size_t elements) = 0;
4993
4998 virtual bool end_array() = 0;
4999
5007 virtual bool parse_error(std::size_t position,
5008 const std::string& last_token,
5009 const detail::exception& ex) = 0;
5010
5011 virtual ~json_sax() = default;
5012 };
5013
5014
5015 namespace detail
5016 {
5030 template<typename BasicJsonType>
5031 class json_sax_dom_parser
5032 {
5033 public:
5034 using number_integer_t = typename BasicJsonType::number_integer_t;
5035 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5036 using number_float_t = typename BasicJsonType::number_float_t;
5037 using string_t = typename BasicJsonType::string_t;
5038 using binary_t = typename BasicJsonType::binary_t;
5039
5045 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
5046 : root(r), allow_exceptions(allow_exceptions_)
5047 {}
5048
5049 // make class move-only
5050 json_sax_dom_parser(const json_sax_dom_parser&) = delete;
5051 json_sax_dom_parser(json_sax_dom_parser&&) = default;
5052 json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
5053 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
5054 ~json_sax_dom_parser() = default;
5055
5056 bool null()
5057 {
5058 handle_value(nullptr);
5059 return true;
5060 }
5061
5062 bool boolean(bool val)
5063 {
5064 handle_value(val);
5065 return true;
5066 }
5067
5068 bool number_integer(number_integer_t val)
5069 {
5070 handle_value(val);
5071 return true;
5072 }
5073
5074 bool number_unsigned(number_unsigned_t val)
5075 {
5076 handle_value(val);
5077 return true;
5078 }
5079
5080 bool number_float(number_float_t val, const string_t& /*unused*/)
5081 {
5082 handle_value(val);
5083 return true;
5084 }
5085
5086 bool string(string_t& val)
5087 {
5088 handle_value(val);
5089 return true;
5090 }
5091
5092 bool binary(binary_t& val)
5093 {
5094 handle_value(std::move(val));
5095 return true;
5096 }
5097
5098 bool start_object(std::size_t len)
5099 {
5100 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
5101
5102 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
5103 {
5104 JSON_THROW(out_of_range::create(408,
5105 "excessive object size: " + std::to_string(len)));
5106 }
5107
5108 return true;
5109 }
5110
5111 bool key(string_t& val)
5112 {
5113 // add null at given key and store the reference for later
5114 object_element = &(ref_stack.back()->m_value.object->operator[](val));
5115 return true;
5116 }
5117
5118 bool end_object()
5119 {
5120 ref_stack.pop_back();
5121 return true;
5122 }
5123
5124 bool start_array(std::size_t len)
5125 {
5126 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
5127
5128 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
5129 {
5130 JSON_THROW(out_of_range::create(408,
5131 "excessive array size: " + std::to_string(len)));
5132 }
5133
5134 return true;
5135 }
5136
5137 bool end_array()
5138 {
5139 ref_stack.pop_back();
5140 return true;
5141 }
5142
5143 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5144 const detail::exception& ex)
5145 {
5146 errored = true;
5147 if (allow_exceptions)
5148 {
5149 // determine the proper exception type from the id
5150 switch ((ex.id / 100) % 100)
5151 {
5152 case 1:
5153 JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
5154 case 4:
5155 JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
5156 // LCOV_EXCL_START
5157 case 2:
5158 JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
5159 case 3:
5160 JSON_THROW(*static_cast<const detail::type_error*>(&ex));
5161 case 5:
5162 JSON_THROW(*static_cast<const detail::other_error*>(&ex));
5163 default:
5164 assert(false);
5165 // LCOV_EXCL_STOP
5166 }
5167 }
5168 return false;
5169 }
5170
5171 constexpr bool is_errored() const
5172 {
5173 return errored;
5174 }
5175
5176 private:
5183 template<typename Value>
5184
5185 BasicJsonType* handle_value(Value&& v)
5186 {
5187 if (ref_stack.empty())
5188 {
5189 root = BasicJsonType(std::forward<Value>(v));
5190 return &root;
5191 }
5192
5193 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
5194
5195 if (ref_stack.back()->is_array())
5196 {
5197 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
5198 return &(ref_stack.back()->m_value.array->back());
5199 }
5200
5201 assert(ref_stack.back()->is_object());
5202 assert(object_element);
5203 *object_element = BasicJsonType(std::forward<Value>(v));
5204 return object_element;
5205 }
5206
5208 BasicJsonType& root;
5210 std::vector<BasicJsonType*> ref_stack {};
5212 BasicJsonType* object_element = nullptr;
5214 bool errored = false;
5216 const bool allow_exceptions = true;
5217 };
5218
5219 template<typename BasicJsonType>
5220 class json_sax_dom_callback_parser
5221 {
5222 public:
5223 using number_integer_t = typename BasicJsonType::number_integer_t;
5224 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5225 using number_float_t = typename BasicJsonType::number_float_t;
5226 using string_t = typename BasicJsonType::string_t;
5227 using binary_t = typename BasicJsonType::binary_t;
5228 using parser_callback_t = typename BasicJsonType::parser_callback_t;
5229 using parse_event_t = typename BasicJsonType::parse_event_t;
5230
5231 json_sax_dom_callback_parser(BasicJsonType& r,
5232 const parser_callback_t cb,
5233 const bool allow_exceptions_ = true)
5234 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
5235 {
5236 keep_stack.push_back(true);
5237 }
5238
5239 // make class move-only
5240 json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
5241 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default;
5242 json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
5243 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default;
5244 ~json_sax_dom_callback_parser() = default;
5245
5246 bool null()
5247 {
5248 handle_value(nullptr);
5249 return true;
5250 }
5251
5252 bool boolean(bool val)
5253 {
5254 handle_value(val);
5255 return true;
5256 }
5257
5258 bool number_integer(number_integer_t val)
5259 {
5260 handle_value(val);
5261 return true;
5262 }
5263
5264 bool number_unsigned(number_unsigned_t val)
5265 {
5266 handle_value(val);
5267 return true;
5268 }
5269
5270 bool number_float(number_float_t val, const string_t& /*unused*/)
5271 {
5272 handle_value(val);
5273 return true;
5274 }
5275
5276 bool string(string_t& val)
5277 {
5278 handle_value(val);
5279 return true;
5280 }
5281
5282 bool binary(binary_t& val)
5283 {
5284 handle_value(std::move(val));
5285 return true;
5286 }
5287
5288 bool start_object(std::size_t len)
5289 {
5290 // check callback for object start
5291 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
5292 keep_stack.push_back(keep);
5293
5294 auto val = handle_value(BasicJsonType::value_t::object, true);
5295 ref_stack.push_back(val.second);
5296
5297 // check object limit
5298 if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
5299 {
5300 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
5301 }
5302
5303 return true;
5304 }
5305
5306 bool key(string_t& val)
5307 {
5308 BasicJsonType k = BasicJsonType(val);
5309
5310 // check callback for key
5311 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
5312 key_keep_stack.push_back(keep);
5313
5314 // add discarded value at given key and store the reference for later
5315 if (keep and ref_stack.back())
5316 {
5317 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
5318 }
5319
5320 return true;
5321 }
5322
5323 bool end_object()
5324 {
5325 if (ref_stack.back() and not callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
5326 {
5327 // discard object
5328 *ref_stack.back() = discarded;
5329 }
5330
5331 assert(not ref_stack.empty());
5332 assert(not keep_stack.empty());
5333 ref_stack.pop_back();
5334 keep_stack.pop_back();
5335
5336 if (not ref_stack.empty() and ref_stack.back() and ref_stack.back()->is_structured())
5337 {
5338 // remove discarded value
5339 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
5340 {
5341 if (it->is_discarded())
5342 {
5343 ref_stack.back()->erase(it);
5344 break;
5345 }
5346 }
5347 }
5348
5349 return true;
5350 }
5351
5352 bool start_array(std::size_t len)
5353 {
5354 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
5355 keep_stack.push_back(keep);
5356
5357 auto val = handle_value(BasicJsonType::value_t::array, true);
5358 ref_stack.push_back(val.second);
5359
5360 // check array limit
5361 if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
5362 {
5363 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
5364 }
5365
5366 return true;
5367 }
5368
5369 bool end_array()
5370 {
5371 bool keep = true;
5372
5373 if (ref_stack.back())
5374 {
5375 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
5376 if (not keep)
5377 {
5378 // discard array
5379 *ref_stack.back() = discarded;
5380 }
5381 }
5382
5383 assert(not ref_stack.empty());
5384 assert(not keep_stack.empty());
5385 ref_stack.pop_back();
5386 keep_stack.pop_back();
5387
5388 // remove discarded value
5389 if (not keep and not ref_stack.empty() and ref_stack.back()->is_array())
5390 {
5391 ref_stack.back()->m_value.array->pop_back();
5392 }
5393
5394 return true;
5395 }
5396
5397 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5398 const detail::exception& ex)
5399 {
5400 errored = true;
5401 if (allow_exceptions)
5402 {
5403 // determine the proper exception type from the id
5404 switch ((ex.id / 100) % 100)
5405 {
5406 case 1:
5407 JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
5408 case 4:
5409 JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
5410 // LCOV_EXCL_START
5411 case 2:
5412 JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
5413 case 3:
5414 JSON_THROW(*static_cast<const detail::type_error*>(&ex));
5415 case 5:
5416 JSON_THROW(*static_cast<const detail::other_error*>(&ex));
5417 default:
5418 assert(false);
5419 // LCOV_EXCL_STOP
5420 }
5421 }
5422 return false;
5423 }
5424
5425 constexpr bool is_errored() const
5426 {
5427 return errored;
5428 }
5429
5430 private:
5446 template<typename Value>
5447 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
5448 {
5449 assert(not keep_stack.empty());
5450
5451 // do not handle this value if we know it would be added to a discarded
5452 // container
5453 if (not keep_stack.back())
5454 {
5455 return {false, nullptr};
5456 }
5457
5458 // create value
5459 auto value = BasicJsonType(std::forward<Value>(v));
5460
5461 // check callback
5462 const bool keep = skip_callback or callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
5463
5464 // do not handle this value if we just learnt it shall be discarded
5465 if (not keep)
5466 {
5467 return {false, nullptr};
5468 }
5469
5470 if (ref_stack.empty())
5471 {
5472 root = std::move(value);
5473 return {true, &root};
5474 }
5475
5476 // skip this value if we already decided to skip the parent
5477 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
5478 if (not ref_stack.back())
5479 {
5480 return {false, nullptr};
5481 }
5482
5483 // we now only expect arrays and objects
5484 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
5485
5486 // array
5487 if (ref_stack.back()->is_array())
5488 {
5489 ref_stack.back()->m_value.array->push_back(std::move(value));
5490 return {true, &(ref_stack.back()->m_value.array->back())};
5491 }
5492
5493 // object
5494 assert(ref_stack.back()->is_object());
5495 // check if we should store an element for the current key
5496 assert(not key_keep_stack.empty());
5497 const bool store_element = key_keep_stack.back();
5498 key_keep_stack.pop_back();
5499
5500 if (not store_element)
5501 {
5502 return {false, nullptr};
5503 }
5504
5505 assert(object_element);
5506 *object_element = std::move(value);
5507 return {true, object_element};
5508 }
5509
5511 BasicJsonType& root;
5513 std::vector<BasicJsonType*> ref_stack {};
5515 std::vector<bool> keep_stack {};
5517 std::vector<bool> key_keep_stack {};
5519 BasicJsonType* object_element = nullptr;
5521 bool errored = false;
5523 const parser_callback_t callback = nullptr;
5525 const bool allow_exceptions = true;
5527 BasicJsonType discarded = BasicJsonType::value_t::discarded;
5528 };
5529
5530 template<typename BasicJsonType>
5531 class json_sax_acceptor
5532 {
5533 public:
5534 using number_integer_t = typename BasicJsonType::number_integer_t;
5535 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5536 using number_float_t = typename BasicJsonType::number_float_t;
5537 using string_t = typename BasicJsonType::string_t;
5538 using binary_t = typename BasicJsonType::binary_t;
5539
5540 bool null()
5541 {
5542 return true;
5543 }
5544
5545 bool boolean(bool /*unused*/)
5546 {
5547 return true;
5548 }
5549
5550 bool number_integer(number_integer_t /*unused*/)
5551 {
5552 return true;
5553 }
5554
5555 bool number_unsigned(number_unsigned_t /*unused*/)
5556 {
5557 return true;
5558 }
5559
5560 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
5561 {
5562 return true;
5563 }
5564
5565 bool string(string_t& /*unused*/)
5566 {
5567 return true;
5568 }
5569
5570 bool binary(binary_t& /*unused*/)
5571 {
5572 return true;
5573 }
5574
5575 bool start_object(std::size_t /*unused*/ = std::size_t(-1))
5576 {
5577 return true;
5578 }
5579
5580 bool key(string_t& /*unused*/)
5581 {
5582 return true;
5583 }
5584
5585 bool end_object()
5586 {
5587 return true;
5588 }
5589
5590 bool start_array(std::size_t /*unused*/ = std::size_t(-1))
5591 {
5592 return true;
5593 }
5594
5595 bool end_array()
5596 {
5597 return true;
5598 }
5599
5600 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
5601 {
5602 return false;
5603 }
5604 };
5605 } // namespace detail
5606
5607 } // namespace nlohmann
5608
5609 // #include <nlohmann/detail/macro_scope.hpp>
5610
5611 // #include <nlohmann/detail/meta/is_sax.hpp>
5612
5613
5614 #include <cstdint> // size_t
5615 #include <utility> // declval
5616 #include <string> // string
5617
5618 // #include <nlohmann/detail/meta/detected.hpp>
5619
5620 // #include <nlohmann/detail/meta/type_traits.hpp>
5621
5622
5623 namespace nlohmann
5624 {
5625 namespace detail
5626 {
5627 template <typename T>
5628 using null_function_t = decltype(std::declval<T&>().null());
5629
5630 template <typename T>
5631 using boolean_function_t =
5632 decltype(std::declval<T&>().boolean(std::declval<bool>()));
5633
5634 template <typename T, typename Integer>
5635 using number_integer_function_t =
5636 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
5637
5638 template <typename T, typename Unsigned>
5639 using number_unsigned_function_t =
5640 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
5641
5642 template <typename T, typename Float, typename String>
5643 using number_float_function_t = decltype(std::declval<T&>().number_float(
5644 std::declval<Float>(), std::declval<const String&>()));
5645
5646 template <typename T, typename String>
5647 using string_function_t =
5648 decltype(std::declval<T&>().string(std::declval<String&>()));
5649
5650 template <typename T>
5651 using start_object_function_t =
5652 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
5653
5654 template <typename T, typename String>
5655 using key_function_t =
5656 decltype(std::declval<T&>().key(std::declval<String&>()));
5657
5658 template <typename T>
5659 using end_object_function_t = decltype(std::declval<T&>().end_object());
5660
5661 template <typename T>
5662 using start_array_function_t =
5663 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
5664
5665 template <typename T>
5666 using end_array_function_t = decltype(std::declval<T&>().end_array());
5667
5668 template <typename T, typename Exception>
5669 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
5670 std::declval<std::size_t>(), std::declval<const std::string&>(),
5671 std::declval<const Exception&>()));
5672
5673 template <typename SAX, typename BasicJsonType>
5674 struct is_sax
5675 {
5676 private:
5677 static_assert(is_basic_json<BasicJsonType>::value,
5678 "BasicJsonType must be of type basic_json<...>");
5679
5680 using number_integer_t = typename BasicJsonType::number_integer_t;
5681 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5682 using number_float_t = typename BasicJsonType::number_float_t;
5683 using string_t = typename BasicJsonType::string_t;
5684 using exception_t = typename BasicJsonType::exception;
5685
5686 public:
5687 static constexpr bool value =
5688 is_detected_exact<bool, null_function_t, SAX>::value &&
5689 is_detected_exact<bool, boolean_function_t, SAX>::value &&
5690 is_detected_exact<bool, number_integer_function_t, SAX,
5691 number_integer_t>::value &&
5692 is_detected_exact<bool, number_unsigned_function_t, SAX,
5693 number_unsigned_t>::value &&
5694 is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
5695 string_t>::value &&
5696 is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
5697 is_detected_exact<bool, start_object_function_t, SAX>::value &&
5698 is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
5699 is_detected_exact<bool, end_object_function_t, SAX>::value &&
5700 is_detected_exact<bool, start_array_function_t, SAX>::value &&
5701 is_detected_exact<bool, end_array_function_t, SAX>::value &&
5702 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
5703 };
5704
5705 template <typename SAX, typename BasicJsonType>
5706 struct is_sax_static_asserts
5707 {
5708 private:
5709 static_assert(is_basic_json<BasicJsonType>::value,
5710 "BasicJsonType must be of type basic_json<...>");
5711
5712 using number_integer_t = typename BasicJsonType::number_integer_t;
5713 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5714 using number_float_t = typename BasicJsonType::number_float_t;
5715 using string_t = typename BasicJsonType::string_t;
5716 using exception_t = typename BasicJsonType::exception;
5717
5718 public:
5719 static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
5720 "Missing/invalid function: bool null()");
5721 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
5722 "Missing/invalid function: bool boolean(bool)");
5723 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
5724 "Missing/invalid function: bool boolean(bool)");
5725 static_assert(
5726 is_detected_exact<bool, number_integer_function_t, SAX,
5727 number_integer_t>::value,
5728 "Missing/invalid function: bool number_integer(number_integer_t)");
5729 static_assert(
5730 is_detected_exact<bool, number_unsigned_function_t, SAX,
5731 number_unsigned_t>::value,
5732 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
5733 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
5734 number_float_t, string_t>::value,
5735 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
5736 static_assert(
5737 is_detected_exact<bool, string_function_t, SAX, string_t>::value,
5738 "Missing/invalid function: bool string(string_t&)");
5739 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
5740 "Missing/invalid function: bool start_object(std::size_t)");
5741 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
5742 "Missing/invalid function: bool key(string_t&)");
5743 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
5744 "Missing/invalid function: bool end_object()");
5745 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
5746 "Missing/invalid function: bool start_array(std::size_t)");
5747 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
5748 "Missing/invalid function: bool end_array()");
5749 static_assert(
5750 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
5751 "Missing/invalid function: bool parse_error(std::size_t, const "
5752 "std::string&, const exception&)");
5753 };
5754 } // namespace detail
5755 } // namespace nlohmann
5756
5757 // #include <nlohmann/detail/value_t.hpp>
5758
5759
5760 namespace nlohmann
5761 {
5762 namespace detail
5763 {
5764
5772 static inline bool little_endianess(int num = 1) noexcept
5773 {
5774 return *reinterpret_cast<char*>(&num) == 1;
5775 }
5776
5777
5779 // binary reader //
5781
5785 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
5786 class binary_reader
5787 {
5788 using number_integer_t = typename BasicJsonType::number_integer_t;
5789 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5790 using number_float_t = typename BasicJsonType::number_float_t;
5791 using string_t = typename BasicJsonType::string_t;
5792 using binary_t = typename BasicJsonType::binary_t;
5793 using json_sax_t = SAX;
5794 using char_type = typename InputAdapterType::char_type;
5795 using char_int_type = typename std::char_traits<char_type>::int_type;
5796
5797 public:
5803 explicit binary_reader(InputAdapterType&& adapter) : ia(std::move(adapter))
5804 {
5805 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
5806 }
5807
5808 // make class move-only
5809 binary_reader(const binary_reader&) = delete;
5810 binary_reader(binary_reader&&) = default;
5811 binary_reader& operator=(const binary_reader&) = delete;
5812 binary_reader& operator=(binary_reader&&) = default;
5813 ~binary_reader() = default;
5814
5822 JSON_HEDLEY_NON_NULL(3)
5823 bool sax_parse(const input_format_t format,
5824 json_sax_t* sax_,
5825 const bool strict = true)
5826 {
5827 sax = sax_;
5828 bool result = false;
5829
5830 switch (format)
5831 {
5832 case input_format_t::bson:
5833 result = parse_bson_internal();
5834 break;
5835
5836 case input_format_t::cbor:
5837 result = parse_cbor_internal();
5838 break;
5839
5840 case input_format_t::msgpack:
5841 result = parse_msgpack_internal();
5842 break;
5843
5844 case input_format_t::ubjson:
5845 result = parse_ubjson_internal();
5846 break;
5847
5848 default: // LCOV_EXCL_LINE
5849 assert(false); // LCOV_EXCL_LINE
5850 }
5851
5852 // strict mode: next byte must be EOF
5853 if (result and strict)
5854 {
5855 if (format == input_format_t::ubjson)
5856 {
5857 get_ignore_noop();
5858 }
5859 else
5860 {
5861 get();
5862 }
5863
5864 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
5865 {
5866 return sax->parse_error(chars_read, get_token_string(),
5867 parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
5868 }
5869 }
5870
5871 return result;
5872 }
5873
5874 private:
5876 // BSON //
5878
5883 bool parse_bson_internal()
5884 {
5885 std::int32_t document_size;
5886 get_number<std::int32_t, true>(input_format_t::bson, document_size);
5887
5888 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
5889 {
5890 return false;
5891 }
5892
5893 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(/*is_array*/false)))
5894 {
5895 return false;
5896 }
5897
5898 return sax->end_object();
5899 }
5900
5908 bool get_bson_cstr(string_t& result)
5909 {
5910 auto out = std::back_inserter(result);
5911 while (true)
5912 {
5913 get();
5914 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "cstring")))
5915 {
5916 return false;
5917 }
5918 if (current == 0x00)
5919 {
5920 return true;
5921 }
5922 *out++ = static_cast<typename string_t::value_type>(current);
5923 }
5924
5925 return true;
5926 }
5927
5939 template<typename NumberType>
5940 bool get_bson_string(const NumberType len, string_t& result)
5941 {
5942 if (JSON_HEDLEY_UNLIKELY(len < 1))
5943 {
5944 auto last_token = get_token_string();
5945 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string")));
5946 }
5947
5948 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) and get() != std::char_traits<char_type>::eof();
5949 }
5950
5960 template<typename NumberType>
5961 bool get_bson_binary(const NumberType len, binary_t& result)
5962 {
5963 if (JSON_HEDLEY_UNLIKELY(len < 0))
5964 {
5965 auto last_token = get_token_string();
5966 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary")));
5967 }
5968
5969 // All BSON binary values have a subtype
5970 std::uint8_t subtype;
5971 get_number<std::uint8_t>(input_format_t::bson, subtype);
5972 result.set_subtype(subtype);
5973
5974 return get_binary(input_format_t::bson, len, result);
5975 }
5976
5987 bool parse_bson_element_internal(const char_int_type element_type,
5988 const std::size_t element_type_parse_position)
5989 {
5990 switch (element_type)
5991 {
5992 case 0x01: // double
5993 {
5994 double number;
5995 return get_number<double, true>(input_format_t::bson, number) and sax->number_float(static_cast<number_float_t>(number), "");
5996 }
5997
5998 case 0x02: // string
5999 {
6000 std::int32_t len;
6001 string_t value;
6002 return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_string(len, value) and sax->string(value);
6003 }
6004
6005 case 0x03: // object
6006 {
6007 return parse_bson_internal();
6008 }
6009
6010 case 0x04: // array
6011 {
6012 return parse_bson_array();
6013 }
6014
6015 case 0x05: // binary
6016 {
6017 std::int32_t len;
6018 binary_t value;
6019 return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_binary(len, value) and sax->binary(value);
6020 }
6021
6022 case 0x08: // boolean
6023 {
6024 return sax->boolean(get() != 0);
6025 }
6026
6027 case 0x0A: // null
6028 {
6029 return sax->null();
6030 }
6031
6032 case 0x10: // int32
6033 {
6034 std::int32_t value;
6035 return get_number<std::int32_t, true>(input_format_t::bson, value) and sax->number_integer(value);
6036 }
6037
6038 case 0x12: // int64
6039 {
6040 std::int64_t value;
6041 return get_number<std::int64_t, true>(input_format_t::bson, value) and sax->number_integer(value);
6042 }
6043
6044 default: // anything else not supported (yet)
6045 {
6046 std::array<char, 3> cr{{}};
6047 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type));
6048 return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data())));
6049 }
6050 }
6051 }
6052
6065 bool parse_bson_element_list(const bool is_array)
6066 {
6067 string_t key;
6068
6069 while (auto element_type = get())
6070 {
6071 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list")))
6072 {
6073 return false;
6074 }
6075
6076 const std::size_t element_type_parse_position = chars_read;
6077 if (JSON_HEDLEY_UNLIKELY(not get_bson_cstr(key)))
6078 {
6079 return false;
6080 }
6081
6082 if (not is_array and not sax->key(key))
6083 {
6084 return false;
6085 }
6086
6087 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
6088 {
6089 return false;
6090 }
6091
6092 // get_bson_cstr only appends
6093 key.clear();
6094 }
6095
6096 return true;
6097 }
6098
6103 bool parse_bson_array()
6104 {
6105 std::int32_t document_size;
6106 get_number<std::int32_t, true>(input_format_t::bson, document_size);
6107
6108 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
6109 {
6110 return false;
6111 }
6112
6113 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(/*is_array*/true)))
6114 {
6115 return false;
6116 }
6117
6118 return sax->end_array();
6119 }
6120
6122 // CBOR //
6124
6132 bool parse_cbor_internal(const bool get_char = true)
6133 {
6134 switch (get_char ? get() : current)
6135 {
6136 // EOF
6137 case std::char_traits<char_type>::eof():
6138 return unexpect_eof(input_format_t::cbor, "value");
6139
6140 // Integer 0x00..0x17 (0..23)
6141 case 0x00:
6142 case 0x01:
6143 case 0x02:
6144 case 0x03:
6145 case 0x04:
6146 case 0x05:
6147 case 0x06:
6148 case 0x07:
6149 case 0x08:
6150 case 0x09:
6151 case 0x0A:
6152 case 0x0B:
6153 case 0x0C:
6154 case 0x0D:
6155 case 0x0E:
6156 case 0x0F:
6157 case 0x10:
6158 case 0x11:
6159 case 0x12:
6160 case 0x13:
6161 case 0x14:
6162 case 0x15:
6163 case 0x16:
6164 case 0x17:
6165 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
6166
6167 case 0x18: // Unsigned integer (one-byte uint8_t follows)
6168 {
6169 std::uint8_t number;
6170 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6171 }
6172
6173 case 0x19: // Unsigned integer (two-byte uint16_t follows)
6174 {
6175 std::uint16_t number;
6176 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6177 }
6178
6179 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
6180 {
6181 std::uint32_t number;
6182 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6183 }
6184
6185 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
6186 {
6187 std::uint64_t number;
6188 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6189 }
6190
6191 // Negative integer -1-0x00..-1-0x17 (-1..-24)
6192 case 0x20:
6193 case 0x21:
6194 case 0x22:
6195 case 0x23:
6196 case 0x24:
6197 case 0x25:
6198 case 0x26:
6199 case 0x27:
6200 case 0x28:
6201 case 0x29:
6202 case 0x2A:
6203 case 0x2B:
6204 case 0x2C:
6205 case 0x2D:
6206 case 0x2E:
6207 case 0x2F:
6208 case 0x30:
6209 case 0x31:
6210 case 0x32:
6211 case 0x33:
6212 case 0x34:
6213 case 0x35:
6214 case 0x36:
6215 case 0x37:
6216 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
6217
6218 case 0x38: // Negative integer (one-byte uint8_t follows)
6219 {
6220 std::uint8_t number;
6221 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6222 }
6223
6224 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
6225 {
6226 std::uint16_t number;
6227 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6228 }
6229
6230 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
6231 {
6232 std::uint32_t number;
6233 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6234 }
6235
6236 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
6237 {
6238 std::uint64_t number;
6239 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1)
6240 - static_cast<number_integer_t>(number));
6241 }
6242
6243 // Binary data (0x00..0x17 bytes follow)
6244 case 0x40:
6245 case 0x41:
6246 case 0x42:
6247 case 0x43:
6248 case 0x44:
6249 case 0x45:
6250 case 0x46:
6251 case 0x47:
6252 case 0x48:
6253 case 0x49:
6254 case 0x4A:
6255 case 0x4B:
6256 case 0x4C:
6257 case 0x4D:
6258 case 0x4E:
6259 case 0x4F:
6260 case 0x50:
6261 case 0x51:
6262 case 0x52:
6263 case 0x53:
6264 case 0x54:
6265 case 0x55:
6266 case 0x56:
6267 case 0x57:
6268 case 0x58: // Binary data (one-byte uint8_t for n follows)
6269 case 0x59: // Binary data (two-byte uint16_t for n follow)
6270 case 0x5A: // Binary data (four-byte uint32_t for n follow)
6271 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
6272 case 0x5F: // Binary data (indefinite length)
6273 {
6274 binary_t b;
6275 return get_cbor_binary(b) and sax->binary(b);
6276 }
6277
6278 // UTF-8 string (0x00..0x17 bytes follow)
6279 case 0x60:
6280 case 0x61:
6281 case 0x62:
6282 case 0x63:
6283 case 0x64:
6284 case 0x65:
6285 case 0x66:
6286 case 0x67:
6287 case 0x68:
6288 case 0x69:
6289 case 0x6A:
6290 case 0x6B:
6291 case 0x6C:
6292 case 0x6D:
6293 case 0x6E:
6294 case 0x6F:
6295 case 0x70:
6296 case 0x71:
6297 case 0x72:
6298 case 0x73:
6299 case 0x74:
6300 case 0x75:
6301 case 0x76:
6302 case 0x77:
6303 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
6304 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
6305 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
6306 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
6307 case 0x7F: // UTF-8 string (indefinite length)
6308 {
6309 string_t s;
6310 return get_cbor_string(s) and sax->string(s);
6311 }
6312
6313 // array (0x00..0x17 data items follow)
6314 case 0x80:
6315 case 0x81:
6316 case 0x82:
6317 case 0x83:
6318 case 0x84:
6319 case 0x85:
6320 case 0x86:
6321 case 0x87:
6322 case 0x88:
6323 case 0x89:
6324 case 0x8A:
6325 case 0x8B:
6326 case 0x8C:
6327 case 0x8D:
6328 case 0x8E:
6329 case 0x8F:
6330 case 0x90:
6331 case 0x91:
6332 case 0x92:
6333 case 0x93:
6334 case 0x94:
6335 case 0x95:
6336 case 0x96:
6337 case 0x97:
6338 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
6339
6340 case 0x98: // array (one-byte uint8_t for n follows)
6341 {
6342 std::uint8_t len;
6343 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6344 }
6345
6346 case 0x99: // array (two-byte uint16_t for n follow)
6347 {
6348 std::uint16_t len;
6349 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6350 }
6351
6352 case 0x9A: // array (four-byte uint32_t for n follow)
6353 {
6354 std::uint32_t len;
6355 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6356 }
6357
6358 case 0x9B: // array (eight-byte uint64_t for n follow)
6359 {
6360 std::uint64_t len;
6361 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6362 }
6363
6364 case 0x9F: // array (indefinite length)
6365 return get_cbor_array(std::size_t(-1));
6366
6367 // map (0x00..0x17 pairs of data items follow)
6368 case 0xA0:
6369 case 0xA1:
6370 case 0xA2:
6371 case 0xA3:
6372 case 0xA4:
6373 case 0xA5:
6374 case 0xA6:
6375 case 0xA7:
6376 case 0xA8:
6377 case 0xA9:
6378 case 0xAA:
6379 case 0xAB:
6380 case 0xAC:
6381 case 0xAD:
6382 case 0xAE:
6383 case 0xAF:
6384 case 0xB0:
6385 case 0xB1:
6386 case 0xB2:
6387 case 0xB3:
6388 case 0xB4:
6389 case 0xB5:
6390 case 0xB6:
6391 case 0xB7:
6392 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
6393
6394 case 0xB8: // map (one-byte uint8_t for n follows)
6395 {
6396 std::uint8_t len;
6397 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
6398 }
6399
6400 case 0xB9: // map (two-byte uint16_t for n follow)
6401 {
6402 std::uint16_t len;
6403 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
6404 }
6405
6406 case 0xBA: // map (four-byte uint32_t for n follow)
6407 {
6408 std::uint32_t len;
6409 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
6410 }
6411
6412 case 0xBB: // map (eight-byte uint64_t for n follow)
6413 {
6414 std::uint64_t len;
6415 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
6416 }
6417
6418 case 0xBF: // map (indefinite length)
6419 return get_cbor_object(std::size_t(-1));
6420
6421 case 0xF4: // false
6422 return sax->boolean(false);
6423
6424 case 0xF5: // true
6425 return sax->boolean(true);
6426
6427 case 0xF6: // null
6428 return sax->null();
6429
6430 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
6431 {
6432 const auto byte1_raw = get();
6433 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
6434 {
6435 return false;
6436 }
6437 const auto byte2_raw = get();
6438 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
6439 {
6440 return false;
6441 }
6442
6443 const auto byte1 = static_cast<unsigned char>(byte1_raw);
6444 const auto byte2 = static_cast<unsigned char>(byte2_raw);
6445
6446 // code from RFC 7049, Appendix D, Figure 3:
6447 // As half-precision floating-point numbers were only added
6448 // to IEEE 754 in 2008, today's programming platforms often
6449 // still only have limited support for them. It is very
6450 // easy to include at least decoding support for them even
6451 // without such support. An example of a small decoder for
6452 // half-precision floating-point numbers in the C language
6453 // is shown in Fig. 3.
6454 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
6455 const double val = [&half]
6456 {
6457 const int exp = (half >> 10u) & 0x1Fu;
6458 const unsigned int mant = half & 0x3FFu;
6459 assert(0 <= exp and exp <= 32);
6460 assert(mant <= 1024);
6461 switch (exp)
6462 {
6463 case 0:
6464 return std::ldexp(mant, -24);
6465 case 31:
6466 return (mant == 0)
6467 ? std::numeric_limits<double>::infinity()
6468 : std::numeric_limits<double>::quiet_NaN();
6469 default:
6470 return std::ldexp(mant + 1024, exp - 25);
6471 }
6472 }();
6473 return sax->number_float((half & 0x8000u) != 0
6474 ? static_cast<number_float_t>(-val)
6475 : static_cast<number_float_t>(val), "");
6476 }
6477
6478 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
6479 {
6480 float number;
6481 return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
6482 }
6483
6484 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
6485 {
6486 double number;
6487 return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
6488 }
6489
6490 default: // anything else (0xFF is handled inside the other types)
6491 {
6492 auto last_token = get_token_string();
6493 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));
6494 }
6495 }
6496 }
6497
6509 bool get_cbor_string(string_t& result)
6510 {
6511 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "string")))
6512 {
6513 return false;
6514 }
6515
6516 switch (current)
6517 {
6518 // UTF-8 string (0x00..0x17 bytes follow)
6519 case 0x60:
6520 case 0x61:
6521 case 0x62:
6522 case 0x63:
6523 case 0x64:
6524 case 0x65:
6525 case 0x66:
6526 case 0x67:
6527 case 0x68:
6528 case 0x69:
6529 case 0x6A:
6530 case 0x6B:
6531 case 0x6C:
6532 case 0x6D:
6533 case 0x6E:
6534 case 0x6F:
6535 case 0x70:
6536 case 0x71:
6537 case 0x72:
6538 case 0x73:
6539 case 0x74:
6540 case 0x75:
6541 case 0x76:
6542 case 0x77:
6543 {
6544 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
6545 }
6546
6547 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
6548 {
6549 std::uint8_t len;
6550 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
6551 }
6552
6553 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
6554 {
6555 std::uint16_t len;
6556 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
6557 }
6558
6559 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
6560 {
6561 std::uint32_t len;
6562 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
6563 }
6564
6565 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
6566 {
6567 std::uint64_t len;
6568 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
6569 }
6570
6571 case 0x7F: // UTF-8 string (indefinite length)
6572 {
6573 while (get() != 0xFF)
6574 {
6575 string_t chunk;
6576 if (not get_cbor_string(chunk))
6577 {
6578 return false;
6579 }
6580 result.append(chunk);
6581 }
6582 return true;
6583 }
6584
6585 default:
6586 {
6587 auto last_token = get_token_string();
6588 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string")));
6589 }
6590 }
6591 }
6592
6604 bool get_cbor_binary(binary_t& result)
6605 {
6606 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "binary")))
6607 {
6608 return false;
6609 }
6610
6611 switch (current)
6612 {
6613 // Binary data (0x00..0x17 bytes follow)
6614 case 0x40:
6615 case 0x41:
6616 case 0x42:
6617 case 0x43:
6618 case 0x44:
6619 case 0x45:
6620 case 0x46:
6621 case 0x47:
6622 case 0x48:
6623 case 0x49:
6624 case 0x4A:
6625 case 0x4B:
6626 case 0x4C:
6627 case 0x4D:
6628 case 0x4E:
6629 case 0x4F:
6630 case 0x50:
6631 case 0x51:
6632 case 0x52:
6633 case 0x53:
6634 case 0x54:
6635 case 0x55:
6636 case 0x56:
6637 case 0x57:
6638 {
6639 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
6640 }
6641
6642 case 0x58: // Binary data (one-byte uint8_t for n follows)
6643 {
6644 std::uint8_t len;
6645 return get_number(input_format_t::cbor, len) and
6646 get_binary(input_format_t::cbor, len, result);
6647 }
6648
6649 case 0x59: // Binary data (two-byte uint16_t for n follow)
6650 {
6651 std::uint16_t len;
6652 return get_number(input_format_t::cbor, len) and
6653 get_binary(input_format_t::cbor, len, result);
6654 }
6655
6656 case 0x5A: // Binary data (four-byte uint32_t for n follow)
6657 {
6658 std::uint32_t len;
6659 return get_number(input_format_t::cbor, len) and
6660 get_binary(input_format_t::cbor, len, result);
6661 }
6662
6663 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
6664 {
6665 std::uint64_t len;
6666 return get_number(input_format_t::cbor, len) and
6667 get_binary(input_format_t::cbor, len, result);
6668 }
6669
6670 case 0x5F: // Binary data (indefinite length)
6671 {
6672 while (get() != 0xFF)
6673 {
6674 binary_t chunk;
6675 if (not get_cbor_binary(chunk))
6676 {
6677 return false;
6678 }
6679 result.insert(result.end(), chunk.begin(), chunk.end());
6680 }
6681 return true;
6682 }
6683
6684 default:
6685 {
6686 auto last_token = get_token_string();
6687 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token, "binary")));
6688 }
6689 }
6690 }
6691
6697 bool get_cbor_array(const std::size_t len)
6698 {
6699 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len)))
6700 {
6701 return false;
6702 }
6703
6704 if (len != std::size_t(-1))
6705 {
6706 for (std::size_t i = 0; i < len; ++i)
6707 {
6708 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
6709 {
6710 return false;
6711 }
6712 }
6713 }
6714 else
6715 {
6716 while (get() != 0xFF)
6717 {
6718 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal(false)))
6719 {
6720 return false;
6721 }
6722 }
6723 }
6724
6725 return sax->end_array();
6726 }
6727
6733 bool get_cbor_object(const std::size_t len)
6734 {
6735 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len)))
6736 {
6737 return false;
6738 }
6739
6740 string_t key;
6741 if (len != std::size_t(-1))
6742 {
6743 for (std::size_t i = 0; i < len; ++i)
6744 {
6745 get();
6746 if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
6747 {
6748 return false;
6749 }
6750
6751 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
6752 {
6753 return false;
6754 }
6755 key.clear();
6756 }
6757 }
6758 else
6759 {
6760 while (get() != 0xFF)
6761 {
6762 if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
6763 {
6764 return false;
6765 }
6766
6767 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
6768 {
6769 return false;
6770 }
6771 key.clear();
6772 }
6773 }
6774
6775 return sax->end_object();
6776 }
6777
6779 // MsgPack //
6781
6785 bool parse_msgpack_internal()
6786 {
6787 switch (get())
6788 {
6789 // EOF
6790 case std::char_traits<char_type>::eof():
6791 return unexpect_eof(input_format_t::msgpack, "value");
6792
6793 // positive fixint
6794 case 0x00:
6795 case 0x01:
6796 case 0x02:
6797 case 0x03:
6798 case 0x04:
6799 case 0x05:
6800 case 0x06:
6801 case 0x07:
6802 case 0x08:
6803 case 0x09:
6804 case 0x0A:
6805 case 0x0B:
6806 case 0x0C:
6807 case 0x0D:
6808 case 0x0E:
6809 case 0x0F:
6810 case 0x10:
6811 case 0x11:
6812 case 0x12:
6813 case 0x13:
6814 case 0x14:
6815 case 0x15:
6816 case 0x16:
6817 case 0x17:
6818 case 0x18:
6819 case 0x19:
6820 case 0x1A:
6821 case 0x1B:
6822 case 0x1C:
6823 case 0x1D:
6824 case 0x1E:
6825 case 0x1F:
6826 case 0x20:
6827 case 0x21:
6828 case 0x22:
6829 case 0x23:
6830 case 0x24:
6831 case 0x25:
6832 case 0x26:
6833 case 0x27:
6834 case 0x28:
6835 case 0x29:
6836 case 0x2A:
6837 case 0x2B:
6838 case 0x2C:
6839 case 0x2D:
6840 case 0x2E:
6841 case 0x2F:
6842 case 0x30:
6843 case 0x31:
6844 case 0x32:
6845 case 0x33:
6846 case 0x34:
6847 case 0x35:
6848 case 0x36:
6849 case 0x37:
6850 case 0x38:
6851 case 0x39:
6852 case 0x3A:
6853 case 0x3B:
6854 case 0x3C:
6855 case 0x3D:
6856 case 0x3E:
6857 case 0x3F:
6858 case 0x40:
6859 case 0x41:
6860 case 0x42:
6861 case 0x43:
6862 case 0x44:
6863 case 0x45:
6864 case 0x46:
6865 case 0x47:
6866 case 0x48:
6867 case 0x49:
6868 case 0x4A:
6869 case 0x4B:
6870 case 0x4C:
6871 case 0x4D:
6872 case 0x4E:
6873 case 0x4F:
6874 case 0x50:
6875 case 0x51:
6876 case 0x52:
6877 case 0x53:
6878 case 0x54:
6879 case 0x55:
6880 case 0x56:
6881 case 0x57:
6882 case 0x58:
6883 case 0x59:
6884 case 0x5A:
6885 case 0x5B:
6886 case 0x5C:
6887 case 0x5D:
6888 case 0x5E:
6889 case 0x5F:
6890 case 0x60:
6891 case 0x61:
6892 case 0x62:
6893 case 0x63:
6894 case 0x64:
6895 case 0x65:
6896 case 0x66:
6897 case 0x67:
6898 case 0x68:
6899 case 0x69:
6900 case 0x6A:
6901 case 0x6B:
6902 case 0x6C:
6903 case 0x6D:
6904 case 0x6E:
6905 case 0x6F:
6906 case 0x70:
6907 case 0x71:
6908 case 0x72:
6909 case 0x73:
6910 case 0x74:
6911 case 0x75:
6912 case 0x76:
6913 case 0x77:
6914 case 0x78:
6915 case 0x79:
6916 case 0x7A:
6917 case 0x7B:
6918 case 0x7C:
6919 case 0x7D:
6920 case 0x7E:
6921 case 0x7F:
6922 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
6923
6924 // fixmap
6925 case 0x80:
6926 case 0x81:
6927 case 0x82:
6928 case 0x83:
6929 case 0x84:
6930 case 0x85:
6931 case 0x86:
6932 case 0x87:
6933 case 0x88:
6934 case 0x89:
6935 case 0x8A:
6936 case 0x8B:
6937 case 0x8C:
6938 case 0x8D:
6939 case 0x8E:
6940 case 0x8F:
6941 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
6942
6943 // fixarray
6944 case 0x90:
6945 case 0x91:
6946 case 0x92:
6947 case 0x93:
6948 case 0x94:
6949 case 0x95:
6950 case 0x96:
6951 case 0x97:
6952 case 0x98:
6953 case 0x99:
6954 case 0x9A:
6955 case 0x9B:
6956 case 0x9C:
6957 case 0x9D:
6958 case 0x9E:
6959 case 0x9F:
6960 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
6961
6962 // fixstr
6963 case 0xA0:
6964 case 0xA1:
6965 case 0xA2:
6966 case 0xA3:
6967 case 0xA4:
6968 case 0xA5:
6969 case 0xA6:
6970 case 0xA7:
6971 case 0xA8:
6972 case 0xA9:
6973 case 0xAA:
6974 case 0xAB:
6975 case 0xAC:
6976 case 0xAD:
6977 case 0xAE:
6978 case 0xAF:
6979 case 0xB0:
6980 case 0xB1:
6981 case 0xB2:
6982 case 0xB3:
6983 case 0xB4:
6984 case 0xB5:
6985 case 0xB6:
6986 case 0xB7:
6987 case 0xB8:
6988 case 0xB9:
6989 case 0xBA:
6990 case 0xBB:
6991 case 0xBC:
6992 case 0xBD:
6993 case 0xBE:
6994 case 0xBF:
6995 case 0xD9: // str 8
6996 case 0xDA: // str 16
6997 case 0xDB: // str 32
6998 {
6999 string_t s;
7000 return get_msgpack_string(s) and sax->string(s);
7001 }
7002
7003 case 0xC0: // nil
7004 return sax->null();
7005
7006 case 0xC2: // false
7007 return sax->boolean(false);
7008
7009 case 0xC3: // true
7010 return sax->boolean(true);
7011
7012 case 0xC4: // bin 8
7013 case 0xC5: // bin 16
7014 case 0xC6: // bin 32
7015 case 0xC7: // ext 8
7016 case 0xC8: // ext 16
7017 case 0xC9: // ext 32
7018 case 0xD4: // fixext 1
7019 case 0xD5: // fixext 2
7020 case 0xD6: // fixext 4
7021 case 0xD7: // fixext 8
7022 case 0xD8: // fixext 16
7023 {
7024 binary_t b;
7025 return get_msgpack_binary(b) and sax->binary(b);
7026 }
7027
7028 case 0xCA: // float 32
7029 {
7030 float number;
7031 return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
7032 }
7033
7034 case 0xCB: // float 64
7035 {
7036 double number;
7037 return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
7038 }
7039
7040 case 0xCC: // uint 8
7041 {
7042 std::uint8_t number;
7043 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7044 }
7045
7046 case 0xCD: // uint 16
7047 {
7048 std::uint16_t number;
7049 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7050 }
7051
7052 case 0xCE: // uint 32
7053 {
7054 std::uint32_t number;
7055 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7056 }
7057
7058 case 0xCF: // uint 64
7059 {
7060 std::uint64_t number;
7061 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7062 }
7063
7064 case 0xD0: // int 8
7065 {
7066 std::int8_t number;
7067 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7068 }
7069
7070 case 0xD1: // int 16
7071 {
7072 std::int16_t number;
7073 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7074 }
7075
7076 case 0xD2: // int 32
7077 {
7078 std::int32_t number;
7079 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7080 }
7081
7082 case 0xD3: // int 64
7083 {
7084 std::int64_t number;
7085 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7086 }
7087
7088 case 0xDC: // array 16
7089 {
7090 std::uint16_t len;
7091 return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
7092 }
7093
7094 case 0xDD: // array 32
7095 {
7096 std::uint32_t len;
7097 return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
7098 }
7099
7100 case 0xDE: // map 16
7101 {
7102 std::uint16_t len;
7103 return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
7104 }
7105
7106 case 0xDF: // map 32
7107 {
7108 std::uint32_t len;
7109 return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
7110 }
7111
7112 // negative fixint
7113 case 0xE0:
7114 case 0xE1:
7115 case 0xE2:
7116 case 0xE3:
7117 case 0xE4:
7118 case 0xE5:
7119 case 0xE6:
7120 case 0xE7:
7121 case 0xE8:
7122 case 0xE9:
7123 case 0xEA:
7124 case 0xEB:
7125 case 0xEC:
7126 case 0xED:
7127 case 0xEE:
7128 case 0xEF:
7129 case 0xF0:
7130 case 0xF1:
7131 case 0xF2:
7132 case 0xF3:
7133 case 0xF4:
7134 case 0xF5:
7135 case 0xF6:
7136 case 0xF7:
7137 case 0xF8:
7138 case 0xF9:
7139 case 0xFA:
7140 case 0xFB:
7141 case 0xFC:
7142 case 0xFD:
7143 case 0xFE:
7144 case 0xFF:
7145 return sax->number_integer(static_cast<std::int8_t>(current));
7146
7147 default: // anything else
7148 {
7149 auto last_token = get_token_string();
7150 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value")));
7151 }
7152 }
7153 }
7154
7165 bool get_msgpack_string(string_t& result)
7166 {
7167 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string")))
7168 {
7169 return false;
7170 }
7171
7172 switch (current)
7173 {
7174 // fixstr
7175 case 0xA0:
7176 case 0xA1:
7177 case 0xA2:
7178 case 0xA3:
7179 case 0xA4:
7180 case 0xA5:
7181 case 0xA6:
7182 case 0xA7:
7183 case 0xA8:
7184 case 0xA9:
7185 case 0xAA:
7186 case 0xAB:
7187 case 0xAC:
7188 case 0xAD:
7189 case 0xAE:
7190 case 0xAF:
7191 case 0xB0:
7192 case 0xB1:
7193 case 0xB2:
7194 case 0xB3:
7195 case 0xB4:
7196 case 0xB5:
7197 case 0xB6:
7198 case 0xB7:
7199 case 0xB8:
7200 case 0xB9:
7201 case 0xBA:
7202 case 0xBB:
7203 case 0xBC:
7204 case 0xBD:
7205 case 0xBE:
7206 case 0xBF:
7207 {
7208 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
7209 }
7210
7211 case 0xD9: // str 8
7212 {
7213 std::uint8_t len;
7214 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7215 }
7216
7217 case 0xDA: // str 16
7218 {
7219 std::uint16_t len;
7220 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7221 }
7222
7223 case 0xDB: // str 32
7224 {
7225 std::uint32_t len;
7226 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7227 }
7228
7229 default:
7230 {
7231 auto last_token = get_token_string();
7232 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string")));
7233 }
7234 }
7235 }
7236
7247 bool get_msgpack_binary(binary_t& result)
7248 {
7249 // helper function to set the subtype
7250 auto assign_and_return_true = [&result](std::int8_t subtype)
7251 {
7252 result.set_subtype(static_cast<std::uint8_t>(subtype));
7253 return true;
7254 };
7255
7256 switch (current)
7257 {
7258 case 0xC4: // bin 8
7259 {
7260 std::uint8_t len;
7261 return get_number(input_format_t::msgpack, len) and
7262 get_binary(input_format_t::msgpack, len, result);
7263 }
7264
7265 case 0xC5: // bin 16
7266 {
7267 std::uint16_t len;
7268 return get_number(input_format_t::msgpack, len) and
7269 get_binary(input_format_t::msgpack, len, result);
7270 }
7271
7272 case 0xC6: // bin 32
7273 {
7274 std::uint32_t len;
7275 return get_number(input_format_t::msgpack, len) and
7276 get_binary(input_format_t::msgpack, len, result);
7277 }
7278
7279 case 0xC7: // ext 8
7280 {
7281 std::uint8_t len;
7282 std::int8_t subtype;
7283 return get_number(input_format_t::msgpack, len) and
7284 get_number(input_format_t::msgpack, subtype) and
7285 get_binary(input_format_t::msgpack, len, result) and
7286 assign_and_return_true(subtype);
7287 }
7288
7289 case 0xC8: // ext 16
7290 {
7291 std::uint16_t len;
7292 std::int8_t subtype;
7293 return get_number(input_format_t::msgpack, len) and
7294 get_number(input_format_t::msgpack, subtype) and
7295 get_binary(input_format_t::msgpack, len, result) and
7296 assign_and_return_true(subtype);
7297 }
7298
7299 case 0xC9: // ext 32
7300 {
7301 std::uint32_t len;
7302 std::int8_t subtype;
7303 return get_number(input_format_t::msgpack, len) and
7304 get_number(input_format_t::msgpack, subtype) and
7305 get_binary(input_format_t::msgpack, len, result) and
7306 assign_and_return_true(subtype);
7307 }
7308
7309 case 0xD4: // fixext 1
7310 {
7311 std::int8_t subtype;
7312 return get_number(input_format_t::msgpack, subtype) and
7313 get_binary(input_format_t::msgpack, 1, result) and
7314 assign_and_return_true(subtype);
7315 }
7316
7317 case 0xD5: // fixext 2
7318 {
7319 std::int8_t subtype;
7320 return get_number(input_format_t::msgpack, subtype) and
7321 get_binary(input_format_t::msgpack, 2, result) and
7322 assign_and_return_true(subtype);
7323 }
7324
7325 case 0xD6: // fixext 4
7326 {
7327 std::int8_t subtype;
7328 return get_number(input_format_t::msgpack, subtype) and
7329 get_binary(input_format_t::msgpack, 4, result) and
7330 assign_and_return_true(subtype);
7331 }
7332
7333 case 0xD7: // fixext 8
7334 {
7335 std::int8_t subtype;
7336 return get_number(input_format_t::msgpack, subtype) and
7337 get_binary(input_format_t::msgpack, 8, result) and
7338 assign_and_return_true(subtype);
7339 }
7340
7341 case 0xD8: // fixext 16
7342 {
7343 std::int8_t subtype;
7344 return get_number(input_format_t::msgpack, subtype) and
7345 get_binary(input_format_t::msgpack, 16, result) and
7346 assign_and_return_true(subtype);
7347 }
7348
7349 default: // LCOV_EXCL_LINE
7350 return false; // LCOV_EXCL_LINE
7351 }
7352 }
7353
7358 bool get_msgpack_array(const std::size_t len)
7359 {
7360 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len)))
7361 {
7362 return false;
7363 }
7364
7365 for (std::size_t i = 0; i < len; ++i)
7366 {
7367 if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal()))
7368 {
7369 return false;
7370 }
7371 }
7372
7373 return sax->end_array();
7374 }
7375
7380 bool get_msgpack_object(const std::size_t len)
7381 {
7382 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len)))
7383 {
7384 return false;
7385 }
7386
7387 string_t key;
7388 for (std::size_t i = 0; i < len; ++i)
7389 {
7390 get();
7391 if (JSON_HEDLEY_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
7392 {
7393 return false;
7394 }
7395
7396 if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal()))
7397 {
7398 return false;
7399 }
7400 key.clear();
7401 }
7402
7403 return sax->end_object();
7404 }
7405
7407 // UBJSON //
7409
7417 bool parse_ubjson_internal(const bool get_char = true)
7418 {
7419 return get_ubjson_value(get_char ? get_ignore_noop() : current);
7420 }
7421
7436 bool get_ubjson_string(string_t& result, const bool get_char = true)
7437 {
7438 if (get_char)
7439 {
7440 get(); // TODO(niels): may we ignore N here?
7441 }
7442
7443 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
7444 {
7445 return false;
7446 }
7447
7448 switch (current)
7449 {
7450 case 'U':
7451 {
7452 std::uint8_t len;
7453 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7454 }
7455
7456 case 'i':
7457 {
7458 std::int8_t len;
7459 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7460 }
7461
7462 case 'I':
7463 {
7464 std::int16_t len;
7465 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7466 }
7467
7468 case 'l':
7469 {
7470 std::int32_t len;
7471 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7472 }
7473
7474 case 'L':
7475 {
7476 std::int64_t len;
7477 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7478 }
7479
7480 default:
7481 auto last_token = get_token_string();
7482 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string")));
7483 }
7484 }
7485
7490 bool get_ubjson_size_value(std::size_t& result)
7491 {
7492 switch (get_ignore_noop())
7493 {
7494 case 'U':
7495 {
7496 std::uint8_t number;
7497 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7498 {
7499 return false;
7500 }
7501 result = static_cast<std::size_t>(number);
7502 return true;
7503 }
7504
7505 case 'i':
7506 {
7507 std::int8_t number;
7508 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7509 {
7510 return false;
7511 }
7512 result = static_cast<std::size_t>(number);
7513 return true;
7514 }
7515
7516 case 'I':
7517 {
7518 std::int16_t number;
7519 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7520 {
7521 return false;
7522 }
7523 result = static_cast<std::size_t>(number);
7524 return true;
7525 }
7526
7527 case 'l':
7528 {
7529 std::int32_t number;
7530 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7531 {
7532 return false;
7533 }
7534 result = static_cast<std::size_t>(number);
7535 return true;
7536 }
7537
7538 case 'L':
7539 {
7540 std::int64_t number;
7541 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7542 {
7543 return false;
7544 }
7545 result = static_cast<std::size_t>(number);
7546 return true;
7547 }
7548
7549 default:
7550 {
7551 auto last_token = get_token_string();
7552 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size")));
7553 }
7554 }
7555 }
7556
7567 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
7568 {
7569 result.first = string_t::npos; // size
7570 result.second = 0; // type
7571
7572 get_ignore_noop();
7573
7574 if (current == '$')
7575 {
7576 result.second = get(); // must not ignore 'N', because 'N' maybe the type
7577 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "type")))
7578 {
7579 return false;
7580 }
7581
7582 get_ignore_noop();
7583 if (JSON_HEDLEY_UNLIKELY(current != '#'))
7584 {
7585 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
7586 {
7587 return false;
7588 }
7589 auto last_token = get_token_string();
7590 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size")));
7591 }
7592
7593 return get_ubjson_size_value(result.first);
7594 }
7595
7596 if (current == '#')
7597 {
7598 return get_ubjson_size_value(result.first);
7599 }
7600
7601 return true;
7602 }
7603
7608 bool get_ubjson_value(const char_int_type prefix)
7609 {
7610 switch (prefix)
7611 {
7612 case std::char_traits<char_type>::eof(): // EOF
7613 return unexpect_eof(input_format_t::ubjson, "value");
7614
7615 case 'T': // true
7616 return sax->boolean(true);
7617 case 'F': // false
7618 return sax->boolean(false);
7619
7620 case 'Z': // null
7621 return sax->null();
7622
7623 case 'U':
7624 {
7625 std::uint8_t number;
7626 return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number);
7627 }
7628
7629 case 'i':
7630 {
7631 std::int8_t number;
7632 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7633 }
7634
7635 case 'I':
7636 {
7637 std::int16_t number;
7638 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7639 }
7640
7641 case 'l':
7642 {
7643 std::int32_t number;
7644 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7645 }
7646
7647 case 'L':
7648 {
7649 std::int64_t number;
7650 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7651 }
7652
7653 case 'd':
7654 {
7655 float number;
7656 return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
7657 }
7658
7659 case 'D':
7660 {
7661 double number;
7662 return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
7663 }
7664
7665 case 'C': // char
7666 {
7667 get();
7668 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char")))
7669 {
7670 return false;
7671 }
7672 if (JSON_HEDLEY_UNLIKELY(current > 127))
7673 {
7674 auto last_token = get_token_string();
7675 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char")));
7676 }
7677 string_t s(1, static_cast<typename string_t::value_type>(current));
7678 return sax->string(s);
7679 }
7680
7681 case 'S': // string
7682 {
7683 string_t s;
7684 return get_ubjson_string(s) and sax->string(s);
7685 }
7686
7687 case '[': // array
7688 return get_ubjson_array();
7689
7690 case '{': // object
7691 return get_ubjson_object();
7692
7693 default: // anything else
7694 {
7695 auto last_token = get_token_string();
7696 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value")));
7697 }
7698 }
7699 }
7700
7704 bool get_ubjson_array()
7705 {
7706 std::pair<std::size_t, char_int_type> size_and_type;
7707 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
7708 {
7709 return false;
7710 }
7711
7712 if (size_and_type.first != string_t::npos)
7713 {
7714 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(size_and_type.first)))
7715 {
7716 return false;
7717 }
7718
7719 if (size_and_type.second != 0)
7720 {
7721 if (size_and_type.second != 'N')
7722 {
7723 for (std::size_t i = 0; i < size_and_type.first; ++i)
7724 {
7725 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second)))
7726 {
7727 return false;
7728 }
7729 }
7730 }
7731 }
7732 else
7733 {
7734 for (std::size_t i = 0; i < size_and_type.first; ++i)
7735 {
7736 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
7737 {
7738 return false;
7739 }
7740 }
7741 }
7742 }
7743 else
7744 {
7745 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
7746 {
7747 return false;
7748 }
7749
7750 while (current != ']')
7751 {
7752 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal(false)))
7753 {
7754 return false;
7755 }
7756 get_ignore_noop();
7757 }
7758 }
7759
7760 return sax->end_array();
7761 }
7762
7766 bool get_ubjson_object()
7767 {
7768 std::pair<std::size_t, char_int_type> size_and_type;
7769 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
7770 {
7771 return false;
7772 }
7773
7774 string_t key;
7775 if (size_and_type.first != string_t::npos)
7776 {
7777 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(size_and_type.first)))
7778 {
7779 return false;
7780 }
7781
7782 if (size_and_type.second != 0)
7783 {
7784 for (std::size_t i = 0; i < size_and_type.first; ++i)
7785 {
7786 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
7787 {
7788 return false;
7789 }
7790 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second)))
7791 {
7792 return false;
7793 }
7794 key.clear();
7795 }
7796 }
7797 else
7798 {
7799 for (std::size_t i = 0; i < size_and_type.first; ++i)
7800 {
7801 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
7802 {
7803 return false;
7804 }
7805 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
7806 {
7807 return false;
7808 }
7809 key.clear();
7810 }
7811 }
7812 }
7813 else
7814 {
7815 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
7816 {
7817 return false;
7818 }
7819
7820 while (current != '}')
7821 {
7822 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key, false) or not sax->key(key)))
7823 {
7824 return false;
7825 }
7826 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
7827 {
7828 return false;
7829 }
7830 get_ignore_noop();
7831 key.clear();
7832 }
7833 }
7834
7835 return sax->end_object();
7836 }
7837
7838 // Note, no reader for UBJSON binary types is implemented because they do
7839 // not exist
7840
7842 // Utility functions //
7844
7854 char_int_type get()
7855 {
7856 ++chars_read;
7857 return current = ia.get_character();
7858 }
7859
7863 char_int_type get_ignore_noop()
7864 {
7865 do
7866 {
7867 get();
7868 }
7869 while (current == 'N');
7870
7871 return current;
7872 }
7873
7874 /*
7875 @brief read a number from the input
7876
7877 @tparam NumberType the type of the number
7878 @param[in] format the current format (for diagnostics)
7879 @param[out] result number of type @a NumberType
7880
7881 @return whether conversion completed
7882
7883 @note This function needs to respect the system's endianess, because
7884 bytes in CBOR, MessagePack, and UBJSON are stored in network order
7885 (big endian) and therefore need reordering on little endian systems.
7886 */
7887 template<typename NumberType, bool InputIsLittleEndian = false>
7888 bool get_number(const input_format_t format, NumberType& result)
7889 {
7890 // step 1: read input into array with system's byte order
7891 std::array<std::uint8_t, sizeof(NumberType)> vec;
7892 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
7893 {
7894 get();
7895 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format, "number")))
7896 {
7897 return false;
7898 }
7899
7900 // reverse byte order prior to conversion if necessary
7901 if (is_little_endian != InputIsLittleEndian)
7902 {
7903 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
7904 }
7905 else
7906 {
7907 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
7908 }
7909 }
7910
7911 // step 2: convert array into number of type T and return
7912 std::memcpy(&result, vec.data(), sizeof(NumberType));
7913 return true;
7914 }
7915
7930 template<typename NumberType>
7931 bool get_string(const input_format_t format,
7932 const NumberType len,
7933 string_t& result)
7934 {
7935 bool success = true;
7936 std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
7937 {
7938 get();
7939 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format, "string")))
7940 {
7941 success = false;
7942 }
7943 return std::char_traits<char_type>::to_char_type(current);
7944 });
7945 return success;
7946 }
7947
7962 template<typename NumberType>
7963 bool get_binary(const input_format_t format,
7964 const NumberType len,
7965 binary_t& result)
7966 {
7967 bool success = true;
7968 std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
7969 {
7970 get();
7971 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format, "binary")))
7972 {
7973 success = false;
7974 }
7975 return static_cast<std::uint8_t>(current);
7976 });
7977 return success;
7978 }
7979
7985 JSON_HEDLEY_NON_NULL(3)
7986 bool unexpect_eof(const input_format_t format, const char* context) const
7987 {
7988 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
7989 {
7990 return sax->parse_error(chars_read, "<end of file>",
7991 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
7992 }
7993 return true;
7994 }
7995
7999 std::string get_token_string() const
8000 {
8001 std::array<char, 3> cr{{}};
8002 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current));
8003 return std::string{cr.data()};
8004 }
8005
8012 std::string exception_message(const input_format_t format,
8013 const std::string& detail,
8014 const std::string& context) const
8015 {
8016 std::string error_msg = "syntax error while parsing ";
8017
8018 switch (format)
8019 {
8020 case input_format_t::cbor:
8021 error_msg += "CBOR";
8022 break;
8023
8024 case input_format_t::msgpack:
8025 error_msg += "MessagePack";
8026 break;
8027
8028 case input_format_t::ubjson:
8029 error_msg += "UBJSON";
8030 break;
8031
8032 case input_format_t::bson:
8033 error_msg += "BSON";
8034 break;
8035
8036 default: // LCOV_EXCL_LINE
8037 assert(false); // LCOV_EXCL_LINE
8038 }
8039
8040 return error_msg + " " + context + ": " + detail;
8041 }
8042
8043 private:
8045 InputAdapterType ia;
8046
8048 char_int_type current = std::char_traits<char_type>::eof();
8049
8051 std::size_t chars_read = 0;
8052
8054 const bool is_little_endian = little_endianess();
8055
8057 json_sax_t* sax = nullptr;
8058 };
8059 } // namespace detail
8060 } // namespace nlohmann
8061
8062 // #include <nlohmann/detail/input/input_adapters.hpp>
8063
8064 // #include <nlohmann/detail/input/lexer.hpp>
8065
8066
8067 #include <array> // array
8068 #include <clocale> // localeconv
8069 #include <cstddef> // size_t
8070 #include <cstdio> // snprintf
8071 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
8072 #include <initializer_list> // initializer_list
8073 #include <string> // char_traits, string
8074 #include <utility> // move
8075 #include <vector> // vector
8076
8077 // #include <nlohmann/detail/input/input_adapters.hpp>
8078
8079 // #include <nlohmann/detail/input/position_t.hpp>
8080
8081 // #include <nlohmann/detail/macro_scope.hpp>
8082
8083
8084 namespace nlohmann
8085 {
8086 namespace detail
8087 {
8089 // lexer //
8091
8092 template<typename BasicJsonType>
8093 class lexer_base
8094 {
8095 public:
8097 enum class token_type
8098 {
8099 uninitialized,
8100 literal_true,
8101 literal_false,
8102 literal_null,
8103 value_string,
8104 value_unsigned,
8105 value_integer,
8106 value_float,
8107 begin_array,
8108 begin_object,
8109 end_array,
8110 end_object,
8111 name_separator,
8112 value_separator,
8113 parse_error,
8114 end_of_input,
8115 literal_or_value
8116 };
8117
8119
8120 JSON_HEDLEY_CONST
8121 static const char* token_type_name(const token_type t) noexcept
8122 {
8123 switch (t)
8124 {
8125 case token_type::uninitialized:
8126 return "<uninitialized>";
8127 case token_type::literal_true:
8128 return "true literal";
8129 case token_type::literal_false:
8130 return "false literal";
8131 case token_type::literal_null:
8132 return "null literal";
8133 case token_type::value_string:
8134 return "string literal";
8135 case token_type::value_unsigned:
8136 case token_type::value_integer:
8137 case token_type::value_float:
8138 return "number literal";
8139 case token_type::begin_array:
8140 return "'['";
8141 case token_type::begin_object:
8142 return "'{'";
8143 case token_type::end_array:
8144 return "']'";
8145 case token_type::end_object:
8146 return "'}'";
8147 case token_type::name_separator:
8148 return "':'";
8149 case token_type::value_separator:
8150 return "','";
8151 case token_type::parse_error:
8152 return "<parse error>";
8153 case token_type::end_of_input:
8154 return "end of input";
8155 case token_type::literal_or_value:
8156 return "'[', '{', or a literal";
8157 // LCOV_EXCL_START
8158 default: // catch non-enum values
8159 return "unknown token";
8160 // LCOV_EXCL_STOP
8161 }
8162 }
8163 };
8169 template<typename BasicJsonType, typename InputAdapterType>
8170 class lexer : public lexer_base<BasicJsonType>
8171 {
8172 using number_integer_t = typename BasicJsonType::number_integer_t;
8173 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8174 using number_float_t = typename BasicJsonType::number_float_t;
8175 using string_t = typename BasicJsonType::string_t;
8176 using char_type = typename InputAdapterType::char_type;
8177 using char_int_type = typename std::char_traits<char_type>::int_type;
8178
8179 public:
8180 using token_type = typename lexer_base<BasicJsonType>::token_type;
8181
8182 explicit lexer(InputAdapterType&& adapter)
8183 : ia(std::move(adapter)), decimal_point_char(static_cast<char_int_type>(get_decimal_point())) {}
8184
8185 // delete because of pointer members
8186 lexer(const lexer&) = delete;
8187 lexer(lexer&&) = default;
8188 lexer& operator=(lexer&) = delete;
8189 lexer& operator=(lexer&&) = default;
8190 ~lexer() = default;
8191
8192 private:
8194 // locales
8196
8198 JSON_HEDLEY_PURE
8199 static char get_decimal_point() noexcept
8200 {
8201 const auto loc = localeconv();
8202 assert(loc != nullptr);
8203 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
8204 }
8205
8207 // scan functions
8209
8225 int get_codepoint()
8226 {
8227 // this function only makes sense after reading `\u`
8228 assert(current == 'u');
8229 int codepoint = 0;
8230
8231 const auto factors = { 12u, 8u, 4u, 0u };
8232 for (const auto factor : factors)
8233 {
8234 get();
8235
8236 if (current >= '0' and current <= '9')
8237 {
8238 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
8239 }
8240 else if (current >= 'A' and current <= 'F')
8241 {
8242 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
8243 }
8244 else if (current >= 'a' and current <= 'f')
8245 {
8246 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
8247 }
8248 else
8249 {
8250 return -1;
8251 }
8252 }
8253
8254 assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
8255 return codepoint;
8256 }
8257
8273 bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
8274 {
8275 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
8276 add(current);
8277
8278 for (auto range = ranges.begin(); range != ranges.end(); ++range)
8279 {
8280 get();
8281 if (JSON_HEDLEY_LIKELY(*range <= current and current <= *(++range)))
8282 {
8283 add(current);
8284 }
8285 else
8286 {
8287 error_message = "invalid string: ill-formed UTF-8 byte";
8288 return false;
8289 }
8290 }
8291
8292 return true;
8293 }
8294
8310 token_type scan_string()
8311 {
8312 // reset token_buffer (ignore opening quote)
8313 reset();
8314
8315 // we entered the function by reading an open quote
8316 assert(current == '\"');
8317
8318 while (true)
8319 {
8320 // get next character
8321 switch (get())
8322 {
8323 // end of file while parsing string
8324 case std::char_traits<char_type>::eof():
8325 {
8326 error_message = "invalid string: missing closing quote";
8327 return token_type::parse_error;
8328 }
8329
8330 // closing quote
8331 case '\"':
8332 {
8333 return token_type::value_string;
8334 }
8335
8336 // escapes
8337 case '\\':
8338 {
8339 switch (get())
8340 {
8341 // quotation mark
8342 case '\"':
8343 add('\"');
8344 break;
8345 // reverse solidus
8346 case '\\':
8347 add('\\');
8348 break;
8349 // solidus
8350 case '/':
8351 add('/');
8352 break;
8353 // backspace
8354 case 'b':
8355 add('\b');
8356 break;
8357 // form feed
8358 case 'f':
8359 add('\f');
8360 break;
8361 // line feed
8362 case 'n':
8363 add('\n');
8364 break;
8365 // carriage return
8366 case 'r':
8367 add('\r');
8368 break;
8369 // tab
8370 case 't':
8371 add('\t');
8372 break;
8373
8374 // unicode escapes
8375 case 'u':
8376 {
8377 const int codepoint1 = get_codepoint();
8378 int codepoint = codepoint1; // start with codepoint1
8379
8380 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
8381 {
8382 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
8383 return token_type::parse_error;
8384 }
8385
8386 // check if code point is a high surrogate
8387 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
8388 {
8389 // expect next \uxxxx entry
8390 if (JSON_HEDLEY_LIKELY(get() == '\\' and get() == 'u'))
8391 {
8392 const int codepoint2 = get_codepoint();
8393
8394 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
8395 {
8396 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
8397 return token_type::parse_error;
8398 }
8399
8400 // check if codepoint2 is a low surrogate
8401 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
8402 {
8403 // overwrite codepoint
8404 codepoint = static_cast<int>(
8405 // high surrogate occupies the most significant 22 bits
8406 (static_cast<unsigned int>(codepoint1) << 10u)
8407 // low surrogate occupies the least significant 15 bits
8408 + static_cast<unsigned int>(codepoint2)
8409 // there is still the 0xD800, 0xDC00 and 0x10000 noise
8410 // in the result so we have to subtract with:
8411 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
8412 - 0x35FDC00u);
8413 }
8414 else
8415 {
8416 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
8417 return token_type::parse_error;
8418 }
8419 }
8420 else
8421 {
8422 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
8423 return token_type::parse_error;
8424 }
8425 }
8426 else
8427 {
8428 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
8429 {
8430 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
8431 return token_type::parse_error;
8432 }
8433 }
8434
8435 // result of the above calculation yields a proper codepoint
8436 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
8437
8438 // translate codepoint into bytes
8439 if (codepoint < 0x80)
8440 {
8441 // 1-byte characters: 0xxxxxxx (ASCII)
8442 add(static_cast<char_int_type>(codepoint));
8443 }
8444 else if (codepoint <= 0x7FF)
8445 {
8446 // 2-byte characters: 110xxxxx 10xxxxxx
8447 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
8448 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
8449 }
8450 else if (codepoint <= 0xFFFF)
8451 {
8452 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
8453 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
8454 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
8455 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
8456 }
8457 else
8458 {
8459 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
8460 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
8461 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
8462 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
8463 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
8464 }
8465
8466 break;
8467 }
8468
8469 // other characters after escape
8470 default:
8471 error_message = "invalid string: forbidden character after backslash";
8472 return token_type::parse_error;
8473 }
8474
8475 break;
8476 }
8477
8478 // invalid control characters
8479 case 0x00:
8480 {
8481 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
8482 return token_type::parse_error;
8483 }
8484
8485 case 0x01:
8486 {
8487 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
8488 return token_type::parse_error;
8489 }
8490
8491 case 0x02:
8492 {
8493 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
8494 return token_type::parse_error;
8495 }
8496
8497 case 0x03:
8498 {
8499 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
8500 return token_type::parse_error;
8501 }
8502
8503 case 0x04:
8504 {
8505 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
8506 return token_type::parse_error;
8507 }
8508
8509 case 0x05:
8510 {
8511 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
8512 return token_type::parse_error;
8513 }
8514
8515 case 0x06:
8516 {
8517 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
8518 return token_type::parse_error;
8519 }
8520
8521 case 0x07:
8522 {
8523 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
8524 return token_type::parse_error;
8525 }
8526
8527 case 0x08:
8528 {
8529 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
8530 return token_type::parse_error;
8531 }
8532
8533 case 0x09:
8534 {
8535 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
8536 return token_type::parse_error;
8537 }
8538
8539 case 0x0A:
8540 {
8541 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
8542 return token_type::parse_error;
8543 }
8544
8545 case 0x0B:
8546 {
8547 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
8548 return token_type::parse_error;
8549 }
8550
8551 case 0x0C:
8552 {
8553 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
8554 return token_type::parse_error;
8555 }
8556
8557 case 0x0D:
8558 {
8559 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
8560 return token_type::parse_error;
8561 }
8562
8563 case 0x0E:
8564 {
8565 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
8566 return token_type::parse_error;
8567 }
8568
8569 case 0x0F:
8570 {
8571 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
8572 return token_type::parse_error;
8573 }
8574
8575 case 0x10:
8576 {
8577 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
8578 return token_type::parse_error;
8579 }
8580
8581 case 0x11:
8582 {
8583 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
8584 return token_type::parse_error;
8585 }
8586
8587 case 0x12:
8588 {
8589 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
8590 return token_type::parse_error;
8591 }
8592
8593 case 0x13:
8594 {
8595 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
8596 return token_type::parse_error;
8597 }
8598
8599 case 0x14:
8600 {
8601 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
8602 return token_type::parse_error;
8603 }
8604
8605 case 0x15:
8606 {
8607 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
8608 return token_type::parse_error;
8609 }
8610
8611 case 0x16:
8612 {
8613 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
8614 return token_type::parse_error;
8615 }
8616
8617 case 0x17:
8618 {
8619 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
8620 return token_type::parse_error;
8621 }
8622
8623 case 0x18:
8624 {
8625 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
8626 return token_type::parse_error;
8627 }
8628
8629 case 0x19:
8630 {
8631 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
8632 return token_type::parse_error;
8633 }
8634
8635 case 0x1A:
8636 {
8637 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
8638 return token_type::parse_error;
8639 }
8640
8641 case 0x1B:
8642 {
8643 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
8644 return token_type::parse_error;
8645 }
8646
8647 case 0x1C:
8648 {
8649 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
8650 return token_type::parse_error;
8651 }
8652
8653 case 0x1D:
8654 {
8655 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
8656 return token_type::parse_error;
8657 }
8658
8659 case 0x1E:
8660 {
8661 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
8662 return token_type::parse_error;
8663 }
8664
8665 case 0x1F:
8666 {
8667 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
8668 return token_type::parse_error;
8669 }
8670
8671 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
8672 case 0x20:
8673 case 0x21:
8674 case 0x23:
8675 case 0x24:
8676 case 0x25:
8677 case 0x26:
8678 case 0x27:
8679 case 0x28:
8680 case 0x29:
8681 case 0x2A:
8682 case 0x2B:
8683 case 0x2C:
8684 case 0x2D:
8685 case 0x2E:
8686 case 0x2F:
8687 case 0x30:
8688 case 0x31:
8689 case 0x32:
8690 case 0x33:
8691 case 0x34:
8692 case 0x35:
8693 case 0x36:
8694 case 0x37:
8695 case 0x38:
8696 case 0x39:
8697 case 0x3A:
8698 case 0x3B:
8699 case 0x3C:
8700 case 0x3D:
8701 case 0x3E:
8702 case 0x3F:
8703 case 0x40:
8704 case 0x41:
8705 case 0x42:
8706 case 0x43:
8707 case 0x44:
8708 case 0x45:
8709 case 0x46:
8710 case 0x47:
8711 case 0x48:
8712 case 0x49:
8713 case 0x4A:
8714 case 0x4B:
8715 case 0x4C:
8716 case 0x4D:
8717 case 0x4E:
8718 case 0x4F:
8719 case 0x50:
8720 case 0x51:
8721 case 0x52:
8722 case 0x53:
8723 case 0x54:
8724 case 0x55:
8725 case 0x56:
8726 case 0x57:
8727 case 0x58:
8728 case 0x59:
8729 case 0x5A:
8730 case 0x5B:
8731 case 0x5D:
8732 case 0x5E:
8733 case 0x5F:
8734 case 0x60:
8735 case 0x61:
8736 case 0x62:
8737 case 0x63:
8738 case 0x64:
8739 case 0x65:
8740 case 0x66:
8741 case 0x67:
8742 case 0x68:
8743 case 0x69:
8744 case 0x6A:
8745 case 0x6B:
8746 case 0x6C:
8747 case 0x6D:
8748 case 0x6E:
8749 case 0x6F:
8750 case 0x70:
8751 case 0x71:
8752 case 0x72:
8753 case 0x73:
8754 case 0x74:
8755 case 0x75:
8756 case 0x76:
8757 case 0x77:
8758 case 0x78:
8759 case 0x79:
8760 case 0x7A:
8761 case 0x7B:
8762 case 0x7C:
8763 case 0x7D:
8764 case 0x7E:
8765 case 0x7F:
8766 {
8767 add(current);
8768 break;
8769 }
8770
8771 // U+0080..U+07FF: bytes C2..DF 80..BF
8772 case 0xC2:
8773 case 0xC3:
8774 case 0xC4:
8775 case 0xC5:
8776 case 0xC6:
8777 case 0xC7:
8778 case 0xC8:
8779 case 0xC9:
8780 case 0xCA:
8781 case 0xCB:
8782 case 0xCC:
8783 case 0xCD:
8784 case 0xCE:
8785 case 0xCF:
8786 case 0xD0:
8787 case 0xD1:
8788 case 0xD2:
8789 case 0xD3:
8790 case 0xD4:
8791 case 0xD5:
8792 case 0xD6:
8793 case 0xD7:
8794 case 0xD8:
8795 case 0xD9:
8796 case 0xDA:
8797 case 0xDB:
8798 case 0xDC:
8799 case 0xDD:
8800 case 0xDE:
8801 case 0xDF:
8802 {
8803 if (JSON_HEDLEY_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
8804 {
8805 return token_type::parse_error;
8806 }
8807 break;
8808 }
8809
8810 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
8811 case 0xE0:
8812 {
8813 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
8814 {
8815 return token_type::parse_error;
8816 }
8817 break;
8818 }
8819
8820 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
8821 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
8822 case 0xE1:
8823 case 0xE2:
8824 case 0xE3:
8825 case 0xE4:
8826 case 0xE5:
8827 case 0xE6:
8828 case 0xE7:
8829 case 0xE8:
8830 case 0xE9:
8831 case 0xEA:
8832 case 0xEB:
8833 case 0xEC:
8834 case 0xEE:
8835 case 0xEF:
8836 {
8837 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
8838 {
8839 return token_type::parse_error;
8840 }
8841 break;
8842 }
8843
8844 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
8845 case 0xED:
8846 {
8847 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
8848 {
8849 return token_type::parse_error;
8850 }
8851 break;
8852 }
8853
8854 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
8855 case 0xF0:
8856 {
8857 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
8858 {
8859 return token_type::parse_error;
8860 }
8861 break;
8862 }
8863
8864 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
8865 case 0xF1:
8866 case 0xF2:
8867 case 0xF3:
8868 {
8869 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
8870 {
8871 return token_type::parse_error;
8872 }
8873 break;
8874 }
8875
8876 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
8877 case 0xF4:
8878 {
8879 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
8880 {
8881 return token_type::parse_error;
8882 }
8883 break;
8884 }
8885
8886 // remaining bytes (80..C1 and F5..FF) are ill-formed
8887 default:
8888 {
8889 error_message = "invalid string: ill-formed UTF-8 byte";
8890 return token_type::parse_error;
8891 }
8892 }
8893 }
8894 }
8895
8896 JSON_HEDLEY_NON_NULL(2)
8897 static void strtof(float& f, const char* str, char** endptr) noexcept
8898 {
8899 f = std::strtof(str, endptr);
8900 }
8901
8902 JSON_HEDLEY_NON_NULL(2)
8903 static void strtof(double& f, const char* str, char** endptr) noexcept
8904 {
8905 f = std::strtod(str, endptr);
8906 }
8907
8908 JSON_HEDLEY_NON_NULL(2)
8909 static void strtof(long double& f, const char* str, char** endptr) noexcept
8910 {
8911 f = std::strtold(str, endptr);
8912 }
8913
8954 token_type scan_number() // lgtm [cpp/use-of-goto]
8955 {
8956 // reset token_buffer to store the number's bytes
8957 reset();
8958
8959 // the type of the parsed number; initially set to unsigned; will be
8960 // changed if minus sign, decimal point or exponent is read
8961 token_type number_type = token_type::value_unsigned;
8962
8963 // state (init): we just found out we need to scan a number
8964 switch (current)
8965 {
8966 case '-':
8967 {
8968 add(current);
8969 goto scan_number_minus;
8970 }
8971
8972 case '0':
8973 {
8974 add(current);
8975 goto scan_number_zero;
8976 }
8977
8978 case '1':
8979 case '2':
8980 case '3':
8981 case '4':
8982 case '5':
8983 case '6':
8984 case '7':
8985 case '8':
8986 case '9':
8987 {
8988 add(current);
8989 goto scan_number_any1;
8990 }
8991
8992 // all other characters are rejected outside scan_number()
8993 default: // LCOV_EXCL_LINE
8994 assert(false); // LCOV_EXCL_LINE
8995 }
8996
8997 scan_number_minus:
8998 // state: we just parsed a leading minus sign
8999 number_type = token_type::value_integer;
9000 switch (get())
9001 {
9002 case '0':
9003 {
9004 add(current);
9005 goto scan_number_zero;
9006 }
9007
9008 case '1':
9009 case '2':
9010 case '3':
9011 case '4':
9012 case '5':
9013 case '6':
9014 case '7':
9015 case '8':
9016 case '9':
9017 {
9018 add(current);
9019 goto scan_number_any1;
9020 }
9021
9022 default:
9023 {
9024 error_message = "invalid number; expected digit after '-'";
9025 return token_type::parse_error;
9026 }
9027 }
9028
9029 scan_number_zero:
9030 // state: we just parse a zero (maybe with a leading minus sign)
9031 switch (get())
9032 {
9033 case '.':
9034 {
9035 add(decimal_point_char);
9036 goto scan_number_decimal1;
9037 }
9038
9039 case 'e':
9040 case 'E':
9041 {
9042 add(current);
9043 goto scan_number_exponent;
9044 }
9045
9046 default:
9047 goto scan_number_done;
9048 }
9049
9050 scan_number_any1:
9051 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
9052 switch (get())
9053 {
9054 case '0':
9055 case '1':
9056 case '2':
9057 case '3':
9058 case '4':
9059 case '5':
9060 case '6':
9061 case '7':
9062 case '8':
9063 case '9':
9064 {
9065 add(current);
9066 goto scan_number_any1;
9067 }
9068
9069 case '.':
9070 {
9071 add(decimal_point_char);
9072 goto scan_number_decimal1;
9073 }
9074
9075 case 'e':
9076 case 'E':
9077 {
9078 add(current);
9079 goto scan_number_exponent;
9080 }
9081
9082 default:
9083 goto scan_number_done;
9084 }
9085
9086 scan_number_decimal1:
9087 // state: we just parsed a decimal point
9088 number_type = token_type::value_float;
9089 switch (get())
9090 {
9091 case '0':
9092 case '1':
9093 case '2':
9094 case '3':
9095 case '4':
9096 case '5':
9097 case '6':
9098 case '7':
9099 case '8':
9100 case '9':
9101 {
9102 add(current);
9103 goto scan_number_decimal2;
9104 }
9105
9106 default:
9107 {
9108 error_message = "invalid number; expected digit after '.'";
9109 return token_type::parse_error;
9110 }
9111 }
9112
9113 scan_number_decimal2:
9114 // we just parsed at least one number after a decimal point
9115 switch (get())
9116 {
9117 case '0':
9118 case '1':
9119 case '2':
9120 case '3':
9121 case '4':
9122 case '5':
9123 case '6':
9124 case '7':
9125 case '8':
9126 case '9':
9127 {
9128 add(current);
9129 goto scan_number_decimal2;
9130 }
9131
9132 case 'e':
9133 case 'E':
9134 {
9135 add(current);
9136 goto scan_number_exponent;
9137 }
9138
9139 default:
9140 goto scan_number_done;
9141 }
9142
9143 scan_number_exponent:
9144 // we just parsed an exponent
9145 number_type = token_type::value_float;
9146 switch (get())
9147 {
9148 case '+':
9149 case '-':
9150 {
9151 add(current);
9152 goto scan_number_sign;
9153 }
9154
9155 case '0':
9156 case '1':
9157 case '2':
9158 case '3':
9159 case '4':
9160 case '5':
9161 case '6':
9162 case '7':
9163 case '8':
9164 case '9':
9165 {
9166 add(current);
9167 goto scan_number_any2;
9168 }
9169
9170 default:
9171 {
9172 error_message =
9173 "invalid number; expected '+', '-', or digit after exponent";
9174 return token_type::parse_error;
9175 }
9176 }
9177
9178 scan_number_sign:
9179 // we just parsed an exponent sign
9180 switch (get())
9181 {
9182 case '0':
9183 case '1':
9184 case '2':
9185 case '3':
9186 case '4':
9187 case '5':
9188 case '6':
9189 case '7':
9190 case '8':
9191 case '9':
9192 {
9193 add(current);
9194 goto scan_number_any2;
9195 }
9196
9197 default:
9198 {
9199 error_message = "invalid number; expected digit after exponent sign";
9200 return token_type::parse_error;
9201 }
9202 }
9203
9204 scan_number_any2:
9205 // we just parsed a number after the exponent or exponent sign
9206 switch (get())
9207 {
9208 case '0':
9209 case '1':
9210 case '2':
9211 case '3':
9212 case '4':
9213 case '5':
9214 case '6':
9215 case '7':
9216 case '8':
9217 case '9':
9218 {
9219 add(current);
9220 goto scan_number_any2;
9221 }
9222
9223 default:
9224 goto scan_number_done;
9225 }
9226
9227 scan_number_done:
9228 // unget the character after the number (we only read it to know that
9229 // we are done scanning a number)
9230 unget();
9231
9232 char* endptr = nullptr;
9233 errno = 0;
9234
9235 // try to parse integers first and fall back to floats
9236 if (number_type == token_type::value_unsigned)
9237 {
9238 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
9239
9240 // we checked the number format before
9241 assert(endptr == token_buffer.data() + token_buffer.size());
9242
9243 if (errno == 0)
9244 {
9245 value_unsigned = static_cast<number_unsigned_t>(x);
9246 if (value_unsigned == x)
9247 {
9248 return token_type::value_unsigned;
9249 }
9250 }
9251 }
9252 else if (number_type == token_type::value_integer)
9253 {
9254 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
9255
9256 // we checked the number format before
9257 assert(endptr == token_buffer.data() + token_buffer.size());
9258
9259 if (errno == 0)
9260 {
9261 value_integer = static_cast<number_integer_t>(x);
9262 if (value_integer == x)
9263 {
9264 return token_type::value_integer;
9265 }
9266 }
9267 }
9268
9269 // this code is reached if we parse a floating-point number or if an
9270 // integer conversion above failed
9271 strtof(value_float, token_buffer.data(), &endptr);
9272
9273 // we checked the number format before
9274 assert(endptr == token_buffer.data() + token_buffer.size());
9275
9276 return token_type::value_float;
9277 }
9278
9284 JSON_HEDLEY_NON_NULL(2)
9285 token_type scan_literal(const char_type* literal_text, const std::size_t length,
9286 token_type return_type)
9287 {
9288 assert(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
9289 for (std::size_t i = 1; i < length; ++i)
9290 {
9291 if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
9292 {
9293 error_message = "invalid literal";
9294 return token_type::parse_error;
9295 }
9296 }
9297 return return_type;
9298 }
9299
9301 // input management
9303
9305 void reset() noexcept
9306 {
9307 token_buffer.clear();
9308 token_string.clear();
9309 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
9310 }
9311
9312 /*
9313 @brief get next character from the input
9314
9315 This function provides the interface to the used input adapter. It does
9316 not throw in case the input reached EOF, but returns a
9317 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
9318 for use in error messages.
9319
9320 @return character read from the input
9321 */
9322 char_int_type get()
9323 {
9324 ++position.chars_read_total;
9325 ++position.chars_read_current_line;
9326
9327 if (next_unget)
9328 {
9329 // just reset the next_unget variable and work with current
9330 next_unget = false;
9331 }
9332 else
9333 {
9334 current = ia.get_character();
9335 }
9336
9337 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
9338 {
9339 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
9340 }
9341
9342 if (current == '\n')
9343 {
9344 ++position.lines_read;
9345 position.chars_read_current_line = 0;
9346 }
9347
9348 return current;
9349 }
9350
9359 void unget()
9360 {
9361 next_unget = true;
9362
9363 --position.chars_read_total;
9364
9365 // in case we "unget" a newline, we have to also decrement the lines_read
9366 if (position.chars_read_current_line == 0)
9367 {
9368 if (position.lines_read > 0)
9369 {
9370 --position.lines_read;
9371 }
9372 }
9373 else
9374 {
9375 --position.chars_read_current_line;
9376 }
9377
9378 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
9379 {
9380 assert(not token_string.empty());
9381 token_string.pop_back();
9382 }
9383 }
9384
9386 void add(char_int_type c)
9387 {
9388 token_buffer.push_back(static_cast<typename string_t::value_type>(c));
9389 }
9390
9391 public:
9393 // value getters
9395
9397 constexpr number_integer_t get_number_integer() const noexcept
9398 {
9399 return value_integer;
9400 }
9401
9403 constexpr number_unsigned_t get_number_unsigned() const noexcept
9404 {
9405 return value_unsigned;
9406 }
9407
9409 constexpr number_float_t get_number_float() const noexcept
9410 {
9411 return value_float;
9412 }
9413
9415 string_t& get_string()
9416 {
9417 return token_buffer;
9418 }
9419
9421 // diagnostics
9423
9425 constexpr position_t get_position() const noexcept
9426 {
9427 return position;
9428 }
9429
9433 std::string get_token_string() const
9434 {
9435 // escape control characters
9436 std::string result;
9437 for (const auto c : token_string)
9438 {
9439 if (static_cast<unsigned char>(c) <= '\x1F')
9440 {
9441 // escape control characters
9442 std::array<char, 9> cs{{}};
9443 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c));
9444 result += cs.data();
9445 }
9446 else
9447 {
9448 // add character as is
9449 result.push_back(static_cast<std::string::value_type>(c));
9450 }
9451 }
9452
9453 return result;
9454 }
9455
9457
9458 constexpr const char* get_error_message() const noexcept
9459 {
9460 return error_message;
9461 }
9462
9464 // actual scanner
9466
9471 bool skip_bom()
9472 {
9473 if (get() == 0xEF)
9474 {
9475 // check if we completely parse the BOM
9476 return get() == 0xBB and get() == 0xBF;
9477 }
9478
9479 // the first character is not the beginning of the BOM; unget it to
9480 // process is later
9481 unget();
9482 return true;
9483 }
9484
9485 token_type scan()
9486 {
9487 // initially, skip the BOM
9488 if (position.chars_read_total == 0 and not skip_bom())
9489 {
9490 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
9491 return token_type::parse_error;
9492 }
9493
9494 // read next character and ignore whitespace
9495 do
9496 {
9497 get();
9498 }
9499 while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
9500
9501 switch (current)
9502 {
9503 // structural characters
9504 case '[':
9505 return token_type::begin_array;
9506 case ']':
9507 return token_type::end_array;
9508 case '{':
9509 return token_type::begin_object;
9510 case '}':
9511 return token_type::end_object;
9512 case ':':
9513 return token_type::name_separator;
9514 case ',':
9515 return token_type::value_separator;
9516
9517 // literals
9518 case 't':
9519 {
9520 std::array<char_type, 4> true_literal = {{'t', 'r', 'u', 'e'}};
9521 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
9522 }
9523 case 'f':
9524 {
9525 std::array<char_type, 5> false_literal = {{'f', 'a', 'l', 's', 'e'}};
9526 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
9527 }
9528 case 'n':
9529 {
9530 std::array<char_type, 4> null_literal = {{'n', 'u', 'l', 'l'}};
9531 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
9532 }
9533
9534 // string
9535 case '\"':
9536 return scan_string();
9537
9538 // number
9539 case '-':
9540 case '0':
9541 case '1':
9542 case '2':
9543 case '3':
9544 case '4':
9545 case '5':
9546 case '6':
9547 case '7':
9548 case '8':
9549 case '9':
9550 return scan_number();
9551
9552 // end of input (the null byte is needed when parsing from
9553 // string literals)
9554 case '\0':
9555 case std::char_traits<char_type>::eof():
9556 return token_type::end_of_input;
9557
9558 // error
9559 default:
9560 error_message = "invalid literal";
9561 return token_type::parse_error;
9562 }
9563 }
9564
9565 private:
9567 InputAdapterType ia;
9568
9570 char_int_type current = std::char_traits<char_type>::eof();
9571
9573 bool next_unget = false;
9574
9576 position_t position {};
9577
9579 std::vector<char_type> token_string {};
9580
9582 string_t token_buffer {};
9583
9585 const char* error_message = "";
9586
9587 // number values
9588 number_integer_t value_integer = 0;
9589 number_unsigned_t value_unsigned = 0;
9590 number_float_t value_float = 0;
9591
9593 const char_int_type decimal_point_char = '.';
9594 };
9595 } // namespace detail
9596 } // namespace nlohmann
9597
9598 // #include <nlohmann/detail/input/parser.hpp>
9599
9600
9601 #include <cassert> // assert
9602 #include <cmath> // isfinite
9603 #include <cstdint> // uint8_t
9604 #include <functional> // function
9605 #include <string> // string
9606 #include <utility> // move
9607 #include <vector> // vector
9608
9609 // #include <nlohmann/detail/exceptions.hpp>
9610
9611 // #include <nlohmann/detail/input/input_adapters.hpp>
9612
9613 // #include <nlohmann/detail/input/json_sax.hpp>
9614
9615 // #include <nlohmann/detail/input/lexer.hpp>
9616
9617 // #include <nlohmann/detail/macro_scope.hpp>
9618
9619 // #include <nlohmann/detail/meta/is_sax.hpp>
9620
9621 // #include <nlohmann/detail/value_t.hpp>
9622
9623
9624 namespace nlohmann
9625 {
9626 namespace detail
9627 {
9629 // parser //
9631
9632 enum class parse_event_t : uint8_t
9633 {
9635 object_start,
9637 object_end,
9639 array_start,
9641 array_end,
9643 key,
9645 value
9646 };
9647
9648 template<typename BasicJsonType>
9649 using parser_callback_t =
9650 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
9651
9657 template<typename BasicJsonType, typename InputAdapterType>
9658 class parser
9659 {
9660 using number_integer_t = typename BasicJsonType::number_integer_t;
9661 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9662 using number_float_t = typename BasicJsonType::number_float_t;
9663 using string_t = typename BasicJsonType::string_t;
9664 using lexer_t = lexer<BasicJsonType, InputAdapterType>;
9665 using token_type = typename lexer_t::token_type;
9666
9667 public:
9669 explicit parser(InputAdapterType&& adapter,
9670 const parser_callback_t<BasicJsonType> cb = nullptr,
9671 const bool allow_exceptions_ = true)
9672 : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
9673 {
9674 // read first token
9675 get_token();
9676 }
9677
9688 void parse(const bool strict, BasicJsonType& result)
9689 {
9690 if (callback)
9691 {
9692 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
9693 sax_parse_internal(&sdp);
9694 result.assert_invariant();
9695
9696 // in strict mode, input must be completely read
9697 if (strict and (get_token() != token_type::end_of_input))
9698 {
9699 sdp.parse_error(m_lexer.get_position(),
9700 m_lexer.get_token_string(),
9701 parse_error::create(101, m_lexer.get_position(),
9702 exception_message(token_type::end_of_input, "value")));
9703 }
9704
9705 // in case of an error, return discarded value
9706 if (sdp.is_errored())
9707 {
9708 result = value_t::discarded;
9709 return;
9710 }
9711
9712 // set top-level value to null if it was discarded by the callback
9713 // function
9714 if (result.is_discarded())
9715 {
9716 result = nullptr;
9717 }
9718 }
9719 else
9720 {
9721 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
9722 sax_parse_internal(&sdp);
9723 result.assert_invariant();
9724
9725 // in strict mode, input must be completely read
9726 if (strict and (get_token() != token_type::end_of_input))
9727 {
9728 sdp.parse_error(m_lexer.get_position(),
9729 m_lexer.get_token_string(),
9730 parse_error::create(101, m_lexer.get_position(),
9731 exception_message(token_type::end_of_input, "value")));
9732 }
9733
9734 // in case of an error, return discarded value
9735 if (sdp.is_errored())
9736 {
9737 result = value_t::discarded;
9738 return;
9739 }
9740 }
9741 }
9742
9749 bool accept(const bool strict = true)
9750 {
9751 json_sax_acceptor<BasicJsonType> sax_acceptor;
9752 return sax_parse(&sax_acceptor, strict);
9753 }
9754
9755 template <typename SAX>
9756 JSON_HEDLEY_NON_NULL(2)
9757 bool sax_parse(SAX* sax, const bool strict = true)
9758 {
9759 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
9760 const bool result = sax_parse_internal(sax);
9761
9762 // strict mode: next byte must be EOF
9763 if (result and strict and (get_token() != token_type::end_of_input))
9764 {
9765 return sax->parse_error(m_lexer.get_position(),
9766 m_lexer.get_token_string(),
9767 parse_error::create(101, m_lexer.get_position(),
9768 exception_message(token_type::end_of_input, "value")));
9769 }
9770
9771 return result;
9772 }
9773
9774 private:
9775 template <typename SAX>
9776 JSON_HEDLEY_NON_NULL(2)
9777 bool sax_parse_internal(SAX* sax)
9778 {
9779 // stack to remember the hierarchy of structured values we are parsing
9780 // true = array; false = object
9781 std::vector<bool> states;
9782 // value to avoid a goto (see comment where set to true)
9783 bool skip_to_state_evaluation = false;
9784
9785 while (true)
9786 {
9787 if (not skip_to_state_evaluation)
9788 {
9789 // invariant: get_token() was called before each iteration
9790 switch (last_token)
9791 {
9792 case token_type::begin_object:
9793 {
9794 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
9795 {
9796 return false;
9797 }
9798
9799 // closing } -> we are done
9800 if (get_token() == token_type::end_object)
9801 {
9802 if (JSON_HEDLEY_UNLIKELY(not sax->end_object()))
9803 {
9804 return false;
9805 }
9806 break;
9807 }
9808
9809 // parse key
9810 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
9811 {
9812 return sax->parse_error(m_lexer.get_position(),
9813 m_lexer.get_token_string(),
9814 parse_error::create(101, m_lexer.get_position(),
9815 exception_message(token_type::value_string, "object key")));
9816 }
9817 if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
9818 {
9819 return false;
9820 }
9821
9822 // parse separator (:)
9823 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
9824 {
9825 return sax->parse_error(m_lexer.get_position(),
9826 m_lexer.get_token_string(),
9827 parse_error::create(101, m_lexer.get_position(),
9828 exception_message(token_type::name_separator, "object separator")));
9829 }
9830
9831 // remember we are now inside an object
9832 states.push_back(false);
9833
9834 // parse values
9835 get_token();
9836 continue;
9837 }
9838
9839 case token_type::begin_array:
9840 {
9841 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
9842 {
9843 return false;
9844 }
9845
9846 // closing ] -> we are done
9847 if (get_token() == token_type::end_array)
9848 {
9849 if (JSON_HEDLEY_UNLIKELY(not sax->end_array()))
9850 {
9851 return false;
9852 }
9853 break;
9854 }
9855
9856 // remember we are now inside an array
9857 states.push_back(true);
9858
9859 // parse values (no need to call get_token)
9860 continue;
9861 }
9862
9863 case token_type::value_float:
9864 {
9865 const auto res = m_lexer.get_number_float();
9866
9867 if (JSON_HEDLEY_UNLIKELY(not std::isfinite(res)))
9868 {
9869 return sax->parse_error(m_lexer.get_position(),
9870 m_lexer.get_token_string(),
9871 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
9872 }
9873
9874 if (JSON_HEDLEY_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
9875 {
9876 return false;
9877 }
9878
9879 break;
9880 }
9881
9882 case token_type::literal_false:
9883 {
9884 if (JSON_HEDLEY_UNLIKELY(not sax->boolean(false)))
9885 {
9886 return false;
9887 }
9888 break;
9889 }
9890
9891 case token_type::literal_null:
9892 {
9893 if (JSON_HEDLEY_UNLIKELY(not sax->null()))
9894 {
9895 return false;
9896 }
9897 break;
9898 }
9899
9900 case token_type::literal_true:
9901 {
9902 if (JSON_HEDLEY_UNLIKELY(not sax->boolean(true)))
9903 {
9904 return false;
9905 }
9906 break;
9907 }
9908
9909 case token_type::value_integer:
9910 {
9911 if (JSON_HEDLEY_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
9912 {
9913 return false;
9914 }
9915 break;
9916 }
9917
9918 case token_type::value_string:
9919 {
9920 if (JSON_HEDLEY_UNLIKELY(not sax->string(m_lexer.get_string())))
9921 {
9922 return false;
9923 }
9924 break;
9925 }
9926
9927 case token_type::value_unsigned:
9928 {
9929 if (JSON_HEDLEY_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
9930 {
9931 return false;
9932 }
9933 break;
9934 }
9935
9936 case token_type::parse_error:
9937 {
9938 // using "uninitialized" to avoid "expected" message
9939 return sax->parse_error(m_lexer.get_position(),
9940 m_lexer.get_token_string(),
9941 parse_error::create(101, m_lexer.get_position(),
9942 exception_message(token_type::uninitialized, "value")));
9943 }
9944
9945 default: // the last token was unexpected
9946 {
9947 return sax->parse_error(m_lexer.get_position(),
9948 m_lexer.get_token_string(),
9949 parse_error::create(101, m_lexer.get_position(),
9950 exception_message(token_type::literal_or_value, "value")));
9951 }
9952 }
9953 }
9954 else
9955 {
9956 skip_to_state_evaluation = false;
9957 }
9958
9959 // we reached this line after we successfully parsed a value
9960 if (states.empty())
9961 {
9962 // empty stack: we reached the end of the hierarchy: done
9963 return true;
9964 }
9965
9966 if (states.back()) // array
9967 {
9968 // comma -> next value
9969 if (get_token() == token_type::value_separator)
9970 {
9971 // parse a new value
9972 get_token();
9973 continue;
9974 }
9975
9976 // closing ]
9977 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
9978 {
9979 if (JSON_HEDLEY_UNLIKELY(not sax->end_array()))
9980 {
9981 return false;
9982 }
9983
9984 // We are done with this array. Before we can parse a
9985 // new value, we need to evaluate the new state first.
9986 // By setting skip_to_state_evaluation to false, we
9987 // are effectively jumping to the beginning of this if.
9988 assert(not states.empty());
9989 states.pop_back();
9990 skip_to_state_evaluation = true;
9991 continue;
9992 }
9993
9994 return sax->parse_error(m_lexer.get_position(),
9995 m_lexer.get_token_string(),
9996 parse_error::create(101, m_lexer.get_position(),
9997 exception_message(token_type::end_array, "array")));
9998 }
9999 else // object
10000 {
10001 // comma -> next value
10002 if (get_token() == token_type::value_separator)
10003 {
10004 // parse key
10005 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
10006 {
10007 return sax->parse_error(m_lexer.get_position(),
10008 m_lexer.get_token_string(),
10009 parse_error::create(101, m_lexer.get_position(),
10010 exception_message(token_type::value_string, "object key")));
10011 }
10012
10013 if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
10014 {
10015 return false;
10016 }
10017
10018 // parse separator (:)
10019 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10020 {
10021 return sax->parse_error(m_lexer.get_position(),
10022 m_lexer.get_token_string(),
10023 parse_error::create(101, m_lexer.get_position(),
10024 exception_message(token_type::name_separator, "object separator")));
10025 }
10026
10027 // parse values
10028 get_token();
10029 continue;
10030 }
10031
10032 // closing }
10033 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
10034 {
10035 if (JSON_HEDLEY_UNLIKELY(not sax->end_object()))
10036 {
10037 return false;
10038 }
10039
10040 // We are done with this object. Before we can parse a
10041 // new value, we need to evaluate the new state first.
10042 // By setting skip_to_state_evaluation to false, we
10043 // are effectively jumping to the beginning of this if.
10044 assert(not states.empty());
10045 states.pop_back();
10046 skip_to_state_evaluation = true;
10047 continue;
10048 }
10049
10050 return sax->parse_error(m_lexer.get_position(),
10051 m_lexer.get_token_string(),
10052 parse_error::create(101, m_lexer.get_position(),
10053 exception_message(token_type::end_object, "object")));
10054 }
10055 }
10056 }
10057
10059 token_type get_token()
10060 {
10061 return last_token = m_lexer.scan();
10062 }
10063
10064 std::string exception_message(const token_type expected, const std::string& context)
10065 {
10066 std::string error_msg = "syntax error ";
10067
10068 if (not context.empty())
10069 {
10070 error_msg += "while parsing " + context + " ";
10071 }
10072
10073 error_msg += "- ";
10074
10075 if (last_token == token_type::parse_error)
10076 {
10077 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
10078 m_lexer.get_token_string() + "'";
10079 }
10080 else
10081 {
10082 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
10083 }
10084
10085 if (expected != token_type::uninitialized)
10086 {
10087 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
10088 }
10089
10090 return error_msg;
10091 }
10092
10093 private:
10095 const parser_callback_t<BasicJsonType> callback = nullptr;
10097 token_type last_token = token_type::uninitialized;
10099 lexer_t m_lexer;
10101 const bool allow_exceptions = true;
10102 };
10103 } // namespace detail
10104 } // namespace nlohmann
10105
10106 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
10107
10108
10109 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10110
10111
10112 #include <cstddef> // ptrdiff_t
10113 #include <limits> // numeric_limits
10114
10115 namespace nlohmann
10116 {
10117 namespace detail
10118 {
10119 /*
10120 @brief an iterator for primitive JSON types
10121
10122 This class models an iterator for primitive JSON types (boolean, number,
10123 string). It's only purpose is to allow the iterator/const_iterator classes
10124 to "iterate" over primitive values. Internally, the iterator is modeled by
10125 a `difference_type` variable. Value begin_value (`0`) models the begin,
10126 end_value (`1`) models past the end.
10127 */
10128 class primitive_iterator_t
10129 {
10130 private:
10131 using difference_type = std::ptrdiff_t;
10132 static constexpr difference_type begin_value = 0;
10133 static constexpr difference_type end_value = begin_value + 1;
10134
10136 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
10137
10138 public:
10139 constexpr difference_type get_value() const noexcept
10140 {
10141 return m_it;
10142 }
10143
10145 void set_begin() noexcept
10146 {
10147 m_it = begin_value;
10148 }
10149
10151 void set_end() noexcept
10152 {
10153 m_it = end_value;
10154 }
10155
10157 constexpr bool is_begin() const noexcept
10158 {
10159 return m_it == begin_value;
10160 }
10161
10163 constexpr bool is_end() const noexcept
10164 {
10165 return m_it == end_value;
10166 }
10167
10168 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10169 {
10170 return lhs.m_it == rhs.m_it;
10171 }
10172
10173 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10174 {
10175 return lhs.m_it < rhs.m_it;
10176 }
10177
10178 primitive_iterator_t operator+(difference_type n) noexcept
10179 {
10180 auto result = *this;
10181 result += n;
10182 return result;
10183 }
10184
10185 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10186 {
10187 return lhs.m_it - rhs.m_it;
10188 }
10189
10190 primitive_iterator_t& operator++() noexcept
10191 {
10192 ++m_it;
10193 return *this;
10194 }
10195
10196 primitive_iterator_t const operator++(int) noexcept
10197 {
10198 auto result = *this;
10199 ++m_it;
10200 return result;
10201 }
10202
10203 primitive_iterator_t& operator--() noexcept
10204 {
10205 --m_it;
10206 return *this;
10207 }
10208
10209 primitive_iterator_t const operator--(int) noexcept
10210 {
10211 auto result = *this;
10212 --m_it;
10213 return result;
10214 }
10215
10216 primitive_iterator_t& operator+=(difference_type n) noexcept
10217 {
10218 m_it += n;
10219 return *this;
10220 }
10221
10222 primitive_iterator_t& operator-=(difference_type n) noexcept
10223 {
10224 m_it -= n;
10225 return *this;
10226 }
10227 };
10228 } // namespace detail
10229 } // namespace nlohmann
10230
10231
10232 namespace nlohmann
10233 {
10234 namespace detail
10235 {
10242 template<typename BasicJsonType> struct internal_iterator
10243 {
10245 typename BasicJsonType::object_t::iterator object_iterator {};
10247 typename BasicJsonType::array_t::iterator array_iterator {};
10249 typename BasicJsonType::binary_t::container_type::iterator binary_iterator {};
10251 primitive_iterator_t primitive_iterator {};
10252 };
10253 } // namespace detail
10254 } // namespace nlohmann
10255
10256 // #include <nlohmann/detail/iterators/iter_impl.hpp>
10257
10258
10259 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
10260 #include <type_traits> // conditional, is_const, remove_const
10261
10262 // #include <nlohmann/detail/boolean_operators.hpp>
10263
10264 // #include <nlohmann/detail/exceptions.hpp>
10265
10266 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
10267
10268 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10269
10270 // #include <nlohmann/detail/macro_scope.hpp>
10271
10272 // #include <nlohmann/detail/meta/cpp_future.hpp>
10273
10274 // #include <nlohmann/detail/meta/type_traits.hpp>
10275
10276 // #include <nlohmann/detail/value_t.hpp>
10277
10278
10279 namespace nlohmann
10280 {
10281 namespace detail
10282 {
10283 // forward declare, to be able to friend it later on
10284 template<typename IteratorType> class iteration_proxy;
10285 template<typename IteratorType> class iteration_proxy_value;
10286
10303 template<typename BasicJsonType>
10304 class iter_impl
10305 {
10307 friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
10308 friend BasicJsonType;
10309 friend iteration_proxy<iter_impl>;
10310 friend iteration_proxy_value<iter_impl>;
10311
10312 using object_t = typename BasicJsonType::object_t;
10313 using array_t = typename BasicJsonType::array_t;
10314 // make sure BasicJsonType is basic_json or const basic_json
10315 static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
10316 "iter_impl only accepts (const) basic_json");
10317
10318 public:
10319
10325 using iterator_category = std::bidirectional_iterator_tag;
10326
10328 using value_type = typename BasicJsonType::value_type;
10330 using difference_type = typename BasicJsonType::difference_type;
10332 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
10333 typename BasicJsonType::const_pointer,
10334 typename BasicJsonType::pointer>::type;
10336 using reference =
10337 typename std::conditional<std::is_const<BasicJsonType>::value,
10338 typename BasicJsonType::const_reference,
10339 typename BasicJsonType::reference>::type;
10340
10342 iter_impl() = default;
10343
10350 explicit iter_impl(pointer object) noexcept : m_object(object)
10351 {
10352 assert(m_object != nullptr);
10353
10354 switch (m_object->m_type)
10355 {
10356 case value_t::object:
10357 {
10358 m_it.object_iterator = typename object_t::iterator();
10359 break;
10360 }
10361
10362 case value_t::array:
10363 {
10364 m_it.array_iterator = typename array_t::iterator();
10365 break;
10366 }
10367
10368 default:
10369 {
10370 m_it.primitive_iterator = primitive_iterator_t();
10371 break;
10372 }
10373 }
10374 }
10375
10392 iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
10393 : m_object(other.m_object), m_it(other.m_it)
10394 {}
10395
10402 iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
10403 {
10404 m_object = other.m_object;
10405 m_it = other.m_it;
10406 return *this;
10407 }
10408
10414 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
10415 : m_object(other.m_object), m_it(other.m_it)
10416 {}
10417
10424 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
10425 {
10426 m_object = other.m_object;
10427 m_it = other.m_it;
10428 return *this;
10429 }
10430
10431 private:
10436 void set_begin() noexcept
10437 {
10438 assert(m_object != nullptr);
10439
10440 switch (m_object->m_type)
10441 {
10442 case value_t::object:
10443 {
10444 m_it.object_iterator = m_object->m_value.object->begin();
10445 break;
10446 }
10447
10448 case value_t::array:
10449 {
10450 m_it.array_iterator = m_object->m_value.array->begin();
10451 break;
10452 }
10453
10454 case value_t::null:
10455 {
10456 // set to end so begin()==end() is true: null is empty
10457 m_it.primitive_iterator.set_end();
10458 break;
10459 }
10460
10461 default:
10462 {
10463 m_it.primitive_iterator.set_begin();
10464 break;
10465 }
10466 }
10467 }
10468
10473 void set_end() noexcept
10474 {
10475 assert(m_object != nullptr);
10476
10477 switch (m_object->m_type)
10478 {
10479 case value_t::object:
10480 {
10481 m_it.object_iterator = m_object->m_value.object->end();
10482 break;
10483 }
10484
10485 case value_t::array:
10486 {
10487 m_it.array_iterator = m_object->m_value.array->end();
10488 break;
10489 }
10490
10491 default:
10492 {
10493 m_it.primitive_iterator.set_end();
10494 break;
10495 }
10496 }
10497 }
10498
10499 public:
10504 reference operator*() const
10505 {
10506 assert(m_object != nullptr);
10507
10508 switch (m_object->m_type)
10509 {
10510 case value_t::object:
10511 {
10512 assert(m_it.object_iterator != m_object->m_value.object->end());
10513 return m_it.object_iterator->second;
10514 }
10515
10516 case value_t::array:
10517 {
10518 assert(m_it.array_iterator != m_object->m_value.array->end());
10519 return *m_it.array_iterator;
10520 }
10521
10522 case value_t::null:
10523 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
10524
10525 default:
10526 {
10527 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
10528 {
10529 return *m_object;
10530 }
10531
10532 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
10533 }
10534 }
10535 }
10536
10541 pointer operator->() const
10542 {
10543 assert(m_object != nullptr);
10544
10545 switch (m_object->m_type)
10546 {
10547 case value_t::object:
10548 {
10549 assert(m_it.object_iterator != m_object->m_value.object->end());
10550 return &(m_it.object_iterator->second);
10551 }
10552
10553 case value_t::array:
10554 {
10555 assert(m_it.array_iterator != m_object->m_value.array->end());
10556 return &*m_it.array_iterator;
10557 }
10558
10559 default:
10560 {
10561 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
10562 {
10563 return m_object;
10564 }
10565
10566 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
10567 }
10568 }
10569 }
10570
10575 iter_impl const operator++(int)
10576 {
10577 auto result = *this;
10578 ++(*this);
10579 return result;
10580 }
10581
10586 iter_impl& operator++()
10587 {
10588 assert(m_object != nullptr);
10589
10590 switch (m_object->m_type)
10591 {
10592 case value_t::object:
10593 {
10594 std::advance(m_it.object_iterator, 1);
10595 break;
10596 }
10597
10598 case value_t::array:
10599 {
10600 std::advance(m_it.array_iterator, 1);
10601 break;
10602 }
10603
10604 default:
10605 {
10606 ++m_it.primitive_iterator;
10607 break;
10608 }
10609 }
10610
10611 return *this;
10612 }
10613
10618 iter_impl const operator--(int)
10619 {
10620 auto result = *this;
10621 --(*this);
10622 return result;
10623 }
10624
10629 iter_impl& operator--()
10630 {
10631 assert(m_object != nullptr);
10632
10633 switch (m_object->m_type)
10634 {
10635 case value_t::object:
10636 {
10637 std::advance(m_it.object_iterator, -1);
10638 break;
10639 }
10640
10641 case value_t::array:
10642 {
10643 std::advance(m_it.array_iterator, -1);
10644 break;
10645 }
10646
10647 default:
10648 {
10649 --m_it.primitive_iterator;
10650 break;
10651 }
10652 }
10653
10654 return *this;
10655 }
10656
10661 bool operator==(const iter_impl& other) const
10662 {
10663 // if objects are not the same, the comparison is undefined
10664 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
10665 {
10666 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
10667 }
10668
10669 assert(m_object != nullptr);
10670
10671 switch (m_object->m_type)
10672 {
10673 case value_t::object:
10674 return (m_it.object_iterator == other.m_it.object_iterator);
10675
10676 case value_t::array:
10677 return (m_it.array_iterator == other.m_it.array_iterator);
10678
10679 default:
10680 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
10681 }
10682 }
10683
10688 bool operator!=(const iter_impl& other) const
10689 {
10690 return not operator==(other);
10691 }
10692
10697 bool operator<(const iter_impl& other) const
10698 {
10699 // if objects are not the same, the comparison is undefined
10700 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
10701 {
10702 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
10703 }
10704
10705 assert(m_object != nullptr);
10706
10707 switch (m_object->m_type)
10708 {
10709 case value_t::object:
10710 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
10711
10712 case value_t::array:
10713 return (m_it.array_iterator < other.m_it.array_iterator);
10714
10715 default:
10716 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
10717 }
10718 }
10719
10724 bool operator<=(const iter_impl& other) const
10725 {
10726 return not other.operator < (*this);
10727 }
10728
10733 bool operator>(const iter_impl& other) const
10734 {
10735 return not operator<=(other);
10736 }
10737
10742 bool operator>=(const iter_impl& other) const
10743 {
10744 return not operator<(other);
10745 }
10746
10751 iter_impl& operator+=(difference_type i)
10752 {
10753 assert(m_object != nullptr);
10754
10755 switch (m_object->m_type)
10756 {
10757 case value_t::object:
10758 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
10759
10760 case value_t::array:
10761 {
10762 std::advance(m_it.array_iterator, i);
10763 break;
10764 }
10765
10766 default:
10767 {
10768 m_it.primitive_iterator += i;
10769 break;
10770 }
10771 }
10772
10773 return *this;
10774 }
10775
10780 iter_impl& operator-=(difference_type i)
10781 {
10782 return operator+=(-i);
10783 }
10784
10789 iter_impl operator+(difference_type i) const
10790 {
10791 auto result = *this;
10792 result += i;
10793 return result;
10794 }
10795
10800 friend iter_impl operator+(difference_type i, const iter_impl& it)
10801 {
10802 auto result = it;
10803 result += i;
10804 return result;
10805 }
10806
10811 iter_impl operator-(difference_type i) const
10812 {
10813 auto result = *this;
10814 result -= i;
10815 return result;
10816 }
10817
10822 difference_type operator-(const iter_impl& other) const
10823 {
10824 assert(m_object != nullptr);
10825
10826 switch (m_object->m_type)
10827 {
10828 case value_t::object:
10829 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
10830
10831 case value_t::array:
10832 return m_it.array_iterator - other.m_it.array_iterator;
10833
10834 default:
10835 return m_it.primitive_iterator - other.m_it.primitive_iterator;
10836 }
10837 }
10838
10843 reference operator[](difference_type n) const
10844 {
10845 assert(m_object != nullptr);
10846
10847 switch (m_object->m_type)
10848 {
10849 case value_t::object:
10850 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
10851
10852 case value_t::array:
10853 return *std::next(m_it.array_iterator, n);
10854
10855 case value_t::null:
10856 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
10857
10858 default:
10859 {
10860 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
10861 {
10862 return *m_object;
10863 }
10864
10865 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
10866 }
10867 }
10868 }
10869
10874 const typename object_t::key_type& key() const
10875 {
10876 assert(m_object != nullptr);
10877
10878 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
10879 {
10880 return m_it.object_iterator->first;
10881 }
10882
10883 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
10884 }
10885
10890 reference value() const
10891 {
10892 return operator*();
10893 }
10894
10895 private:
10897 pointer m_object = nullptr;
10899 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
10900 };
10901 } // namespace detail
10902 } // namespace nlohmann
10903
10904 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
10905
10906 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
10907
10908
10909 #include <cstddef> // ptrdiff_t
10910 #include <iterator> // reverse_iterator
10911 #include <utility> // declval
10912
10913 namespace nlohmann
10914 {
10915 namespace detail
10916 {
10918 // reverse_iterator //
10920
10939 template<typename Base>
10940 class json_reverse_iterator : public std::reverse_iterator<Base>
10941 {
10942 public:
10943 using difference_type = std::ptrdiff_t;
10945 using base_iterator = std::reverse_iterator<Base>;
10947 using reference = typename Base::reference;
10948
10950 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
10951 : base_iterator(it) {}
10952
10954 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
10955
10957 json_reverse_iterator const operator++(int)
10958 {
10959 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
10960 }
10961
10963 json_reverse_iterator& operator++()
10964 {
10965 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
10966 }
10967
10969 json_reverse_iterator const operator--(int)
10970 {
10971 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
10972 }
10973
10975 json_reverse_iterator& operator--()
10976 {
10977 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
10978 }
10979
10981 json_reverse_iterator& operator+=(difference_type i)
10982 {
10983 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
10984 }
10985
10987 json_reverse_iterator operator+(difference_type i) const
10988 {
10989 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
10990 }
10991
10993 json_reverse_iterator operator-(difference_type i) const
10994 {
10995 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
10996 }
10997
10999 difference_type operator-(const json_reverse_iterator& other) const
11000 {
11001 return base_iterator(*this) - base_iterator(other);
11002 }
11003
11005 reference operator[](difference_type n) const
11006 {
11007 return *(this->operator+(n));
11008 }
11009
11011 auto key() const -> decltype(std::declval<Base>().key())
11012 {
11013 auto it = --this->base();
11014 return it.key();
11015 }
11016
11018 reference value() const
11019 {
11020 auto it = --this->base();
11021 return it.operator * ();
11022 }
11023 };
11024 } // namespace detail
11025 } // namespace nlohmann
11026
11027 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11028
11029 // #include <nlohmann/detail/json_pointer.hpp>
11030
11031
11032 #include <algorithm> // all_of
11033 #include <cassert> // assert
11034 #include <cctype> // isdigit
11035 #include <numeric> // accumulate
11036 #include <string> // string
11037 #include <utility> // move
11038 #include <vector> // vector
11039
11040 // #include <nlohmann/detail/exceptions.hpp>
11041
11042 // #include <nlohmann/detail/macro_scope.hpp>
11043
11044 // #include <nlohmann/detail/value_t.hpp>
11045
11046
11047 namespace nlohmann
11048 {
11049 template<typename BasicJsonType>
11050 class json_pointer
11051 {
11052 // allow basic_json to access private members
11053 NLOHMANN_BASIC_JSON_TPL_DECLARATION
11054 friend class basic_json;
11055
11056 public:
11078 explicit json_pointer(const std::string& s = "")
11079 : reference_tokens(split(s))
11080 {}
11081
11096 std::string to_string() const
11097 {
11098 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
11099 std::string{},
11100 [](const std::string & a, const std::string & b)
11101 {
11102 return a + "/" + escape(b);
11103 });
11104 }
11105
11107 operator std::string() const
11108 {
11109 return to_string();
11110 }
11111
11128 json_pointer& operator/=(const json_pointer& ptr)
11129 {
11130 reference_tokens.insert(reference_tokens.end(),
11131 ptr.reference_tokens.begin(),
11132 ptr.reference_tokens.end());
11133 return *this;
11134 }
11135
11152 json_pointer& operator/=(std::string token)
11153 {
11154 push_back(std::move(token));
11155 return *this;
11156 }
11157
11174 json_pointer& operator/=(std::size_t array_idx)
11175 {
11176 return *this /= std::to_string(array_idx);
11177 }
11178
11194 friend json_pointer operator/(const json_pointer& lhs,
11195 const json_pointer& rhs)
11196 {
11197 return json_pointer(lhs) /= rhs;
11198 }
11199
11215 friend json_pointer operator/(const json_pointer& ptr, std::string token)
11216 {
11217 return json_pointer(ptr) /= std::move(token);
11218 }
11219
11235 friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
11236 {
11237 return json_pointer(ptr) /= array_idx;
11238 }
11239
11253 json_pointer parent_pointer() const
11254 {
11255 if (empty())
11256 {
11257 return *this;
11258 }
11259
11260 json_pointer res = *this;
11261 res.pop_back();
11262 return res;
11263 }
11264
11278 void pop_back()
11279 {
11280 if (JSON_HEDLEY_UNLIKELY(empty()))
11281 {
11282 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11283 }
11284
11285 reference_tokens.pop_back();
11286 }
11287
11302 const std::string& back() const
11303 {
11304 if (JSON_HEDLEY_UNLIKELY(empty()))
11305 {
11306 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11307 }
11308
11309 return reference_tokens.back();
11310 }
11311
11324 void push_back(const std::string& token)
11325 {
11326 reference_tokens.push_back(token);
11327 }
11328
11330 void push_back(std::string&& token)
11331 {
11332 reference_tokens.push_back(std::move(token));
11333 }
11334
11349 bool empty() const noexcept
11350 {
11351 return reference_tokens.empty();
11352 }
11353
11354 private:
11362 static int array_index(const std::string& s)
11363 {
11364 // error condition (cf. RFC 6901, Sect. 4)
11365 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 and s[0] == '0'))
11366 {
11367 JSON_THROW(detail::parse_error::create(106, 0,
11368 "array index '" + s +
11369 "' must not begin with '0'"));
11370 }
11371
11372 // error condition (cf. RFC 6901, Sect. 4)
11373 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 and not (s[0] >= '1' and s[0] <= '9')))
11374 {
11375 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number"));
11376 }
11377
11378 std::size_t processed_chars = 0;
11379 int res = 0;
11380 JSON_TRY
11381 {
11382 res = std::stoi(s, &processed_chars);
11383 }
11384 JSON_CATCH(std::out_of_range&)
11385 {
11386 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11387 }
11388
11389 // check if the string was completely read
11390 if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
11391 {
11392 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11393 }
11394
11395 return res;
11396 }
11397
11398 json_pointer top() const
11399 {
11400 if (JSON_HEDLEY_UNLIKELY(empty()))
11401 {
11402 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11403 }
11404
11405 json_pointer result = *this;
11406 result.reference_tokens = {reference_tokens[0]};
11407 return result;
11408 }
11409
11418 BasicJsonType& get_and_create(BasicJsonType& j) const
11419 {
11420 using size_type = typename BasicJsonType::size_type;
11421 auto result = &j;
11422
11423 // in case no reference tokens exist, return a reference to the JSON value
11424 // j which will be overwritten by a primitive value
11425 for (const auto& reference_token : reference_tokens)
11426 {
11427 switch (result->type())
11428 {
11429 case detail::value_t::null:
11430 {
11431 if (reference_token == "0")
11432 {
11433 // start a new array if reference token is 0
11434 result = &result->operator[](0);
11435 }
11436 else
11437 {
11438 // start a new object otherwise
11439 result = &result->operator[](reference_token);
11440 }
11441 break;
11442 }
11443
11444 case detail::value_t::object:
11445 {
11446 // create an entry in the object
11447 result = &result->operator[](reference_token);
11448 break;
11449 }
11450
11451 case detail::value_t::array:
11452 {
11453 // create an entry in the array
11454 result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
11455 break;
11456 }
11457
11458 /*
11459 The following code is only reached if there exists a reference
11460 token _and_ the current value is primitive. In this case, we have
11461 an error situation, because primitive values may only occur as
11462 single value; that is, with an empty list of reference tokens.
11463 */
11464 default:
11465 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
11466 }
11467 }
11468
11469 return *result;
11470 }
11471
11491 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
11492 {
11493 using size_type = typename BasicJsonType::size_type;
11494 for (const auto& reference_token : reference_tokens)
11495 {
11496 // convert null values to arrays or objects before continuing
11497 if (ptr->is_null())
11498 {
11499 // check if reference token is a number
11500 const bool nums =
11501 std::all_of(reference_token.begin(), reference_token.end(),
11502 [](const unsigned char x)
11503 {
11504 return std::isdigit(x);
11505 });
11506
11507 // change value to array for numbers or "-" or to object otherwise
11508 *ptr = (nums or reference_token == "-")
11509 ? detail::value_t::array
11510 : detail::value_t::object;
11511 }
11512
11513 switch (ptr->type())
11514 {
11515 case detail::value_t::object:
11516 {
11517 // use unchecked object access
11518 ptr = &ptr->operator[](reference_token);
11519 break;
11520 }
11521
11522 case detail::value_t::array:
11523 {
11524 if (reference_token == "-")
11525 {
11526 // explicitly treat "-" as index beyond the end
11527 ptr = &ptr->operator[](ptr->m_value.array->size());
11528 }
11529 else
11530 {
11531 // convert array index to number; unchecked access
11532 ptr = &ptr->operator[](
11533 static_cast<size_type>(array_index(reference_token)));
11534 }
11535 break;
11536 }
11537
11538 default:
11539 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
11540 }
11541 }
11542
11543 return *ptr;
11544 }
11545
11552 BasicJsonType& get_checked(BasicJsonType* ptr) const
11553 {
11554 using size_type = typename BasicJsonType::size_type;
11555 for (const auto& reference_token : reference_tokens)
11556 {
11557 switch (ptr->type())
11558 {
11559 case detail::value_t::object:
11560 {
11561 // note: at performs range check
11562 ptr = &ptr->at(reference_token);
11563 break;
11564 }
11565
11566 case detail::value_t::array:
11567 {
11568 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
11569 {
11570 // "-" always fails the range check
11571 JSON_THROW(detail::out_of_range::create(402,
11572 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
11573 ") is out of range"));
11574 }
11575
11576 // note: at performs range check
11577 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
11578 break;
11579 }
11580
11581 default:
11582 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
11583 }
11584 }
11585
11586 return *ptr;
11587 }
11588
11602 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
11603 {
11604 using size_type = typename BasicJsonType::size_type;
11605 for (const auto& reference_token : reference_tokens)
11606 {
11607 switch (ptr->type())
11608 {
11609 case detail::value_t::object:
11610 {
11611 // use unchecked object access
11612 ptr = &ptr->operator[](reference_token);
11613 break;
11614 }
11615
11616 case detail::value_t::array:
11617 {
11618 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
11619 {
11620 // "-" cannot be used for const access
11621 JSON_THROW(detail::out_of_range::create(402,
11622 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
11623 ") is out of range"));
11624 }
11625
11626 // use unchecked array access
11627 ptr = &ptr->operator[](
11628 static_cast<size_type>(array_index(reference_token)));
11629 break;
11630 }
11631
11632 default:
11633 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
11634 }
11635 }
11636
11637 return *ptr;
11638 }
11639
11646 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
11647 {
11648 using size_type = typename BasicJsonType::size_type;
11649 for (const auto& reference_token : reference_tokens)
11650 {
11651 switch (ptr->type())
11652 {
11653 case detail::value_t::object:
11654 {
11655 // note: at performs range check
11656 ptr = &ptr->at(reference_token);
11657 break;
11658 }
11659
11660 case detail::value_t::array:
11661 {
11662 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
11663 {
11664 // "-" always fails the range check
11665 JSON_THROW(detail::out_of_range::create(402,
11666 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
11667 ") is out of range"));
11668 }
11669
11670 // note: at performs range check
11671 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
11672 break;
11673 }
11674
11675 default:
11676 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
11677 }
11678 }
11679
11680 return *ptr;
11681 }
11682
11687 bool contains(const BasicJsonType* ptr) const
11688 {
11689 using size_type = typename BasicJsonType::size_type;
11690 for (const auto& reference_token : reference_tokens)
11691 {
11692 switch (ptr->type())
11693 {
11694 case detail::value_t::object:
11695 {
11696 if (not ptr->contains(reference_token))
11697 {
11698 // we did not find the key in the object
11699 return false;
11700 }
11701
11702 ptr = &ptr->operator[](reference_token);
11703 break;
11704 }
11705
11706 case detail::value_t::array:
11707 {
11708 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
11709 {
11710 // "-" always fails the range check
11711 return false;
11712 }
11713 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 and not ("0" <= reference_token and reference_token <= "9")))
11714 {
11715 // invalid char
11716 return false;
11717 }
11718 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
11719 {
11720 if (JSON_HEDLEY_UNLIKELY(not ('1' <= reference_token[0] and reference_token[0] <= '9')))
11721 {
11722 // first char should be between '1' and '9'
11723 return false;
11724 }
11725 for (std::size_t i = 1; i < reference_token.size(); i++)
11726 {
11727 if (JSON_HEDLEY_UNLIKELY(not ('0' <= reference_token[i] and reference_token[i] <= '9')))
11728 {
11729 // other char should be between '0' and '9'
11730 return false;
11731 }
11732 }
11733 }
11734
11735 const auto idx = static_cast<size_type>(array_index(reference_token));
11736 if (idx >= ptr->size())
11737 {
11738 // index out of range
11739 return false;
11740 }
11741
11742 ptr = &ptr->operator[](idx);
11743 break;
11744 }
11745
11746 default:
11747 {
11748 // we do not expect primitive values if there is still a
11749 // reference token to process
11750 return false;
11751 }
11752 }
11753 }
11754
11755 // no reference token left means we found a primitive value
11756 return true;
11757 }
11758
11768 static std::vector<std::string> split(const std::string& reference_string)
11769 {
11770 std::vector<std::string> result;
11771
11772 // special case: empty reference string -> no reference tokens
11773 if (reference_string.empty())
11774 {
11775 return result;
11776 }
11777
11778 // check if nonempty reference string begins with slash
11779 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
11780 {
11781 JSON_THROW(detail::parse_error::create(107, 1,
11782 "JSON pointer must be empty or begin with '/' - was: '" +
11783 reference_string + "'"));
11784 }
11785
11786 // extract the reference tokens:
11787 // - slash: position of the last read slash (or end of string)
11788 // - start: position after the previous slash
11789 for (
11790 // search for the first slash after the first character
11791 std::size_t slash = reference_string.find_first_of('/', 1),
11792 // set the beginning of the first reference token
11793 start = 1;
11794 // we can stop if start == 0 (if slash == std::string::npos)
11795 start != 0;
11796 // set the beginning of the next reference token
11797 // (will eventually be 0 if slash == std::string::npos)
11798 start = (slash == std::string::npos) ? 0 : slash + 1,
11799 // find next slash
11800 slash = reference_string.find_first_of('/', start))
11801 {
11802 // use the text between the beginning of the reference token
11803 // (start) and the last slash (slash).
11804 auto reference_token = reference_string.substr(start, slash - start);
11805
11806 // check reference tokens are properly escaped
11807 for (std::size_t pos = reference_token.find_first_of('~');
11808 pos != std::string::npos;
11809 pos = reference_token.find_first_of('~', pos + 1))
11810 {
11811 assert(reference_token[pos] == '~');
11812
11813 // ~ must be followed by 0 or 1
11814 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 or
11815 (reference_token[pos + 1] != '0' and
11816 reference_token[pos + 1] != '1')))
11817 {
11818 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
11819 }
11820 }
11821
11822 // finally, store the reference token
11823 unescape(reference_token);
11824 result.push_back(reference_token);
11825 }
11826
11827 return result;
11828 }
11829
11843 static void replace_substring(std::string& s, const std::string& f,
11844 const std::string& t)
11845 {
11846 assert(not f.empty());
11847 for (auto pos = s.find(f); // find first occurrence of f
11848 pos != std::string::npos; // make sure f was found
11849 s.replace(pos, f.size(), t), // replace with t, and
11850 pos = s.find(f, pos + t.size())) // find next occurrence of f
11851 {}
11852 }
11853
11855 static std::string escape(std::string s)
11856 {
11857 replace_substring(s, "~", "~0");
11858 replace_substring(s, "/", "~1");
11859 return s;
11860 }
11861
11863 static void unescape(std::string& s)
11864 {
11865 replace_substring(s, "~1", "/");
11866 replace_substring(s, "~0", "~");
11867 }
11868
11876 static void flatten(const std::string& reference_string,
11877 const BasicJsonType& value,
11878 BasicJsonType& result)
11879 {
11880 switch (value.type())
11881 {
11882 case detail::value_t::array:
11883 {
11884 if (value.m_value.array->empty())
11885 {
11886 // flatten empty array as null
11887 result[reference_string] = nullptr;
11888 }
11889 else
11890 {
11891 // iterate array and use index as reference string
11892 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
11893 {
11894 flatten(reference_string + "/" + std::to_string(i),
11895 value.m_value.array->operator[](i), result);
11896 }
11897 }
11898 break;
11899 }
11900
11901 case detail::value_t::object:
11902 {
11903 if (value.m_value.object->empty())
11904 {
11905 // flatten empty object as null
11906 result[reference_string] = nullptr;
11907 }
11908 else
11909 {
11910 // iterate object and use keys as reference string
11911 for (const auto& element : *value.m_value.object)
11912 {
11913 flatten(reference_string + "/" + escape(element.first), element.second, result);
11914 }
11915 }
11916 break;
11917 }
11918
11919 default:
11920 {
11921 // add primitive value with its reference string
11922 result[reference_string] = value;
11923 break;
11924 }
11925 }
11926 }
11927
11938 static BasicJsonType
11939 unflatten(const BasicJsonType& value)
11940 {
11941 if (JSON_HEDLEY_UNLIKELY(not value.is_object()))
11942 {
11943 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
11944 }
11945
11946 BasicJsonType result;
11947
11948 // iterate the JSON object values
11949 for (const auto& element : *value.m_value.object)
11950 {
11951 if (JSON_HEDLEY_UNLIKELY(not element.second.is_primitive()))
11952 {
11953 JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
11954 }
11955
11956 // assign value to reference pointed to by JSON pointer; Note that if
11957 // the JSON pointer is "" (i.e., points to the whole value), function
11958 // get_and_create returns a reference to result itself. An assignment
11959 // will then create a primitive value.
11960 json_pointer(element.first).get_and_create(result) = element.second;
11961 }
11962
11963 return result;
11964 }
11965
11977 friend bool operator==(json_pointer const& lhs,
11978 json_pointer const& rhs) noexcept
11979 {
11980 return lhs.reference_tokens == rhs.reference_tokens;
11981 }
11982
11994 friend bool operator!=(json_pointer const& lhs,
11995 json_pointer const& rhs) noexcept
11996 {
11997 return not (lhs == rhs);
11998 }
11999
12001 std::vector<std::string> reference_tokens;
12002 };
12003 } // namespace nlohmann
12004
12005 // #include <nlohmann/detail/json_ref.hpp>
12006
12007
12008 #include <initializer_list>
12009 #include <utility>
12010
12011 // #include <nlohmann/detail/meta/type_traits.hpp>
12012
12013
12014 namespace nlohmann
12015 {
12016 namespace detail
12017 {
12018 template<typename BasicJsonType>
12019 class json_ref
12020 {
12021 public:
12022 using value_type = BasicJsonType;
12023
12024 json_ref(value_type&& value)
12025 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
12026 {}
12027
12028 json_ref(const value_type& value)
12029 : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
12030 {}
12031
12032 json_ref(std::initializer_list<json_ref> init)
12033 : owned_value(init), value_ref(&owned_value), is_rvalue(true)
12034 {}
12035
12036 template <
12037 class... Args,
12038 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
12039 json_ref(Args && ... args)
12040 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value),
12041 is_rvalue(true) {}
12042
12043 // class should be movable only
12044 json_ref(json_ref&&) = default;
12045 json_ref(const json_ref&) = delete;
12046 json_ref& operator=(const json_ref&) = delete;
12047 json_ref& operator=(json_ref&&) = delete;
12048 ~json_ref() = default;
12049
12050 value_type moved_or_copied() const
12051 {
12052 if (is_rvalue)
12053 {
12054 return std::move(*value_ref);
12055 }
12056 return *value_ref;
12057 }
12058
12059 value_type const& operator*() const
12060 {
12061 return *static_cast<value_type const*>(value_ref);
12062 }
12063
12064 value_type const* operator->() const
12065 {
12066 return static_cast<value_type const*>(value_ref);
12067 }
12068
12069 private:
12070 mutable value_type owned_value = nullptr;
12071 value_type* value_ref = nullptr;
12072 const bool is_rvalue;
12073 };
12074 } // namespace detail
12075 } // namespace nlohmann
12076
12077 // #include <nlohmann/detail/macro_scope.hpp>
12078
12079 // #include <nlohmann/detail/meta/cpp_future.hpp>
12080
12081 // #include <nlohmann/detail/meta/type_traits.hpp>
12082
12083 // #include <nlohmann/detail/output/binary_writer.hpp>
12084
12085
12086 #include <algorithm> // reverse
12087 #include <array> // array
12088 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
12089 #include <cstring> // memcpy
12090 #include <limits> // numeric_limits
12091 #include <string> // string
12092 #include <cmath> // isnan, isinf
12093
12094 // #include <nlohmann/detail/input/binary_reader.hpp>
12095
12096 // #include <nlohmann/detail/macro_scope.hpp>
12097
12098 // #include <nlohmann/detail/output/output_adapters.hpp>
12099
12100
12101 #include <algorithm> // copy
12102 #include <cstddef> // size_t
12103 #include <ios> // streamsize
12104 #include <iterator> // back_inserter
12105 #include <memory> // shared_ptr, make_shared
12106 #include <ostream> // basic_ostream
12107 #include <string> // basic_string
12108 #include <vector> // vector
12109 // #include <nlohmann/detail/macro_scope.hpp>
12110
12111
12112 namespace nlohmann
12113 {
12114 namespace detail
12115 {
12117 template<typename CharType> struct output_adapter_protocol
12118 {
12119 virtual void write_character(CharType c) = 0;
12120 virtual void write_characters(const CharType* s, std::size_t length) = 0;
12121 virtual ~output_adapter_protocol() = default;
12122 };
12123
12125 template<typename CharType>
12126 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
12127
12129 template<typename CharType>
12130 class output_vector_adapter : public output_adapter_protocol<CharType>
12131 {
12132 public:
12133 explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
12134 : v(vec)
12135 {}
12136
12137 void write_character(CharType c) override
12138 {
12139 v.push_back(c);
12140 }
12141
12142 JSON_HEDLEY_NON_NULL(2)
12143 void write_characters(const CharType* s, std::size_t length) override
12144 {
12145 std::copy(s, s + length, std::back_inserter(v));
12146 }
12147
12148 private:
12149 std::vector<CharType>& v;
12150 };
12151
12153 template<typename CharType>
12154 class output_stream_adapter : public output_adapter_protocol<CharType>
12155 {
12156 public:
12157 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
12158 : stream(s)
12159 {}
12160
12161 void write_character(CharType c) override
12162 {
12163 stream.put(c);
12164 }
12165
12166 JSON_HEDLEY_NON_NULL(2)
12167 void write_characters(const CharType* s, std::size_t length) override
12168 {
12169 stream.write(s, static_cast<std::streamsize>(length));
12170 }
12171
12172 private:
12173 std::basic_ostream<CharType>& stream;
12174 };
12175
12177 template<typename CharType, typename StringType = std::basic_string<CharType>>
12178 class output_string_adapter : public output_adapter_protocol<CharType>
12179 {
12180 public:
12181 explicit output_string_adapter(StringType& s) noexcept
12182 : str(s)
12183 {}
12184
12185 void write_character(CharType c) override
12186 {
12187 str.push_back(c);
12188 }
12189
12190 JSON_HEDLEY_NON_NULL(2)
12191 void write_characters(const CharType* s, std::size_t length) override
12192 {
12193 str.append(s, length);
12194 }
12195
12196 private:
12197 StringType& str;
12198 };
12199
12200 template<typename CharType, typename StringType = std::basic_string<CharType>>
12201 class output_adapter
12202 {
12203 public:
12204 output_adapter(std::vector<CharType>& vec)
12205 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
12206
12207 output_adapter(std::basic_ostream<CharType>& s)
12208 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
12209
12210 output_adapter(StringType& s)
12211 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
12212
12213 operator output_adapter_t<CharType>()
12214 {
12215 return oa;
12216 }
12217
12218 private:
12219 output_adapter_t<CharType> oa = nullptr;
12220 };
12221 } // namespace detail
12222 } // namespace nlohmann
12223
12224
12225 namespace nlohmann
12226 {
12227 namespace detail
12228 {
12230 // binary writer //
12232
12236 template<typename BasicJsonType, typename CharType>
12237 class binary_writer
12238 {
12239 using string_t = typename BasicJsonType::string_t;
12240 using binary_t = typename BasicJsonType::binary_t;
12241
12242 public:
12248 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
12249 {
12250 assert(oa);
12251 }
12252
12257 void write_bson(const BasicJsonType& j)
12258 {
12259 switch (j.type())
12260 {
12261 case value_t::object:
12262 {
12263 write_bson_object(*j.m_value.object);
12264 break;
12265 }
12266
12267 default:
12268 {
12269 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
12270 }
12271 }
12272 }
12273
12277 void write_cbor(const BasicJsonType& j)
12278 {
12279 switch (j.type())
12280 {
12281 case value_t::null:
12282 {
12283 oa->write_character(to_char_type(0xF6));
12284 break;
12285 }
12286
12287 case value_t::boolean:
12288 {
12289 oa->write_character(j.m_value.boolean
12290 ? to_char_type(0xF5)
12291 : to_char_type(0xF4));
12292 break;
12293 }
12294
12295 case value_t::number_integer:
12296 {
12297 if (j.m_value.number_integer >= 0)
12298 {
12299 // CBOR does not differentiate between positive signed
12300 // integers and unsigned integers. Therefore, we used the
12301 // code from the value_t::number_unsigned case here.
12302 if (j.m_value.number_integer <= 0x17)
12303 {
12304 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12305 }
12306 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
12307 {
12308 oa->write_character(to_char_type(0x18));
12309 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12310 }
12311 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
12312 {
12313 oa->write_character(to_char_type(0x19));
12314 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
12315 }
12316 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
12317 {
12318 oa->write_character(to_char_type(0x1A));
12319 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
12320 }
12321 else
12322 {
12323 oa->write_character(to_char_type(0x1B));
12324 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
12325 }
12326 }
12327 else
12328 {
12329 // The conversions below encode the sign in the first
12330 // byte, and the value is converted to a positive number.
12331 const auto positive_number = -1 - j.m_value.number_integer;
12332 if (j.m_value.number_integer >= -24)
12333 {
12334 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
12335 }
12336 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
12337 {
12338 oa->write_character(to_char_type(0x38));
12339 write_number(static_cast<std::uint8_t>(positive_number));
12340 }
12341 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
12342 {
12343 oa->write_character(to_char_type(0x39));
12344 write_number(static_cast<std::uint16_t>(positive_number));
12345 }
12346 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
12347 {
12348 oa->write_character(to_char_type(0x3A));
12349 write_number(static_cast<std::uint32_t>(positive_number));
12350 }
12351 else
12352 {
12353 oa->write_character(to_char_type(0x3B));
12354 write_number(static_cast<std::uint64_t>(positive_number));
12355 }
12356 }
12357 break;
12358 }
12359
12360 case value_t::number_unsigned:
12361 {
12362 if (j.m_value.number_unsigned <= 0x17)
12363 {
12364 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
12365 }
12366 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12367 {
12368 oa->write_character(to_char_type(0x18));
12369 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
12370 }
12371 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12372 {
12373 oa->write_character(to_char_type(0x19));
12374 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
12375 }
12376 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12377 {
12378 oa->write_character(to_char_type(0x1A));
12379 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
12380 }
12381 else
12382 {
12383 oa->write_character(to_char_type(0x1B));
12384 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
12385 }
12386 break;
12387 }
12388
12389 case value_t::number_float:
12390 {
12391 if (std::isnan(j.m_value.number_float))
12392 {
12393 // NaN is 0xf97e00 in CBOR
12394 oa->write_character(to_char_type(0xF9));
12395 oa->write_character(to_char_type(0x7E));
12396 oa->write_character(to_char_type(0x00));
12397 }
12398 else if (std::isinf(j.m_value.number_float))
12399 {
12400 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
12401 oa->write_character(to_char_type(0xf9));
12402 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
12403 oa->write_character(to_char_type(0x00));
12404 }
12405 else
12406 {
12407 if (static_cast<double>(j.m_value.number_float) >= static_cast<double>(std::numeric_limits<float>::lowest()) and
12408 static_cast<double>(j.m_value.number_float) <= static_cast<double>((std::numeric_limits<float>::max)()) and
12409 static_cast<double>(static_cast<float>(j.m_value.number_float)) == static_cast<double>(j.m_value.number_float))
12410 {
12411 oa->write_character(get_cbor_float_prefix(static_cast<float>(j.m_value.number_float)));
12412 write_number(static_cast<float>(j.m_value.number_float));
12413 }
12414 else
12415 {
12416 oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
12417 write_number(j.m_value.number_float);
12418 }
12419 }
12420 break;
12421 }
12422
12423 case value_t::string:
12424 {
12425 // step 1: write control byte and the string length
12426 const auto N = j.m_value.string->size();
12427 if (N <= 0x17)
12428 {
12429 write_number(static_cast<std::uint8_t>(0x60 + N));
12430 }
12431 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12432 {
12433 oa->write_character(to_char_type(0x78));
12434 write_number(static_cast<std::uint8_t>(N));
12435 }
12436 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12437 {
12438 oa->write_character(to_char_type(0x79));
12439 write_number(static_cast<std::uint16_t>(N));
12440 }
12441 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12442 {
12443 oa->write_character(to_char_type(0x7A));
12444 write_number(static_cast<std::uint32_t>(N));
12445 }
12446 // LCOV_EXCL_START
12447 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12448 {
12449 oa->write_character(to_char_type(0x7B));
12450 write_number(static_cast<std::uint64_t>(N));
12451 }
12452 // LCOV_EXCL_STOP
12453
12454 // step 2: write the string
12455 oa->write_characters(
12456 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
12457 j.m_value.string->size());
12458 break;
12459 }
12460
12461 case value_t::array:
12462 {
12463 // step 1: write control byte and the array size
12464 const auto N = j.m_value.array->size();
12465 if (N <= 0x17)
12466 {
12467 write_number(static_cast<std::uint8_t>(0x80 + N));
12468 }
12469 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12470 {
12471 oa->write_character(to_char_type(0x98));
12472 write_number(static_cast<std::uint8_t>(N));
12473 }
12474 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12475 {
12476 oa->write_character(to_char_type(0x99));
12477 write_number(static_cast<std::uint16_t>(N));
12478 }
12479 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12480 {
12481 oa->write_character(to_char_type(0x9A));
12482 write_number(static_cast<std::uint32_t>(N));
12483 }
12484 // LCOV_EXCL_START
12485 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12486 {
12487 oa->write_character(to_char_type(0x9B));
12488 write_number(static_cast<std::uint64_t>(N));
12489 }
12490 // LCOV_EXCL_STOP
12491
12492 // step 2: write each element
12493 for (const auto& el : *j.m_value.array)
12494 {
12495 write_cbor(el);
12496 }
12497 break;
12498 }
12499
12500 case value_t::binary:
12501 {
12502 // step 1: write control byte and the binary array size
12503 const auto N = j.m_value.binary->size();
12504 if (N <= 0x17)
12505 {
12506 write_number(static_cast<std::uint8_t>(0x40 + N));
12507 }
12508 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12509 {
12510 oa->write_character(to_char_type(0x58));
12511 write_number(static_cast<std::uint8_t>(N));
12512 }
12513 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12514 {
12515 oa->write_character(to_char_type(0x59));
12516 write_number(static_cast<std::uint16_t>(N));
12517 }
12518 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12519 {
12520 oa->write_character(to_char_type(0x5A));
12521 write_number(static_cast<std::uint32_t>(N));
12522 }
12523 // LCOV_EXCL_START
12524 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12525 {
12526 oa->write_character(to_char_type(0x5B));
12527 write_number(static_cast<std::uint64_t>(N));
12528 }
12529 // LCOV_EXCL_STOP
12530
12531 // step 2: write each element
12532 oa->write_characters(
12533 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
12534 N);
12535
12536 break;
12537 }
12538
12539 case value_t::object:
12540 {
12541 // step 1: write control byte and the object size
12542 const auto N = j.m_value.object->size();
12543 if (N <= 0x17)
12544 {
12545 write_number(static_cast<std::uint8_t>(0xA0 + N));
12546 }
12547 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12548 {
12549 oa->write_character(to_char_type(0xB8));
12550 write_number(static_cast<std::uint8_t>(N));
12551 }
12552 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12553 {
12554 oa->write_character(to_char_type(0xB9));
12555 write_number(static_cast<std::uint16_t>(N));
12556 }
12557 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12558 {
12559 oa->write_character(to_char_type(0xBA));
12560 write_number(static_cast<std::uint32_t>(N));
12561 }
12562 // LCOV_EXCL_START
12563 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12564 {
12565 oa->write_character(to_char_type(0xBB));
12566 write_number(static_cast<std::uint64_t>(N));
12567 }
12568 // LCOV_EXCL_STOP
12569
12570 // step 2: write each element
12571 for (const auto& el : *j.m_value.object)
12572 {
12573 write_cbor(el.first);
12574 write_cbor(el.second);
12575 }
12576 break;
12577 }
12578
12579 default:
12580 break;
12581 }
12582 }
12583
12587 void write_msgpack(const BasicJsonType& j)
12588 {
12589 switch (j.type())
12590 {
12591 case value_t::null: // nil
12592 {
12593 oa->write_character(to_char_type(0xC0));
12594 break;
12595 }
12596
12597 case value_t::boolean: // true and false
12598 {
12599 oa->write_character(j.m_value.boolean
12600 ? to_char_type(0xC3)
12601 : to_char_type(0xC2));
12602 break;
12603 }
12604
12605 case value_t::number_integer:
12606 {
12607 if (j.m_value.number_integer >= 0)
12608 {
12609 // MessagePack does not differentiate between positive
12610 // signed integers and unsigned integers. Therefore, we used
12611 // the code from the value_t::number_unsigned case here.
12612 if (j.m_value.number_unsigned < 128)
12613 {
12614 // positive fixnum
12615 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12616 }
12617 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12618 {
12619 // uint 8
12620 oa->write_character(to_char_type(0xCC));
12621 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12622 }
12623 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12624 {
12625 // uint 16
12626 oa->write_character(to_char_type(0xCD));
12627 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
12628 }
12629 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12630 {
12631 // uint 32
12632 oa->write_character(to_char_type(0xCE));
12633 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
12634 }
12635 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
12636 {
12637 // uint 64
12638 oa->write_character(to_char_type(0xCF));
12639 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
12640 }
12641 }
12642 else
12643 {
12644 if (j.m_value.number_integer >= -32)
12645 {
12646 // negative fixnum
12647 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
12648 }
12649 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() and
12650 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
12651 {
12652 // int 8
12653 oa->write_character(to_char_type(0xD0));
12654 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
12655 }
12656 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() and
12657 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
12658 {
12659 // int 16
12660 oa->write_character(to_char_type(0xD1));
12661 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
12662 }
12663 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() and
12664 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
12665 {
12666 // int 32
12667 oa->write_character(to_char_type(0xD2));
12668 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
12669 }
12670 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() and
12671 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
12672 {
12673 // int 64
12674 oa->write_character(to_char_type(0xD3));
12675 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
12676 }
12677 }
12678 break;
12679 }
12680
12681 case value_t::number_unsigned:
12682 {
12683 if (j.m_value.number_unsigned < 128)
12684 {
12685 // positive fixnum
12686 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12687 }
12688 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12689 {
12690 // uint 8
12691 oa->write_character(to_char_type(0xCC));
12692 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12693 }
12694 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12695 {
12696 // uint 16
12697 oa->write_character(to_char_type(0xCD));
12698 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
12699 }
12700 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12701 {
12702 // uint 32
12703 oa->write_character(to_char_type(0xCE));
12704 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
12705 }
12706 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
12707 {
12708 // uint 64
12709 oa->write_character(to_char_type(0xCF));
12710 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
12711 }
12712 break;
12713 }
12714
12715 case value_t::number_float:
12716 {
12717 oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
12718 write_number(j.m_value.number_float);
12719 break;
12720 }
12721
12722 case value_t::string:
12723 {
12724 // step 1: write control byte and the string length
12725 const auto N = j.m_value.string->size();
12726 if (N <= 31)
12727 {
12728 // fixstr
12729 write_number(static_cast<std::uint8_t>(0xA0 | N));
12730 }
12731 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12732 {
12733 // str 8
12734 oa->write_character(to_char_type(0xD9));
12735 write_number(static_cast<std::uint8_t>(N));
12736 }
12737 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12738 {
12739 // str 16
12740 oa->write_character(to_char_type(0xDA));
12741 write_number(static_cast<std::uint16_t>(N));
12742 }
12743 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12744 {
12745 // str 32
12746 oa->write_character(to_char_type(0xDB));
12747 write_number(static_cast<std::uint32_t>(N));
12748 }
12749
12750 // step 2: write the string
12751 oa->write_characters(
12752 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
12753 j.m_value.string->size());
12754 break;
12755 }
12756
12757 case value_t::array:
12758 {
12759 // step 1: write control byte and the array size
12760 const auto N = j.m_value.array->size();
12761 if (N <= 15)
12762 {
12763 // fixarray
12764 write_number(static_cast<std::uint8_t>(0x90 | N));
12765 }
12766 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12767 {
12768 // array 16
12769 oa->write_character(to_char_type(0xDC));
12770 write_number(static_cast<std::uint16_t>(N));
12771 }
12772 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12773 {
12774 // array 32
12775 oa->write_character(to_char_type(0xDD));
12776 write_number(static_cast<std::uint32_t>(N));
12777 }
12778
12779 // step 2: write each element
12780 for (const auto& el : *j.m_value.array)
12781 {
12782 write_msgpack(el);
12783 }
12784 break;
12785 }
12786
12787 case value_t::binary:
12788 {
12789 // step 0: determine if the binary type has a set subtype to
12790 // determine whether or not to use the ext or fixext types
12791 const bool use_ext = j.m_value.binary->has_subtype();
12792
12793 // step 1: write control byte and the byte string length
12794 const auto N = j.m_value.binary->size();
12795 if (N <= (std::numeric_limits<std::uint8_t>::max)())
12796 {
12797 std::uint8_t output_type;
12798 bool fixed = true;
12799 if (use_ext)
12800 {
12801 switch (N)
12802 {
12803 case 1:
12804 output_type = 0xD4; // fixext 1
12805 break;
12806 case 2:
12807 output_type = 0xD5; // fixext 2
12808 break;
12809 case 4:
12810 output_type = 0xD6; // fixext 4
12811 break;
12812 case 8:
12813 output_type = 0xD7; // fixext 8
12814 break;
12815 case 16:
12816 output_type = 0xD8; // fixext 16
12817 break;
12818 default:
12819 output_type = 0xC7; // ext 8
12820 fixed = false;
12821 break;
12822 }
12823
12824 }
12825 else
12826 {
12827 output_type = 0xC4; // bin 8
12828 fixed = false;
12829 }
12830
12831 oa->write_character(to_char_type(output_type));
12832 if (not fixed)
12833 {
12834 write_number(static_cast<std::uint8_t>(N));
12835 }
12836 }
12837 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12838 {
12839 std::uint8_t output_type;
12840 if (use_ext)
12841 {
12842 output_type = 0xC8; // ext 16
12843 }
12844 else
12845 {
12846 output_type = 0xC5; // bin 16
12847 }
12848
12849 oa->write_character(to_char_type(output_type));
12850 write_number(static_cast<std::uint16_t>(N));
12851 }
12852 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12853 {
12854 std::uint8_t output_type;
12855 if (use_ext)
12856 {
12857 output_type = 0xC9; // ext 32
12858 }
12859 else
12860 {
12861 output_type = 0xC6; // bin 32
12862 }
12863
12864 oa->write_character(to_char_type(output_type));
12865 write_number(static_cast<std::uint32_t>(N));
12866 }
12867
12868 // step 1.5: if this is an ext type, write the subtype
12869 if (use_ext)
12870 {
12871 write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
12872 }
12873
12874 // step 2: write the byte string
12875 oa->write_characters(
12876 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
12877 N);
12878
12879 break;
12880 }
12881
12882 case value_t::object:
12883 {
12884 // step 1: write control byte and the object size
12885 const auto N = j.m_value.object->size();
12886 if (N <= 15)
12887 {
12888 // fixmap
12889 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
12890 }
12891 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12892 {
12893 // map 16
12894 oa->write_character(to_char_type(0xDE));
12895 write_number(static_cast<std::uint16_t>(N));
12896 }
12897 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12898 {
12899 // map 32
12900 oa->write_character(to_char_type(0xDF));
12901 write_number(static_cast<std::uint32_t>(N));
12902 }
12903
12904 // step 2: write each element
12905 for (const auto& el : *j.m_value.object)
12906 {
12907 write_msgpack(el.first);
12908 write_msgpack(el.second);
12909 }
12910 break;
12911 }
12912
12913 default:
12914 break;
12915 }
12916 }
12917
12924 void write_ubjson(const BasicJsonType& j, const bool use_count,
12925 const bool use_type, const bool add_prefix = true)
12926 {
12927 switch (j.type())
12928 {
12929 case value_t::null:
12930 {
12931 if (add_prefix)
12932 {
12933 oa->write_character(to_char_type('Z'));
12934 }
12935 break;
12936 }
12937
12938 case value_t::boolean:
12939 {
12940 if (add_prefix)
12941 {
12942 oa->write_character(j.m_value.boolean
12943 ? to_char_type('T')
12944 : to_char_type('F'));
12945 }
12946 break;
12947 }
12948
12949 case value_t::number_integer:
12950 {
12951 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
12952 break;
12953 }
12954
12955 case value_t::number_unsigned:
12956 {
12957 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
12958 break;
12959 }
12960
12961 case value_t::number_float:
12962 {
12963 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
12964 break;
12965 }
12966
12967 case value_t::string:
12968 {
12969 if (add_prefix)
12970 {
12971 oa->write_character(to_char_type('S'));
12972 }
12973 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
12974 oa->write_characters(
12975 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
12976 j.m_value.string->size());
12977 break;
12978 }
12979
12980 case value_t::array:
12981 {
12982 if (add_prefix)
12983 {
12984 oa->write_character(to_char_type('['));
12985 }
12986
12987 bool prefix_required = true;
12988 if (use_type and not j.m_value.array->empty())
12989 {
12990 assert(use_count);
12991 const CharType first_prefix = ubjson_prefix(j.front());
12992 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
12993 [this, first_prefix](const BasicJsonType & v)
12994 {
12995 return ubjson_prefix(v) == first_prefix;
12996 });
12997
12998 if (same_prefix)
12999 {
13000 prefix_required = false;
13001 oa->write_character(to_char_type('$'));
13002 oa->write_character(first_prefix);
13003 }
13004 }
13005
13006 if (use_count)
13007 {
13008 oa->write_character(to_char_type('#'));
13009 write_number_with_ubjson_prefix(j.m_value.array->size(), true);
13010 }
13011
13012 for (const auto& el : *j.m_value.array)
13013 {
13014 write_ubjson(el, use_count, use_type, prefix_required);
13015 }
13016
13017 if (not use_count)
13018 {
13019 oa->write_character(to_char_type(']'));
13020 }
13021
13022 break;
13023 }
13024
13025 case value_t::binary:
13026 {
13027 if (add_prefix)
13028 {
13029 oa->write_character(to_char_type('['));
13030 }
13031
13032 if (use_type and not j.m_value.binary->empty())
13033 {
13034 assert(use_count);
13035 oa->write_character(to_char_type('$'));
13036 oa->write_character('U');
13037 }
13038
13039 if (use_count)
13040 {
13041 oa->write_character(to_char_type('#'));
13042 write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
13043 }
13044
13045 if (use_type)
13046 {
13047 oa->write_characters(
13048 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13049 j.m_value.binary->size());
13050 }
13051 else
13052 {
13053 for (size_t i = 0; i < j.m_value.binary->size(); ++i)
13054 {
13055 oa->write_character(to_char_type('U'));
13056 oa->write_character(j.m_value.binary->data()[i]);
13057 }
13058 }
13059
13060 if (not use_count)
13061 {
13062 oa->write_character(to_char_type(']'));
13063 }
13064
13065 break;
13066 }
13067
13068 case value_t::object:
13069 {
13070 if (add_prefix)
13071 {
13072 oa->write_character(to_char_type('{'));
13073 }
13074
13075 bool prefix_required = true;
13076 if (use_type and not j.m_value.object->empty())
13077 {
13078 assert(use_count);
13079 const CharType first_prefix = ubjson_prefix(j.front());
13080 const bool same_prefix = std::all_of(j.begin(), j.end(),
13081 [this, first_prefix](const BasicJsonType & v)
13082 {
13083 return ubjson_prefix(v) == first_prefix;
13084 });
13085
13086 if (same_prefix)
13087 {
13088 prefix_required = false;
13089 oa->write_character(to_char_type('$'));
13090 oa->write_character(first_prefix);
13091 }
13092 }
13093
13094 if (use_count)
13095 {
13096 oa->write_character(to_char_type('#'));
13097 write_number_with_ubjson_prefix(j.m_value.object->size(), true);
13098 }
13099
13100 for (const auto& el : *j.m_value.object)
13101 {
13102 write_number_with_ubjson_prefix(el.first.size(), true);
13103 oa->write_characters(
13104 reinterpret_cast<const CharType*>(el.first.c_str()),
13105 el.first.size());
13106 write_ubjson(el.second, use_count, use_type, prefix_required);
13107 }
13108
13109 if (not use_count)
13110 {
13111 oa->write_character(to_char_type('}'));
13112 }
13113
13114 break;
13115 }
13116
13117 default:
13118 break;
13119 }
13120 }
13121
13122 private:
13124 // BSON //
13126
13131 static std::size_t calc_bson_entry_header_size(const string_t& name)
13132 {
13133 const auto it = name.find(static_cast<typename string_t::value_type>(0));
13134 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
13135 {
13136 JSON_THROW(out_of_range::create(409,
13137 "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
13138 }
13139
13140 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
13141 }
13142
13146 void write_bson_entry_header(const string_t& name,
13147 const std::uint8_t element_type)
13148 {
13149 oa->write_character(to_char_type(element_type)); // boolean
13150 oa->write_characters(
13151 reinterpret_cast<const CharType*>(name.c_str()),
13152 name.size() + 1u);
13153 }
13154
13158 void write_bson_boolean(const string_t& name,
13159 const bool value)
13160 {
13161 write_bson_entry_header(name, 0x08);
13162 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
13163 }
13164
13168 void write_bson_double(const string_t& name,
13169 const double value)
13170 {
13171 write_bson_entry_header(name, 0x01);
13172 write_number<double, true>(value);
13173 }
13174
13178 static std::size_t calc_bson_string_size(const string_t& value)
13179 {
13180 return sizeof(std::int32_t) + value.size() + 1ul;
13181 }
13182
13186 void write_bson_string(const string_t& name,
13187 const string_t& value)
13188 {
13189 write_bson_entry_header(name, 0x02);
13190
13191 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
13192 oa->write_characters(
13193 reinterpret_cast<const CharType*>(value.c_str()),
13194 value.size() + 1);
13195 }
13196
13200 void write_bson_null(const string_t& name)
13201 {
13202 write_bson_entry_header(name, 0x0A);
13203 }
13204
13208 static std::size_t calc_bson_integer_size(const std::int64_t value)
13209 {
13210 return (std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)()
13211 ? sizeof(std::int32_t)
13212 : sizeof(std::int64_t);
13213 }
13214
13218 void write_bson_integer(const string_t& name,
13219 const std::int64_t value)
13220 {
13221 if ((std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)())
13222 {
13223 write_bson_entry_header(name, 0x10); // int32
13224 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
13225 }
13226 else
13227 {
13228 write_bson_entry_header(name, 0x12); // int64
13229 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
13230 }
13231 }
13232
13236 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
13237 {
13238 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13239 ? sizeof(std::int32_t)
13240 : sizeof(std::int64_t);
13241 }
13242
13246 void write_bson_unsigned(const string_t& name,
13247 const std::uint64_t value)
13248 {
13249 if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13250 {
13251 write_bson_entry_header(name, 0x10 /* int32 */);
13252 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
13253 }
13254 else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
13255 {
13256 write_bson_entry_header(name, 0x12 /* int64 */);
13257 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
13258 }
13259 else
13260 {
13261 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
13262 }
13263 }
13264
13268 void write_bson_object_entry(const string_t& name,
13269 const typename BasicJsonType::object_t& value)
13270 {
13271 write_bson_entry_header(name, 0x03); // object
13272 write_bson_object(value);
13273 }
13274
13278 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
13279 {
13280 std::size_t array_index = 0ul;
13281
13282 const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
13283 {
13284 return result + calc_bson_element_size(std::to_string(array_index++), el);
13285 });
13286
13287 return sizeof(std::int32_t) + embedded_document_size + 1ul;
13288 }
13289
13293 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
13294 {
13295 return sizeof(std::int32_t) + value.size() + 1ul;
13296 }
13297
13301 void write_bson_array(const string_t& name,
13302 const typename BasicJsonType::array_t& value)
13303 {
13304 write_bson_entry_header(name, 0x04); // array
13305 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
13306
13307 std::size_t array_index = 0ul;
13308
13309 for (const auto& el : value)
13310 {
13311 write_bson_element(std::to_string(array_index++), el);
13312 }
13313
13314 oa->write_character(to_char_type(0x00));
13315 }
13316
13320 void write_bson_binary(const string_t& name,
13321 const binary_t& value)
13322 {
13323 write_bson_entry_header(name, 0x05);
13324
13325 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
13326 write_number(value.has_subtype() ? value.subtype() : std::uint8_t(0x00));
13327
13328 oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
13329 }
13330
13335 static std::size_t calc_bson_element_size(const string_t& name,
13336 const BasicJsonType& j)
13337 {
13338 const auto header_size = calc_bson_entry_header_size(name);
13339 switch (j.type())
13340 {
13341 case value_t::object:
13342 return header_size + calc_bson_object_size(*j.m_value.object);
13343
13344 case value_t::array:
13345 return header_size + calc_bson_array_size(*j.m_value.array);
13346
13347 case value_t::binary:
13348 return header_size + calc_bson_binary_size(*j.m_value.binary);
13349
13350 case value_t::boolean:
13351 return header_size + 1ul;
13352
13353 case value_t::number_float:
13354 return header_size + 8ul;
13355
13356 case value_t::number_integer:
13357 return header_size + calc_bson_integer_size(j.m_value.number_integer);
13358
13359 case value_t::number_unsigned:
13360 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
13361
13362 case value_t::string:
13363 return header_size + calc_bson_string_size(*j.m_value.string);
13364
13365 case value_t::null:
13366 return header_size + 0ul;
13367
13368 // LCOV_EXCL_START
13369 default:
13370 assert(false);
13371 return 0ul;
13372 // LCOV_EXCL_STOP
13373 }
13374 }
13375
13383 void write_bson_element(const string_t& name,
13384 const BasicJsonType& j)
13385 {
13386 switch (j.type())
13387 {
13388 case value_t::object:
13389 return write_bson_object_entry(name, *j.m_value.object);
13390
13391 case value_t::array:
13392 return write_bson_array(name, *j.m_value.array);
13393
13394 case value_t::binary:
13395 return write_bson_binary(name, *j.m_value.binary);
13396
13397 case value_t::boolean:
13398 return write_bson_boolean(name, j.m_value.boolean);
13399
13400 case value_t::number_float:
13401 return write_bson_double(name, j.m_value.number_float);
13402
13403 case value_t::number_integer:
13404 return write_bson_integer(name, j.m_value.number_integer);
13405
13406 case value_t::number_unsigned:
13407 return write_bson_unsigned(name, j.m_value.number_unsigned);
13408
13409 case value_t::string:
13410 return write_bson_string(name, *j.m_value.string);
13411
13412 case value_t::null:
13413 return write_bson_null(name);
13414
13415 // LCOV_EXCL_START
13416 default:
13417 assert(false);
13418 return;
13419 // LCOV_EXCL_STOP
13420 }
13421 }
13422
13429 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
13430 {
13431 std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
13432 [](size_t result, const typename BasicJsonType::object_t::value_type & el)
13433 {
13434 return result += calc_bson_element_size(el.first, el.second);
13435 });
13436
13437 return sizeof(std::int32_t) + document_size + 1ul;
13438 }
13439
13444 void write_bson_object(const typename BasicJsonType::object_t& value)
13445 {
13446 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
13447
13448 for (const auto& el : value)
13449 {
13450 write_bson_element(el.first, el.second);
13451 }
13452
13453 oa->write_character(to_char_type(0x00));
13454 }
13455
13457 // CBOR //
13459
13460 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
13461 {
13462 return to_char_type(0xFA); // Single-Precision Float
13463 }
13464
13465 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
13466 {
13467 return to_char_type(0xFB); // Double-Precision Float
13468 }
13469
13471 // MsgPack //
13473
13474 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
13475 {
13476 return to_char_type(0xCA); // float 32
13477 }
13478
13479 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
13480 {
13481 return to_char_type(0xCB); // float 64
13482 }
13483
13485 // UBJSON //
13487
13488 // UBJSON: write number (floating point)
13489 template<typename NumberType, typename std::enable_if<
13490 std::is_floating_point<NumberType>::value, int>::type = 0>
13491 void write_number_with_ubjson_prefix(const NumberType n,
13492 const bool add_prefix)
13493 {
13494 if (add_prefix)
13495 {
13496 oa->write_character(get_ubjson_float_prefix(n));
13497 }
13498 write_number(n);
13499 }
13500
13501 // UBJSON: write number (unsigned integer)
13502 template<typename NumberType, typename std::enable_if<
13503 std::is_unsigned<NumberType>::value, int>::type = 0>
13504 void write_number_with_ubjson_prefix(const NumberType n,
13505 const bool add_prefix)
13506 {
13507 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
13508 {
13509 if (add_prefix)
13510 {
13511 oa->write_character(to_char_type('i')); // int8
13512 }
13513 write_number(static_cast<std::uint8_t>(n));
13514 }
13515 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
13516 {
13517 if (add_prefix)
13518 {
13519 oa->write_character(to_char_type('U')); // uint8
13520 }
13521 write_number(static_cast<std::uint8_t>(n));
13522 }
13523 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
13524 {
13525 if (add_prefix)
13526 {
13527 oa->write_character(to_char_type('I')); // int16
13528 }
13529 write_number(static_cast<std::int16_t>(n));
13530 }
13531 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13532 {
13533 if (add_prefix)
13534 {
13535 oa->write_character(to_char_type('l')); // int32
13536 }
13537 write_number(static_cast<std::int32_t>(n));
13538 }
13539 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
13540 {
13541 if (add_prefix)
13542 {
13543 oa->write_character(to_char_type('L')); // int64
13544 }
13545 write_number(static_cast<std::int64_t>(n));
13546 }
13547 else
13548 {
13549 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
13550 }
13551 }
13552
13553 // UBJSON: write number (signed integer)
13554 template<typename NumberType, typename std::enable_if<
13555 std::is_signed<NumberType>::value and
13556 not std::is_floating_point<NumberType>::value, int>::type = 0>
13557 void write_number_with_ubjson_prefix(const NumberType n,
13558 const bool add_prefix)
13559 {
13560 if ((std::numeric_limits<std::int8_t>::min)() <= n and n <= (std::numeric_limits<std::int8_t>::max)())
13561 {
13562 if (add_prefix)
13563 {
13564 oa->write_character(to_char_type('i')); // int8
13565 }
13566 write_number(static_cast<std::int8_t>(n));
13567 }
13568 else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n and n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
13569 {
13570 if (add_prefix)
13571 {
13572 oa->write_character(to_char_type('U')); // uint8
13573 }
13574 write_number(static_cast<std::uint8_t>(n));
13575 }
13576 else if ((std::numeric_limits<std::int16_t>::min)() <= n and n <= (std::numeric_limits<std::int16_t>::max)())
13577 {
13578 if (add_prefix)
13579 {
13580 oa->write_character(to_char_type('I')); // int16
13581 }
13582 write_number(static_cast<std::int16_t>(n));
13583 }
13584 else if ((std::numeric_limits<std::int32_t>::min)() <= n and n <= (std::numeric_limits<std::int32_t>::max)())
13585 {
13586 if (add_prefix)
13587 {
13588 oa->write_character(to_char_type('l')); // int32
13589 }
13590 write_number(static_cast<std::int32_t>(n));
13591 }
13592 else if ((std::numeric_limits<std::int64_t>::min)() <= n and n <= (std::numeric_limits<std::int64_t>::max)())
13593 {
13594 if (add_prefix)
13595 {
13596 oa->write_character(to_char_type('L')); // int64
13597 }
13598 write_number(static_cast<std::int64_t>(n));
13599 }
13600 // LCOV_EXCL_START
13601 else
13602 {
13603 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
13604 }
13605 // LCOV_EXCL_STOP
13606 }
13607
13617 CharType ubjson_prefix(const BasicJsonType& j) const noexcept
13618 {
13619 switch (j.type())
13620 {
13621 case value_t::null:
13622 return 'Z';
13623
13624 case value_t::boolean:
13625 return j.m_value.boolean ? 'T' : 'F';
13626
13627 case value_t::number_integer:
13628 {
13629 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
13630 {
13631 return 'i';
13632 }
13633 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
13634 {
13635 return 'U';
13636 }
13637 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
13638 {
13639 return 'I';
13640 }
13641 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
13642 {
13643 return 'l';
13644 }
13645 // no check and assume int64_t (see note above)
13646 return 'L';
13647 }
13648
13649 case value_t::number_unsigned:
13650 {
13651 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
13652 {
13653 return 'i';
13654 }
13655 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
13656 {
13657 return 'U';
13658 }
13659 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
13660 {
13661 return 'I';
13662 }
13663 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13664 {
13665 return 'l';
13666 }
13667 // no check and assume int64_t (see note above)
13668 return 'L';
13669 }
13670
13671 case value_t::number_float:
13672 return get_ubjson_float_prefix(j.m_value.number_float);
13673
13674 case value_t::string:
13675 return 'S';
13676
13677 case value_t::array: // fallthrough
13678 case value_t::binary:
13679 return '[';
13680
13681 case value_t::object:
13682 return '{';
13683
13684 default: // discarded values
13685 return 'N';
13686 }
13687 }
13688
13689 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
13690 {
13691 return 'd'; // float 32
13692 }
13693
13694 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
13695 {
13696 return 'D'; // float 64
13697 }
13698
13700 // Utility functions //
13702
13703 /*
13704 @brief write a number to output input
13705 @param[in] n number of type @a NumberType
13706 @tparam NumberType the type of the number
13707 @tparam OutputIsLittleEndian Set to true if output data is
13708 required to be little endian
13709
13710 @note This function needs to respect the system's endianess, because bytes
13711 in CBOR, MessagePack, and UBJSON are stored in network order (big
13712 endian) and therefore need reordering on little endian systems.
13713 */
13714 template<typename NumberType, bool OutputIsLittleEndian = false>
13715 void write_number(const NumberType n)
13716 {
13717 // step 1: write number to array of length NumberType
13718 std::array<CharType, sizeof(NumberType)> vec;
13719 std::memcpy(vec.data(), &n, sizeof(NumberType));
13720
13721 // step 2: write array to output (with possible reordering)
13722 if (is_little_endian != OutputIsLittleEndian)
13723 {
13724 // reverse byte order prior to conversion if necessary
13725 std::reverse(vec.begin(), vec.end());
13726 }
13727
13728 oa->write_characters(vec.data(), sizeof(NumberType));
13729 }
13730
13731 public:
13732 // The following to_char_type functions are implement the conversion
13733 // between uint8_t and CharType. In case CharType is not unsigned,
13734 // such a conversion is required to allow values greater than 128.
13735 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
13736 template < typename C = CharType,
13737 enable_if_t < std::is_signed<C>::value and std::is_signed<char>::value > * = nullptr >
13738 static constexpr CharType to_char_type(std::uint8_t x) noexcept
13739 {
13740 return *reinterpret_cast<char*>(&x);
13741 }
13742
13743 template < typename C = CharType,
13744 enable_if_t < std::is_signed<C>::value and std::is_unsigned<char>::value > * = nullptr >
13745 static CharType to_char_type(std::uint8_t x) noexcept
13746 {
13747 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
13748 static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
13749 CharType result;
13750 std::memcpy(&result, &x, sizeof(x));
13751 return result;
13752 }
13753
13754 template<typename C = CharType,
13755 enable_if_t<std::is_unsigned<C>::value>* = nullptr>
13756 static constexpr CharType to_char_type(std::uint8_t x) noexcept
13757 {
13758 return x;
13759 }
13760
13761 template < typename InputCharType, typename C = CharType,
13762 enable_if_t <
13763 std::is_signed<C>::value and
13764 std::is_signed<char>::value and
13765 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
13766 > * = nullptr >
13767 static constexpr CharType to_char_type(InputCharType x) noexcept
13768 {
13769 return x;
13770 }
13771
13772 private:
13774 const bool is_little_endian = little_endianess();
13775
13777 output_adapter_t<CharType> oa = nullptr;
13778 };
13779 } // namespace detail
13780 } // namespace nlohmann
13781
13782 // #include <nlohmann/detail/output/output_adapters.hpp>
13783
13784 // #include <nlohmann/detail/output/serializer.hpp>
13785
13786
13787 #include <algorithm> // reverse, remove, fill, find, none_of
13788 #include <array> // array
13789 #include <cassert> // assert
13790 #include <clocale> // localeconv, lconv
13791 #include <cmath> // labs, isfinite, isnan, signbit
13792 #include <cstddef> // size_t, ptrdiff_t
13793 #include <cstdint> // uint8_t
13794 #include <cstdio> // snprintf
13795 #include <limits> // numeric_limits
13796 #include <string> // string
13797 #include <type_traits> // is_same
13798 #include <utility> // move
13799
13800 // #include <nlohmann/detail/boolean_operators.hpp>
13801
13802 // #include <nlohmann/detail/conversions/to_chars.hpp>
13803
13804
13805 #include <array> // array
13806 #include <cassert> // assert
13807 #include <cmath> // signbit, isfinite
13808 #include <cstdint> // intN_t, uintN_t
13809 #include <cstring> // memcpy, memmove
13810 #include <limits> // numeric_limits
13811 #include <type_traits> // conditional
13812
13813 // #include <nlohmann/detail/boolean_operators.hpp>
13814
13815 // #include <nlohmann/detail/macro_scope.hpp>
13816
13817
13818 namespace nlohmann
13819 {
13820 namespace detail
13821 {
13822
13842 namespace dtoa_impl
13843 {
13844
13845 template <typename Target, typename Source>
13846 Target reinterpret_bits(const Source source)
13847 {
13848 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
13849
13850 Target target;
13851 std::memcpy(&target, &source, sizeof(Source));
13852 return target;
13853 }
13854
13855 struct diyfp // f * 2^e
13856 {
13857 static constexpr int kPrecision = 64; // = q
13858
13859 std::uint64_t f = 0;
13860 int e = 0;
13861
13862 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
13863
13868 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
13869 {
13870 assert(x.e == y.e);
13871 assert(x.f >= y.f);
13872
13873 return {x.f - y.f, x.e};
13874 }
13875
13880 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
13881 {
13882 static_assert(kPrecision == 64, "internal error");
13883
13884 // Computes:
13885 // f = round((x.f * y.f) / 2^q)
13886 // e = x.e + y.e + q
13887
13888 // Emulate the 64-bit * 64-bit multiplication:
13889 //
13890 // p = u * v
13891 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
13892 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
13893 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
13894 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
13895 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
13896 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
13897 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
13898 //
13899 // (Since Q might be larger than 2^32 - 1)
13900 //
13901 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
13902 //
13903 // (Q_hi + H does not overflow a 64-bit int)
13904 //
13905 // = p_lo + 2^64 p_hi
13906
13907 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
13908 const std::uint64_t u_hi = x.f >> 32u;
13909 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
13910 const std::uint64_t v_hi = y.f >> 32u;
13911
13912 const std::uint64_t p0 = u_lo * v_lo;
13913 const std::uint64_t p1 = u_lo * v_hi;
13914 const std::uint64_t p2 = u_hi * v_lo;
13915 const std::uint64_t p3 = u_hi * v_hi;
13916
13917 const std::uint64_t p0_hi = p0 >> 32u;
13918 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
13919 const std::uint64_t p1_hi = p1 >> 32u;
13920 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
13921 const std::uint64_t p2_hi = p2 >> 32u;
13922
13923 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
13924
13925 // The full product might now be computed as
13926 //
13927 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
13928 // p_lo = p0_lo + (Q << 32)
13929 //
13930 // But in this particular case here, the full p_lo is not required.
13931 // Effectively we only need to add the highest bit in p_lo to p_hi (and
13932 // Q_hi + 1 does not overflow).
13933
13934 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
13935
13936 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
13937
13938 return {h, x.e + y.e + 64};
13939 }
13940
13945 static diyfp normalize(diyfp x) noexcept
13946 {
13947 assert(x.f != 0);
13948
13949 while ((x.f >> 63u) == 0)
13950 {
13951 x.f <<= 1u;
13952 x.e--;
13953 }
13954
13955 return x;
13956 }
13957
13962 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
13963 {
13964 const int delta = x.e - target_exponent;
13965
13966 assert(delta >= 0);
13967 assert(((x.f << delta) >> delta) == x.f);
13968
13969 return {x.f << delta, target_exponent};
13970 }
13971 };
13972
13973 struct boundaries
13974 {
13975 diyfp w;
13976 diyfp minus;
13977 diyfp plus;
13978 };
13979
13986 template <typename FloatType>
13987 boundaries compute_boundaries(FloatType value)
13988 {
13989 assert(std::isfinite(value));
13990 assert(value > 0);
13991
13992 // Convert the IEEE representation into a diyfp.
13993 //
13994 // If v is denormal:
13995 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
13996 // If v is normalized:
13997 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
13998
13999 static_assert(std::numeric_limits<FloatType>::is_iec559,
14000 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
14001
14002 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
14003 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
14004 constexpr int kMinExp = 1 - kBias;
14005 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
14006
14007 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
14008
14009 const std::uint64_t bits = reinterpret_bits<bits_type>(value);
14010 const std::uint64_t E = bits >> (kPrecision - 1);
14011 const std::uint64_t F = bits & (kHiddenBit - 1);
14012
14013 const bool is_denormal = E == 0;
14014 const diyfp v = is_denormal
14015 ? diyfp(F, kMinExp)
14016 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
14017
14018 // Compute the boundaries m- and m+ of the floating-point value
14019 // v = f * 2^e.
14020 //
14021 // Determine v- and v+, the floating-point predecessor and successor if v,
14022 // respectively.
14023 //
14024 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
14025 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
14026 //
14027 // v+ = v + 2^e
14028 //
14029 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
14030 // between m- and m+ round to v, regardless of how the input rounding
14031 // algorithm breaks ties.
14032 //
14033 // ---+-------------+-------------+-------------+-------------+--- (A)
14034 // v- m- v m+ v+
14035 //
14036 // -----------------+------+------+-------------+-------------+--- (B)
14037 // v- m- v m+ v+
14038
14039 const bool lower_boundary_is_closer = F == 0 and E > 1;
14040 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
14041 const diyfp m_minus = lower_boundary_is_closer
14042 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
14043 : diyfp(2 * v.f - 1, v.e - 1); // (A)
14044
14045 // Determine the normalized w+ = m+.
14046 const diyfp w_plus = diyfp::normalize(m_plus);
14047
14048 // Determine w- = m- such that e_(w-) = e_(w+).
14049 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
14050
14051 return {diyfp::normalize(v), w_minus, w_plus};
14052 }
14053
14054 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
14055 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
14056 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
14057 //
14058 // alpha <= e = e_c + e_w + q <= gamma
14059 //
14060 // or
14061 //
14062 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
14063 // <= f_c * f_w * 2^gamma
14064 //
14065 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
14066 //
14067 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
14068 //
14069 // or
14070 //
14071 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
14072 //
14073 // The choice of (alpha,gamma) determines the size of the table and the form of
14074 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
14075 // in practice:
14076 //
14077 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
14078 // processed independently: An integral part p1, and a fractional part p2:
14079 //
14080 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
14081 // = (f div 2^-e) + (f mod 2^-e) * 2^e
14082 // = p1 + p2 * 2^e
14083 //
14084 // The conversion of p1 into decimal form requires a series of divisions and
14085 // modulos by (a power of) 10. These operations are faster for 32-bit than for
14086 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
14087 // achieved by choosing
14088 //
14089 // -e >= 32 or e <= -32 := gamma
14090 //
14091 // In order to convert the fractional part
14092 //
14093 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
14094 //
14095 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
14096 // d[-i] are extracted in order:
14097 //
14098 // (10 * p2) div 2^-e = d[-1]
14099 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
14100 //
14101 // The multiplication by 10 must not overflow. It is sufficient to choose
14102 //
14103 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
14104 //
14105 // Since p2 = f mod 2^-e < 2^-e,
14106 //
14107 // -e <= 60 or e >= -60 := alpha
14108
14109 constexpr int kAlpha = -60;
14110 constexpr int kGamma = -32;
14111
14112 struct cached_power // c = f * 2^e ~= 10^k
14113 {
14114 std::uint64_t f;
14115 int e;
14116 int k;
14117 };
14118
14126 inline cached_power get_cached_power_for_binary_exponent(int e)
14127 {
14128 // Now
14129 //
14130 // alpha <= e_c + e + q <= gamma (1)
14131 // ==> f_c * 2^alpha <= c * 2^e * 2^q
14132 //
14133 // and since the c's are normalized, 2^(q-1) <= f_c,
14134 //
14135 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
14136 // ==> 2^(alpha - e - 1) <= c
14137 //
14138 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
14139 //
14140 // k = ceil( log_10( 2^(alpha - e - 1) ) )
14141 // = ceil( (alpha - e - 1) * log_10(2) )
14142 //
14143 // From the paper:
14144 // "In theory the result of the procedure could be wrong since c is rounded,
14145 // and the computation itself is approximated [...]. In practice, however,
14146 // this simple function is sufficient."
14147 //
14148 // For IEEE double precision floating-point numbers converted into
14149 // normalized diyfp's w = f * 2^e, with q = 64,
14150 //
14151 // e >= -1022 (min IEEE exponent)
14152 // -52 (p - 1)
14153 // -52 (p - 1, possibly normalize denormal IEEE numbers)
14154 // -11 (normalize the diyfp)
14155 // = -1137
14156 //
14157 // and
14158 //
14159 // e <= +1023 (max IEEE exponent)
14160 // -52 (p - 1)
14161 // -11 (normalize the diyfp)
14162 // = 960
14163 //
14164 // This binary exponent range [-1137,960] results in a decimal exponent
14165 // range [-307,324]. One does not need to store a cached power for each
14166 // k in this range. For each such k it suffices to find a cached power
14167 // such that the exponent of the product lies in [alpha,gamma].
14168 // This implies that the difference of the decimal exponents of adjacent
14169 // table entries must be less than or equal to
14170 //
14171 // floor( (gamma - alpha) * log_10(2) ) = 8.
14172 //
14173 // (A smaller distance gamma-alpha would require a larger table.)
14174
14175 // NB:
14176 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
14177
14178 constexpr int kCachedPowersMinDecExp = -300;
14179 constexpr int kCachedPowersDecStep = 8;
14180
14181 static constexpr std::array<cached_power, 79> kCachedPowers =
14182 {
14183 {
14184 { 0xAB70FE17C79AC6CA, -1060, -300 },
14185 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
14186 { 0xBE5691EF416BD60C, -1007, -284 },
14187 { 0x8DD01FAD907FFC3C, -980, -276 },
14188 { 0xD3515C2831559A83, -954, -268 },
14189 { 0x9D71AC8FADA6C9B5, -927, -260 },
14190 { 0xEA9C227723EE8BCB, -901, -252 },
14191 { 0xAECC49914078536D, -874, -244 },
14192 { 0x823C12795DB6CE57, -847, -236 },
14193 { 0xC21094364DFB5637, -821, -228 },
14194 { 0x9096EA6F3848984F, -794, -220 },
14195 { 0xD77485CB25823AC7, -768, -212 },
14196 { 0xA086CFCD97BF97F4, -741, -204 },
14197 { 0xEF340A98172AACE5, -715, -196 },
14198 { 0xB23867FB2A35B28E, -688, -188 },
14199 { 0x84C8D4DFD2C63F3B, -661, -180 },
14200 { 0xC5DD44271AD3CDBA, -635, -172 },
14201 { 0x936B9FCEBB25C996, -608, -164 },
14202 { 0xDBAC6C247D62A584, -582, -156 },
14203 { 0xA3AB66580D5FDAF6, -555, -148 },
14204 { 0xF3E2F893DEC3F126, -529, -140 },
14205 { 0xB5B5ADA8AAFF80B8, -502, -132 },
14206 { 0x87625F056C7C4A8B, -475, -124 },
14207 { 0xC9BCFF6034C13053, -449, -116 },
14208 { 0x964E858C91BA2655, -422, -108 },
14209 { 0xDFF9772470297EBD, -396, -100 },
14210 { 0xA6DFBD9FB8E5B88F, -369, -92 },
14211 { 0xF8A95FCF88747D94, -343, -84 },
14212 { 0xB94470938FA89BCF, -316, -76 },
14213 { 0x8A08F0F8BF0F156B, -289, -68 },
14214 { 0xCDB02555653131B6, -263, -60 },
14215 { 0x993FE2C6D07B7FAC, -236, -52 },
14216 { 0xE45C10C42A2B3B06, -210, -44 },
14217 { 0xAA242499697392D3, -183, -36 },
14218 { 0xFD87B5F28300CA0E, -157, -28 },
14219 { 0xBCE5086492111AEB, -130, -20 },
14220 { 0x8CBCCC096F5088CC, -103, -12 },
14221 { 0xD1B71758E219652C, -77, -4 },
14222 { 0x9C40000000000000, -50, 4 },
14223 { 0xE8D4A51000000000, -24, 12 },
14224 { 0xAD78EBC5AC620000, 3, 20 },
14225 { 0x813F3978F8940984, 30, 28 },
14226 { 0xC097CE7BC90715B3, 56, 36 },
14227 { 0x8F7E32CE7BEA5C70, 83, 44 },
14228 { 0xD5D238A4ABE98068, 109, 52 },
14229 { 0x9F4F2726179A2245, 136, 60 },
14230 { 0xED63A231D4C4FB27, 162, 68 },
14231 { 0xB0DE65388CC8ADA8, 189, 76 },
14232 { 0x83C7088E1AAB65DB, 216, 84 },
14233 { 0xC45D1DF942711D9A, 242, 92 },
14234 { 0x924D692CA61BE758, 269, 100 },
14235 { 0xDA01EE641A708DEA, 295, 108 },
14236 { 0xA26DA3999AEF774A, 322, 116 },
14237 { 0xF209787BB47D6B85, 348, 124 },
14238 { 0xB454E4A179DD1877, 375, 132 },
14239 { 0x865B86925B9BC5C2, 402, 140 },
14240 { 0xC83553C5C8965D3D, 428, 148 },
14241 { 0x952AB45CFA97A0B3, 455, 156 },
14242 { 0xDE469FBD99A05FE3, 481, 164 },
14243 { 0xA59BC234DB398C25, 508, 172 },
14244 { 0xF6C69A72A3989F5C, 534, 180 },
14245 { 0xB7DCBF5354E9BECE, 561, 188 },
14246 { 0x88FCF317F22241E2, 588, 196 },
14247 { 0xCC20CE9BD35C78A5, 614, 204 },
14248 { 0x98165AF37B2153DF, 641, 212 },
14249 { 0xE2A0B5DC971F303A, 667, 220 },
14250 { 0xA8D9D1535CE3B396, 694, 228 },
14251 { 0xFB9B7CD9A4A7443C, 720, 236 },
14252 { 0xBB764C4CA7A44410, 747, 244 },
14253 { 0x8BAB8EEFB6409C1A, 774, 252 },
14254 { 0xD01FEF10A657842C, 800, 260 },
14255 { 0x9B10A4E5E9913129, 827, 268 },
14256 { 0xE7109BFBA19C0C9D, 853, 276 },
14257 { 0xAC2820D9623BF429, 880, 284 },
14258 { 0x80444B5E7AA7CF85, 907, 292 },
14259 { 0xBF21E44003ACDD2D, 933, 300 },
14260 { 0x8E679C2F5E44FF8F, 960, 308 },
14261 { 0xD433179D9C8CB841, 986, 316 },
14262 { 0x9E19DB92B4E31BA9, 1013, 324 },
14263 }
14264 };
14265
14266 // This computation gives exactly the same results for k as
14267 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
14268 // for |e| <= 1500, but doesn't require floating-point operations.
14269 // NB: log_10(2) ~= 78913 / 2^18
14270 assert(e >= -1500);
14271 assert(e <= 1500);
14272 const int f = kAlpha - e - 1;
14273 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
14274
14275 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
14276 assert(index >= 0);
14277 assert(static_cast<std::size_t>(index) < kCachedPowers.size());
14278
14279 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
14280 assert(kAlpha <= cached.e + e + 64);
14281 assert(kGamma >= cached.e + e + 64);
14282
14283 return cached;
14284 }
14285
14290 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
14291 {
14292 // LCOV_EXCL_START
14293 if (n >= 1000000000)
14294 {
14295 pow10 = 1000000000;
14296 return 10;
14297 }
14298 // LCOV_EXCL_STOP
14299 else if (n >= 100000000)
14300 {
14301 pow10 = 100000000;
14302 return 9;
14303 }
14304 else if (n >= 10000000)
14305 {
14306 pow10 = 10000000;
14307 return 8;
14308 }
14309 else if (n >= 1000000)
14310 {
14311 pow10 = 1000000;
14312 return 7;
14313 }
14314 else if (n >= 100000)
14315 {
14316 pow10 = 100000;
14317 return 6;
14318 }
14319 else if (n >= 10000)
14320 {
14321 pow10 = 10000;
14322 return 5;
14323 }
14324 else if (n >= 1000)
14325 {
14326 pow10 = 1000;
14327 return 4;
14328 }
14329 else if (n >= 100)
14330 {
14331 pow10 = 100;
14332 return 3;
14333 }
14334 else if (n >= 10)
14335 {
14336 pow10 = 10;
14337 return 2;
14338 }
14339 else
14340 {
14341 pow10 = 1;
14342 return 1;
14343 }
14344 }
14345
14346 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
14347 std::uint64_t rest, std::uint64_t ten_k)
14348 {
14349 assert(len >= 1);
14350 assert(dist <= delta);
14351 assert(rest <= delta);
14352 assert(ten_k > 0);
14353
14354 // <--------------------------- delta ---->
14355 // <---- dist --------->
14356 // --------------[------------------+-------------------]--------------
14357 // M- w M+
14358 //
14359 // ten_k
14360 // <------>
14361 // <---- rest ---->
14362 // --------------[------------------+----+--------------]--------------
14363 // w V
14364 // = buf * 10^k
14365 //
14366 // ten_k represents a unit-in-the-last-place in the decimal representation
14367 // stored in buf.
14368 // Decrement buf by ten_k while this takes buf closer to w.
14369
14370 // The tests are written in this order to avoid overflow in unsigned
14371 // integer arithmetic.
14372
14373 while (rest < dist
14374 and delta - rest >= ten_k
14375 and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
14376 {
14377 assert(buf[len - 1] != '0');
14378 buf[len - 1]--;
14379 rest += ten_k;
14380 }
14381 }
14382
14387 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
14388 diyfp M_minus, diyfp w, diyfp M_plus)
14389 {
14390 static_assert(kAlpha >= -60, "internal error");
14391 static_assert(kGamma <= -32, "internal error");
14392
14393 // Generates the digits (and the exponent) of a decimal floating-point
14394 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
14395 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
14396 //
14397 // <--------------------------- delta ---->
14398 // <---- dist --------->
14399 // --------------[------------------+-------------------]--------------
14400 // M- w M+
14401 //
14402 // Grisu2 generates the digits of M+ from left to right and stops as soon as
14403 // V is in [M-,M+].
14404
14405 assert(M_plus.e >= kAlpha);
14406 assert(M_plus.e <= kGamma);
14407
14408 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
14409 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
14410
14411 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
14412 //
14413 // M+ = f * 2^e
14414 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
14415 // = ((p1 ) * 2^-e + (p2 )) * 2^e
14416 // = p1 + p2 * 2^e
14417
14418 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
14419
14420 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.)
14421 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
14422
14423 // 1)
14424 //
14425 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
14426
14427 assert(p1 > 0);
14428
14429 std::uint32_t pow10;
14430 const int k = find_largest_pow10(p1, pow10);
14431
14432 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
14433 //
14434 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
14435 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
14436 //
14437 // M+ = p1 + p2 * 2^e
14438 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
14439 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
14440 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
14441 //
14442 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
14443 //
14444 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
14445 //
14446 // but stop as soon as
14447 //
14448 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
14449
14450 int n = k;
14451 while (n > 0)
14452 {
14453 // Invariants:
14454 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
14455 // pow10 = 10^(n-1) <= p1 < 10^n
14456 //
14457 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
14458 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
14459 //
14460 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
14461 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
14462 //
14463 assert(d <= 9);
14464 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
14465 //
14466 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
14467 //
14468 p1 = r;
14469 n--;
14470 //
14471 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
14472 // pow10 = 10^n
14473 //
14474
14475 // Now check if enough digits have been generated.
14476 // Compute
14477 //
14478 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
14479 //
14480 // Note:
14481 // Since rest and delta share the same exponent e, it suffices to
14482 // compare the significands.
14483 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
14484 if (rest <= delta)
14485 {
14486 // V = buffer * 10^n, with M- <= V <= M+.
14487
14488 decimal_exponent += n;
14489
14490 // We may now just stop. But instead look if the buffer could be
14491 // decremented to bring V closer to w.
14492 //
14493 // pow10 = 10^n is now 1 ulp in the decimal representation V.
14494 // The rounding procedure works with diyfp's with an implicit
14495 // exponent of e.
14496 //
14497 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
14498 //
14499 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
14500 grisu2_round(buffer, length, dist, delta, rest, ten_n);
14501
14502 return;
14503 }
14504
14505 pow10 /= 10;
14506 //
14507 // pow10 = 10^(n-1) <= p1 < 10^n
14508 // Invariants restored.
14509 }
14510
14511 // 2)
14512 //
14513 // The digits of the integral part have been generated:
14514 //
14515 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
14516 // = buffer + p2 * 2^e
14517 //
14518 // Now generate the digits of the fractional part p2 * 2^e.
14519 //
14520 // Note:
14521 // No decimal point is generated: the exponent is adjusted instead.
14522 //
14523 // p2 actually represents the fraction
14524 //
14525 // p2 * 2^e
14526 // = p2 / 2^-e
14527 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
14528 //
14529 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
14530 //
14531 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
14532 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
14533 //
14534 // using
14535 //
14536 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
14537 // = ( d) * 2^-e + ( r)
14538 //
14539 // or
14540 // 10^m * p2 * 2^e = d + r * 2^e
14541 //
14542 // i.e.
14543 //
14544 // M+ = buffer + p2 * 2^e
14545 // = buffer + 10^-m * (d + r * 2^e)
14546 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
14547 //
14548 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
14549
14550 assert(p2 > delta);
14551
14552 int m = 0;
14553 for (;;)
14554 {
14555 // Invariant:
14556 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
14557 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
14558 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
14559 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
14560 //
14561 assert(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
14562 p2 *= 10;
14563 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
14564 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
14565 //
14566 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
14567 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
14568 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
14569 //
14570 assert(d <= 9);
14571 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
14572 //
14573 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
14574 //
14575 p2 = r;
14576 m++;
14577 //
14578 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
14579 // Invariant restored.
14580
14581 // Check if enough digits have been generated.
14582 //
14583 // 10^-m * p2 * 2^e <= delta * 2^e
14584 // p2 * 2^e <= 10^m * delta * 2^e
14585 // p2 <= 10^m * delta
14586 delta *= 10;
14587 dist *= 10;
14588 if (p2 <= delta)
14589 {
14590 break;
14591 }
14592 }
14593
14594 // V = buffer * 10^-m, with M- <= V <= M+.
14595
14596 decimal_exponent -= m;
14597
14598 // 1 ulp in the decimal representation is now 10^-m.
14599 // Since delta and dist are now scaled by 10^m, we need to do the
14600 // same with ulp in order to keep the units in sync.
14601 //
14602 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
14603 //
14604 const std::uint64_t ten_m = one.f;
14605 grisu2_round(buffer, length, dist, delta, p2, ten_m);
14606
14607 // By construction this algorithm generates the shortest possible decimal
14608 // number (Loitsch, Theorem 6.2) which rounds back to w.
14609 // For an input number of precision p, at least
14610 //
14611 // N = 1 + ceil(p * log_10(2))
14612 //
14613 // decimal digits are sufficient to identify all binary floating-point
14614 // numbers (Matula, "In-and-Out conversions").
14615 // This implies that the algorithm does not produce more than N decimal
14616 // digits.
14617 //
14618 // N = 17 for p = 53 (IEEE double precision)
14619 // N = 9 for p = 24 (IEEE single precision)
14620 }
14621
14627 JSON_HEDLEY_NON_NULL(1)
14628 inline void grisu2(char* buf, int& len, int& decimal_exponent,
14629 diyfp m_minus, diyfp v, diyfp m_plus)
14630 {
14631 assert(m_plus.e == m_minus.e);
14632 assert(m_plus.e == v.e);
14633
14634 // --------(-----------------------+-----------------------)-------- (A)
14635 // m- v m+
14636 //
14637 // --------------------(-----------+-----------------------)-------- (B)
14638 // m- v m+
14639 //
14640 // First scale v (and m- and m+) such that the exponent is in the range
14641 // [alpha, gamma].
14642
14643 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
14644
14645 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
14646
14647 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
14648 const diyfp w = diyfp::mul(v, c_minus_k);
14649 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
14650 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
14651
14652 // ----(---+---)---------------(---+---)---------------(---+---)----
14653 // w- w w+
14654 // = c*m- = c*v = c*m+
14655 //
14656 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
14657 // w+ are now off by a small amount.
14658 // In fact:
14659 //
14660 // w - v * 10^k < 1 ulp
14661 //
14662 // To account for this inaccuracy, add resp. subtract 1 ulp.
14663 //
14664 // --------+---[---------------(---+---)---------------]---+--------
14665 // w- M- w M+ w+
14666 //
14667 // Now any number in [M-, M+] (bounds included) will round to w when input,
14668 // regardless of how the input rounding algorithm breaks ties.
14669 //
14670 // And digit_gen generates the shortest possible such number in [M-, M+].
14671 // Note that this does not mean that Grisu2 always generates the shortest
14672 // possible number in the interval (m-, m+).
14673 const diyfp M_minus(w_minus.f + 1, w_minus.e);
14674 const diyfp M_plus (w_plus.f - 1, w_plus.e );
14675
14676 decimal_exponent = -cached.k; // = -(-k) = k
14677
14678 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
14679 }
14680
14686 template <typename FloatType>
14687 JSON_HEDLEY_NON_NULL(1)
14688 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
14689 {
14690 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
14691 "internal error: not enough precision");
14692
14693 assert(std::isfinite(value));
14694 assert(value > 0);
14695
14696 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
14697 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
14698 // decimal representations are not exactly "short".
14699 //
14700 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
14701 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
14702 // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
14703 // does.
14704 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
14705 // representation using the corresponding std::from_chars function recovers value exactly". That
14706 // indicates that single precision floating-point numbers should be recovered using
14707 // 'std::strtof'.
14708 //
14709 // NB: If the neighbors are computed for single-precision numbers, there is a single float
14710 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
14711 // value is off by 1 ulp.
14712 #if 0
14713 const boundaries w = compute_boundaries(static_cast<double>(value));
14714 #else
14715 const boundaries w = compute_boundaries(value);
14716 #endif
14717
14718 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
14719 }
14720
14726 JSON_HEDLEY_NON_NULL(1)
14727
14728 inline char* append_exponent(char* buf, int e)
14729 {
14730 assert(e > -1000);
14731 assert(e < 1000);
14732
14733 if (e < 0)
14734 {
14735 e = -e;
14736 *buf++ = '-';
14737 }
14738 else
14739 {
14740 *buf++ = '+';
14741 }
14742
14743 auto k = static_cast<std::uint32_t>(e);
14744 if (k < 10)
14745 {
14746 // Always print at least two digits in the exponent.
14747 // This is for compatibility with printf("%g").
14748 *buf++ = '0';
14749 *buf++ = static_cast<char>('0' + k);
14750 }
14751 else if (k < 100)
14752 {
14753 *buf++ = static_cast<char>('0' + k / 10);
14754 k %= 10;
14755 *buf++ = static_cast<char>('0' + k);
14756 }
14757 else
14758 {
14759 *buf++ = static_cast<char>('0' + k / 100);
14760 k %= 100;
14761 *buf++ = static_cast<char>('0' + k / 10);
14762 k %= 10;
14763 *buf++ = static_cast<char>('0' + k);
14764 }
14765
14766 return buf;
14767 }
14768
14778 JSON_HEDLEY_NON_NULL(1)
14779
14780 inline char* format_buffer(char* buf, int len, int decimal_exponent,
14781 int min_exp, int max_exp)
14782 {
14783 assert(min_exp < 0);
14784 assert(max_exp > 0);
14785
14786 const int k = len;
14787 const int n = len + decimal_exponent;
14788
14789 // v = buf * 10^(n-k)
14790 // k is the length of the buffer (number of decimal digits)
14791 // n is the position of the decimal point relative to the start of the buffer.
14792
14793 if (k <= n and n <= max_exp)
14794 {
14795 // digits[000]
14796 // len <= max_exp + 2
14797
14798 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
14799 // Make it look like a floating-point number (#362, #378)
14800 buf[n + 0] = '.';
14801 buf[n + 1] = '0';
14802 return buf + (static_cast<size_t>(n) + 2);
14803 }
14804
14805 if (0 < n and n <= max_exp)
14806 {
14807 // dig.its
14808 // len <= max_digits10 + 1
14809
14810 assert(k > n);
14811
14812 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
14813 buf[n] = '.';
14814 return buf + (static_cast<size_t>(k) + 1U);
14815 }
14816
14817 if (min_exp < n and n <= 0)
14818 {
14819 // 0.[000]digits
14820 // len <= 2 + (-min_exp - 1) + max_digits10
14821
14822 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
14823 buf[0] = '0';
14824 buf[1] = '.';
14825 std::memset(buf + 2, '0', static_cast<size_t>(-n));
14826 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
14827 }
14828
14829 if (k == 1)
14830 {
14831 // dE+123
14832 // len <= 1 + 5
14833
14834 buf += 1;
14835 }
14836 else
14837 {
14838 // d.igitsE+123
14839 // len <= max_digits10 + 1 + 5
14840
14841 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
14842 buf[1] = '.';
14843 buf += 1 + static_cast<size_t>(k);
14844 }
14845
14846 *buf++ = 'e';
14847 return append_exponent(buf, n - 1);
14848 }
14849
14850 } // namespace dtoa_impl
14851
14862 template <typename FloatType>
14863 JSON_HEDLEY_NON_NULL(1, 2)
14864
14865 char* to_chars(char* first, const char* last, FloatType value)
14866 {
14867 static_cast<void>(last); // maybe unused - fix warning
14868 assert(std::isfinite(value));
14869
14870 // Use signbit(value) instead of (value < 0) since signbit works for -0.
14871 if (std::signbit(value))
14872 {
14873 value = -value;
14874 *first++ = '-';
14875 }
14876
14877 if (value == 0) // +-0
14878 {
14879 *first++ = '0';
14880 // Make it look like a floating-point number (#362, #378)
14881 *first++ = '.';
14882 *first++ = '0';
14883 return first;
14884 }
14885
14886 assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
14887
14888 // Compute v = buffer * 10^decimal_exponent.
14889 // The decimal digits are stored in the buffer, which needs to be interpreted
14890 // as an unsigned decimal integer.
14891 // len is the length of the buffer, i.e. the number of decimal digits.
14892 int len = 0;
14893 int decimal_exponent = 0;
14894 dtoa_impl::grisu2(first, len, decimal_exponent, value);
14895
14896 assert(len <= std::numeric_limits<FloatType>::max_digits10);
14897
14898 // Format the buffer like printf("%.*g", prec, value)
14899 constexpr int kMinExp = -4;
14900 // Use digits10 here to increase compatibility with version 2.
14901 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
14902
14903 assert(last - first >= kMaxExp + 2);
14904 assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
14905 assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
14906
14907 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
14908 }
14909
14910 } // namespace detail
14911 } // namespace nlohmann
14912
14913 // #include <nlohmann/detail/exceptions.hpp>
14914
14915 // #include <nlohmann/detail/macro_scope.hpp>
14916
14917 // #include <nlohmann/detail/meta/cpp_future.hpp>
14918
14919 // #include <nlohmann/detail/output/binary_writer.hpp>
14920
14921 // #include <nlohmann/detail/output/output_adapters.hpp>
14922
14923 // #include <nlohmann/detail/value_t.hpp>
14924
14925
14926 namespace nlohmann
14927 {
14928 namespace detail
14929 {
14931 // serialization //
14933
14935 enum class error_handler_t
14936 {
14937 strict,
14938 replace,
14939 ignore
14940 };
14941
14942 template<typename BasicJsonType>
14943 class serializer
14944 {
14945 using string_t = typename BasicJsonType::string_t;
14946 using number_float_t = typename BasicJsonType::number_float_t;
14947 using number_integer_t = typename BasicJsonType::number_integer_t;
14948 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
14949 using binary_char_t = typename BasicJsonType::binary_t::value_type;
14950 static constexpr std::uint8_t UTF8_ACCEPT = 0;
14951 static constexpr std::uint8_t UTF8_REJECT = 1;
14952
14953 public:
14959 serializer(output_adapter_t<char> s, const char ichar,
14960 error_handler_t error_handler_ = error_handler_t::strict)
14961 : o(std::move(s))
14962 , loc(std::localeconv())
14963 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : * (loc->thousands_sep))
14964 , decimal_point(loc->decimal_point == nullptr ? '\0' : * (loc->decimal_point))
14965 , indent_char(ichar)
14966 , indent_string(512, indent_char)
14967 , error_handler(error_handler_)
14968 {}
14969
14970 // delete because of pointer members
14971 serializer(const serializer&) = delete;
14972 serializer& operator=(const serializer&) = delete;
14973 serializer(serializer&&) = delete;
14974 serializer& operator=(serializer&&) = delete;
14975 ~serializer() = default;
14976
14999 void dump(const BasicJsonType& val,
15000 const bool pretty_print,
15001 const bool ensure_ascii,
15002 const unsigned int indent_step,
15003 const unsigned int current_indent = 0)
15004 {
15005 switch (val.m_type)
15006 {
15007 case value_t::object:
15008 {
15009 if (val.m_value.object->empty())
15010 {
15011 o->write_characters("{}", 2);
15012 return;
15013 }
15014
15015 if (pretty_print)
15016 {
15017 o->write_characters("{\n", 2);
15018
15019 // variable to hold indentation for recursive calls
15020 const auto new_indent = current_indent + indent_step;
15021 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15022 {
15023 indent_string.resize(indent_string.size() * 2, ' ');
15024 }
15025
15026 // first n-1 elements
15027 auto i = val.m_value.object->cbegin();
15028 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15029 {
15030 o->write_characters(indent_string.c_str(), new_indent);
15031 o->write_character('\"');
15032 dump_escaped(i->first, ensure_ascii);
15033 o->write_characters("\": ", 3);
15034 dump(i->second, true, ensure_ascii, indent_step, new_indent);
15035 o->write_characters(",\n", 2);
15036 }
15037
15038 // last element
15039 assert(i != val.m_value.object->cend());
15040 assert(std::next(i) == val.m_value.object->cend());
15041 o->write_characters(indent_string.c_str(), new_indent);
15042 o->write_character('\"');
15043 dump_escaped(i->first, ensure_ascii);
15044 o->write_characters("\": ", 3);
15045 dump(i->second, true, ensure_ascii, indent_step, new_indent);
15046
15047 o->write_character('\n');
15048 o->write_characters(indent_string.c_str(), current_indent);
15049 o->write_character('}');
15050 }
15051 else
15052 {
15053 o->write_character('{');
15054
15055 // first n-1 elements
15056 auto i = val.m_value.object->cbegin();
15057 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15058 {
15059 o->write_character('\"');
15060 dump_escaped(i->first, ensure_ascii);
15061 o->write_characters("\":", 2);
15062 dump(i->second, false, ensure_ascii, indent_step, current_indent);
15063 o->write_character(',');
15064 }
15065
15066 // last element
15067 assert(i != val.m_value.object->cend());
15068 assert(std::next(i) == val.m_value.object->cend());
15069 o->write_character('\"');
15070 dump_escaped(i->first, ensure_ascii);
15071 o->write_characters("\":", 2);
15072 dump(i->second, false, ensure_ascii, indent_step, current_indent);
15073
15074 o->write_character('}');
15075 }
15076
15077 return;
15078 }
15079
15080 case value_t::array:
15081 {
15082 if (val.m_value.array->empty())
15083 {
15084 o->write_characters("[]", 2);
15085 return;
15086 }
15087
15088 if (pretty_print)
15089 {
15090 o->write_characters("[\n", 2);
15091
15092 // variable to hold indentation for recursive calls
15093 const auto new_indent = current_indent + indent_step;
15094 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15095 {
15096 indent_string.resize(indent_string.size() * 2, ' ');
15097 }
15098
15099 // first n-1 elements
15100 for (auto i = val.m_value.array->cbegin();
15101 i != val.m_value.array->cend() - 1; ++i)
15102 {
15103 o->write_characters(indent_string.c_str(), new_indent);
15104 dump(*i, true, ensure_ascii, indent_step, new_indent);
15105 o->write_characters(",\n", 2);
15106 }
15107
15108 // last element
15109 assert(not val.m_value.array->empty());
15110 o->write_characters(indent_string.c_str(), new_indent);
15111 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
15112
15113 o->write_character('\n');
15114 o->write_characters(indent_string.c_str(), current_indent);
15115 o->write_character(']');
15116 }
15117 else
15118 {
15119 o->write_character('[');
15120
15121 // first n-1 elements
15122 for (auto i = val.m_value.array->cbegin();
15123 i != val.m_value.array->cend() - 1; ++i)
15124 {
15125 dump(*i, false, ensure_ascii, indent_step, current_indent);
15126 o->write_character(',');
15127 }
15128
15129 // last element
15130 assert(not val.m_value.array->empty());
15131 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
15132
15133 o->write_character(']');
15134 }
15135
15136 return;
15137 }
15138
15139 case value_t::string:
15140 {
15141 o->write_character('\"');
15142 dump_escaped(*val.m_value.string, ensure_ascii);
15143 o->write_character('\"');
15144 return;
15145 }
15146
15147 case value_t::binary:
15148 {
15149 if (pretty_print)
15150 {
15151 o->write_characters("{\n", 2);
15152
15153 // variable to hold indentation for recursive calls
15154 const auto new_indent = current_indent + indent_step;
15155 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15156 {
15157 indent_string.resize(indent_string.size() * 2, ' ');
15158 }
15159
15160 o->write_characters(indent_string.c_str(), new_indent);
15161
15162 o->write_characters("\"bytes\": [", 10);
15163
15164 if (not val.m_value.binary->empty())
15165 {
15166 for (auto i = val.m_value.binary->cbegin();
15167 i != val.m_value.binary->cend() - 1; ++i)
15168 {
15169 dump_integer(*i);
15170 o->write_characters(", ", 2);
15171 }
15172 dump_integer(val.m_value.binary->back());
15173 }
15174
15175 o->write_characters("],\n", 3);
15176 o->write_characters(indent_string.c_str(), new_indent);
15177
15178 o->write_characters("\"subtype\": ", 11);
15179 if (val.m_value.binary->has_subtype())
15180 {
15181 dump_integer(val.m_value.binary->subtype());
15182 }
15183 else
15184 {
15185 o->write_characters("null", 4);
15186 }
15187 o->write_character('\n');
15188 o->write_characters(indent_string.c_str(), current_indent);
15189 o->write_character('}');
15190 }
15191 else
15192 {
15193 o->write_characters("{\"bytes\":[", 10);
15194
15195 if (not val.m_value.binary->empty())
15196 {
15197 for (auto i = val.m_value.binary->cbegin();
15198 i != val.m_value.binary->cend() - 1; ++i)
15199 {
15200 dump_integer(*i);
15201 o->write_character(',');
15202 }
15203 dump_integer(val.m_value.binary->back());
15204 }
15205
15206 o->write_characters("],\"subtype\":", 12);
15207 if (val.m_value.binary->has_subtype())
15208 {
15209 dump_integer(val.m_value.binary->subtype());
15210 o->write_character('}');
15211 }
15212 else
15213 {
15214 o->write_characters("null}", 5);
15215 }
15216 }
15217 return;
15218 }
15219
15220 case value_t::boolean:
15221 {
15222 if (val.m_value.boolean)
15223 {
15224 o->write_characters("true", 4);
15225 }
15226 else
15227 {
15228 o->write_characters("false", 5);
15229 }
15230 return;
15231 }
15232
15233 case value_t::number_integer:
15234 {
15235 dump_integer(val.m_value.number_integer);
15236 return;
15237 }
15238
15239 case value_t::number_unsigned:
15240 {
15241 dump_integer(val.m_value.number_unsigned);
15242 return;
15243 }
15244
15245 case value_t::number_float:
15246 {
15247 dump_float(val.m_value.number_float);
15248 return;
15249 }
15250
15251 case value_t::discarded:
15252 {
15253 o->write_characters("<discarded>", 11);
15254 return;
15255 }
15256
15257 case value_t::null:
15258 {
15259 o->write_characters("null", 4);
15260 return;
15261 }
15262
15263 default: // LCOV_EXCL_LINE
15264 assert(false); // LCOV_EXCL_LINE
15265 }
15266 }
15267
15268 private:
15283 void dump_escaped(const string_t& s, const bool ensure_ascii)
15284 {
15285 std::uint32_t codepoint;
15286 std::uint8_t state = UTF8_ACCEPT;
15287 std::size_t bytes = 0; // number of bytes written to string_buffer
15288
15289 // number of bytes written at the point of the last valid byte
15290 std::size_t bytes_after_last_accept = 0;
15291 std::size_t undumped_chars = 0;
15292
15293 for (std::size_t i = 0; i < s.size(); ++i)
15294 {
15295 const auto byte = static_cast<uint8_t>(s[i]);
15296
15297 switch (decode(state, codepoint, byte))
15298 {
15299 case UTF8_ACCEPT: // decode found a new code point
15300 {
15301 switch (codepoint)
15302 {
15303 case 0x08: // backspace
15304 {
15305 string_buffer[bytes++] = '\\';
15306 string_buffer[bytes++] = 'b';
15307 break;
15308 }
15309
15310 case 0x09: // horizontal tab
15311 {
15312 string_buffer[bytes++] = '\\';
15313 string_buffer[bytes++] = 't';
15314 break;
15315 }
15316
15317 case 0x0A: // newline
15318 {
15319 string_buffer[bytes++] = '\\';
15320 string_buffer[bytes++] = 'n';
15321 break;
15322 }
15323
15324 case 0x0C: // formfeed
15325 {
15326 string_buffer[bytes++] = '\\';
15327 string_buffer[bytes++] = 'f';
15328 break;
15329 }
15330
15331 case 0x0D: // carriage return
15332 {
15333 string_buffer[bytes++] = '\\';
15334 string_buffer[bytes++] = 'r';
15335 break;
15336 }
15337
15338 case 0x22: // quotation mark
15339 {
15340 string_buffer[bytes++] = '\\';
15341 string_buffer[bytes++] = '\"';
15342 break;
15343 }
15344
15345 case 0x5C: // reverse solidus
15346 {
15347 string_buffer[bytes++] = '\\';
15348 string_buffer[bytes++] = '\\';
15349 break;
15350 }
15351
15352 default:
15353 {
15354 // escape control characters (0x00..0x1F) or, if
15355 // ensure_ascii parameter is used, non-ASCII characters
15356 if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
15357 {
15358 if (codepoint <= 0xFFFF)
15359 {
15360 (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
15361 static_cast<std::uint16_t>(codepoint));
15362 bytes += 6;
15363 }
15364 else
15365 {
15366 (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
15367 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
15368 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
15369 bytes += 12;
15370 }
15371 }
15372 else
15373 {
15374 // copy byte to buffer (all previous bytes
15375 // been copied have in default case above)
15376 string_buffer[bytes++] = s[i];
15377 }
15378 break;
15379 }
15380 }
15381
15382 // write buffer and reset index; there must be 13 bytes
15383 // left, as this is the maximal number of bytes to be
15384 // written ("\uxxxx\uxxxx\0") for one code point
15385 if (string_buffer.size() - bytes < 13)
15386 {
15387 o->write_characters(string_buffer.data(), bytes);
15388 bytes = 0;
15389 }
15390
15391 // remember the byte position of this accept
15392 bytes_after_last_accept = bytes;
15393 undumped_chars = 0;
15394 break;
15395 }
15396
15397 case UTF8_REJECT: // decode found invalid UTF-8 byte
15398 {
15399 switch (error_handler)
15400 {
15401 case error_handler_t::strict:
15402 {
15403 std::string sn(3, '\0');
15404 (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
15405 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
15406 }
15407
15408 case error_handler_t::ignore:
15409 case error_handler_t::replace:
15410 {
15411 // in case we saw this character the first time, we
15412 // would like to read it again, because the byte
15413 // may be OK for itself, but just not OK for the
15414 // previous sequence
15415 if (undumped_chars > 0)
15416 {
15417 --i;
15418 }
15419
15420 // reset length buffer to the last accepted index;
15421 // thus removing/ignoring the invalid characters
15422 bytes = bytes_after_last_accept;
15423
15424 if (error_handler == error_handler_t::replace)
15425 {
15426 // add a replacement character
15427 if (ensure_ascii)
15428 {
15429 string_buffer[bytes++] = '\\';
15430 string_buffer[bytes++] = 'u';
15431 string_buffer[bytes++] = 'f';
15432 string_buffer[bytes++] = 'f';
15433 string_buffer[bytes++] = 'f';
15434 string_buffer[bytes++] = 'd';
15435 }
15436 else
15437 {
15438 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
15439 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
15440 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
15441 }
15442
15443 // write buffer and reset index; there must be 13 bytes
15444 // left, as this is the maximal number of bytes to be
15445 // written ("\uxxxx\uxxxx\0") for one code point
15446 if (string_buffer.size() - bytes < 13)
15447 {
15448 o->write_characters(string_buffer.data(), bytes);
15449 bytes = 0;
15450 }
15451
15452 bytes_after_last_accept = bytes;
15453 }
15454
15455 undumped_chars = 0;
15456
15457 // continue processing the string
15458 state = UTF8_ACCEPT;
15459 break;
15460 }
15461
15462 default: // LCOV_EXCL_LINE
15463 assert(false); // LCOV_EXCL_LINE
15464 }
15465 break;
15466 }
15467
15468 default: // decode found yet incomplete multi-byte code point
15469 {
15470 if (not ensure_ascii)
15471 {
15472 // code point will not be escaped - copy byte to buffer
15473 string_buffer[bytes++] = s[i];
15474 }
15475 ++undumped_chars;
15476 break;
15477 }
15478 }
15479 }
15480
15481 // we finished processing the string
15482 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
15483 {
15484 // write buffer
15485 if (bytes > 0)
15486 {
15487 o->write_characters(string_buffer.data(), bytes);
15488 }
15489 }
15490 else
15491 {
15492 // we finish reading, but do not accept: string was incomplete
15493 switch (error_handler)
15494 {
15495 case error_handler_t::strict:
15496 {
15497 std::string sn(3, '\0');
15498 (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
15499 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
15500 }
15501
15502 case error_handler_t::ignore:
15503 {
15504 // write all accepted bytes
15505 o->write_characters(string_buffer.data(), bytes_after_last_accept);
15506 break;
15507 }
15508
15509 case error_handler_t::replace:
15510 {
15511 // write all accepted bytes
15512 o->write_characters(string_buffer.data(), bytes_after_last_accept);
15513 // add a replacement character
15514 if (ensure_ascii)
15515 {
15516 o->write_characters("\\ufffd", 6);
15517 }
15518 else
15519 {
15520 o->write_characters("\xEF\xBF\xBD", 3);
15521 }
15522 break;
15523 }
15524
15525 default: // LCOV_EXCL_LINE
15526 assert(false); // LCOV_EXCL_LINE
15527 }
15528 }
15529 }
15530
15539 inline unsigned int count_digits(number_unsigned_t x) noexcept
15540 {
15541 unsigned int n_digits = 1;
15542 for (;;)
15543 {
15544 if (x < 10)
15545 {
15546 return n_digits;
15547 }
15548 if (x < 100)
15549 {
15550 return n_digits + 1;
15551 }
15552 if (x < 1000)
15553 {
15554 return n_digits + 2;
15555 }
15556 if (x < 10000)
15557 {
15558 return n_digits + 3;
15559 }
15560 x = x / 10000u;
15561 n_digits += 4;
15562 }
15563 }
15564
15574 template<typename NumberType, detail::enable_if_t<
15575 std::is_same<NumberType, number_unsigned_t>::value or
15576 std::is_same<NumberType, number_integer_t>::value or
15577 std::is_same<NumberType, binary_char_t>::value,
15578 int> = 0>
15579 void dump_integer(NumberType x)
15580 {
15581 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
15582 {
15583 {
15584 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
15585 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
15586 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
15587 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
15588 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
15589 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
15590 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
15591 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
15592 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
15593 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
15594 }
15595 };
15596
15597 // special case for "0"
15598 if (x == 0)
15599 {
15600 o->write_character('0');
15601 return;
15602 }
15603
15604 // use a pointer to fill the buffer
15605 auto buffer_ptr = number_buffer.begin();
15606
15607 const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not(x >= 0); // see issue #755
15608 number_unsigned_t abs_value;
15609
15610 unsigned int n_chars;
15611
15612 if (is_negative)
15613 {
15614 *buffer_ptr = '-';
15615 abs_value = remove_sign(static_cast<number_integer_t>(x));
15616
15617 // account one more byte for the minus sign
15618 n_chars = 1 + count_digits(abs_value);
15619 }
15620 else
15621 {
15622 abs_value = static_cast<number_unsigned_t>(x);
15623 n_chars = count_digits(abs_value);
15624 }
15625
15626 // spare 1 byte for '\0'
15627 assert(n_chars < number_buffer.size() - 1);
15628
15629 // jump to the end to generate the string from backward
15630 // so we later avoid reversing the result
15631 buffer_ptr += n_chars;
15632
15633 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
15634 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
15635 while (abs_value >= 100)
15636 {
15637 const auto digits_index = static_cast<unsigned>((abs_value % 100));
15638 abs_value /= 100;
15639 *(--buffer_ptr) = digits_to_99[digits_index][1];
15640 *(--buffer_ptr) = digits_to_99[digits_index][0];
15641 }
15642
15643 if (abs_value >= 10)
15644 {
15645 const auto digits_index = static_cast<unsigned>(abs_value);
15646 *(--buffer_ptr) = digits_to_99[digits_index][1];
15647 *(--buffer_ptr) = digits_to_99[digits_index][0];
15648 }
15649 else
15650 {
15651 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
15652 }
15653
15654 o->write_characters(number_buffer.data(), n_chars);
15655 }
15656
15665 void dump_float(number_float_t x)
15666 {
15667 // NaN / inf
15668 if (not std::isfinite(x))
15669 {
15670 o->write_characters("null", 4);
15671 return;
15672 }
15673
15674 // If number_float_t is an IEEE-754 single or double precision number,
15675 // use the Grisu2 algorithm to produce short numbers which are
15676 // guaranteed to round-trip, using strtof and strtod, resp.
15677 //
15678 // NB: The test below works if <long double> == <double>.
15679 static constexpr bool is_ieee_single_or_double
15680 = (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 24 and std::numeric_limits<number_float_t>::max_exponent == 128) or
15681 (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 53 and std::numeric_limits<number_float_t>::max_exponent == 1024);
15682
15683 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
15684 }
15685
15686 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
15687 {
15688 char* begin = number_buffer.data();
15689 char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
15690
15691 o->write_characters(begin, static_cast<size_t>(end - begin));
15692 }
15693
15694 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
15695 {
15696 // get number of digits for a float -> text -> float round-trip
15697 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
15698
15699 // the actual conversion
15700 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
15701
15702 // negative value indicates an error
15703 assert(len > 0);
15704 // check if buffer was large enough
15705 assert(static_cast<std::size_t>(len) < number_buffer.size());
15706
15707 // erase thousands separator
15708 if (thousands_sep != '\0')
15709 {
15710 const auto end = std::remove(number_buffer.begin(),
15711 number_buffer.begin() + len, thousands_sep);
15712 std::fill(end, number_buffer.end(), '\0');
15713 assert((end - number_buffer.begin()) <= len);
15714 len = (end - number_buffer.begin());
15715 }
15716
15717 // convert decimal point to '.'
15718 if (decimal_point != '\0' and decimal_point != '.')
15719 {
15720 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
15721 if (dec_pos != number_buffer.end())
15722 {
15723 *dec_pos = '.';
15724 }
15725 }
15726
15727 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
15728
15729 // determine if need to append ".0"
15730 const bool value_is_int_like =
15731 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
15732 [](char c)
15733 {
15734 return c == '.' or c == 'e';
15735 });
15736
15737 if (value_is_int_like)
15738 {
15739 o->write_characters(".0", 2);
15740 }
15741 }
15742
15764 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
15765 {
15766 static const std::array<std::uint8_t, 400> utf8d =
15767 {
15768 {
15769 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
15770 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
15771 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
15772 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
15773 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
15774 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
15775 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
15776 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
15777 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
15778 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
15779 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
15780 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
15781 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
15782 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
15783 }
15784 };
15785
15786 const std::uint8_t type = utf8d[byte];
15787
15788 codep = (state != UTF8_ACCEPT)
15789 ? (byte & 0x3fu) | (codep << 6u)
15790 : (0xFFu >> type) & (byte);
15791
15792 std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
15793 assert(index < 400);
15794 state = utf8d[index];
15795 return state;
15796 }
15797
15798 /*
15799 * Overload to make the compiler happy while it is instantiating
15800 * dump_integer for number_unsigned_t.
15801 * Must never be called.
15802 */
15803 number_unsigned_t remove_sign(number_unsigned_t x)
15804 {
15805 assert(false); // LCOV_EXCL_LINE
15806 return x; // LCOV_EXCL_LINE
15807 }
15808
15809 /*
15810 * Helper function for dump_integer
15811 *
15812 * This function takes a negative signed integer and returns its absolute
15813 * value as unsigned integer. The plus/minus shuffling is necessary as we can
15814 * not directly remove the sign of an arbitrary signed integer as the
15815 * absolute values of INT_MIN and INT_MAX are usually not the same. See
15816 * #1708 for details.
15817 */
15818 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
15819 {
15820 assert(x < 0 and x < (std::numeric_limits<number_integer_t>::max)());
15821 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
15822 }
15823
15824 private:
15826 output_adapter_t<char> o = nullptr;
15827
15829 std::array<char, 64> number_buffer{{}};
15830
15832 const std::lconv* loc = nullptr;
15834 const char thousands_sep = '\0';
15836 const char decimal_point = '\0';
15837
15839 std::array<char, 512> string_buffer{{}};
15840
15842 const char indent_char;
15844 string_t indent_string;
15845
15847 const error_handler_t error_handler;
15848 };
15849 } // namespace detail
15850 } // namespace nlohmann
15851
15852 // #include <nlohmann/detail/value_t.hpp>
15853
15854 // #include <nlohmann/json_fwd.hpp>
15855
15856
15862 namespace nlohmann
15863 {
15864
15949 NLOHMANN_BASIC_JSON_TPL_DECLARATION
15950 class basic_json
15951 {
15952 private:
15953 template<detail::value_t> friend struct detail::external_constructor;
15954 friend ::nlohmann::json_pointer<basic_json>;
15955
15956 template<typename BasicJsonType, typename InputType>
15957 friend class ::nlohmann::detail::parser;
15958 friend ::nlohmann::detail::serializer<basic_json>;
15959 template<typename BasicJsonType>
15960 friend class ::nlohmann::detail::iter_impl;
15961 template<typename BasicJsonType, typename CharType>
15962 friend class ::nlohmann::detail::binary_writer;
15963 template<typename BasicJsonType, typename InputType, typename SAX>
15964 friend class ::nlohmann::detail::binary_reader;
15965 template<typename BasicJsonType>
15966 friend class ::nlohmann::detail::json_sax_dom_parser;
15967 template<typename BasicJsonType>
15968 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
15969
15971 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
15972
15973 // convenience aliases for types residing in namespace detail;
15974 using lexer = ::nlohmann::detail::lexer_base<basic_json>;
15975
15976 template<typename InputAdapterType>
15977 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
15978 InputAdapterType adapter,
15979 detail::parser_callback_t<basic_json>cb = nullptr,
15980 bool allow_exceptions = true
15981 )
15982 {
15983 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter), std::move(cb), allow_exceptions);
15984 }
15985
15986 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
15987 template<typename BasicJsonType>
15988 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
15989 template<typename BasicJsonType>
15990 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
15991 template<typename Iterator>
15992 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
15993 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
15994
15995 template<typename CharType>
15996 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
15997
15998 template<typename InputType>
15999 using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
16000 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
16001
16002 using serializer = ::nlohmann::detail::serializer<basic_json>;
16003
16004 public:
16005 using value_t = detail::value_t;
16007 using json_pointer = ::nlohmann::json_pointer<basic_json>;
16008 template<typename T, typename SFINAE>
16009 using json_serializer = JSONSerializer<T, SFINAE>;
16011 using error_handler_t = detail::error_handler_t;
16013 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
16014
16015 using input_format_t = detail::input_format_t;
16017 using json_sax_t = json_sax<basic_json>;
16018
16020 // exceptions //
16022
16026
16028 using exception = detail::exception;
16030 using parse_error = detail::parse_error;
16032 using invalid_iterator = detail::invalid_iterator;
16034 using type_error = detail::type_error;
16036 using out_of_range = detail::out_of_range;
16038 using other_error = detail::other_error;
16039
16041
16042
16044 // container types //
16046
16051
16053 using value_type = basic_json;
16054
16056 using reference = value_type&;
16058 using const_reference = const value_type&;
16059
16061 using difference_type = std::ptrdiff_t;
16063 using size_type = std::size_t;
16064
16066 using allocator_type = AllocatorType<basic_json>;
16067
16069 using pointer = typename std::allocator_traits<allocator_type>::pointer;
16071 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
16072
16074 using iterator = iter_impl<basic_json>;
16076 using const_iterator = iter_impl<const basic_json>;
16078 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
16080 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
16081
16083
16084
16088 static allocator_type get_allocator()
16089 {
16090 return allocator_type();
16091 }
16092
16119
16120 static basic_json meta()
16121 {
16122 basic_json result;
16123
16124 result["copyright"] = "(C) 2013-2017 Niels Lohmann";
16125 result["name"] = "JSON for Modern C++";
16126 result["url"] = "https://github.com/nlohmann/json";
16127 result["version"]["string"] =
16128 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
16129 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
16130 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
16131 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
16132 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
16133 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
16134
16135 #ifdef _WIN32
16136 result["platform"] = "win32";
16137 #elif defined __linux__
16138 result["platform"] = "linux";
16139 #elif defined __APPLE__
16140 result["platform"] = "apple";
16141 #elif defined __unix__
16142 result["platform"] = "unix";
16143 #else
16144 result["platform"] = "unknown";
16145 #endif
16146
16147 #if defined(__ICC) || defined(__INTEL_COMPILER)
16148 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
16149 #elif defined(__clang__)
16150 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
16151 #elif defined(__GNUC__) || defined(__GNUG__)
16152 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
16153 #elif defined(__HP_cc) || defined(__HP_aCC)
16154 result["compiler"] = "hp"
16155 #elif defined(__IBMCPP__)
16156 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
16157 #elif defined(_MSC_VER)
16158 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
16159 #elif defined(__PGI)
16160 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
16161 #elif defined(__SUNPRO_CC)
16162 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
16163 #else
16164 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
16165 #endif
16166
16167 #ifdef __cplusplus
16168 result["compiler"]["c++"] = std::to_string(__cplusplus);
16169 #else
16170 result["compiler"]["c++"] = "unknown";
16171 #endif
16172 return result;
16173 }
16174
16175
16177 // JSON value data types //
16179
16184
16185 #if defined(JSON_HAS_CPP_14)
16186 // Use transparent comparator if possible, combined with perfect forwarding
16187 // on find() and count() calls prevents unnecessary string construction.
16188 using object_comparator_t = std::less<>;
16189 #else
16190 using object_comparator_t = std::less<StringType>;
16191 #endif
16192
16276 using object_t = ObjectType<StringType,
16277 basic_json,
16278 object_comparator_t,
16279 AllocatorType<std::pair<const StringType,
16280 basic_json>>>;
16281
16326 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
16327
16379 using string_t = StringType;
16380
16405 using boolean_t = BooleanType;
16406
16477 using number_integer_t = NumberIntegerType;
16478
16548 using number_unsigned_t = NumberUnsignedType;
16549
16616 using number_float_t = NumberFloatType;
16617
16687 using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
16689
16690 private:
16691
16693 template<typename T, typename... Args>
16694
16695 static T* create(Args&& ... args)
16696 {
16697 AllocatorType<T> alloc;
16698 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
16699
16700 auto deleter = [&](T * object)
16701 {
16702 AllocatorTraits::deallocate(alloc, object, 1);
16703 };
16704 std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
16705 AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
16706 assert(object != nullptr);
16707 return object.release();
16708 }
16709
16711 // JSON value storage //
16713
16739 union json_value
16740 {
16742 object_t* object;
16744 array_t* array;
16746 string_t* string;
16748 binary_t* binary;
16750 boolean_t boolean;
16752 number_integer_t number_integer;
16754 number_unsigned_t number_unsigned;
16756 number_float_t number_float;
16757
16759 json_value() = default;
16761 json_value(boolean_t v) noexcept : boolean(v) {}
16763 json_value(number_integer_t v) noexcept : number_integer(v) {}
16765 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
16767 json_value(number_float_t v) noexcept : number_float(v) {}
16769 json_value(value_t t)
16770 {
16771 switch (t)
16772 {
16773 case value_t::object:
16774 {
16775 object = create<object_t>();
16776 break;
16777 }
16778
16779 case value_t::array:
16780 {
16781 array = create<array_t>();
16782 break;
16783 }
16784
16785 case value_t::string:
16786 {
16787 string = create<string_t>("");
16788 break;
16789 }
16790
16791 case value_t::binary:
16792 {
16793 binary = create<binary_t>();
16794 break;
16795 }
16796
16797 case value_t::boolean:
16798 {
16799 boolean = boolean_t(false);
16800 break;
16801 }
16802
16803 case value_t::number_integer:
16804 {
16805 number_integer = number_integer_t(0);
16806 break;
16807 }
16808
16809 case value_t::number_unsigned:
16810 {
16811 number_unsigned = number_unsigned_t(0);
16812 break;
16813 }
16814
16815 case value_t::number_float:
16816 {
16817 number_float = number_float_t(0.0);
16818 break;
16819 }
16820
16821 case value_t::null:
16822 {
16823 object = nullptr; // silence warning, see #821
16824 break;
16825 }
16826
16827 default:
16828 {
16829 object = nullptr; // silence warning, see #821
16830 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
16831 {
16832 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.8.0")); // LCOV_EXCL_LINE
16833 }
16834 break;
16835 }
16836 }
16837 }
16838
16840 json_value(const string_t& value)
16841 {
16842 string = create<string_t>(value);
16843 }
16844
16846 json_value(string_t&& value)
16847 {
16848 string = create<string_t>(std::move(value));
16849 }
16850
16852 json_value(const object_t& value)
16853 {
16854 object = create<object_t>(value);
16855 }
16856
16858 json_value(object_t&& value)
16859 {
16860 object = create<object_t>(std::move(value));
16861 }
16862
16864 json_value(const array_t& value)
16865 {
16866 array = create<array_t>(value);
16867 }
16868
16870 json_value(array_t&& value)
16871 {
16872 array = create<array_t>(std::move(value));
16873 }
16874
16876 json_value(const typename binary_t::container_type& value)
16877 {
16878 binary = create<binary_t>(value);
16879 }
16880
16882 json_value(typename binary_t::container_type&& value)
16883 {
16884 binary = create<binary_t>(std::move(value));
16885 }
16886
16888 json_value(const binary_t& value)
16889 {
16890 binary = create<binary_t>(value);
16891 }
16892
16894 json_value(binary_t&& value)
16895 {
16896 binary = create<binary_t>(std::move(value));
16897 }
16898
16899 void destroy(value_t t) noexcept
16900 {
16901 // flatten the current json_value to a heap-allocated stack
16902 std::vector<basic_json> stack;
16903
16904 // move the top-level items to stack
16905 if (t == value_t::array)
16906 {
16907 stack.reserve(array->size());
16908 std::move(array->begin(), array->end(), std::back_inserter(stack));
16909 }
16910 else if (t == value_t::object)
16911 {
16912 stack.reserve(object->size());
16913 for (auto&& it : *object)
16914 {
16915 stack.push_back(std::move(it.second));
16916 }
16917 }
16918
16919 while (not stack.empty())
16920 {
16921 // move the last item to local variable to be processed
16922 basic_json current_item(std::move(stack.back()));
16923 stack.pop_back();
16924
16925 // if current_item is array/object, move
16926 // its children to the stack to be processed later
16927 if (current_item.is_array())
16928 {
16929 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
16930 std::back_inserter(stack));
16931
16932 current_item.m_value.array->clear();
16933 }
16934 else if (current_item.is_object())
16935 {
16936 for (auto&& it : *current_item.m_value.object)
16937 {
16938 stack.push_back(std::move(it.second));
16939 }
16940
16941 current_item.m_value.object->clear();
16942 }
16943
16944 // it's now safe that current_item get destructed
16945 // since it doesn't have any children
16946 }
16947
16948 switch (t)
16949 {
16950 case value_t::object:
16951 {
16952 AllocatorType<object_t> alloc;
16953 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
16954 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
16955 break;
16956 }
16957
16958 case value_t::array:
16959 {
16960 AllocatorType<array_t> alloc;
16961 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
16962 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
16963 break;
16964 }
16965
16966 case value_t::string:
16967 {
16968 AllocatorType<string_t> alloc;
16969 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
16970 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
16971 break;
16972 }
16973
16974 case value_t::binary:
16975 {
16976 AllocatorType<binary_t> alloc;
16977 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
16978 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
16979 break;
16980 }
16981
16982 default:
16983 {
16984 break;
16985 }
16986 }
16987 }
16988 };
16989
16999 void assert_invariant() const noexcept
17000 {
17001 assert(m_type != value_t::object or m_value.object != nullptr);
17002 assert(m_type != value_t::array or m_value.array != nullptr);
17003 assert(m_type != value_t::string or m_value.string != nullptr);
17004 assert(m_type != value_t::binary or m_value.binary != nullptr);
17005 }
17006
17007 public:
17009 // JSON parser callback //
17011
17027 using parse_event_t = detail::parse_event_t;
17028
17078 using parser_callback_t = detail::parser_callback_t<basic_json>;
17079
17081 // constructors //
17083
17088
17119 basic_json(const value_t v)
17120 : m_type(v), m_value(v)
17121 {
17122 assert_invariant();
17123 }
17124
17143 basic_json(std::nullptr_t = nullptr) noexcept
17144 : basic_json(value_t::null)
17145 {
17146 assert_invariant();
17147 }
17148
17212 template <typename CompatibleType,
17213 typename U = detail::uncvref_t<CompatibleType>,
17214 detail::enable_if_t<
17215 not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
17216 basic_json(CompatibleType && val) noexcept(noexcept(
17217 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
17218 std::forward<CompatibleType>(val))))
17219 {
17220 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
17221 assert_invariant();
17222 }
17223
17250 template <typename BasicJsonType,
17251 detail::enable_if_t<
17252 detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
17253 basic_json(const BasicJsonType& val)
17254 {
17255 using other_boolean_t = typename BasicJsonType::boolean_t;
17256 using other_number_float_t = typename BasicJsonType::number_float_t;
17257 using other_number_integer_t = typename BasicJsonType::number_integer_t;
17258 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
17259 using other_string_t = typename BasicJsonType::string_t;
17260 using other_object_t = typename BasicJsonType::object_t;
17261 using other_array_t = typename BasicJsonType::array_t;
17262 using other_binary_t = typename BasicJsonType::binary_t;
17263
17264 switch (val.type())
17265 {
17266 case value_t::boolean:
17267 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
17268 break;
17269 case value_t::number_float:
17270 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
17271 break;
17272 case value_t::number_integer:
17273 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
17274 break;
17275 case value_t::number_unsigned:
17276 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
17277 break;
17278 case value_t::string:
17279 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
17280 break;
17281 case value_t::object:
17282 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
17283 break;
17284 case value_t::array:
17285 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
17286 break;
17287 case value_t::binary:
17288 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
17289 break;
17290 case value_t::null:
17291 *this = nullptr;
17292 break;
17293 case value_t::discarded:
17294 m_type = value_t::discarded;
17295 break;
17296 default: // LCOV_EXCL_LINE
17297 assert(false); // LCOV_EXCL_LINE
17298 }
17299 assert_invariant();
17300 }
17301
17376 basic_json(initializer_list_t init,
17377 bool type_deduction = true,
17378 value_t manual_type = value_t::array)
17379 {
17380 // check if each element is an array with two elements whose first
17381 // element is a string
17382 bool is_an_object = std::all_of(init.begin(), init.end(),
17383 [](const detail::json_ref<basic_json>& element_ref)
17384 {
17385 return element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string();
17386 });
17387
17388 // adjust type if type deduction is not wanted
17389 if (not type_deduction)
17390 {
17391 // if array is wanted, do not create an object though possible
17392 if (manual_type == value_t::array)
17393 {
17394 is_an_object = false;
17395 }
17396
17397 // if object is wanted but impossible, throw an exception
17398 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object and not is_an_object))
17399 {
17400 JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
17401 }
17402 }
17403
17404 if (is_an_object)
17405 {
17406 // the initializer list is a list of pairs -> create object
17407 m_type = value_t::object;
17408 m_value = value_t::object;
17409
17410 std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
17411 {
17412 auto element = element_ref.moved_or_copied();
17413 m_value.object->emplace(
17414 std::move(*((*element.m_value.array)[0].m_value.string)),
17415 std::move((*element.m_value.array)[1]));
17416 });
17417 }
17418 else
17419 {
17420 // the initializer list describes an array -> create array
17421 m_type = value_t::array;
17422 m_value.array = create<array_t>(init.begin(), init.end());
17423 }
17424
17425 assert_invariant();
17426 }
17427
17455
17456 static basic_json binary(const typename binary_t::container_type& init)
17457 {
17458 auto res = basic_json();
17459 res.m_type = value_t::binary;
17460 res.m_value = init;
17461 return res;
17462 }
17463
17492
17493 static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype)
17494 {
17495 auto res = basic_json();
17496 res.m_type = value_t::binary;
17497 res.m_value = binary_t(init, subtype);
17498 return res;
17499 }
17500
17502
17503 static basic_json binary(typename binary_t::container_type&& init)
17504 {
17505 auto res = basic_json();
17506 res.m_type = value_t::binary;
17507 res.m_value = std::move(init);
17508 return res;
17509 }
17510
17512
17513 static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype)
17514 {
17515 auto res = basic_json();
17516 res.m_type = value_t::binary;
17517 res.m_value = binary_t(std::move(init), subtype);
17518 return res;
17519 }
17520
17558
17559 static basic_json array(initializer_list_t init = {})
17560 {
17561 return basic_json(init, false, value_t::array);
17562 }
17563
17602
17603 static basic_json object(initializer_list_t init = {})
17604 {
17605 return basic_json(init, false, value_t::object);
17606 }
17607
17630 basic_json(size_type cnt, const basic_json& val)
17631 : m_type(value_t::array)
17632 {
17633 m_value.array = create<array_t>(cnt, val);
17634 assert_invariant();
17635 }
17636
17692 template<class InputIT, typename std::enable_if<
17693 std::is_same<InputIT, typename basic_json_t::iterator>::value or
17694 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
17695 basic_json(InputIT first, InputIT last)
17696 {
17697 assert(first.m_object != nullptr);
17698 assert(last.m_object != nullptr);
17699
17700 // make sure iterator fits the current value
17701 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
17702 {
17703 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
17704 }
17705
17706 // copy type from first iterator
17707 m_type = first.m_object->m_type;
17708
17709 // check if iterator range is complete for primitive values
17710 switch (m_type)
17711 {
17712 case value_t::boolean:
17713 case value_t::number_float:
17714 case value_t::number_integer:
17715 case value_t::number_unsigned:
17716 case value_t::string:
17717 {
17718 if (JSON_HEDLEY_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
17719 or not last.m_it.primitive_iterator.is_end()))
17720 {
17721 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
17722 }
17723 break;
17724 }
17725
17726 default:
17727 break;
17728 }
17729
17730 switch (m_type)
17731 {
17732 case value_t::number_integer:
17733 {
17734 m_value.number_integer = first.m_object->m_value.number_integer;
17735 break;
17736 }
17737
17738 case value_t::number_unsigned:
17739 {
17740 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
17741 break;
17742 }
17743
17744 case value_t::number_float:
17745 {
17746 m_value.number_float = first.m_object->m_value.number_float;
17747 break;
17748 }
17749
17750 case value_t::boolean:
17751 {
17752 m_value.boolean = first.m_object->m_value.boolean;
17753 break;
17754 }
17755
17756 case value_t::string:
17757 {
17758 m_value = *first.m_object->m_value.string;
17759 break;
17760 }
17761
17762 case value_t::object:
17763 {
17764 m_value.object = create<object_t>(first.m_it.object_iterator,
17765 last.m_it.object_iterator);
17766 break;
17767 }
17768
17769 case value_t::array:
17770 {
17771 m_value.array = create<array_t>(first.m_it.array_iterator,
17772 last.m_it.array_iterator);
17773 break;
17774 }
17775
17776 case value_t::binary:
17777 {
17778 m_value = *first.m_object->m_value.binary;
17779 break;
17780 }
17781
17782 default:
17783 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
17784 std::string(first.m_object->type_name())));
17785 }
17786
17787 assert_invariant();
17788 }
17789
17790
17792 // other constructors and destructor //
17794
17795 template <typename JsonRef,
17796 detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
17797 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
17798 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
17799
17825 basic_json(const basic_json& other)
17826 : m_type(other.m_type)
17827 {
17828 // check of passed value is valid
17829 other.assert_invariant();
17830
17831 switch (m_type)
17832 {
17833 case value_t::object:
17834 {
17835 m_value = *other.m_value.object;
17836 break;
17837 }
17838
17839 case value_t::array:
17840 {
17841 m_value = *other.m_value.array;
17842 break;
17843 }
17844
17845 case value_t::string:
17846 {
17847 m_value = *other.m_value.string;
17848 break;
17849 }
17850
17851 case value_t::boolean:
17852 {
17853 m_value = other.m_value.boolean;
17854 break;
17855 }
17856
17857 case value_t::number_integer:
17858 {
17859 m_value = other.m_value.number_integer;
17860 break;
17861 }
17862
17863 case value_t::number_unsigned:
17864 {
17865 m_value = other.m_value.number_unsigned;
17866 break;
17867 }
17868
17869 case value_t::number_float:
17870 {
17871 m_value = other.m_value.number_float;
17872 break;
17873 }
17874
17875 case value_t::binary:
17876 {
17877 m_value = *other.m_value.binary;
17878 break;
17879 }
17880
17881 default:
17882 break;
17883 }
17884
17885 assert_invariant();
17886 }
17887
17914 basic_json(basic_json&& other) noexcept
17915 : m_type(std::move(other.m_type)),
17916 m_value(std::move(other.m_value))
17917 {
17918 // check that passed value is valid
17919 other.assert_invariant();
17920
17921 // invalidate payload
17922 other.m_type = value_t::null;
17923 other.m_value = {};
17924
17925 assert_invariant();
17926 }
17927
17951 basic_json& operator=(basic_json other) noexcept (
17952 std::is_nothrow_move_constructible<value_t>::value and
17953 std::is_nothrow_move_assignable<value_t>::value and
17954 std::is_nothrow_move_constructible<json_value>::value and
17955 std::is_nothrow_move_assignable<json_value>::value
17956 )
17957 {
17958 // check that passed value is valid
17959 other.assert_invariant();
17960
17961 using std::swap;
17962 swap(m_type, other.m_type);
17963 swap(m_value, other.m_value);
17964
17965 assert_invariant();
17966 return *this;
17967 }
17968
17984 ~basic_json() noexcept
17985 {
17986 assert_invariant();
17987 m_value.destroy(m_type);
17988 }
17989
17991
17992 public:
17994 // object inspection //
17996
18000
18047 string_t dump(const int indent = -1,
18048 const char indent_char = ' ',
18049 const bool ensure_ascii = false,
18050 const error_handler_t error_handler = error_handler_t::strict) const
18051 {
18052 string_t result;
18053 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
18054
18055 if (indent >= 0)
18056 {
18057 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
18058 }
18059 else
18060 {
18061 s.dump(*this, false, ensure_ascii, 0);
18062 }
18063
18064 return result;
18065 }
18066
18100 constexpr value_t type() const noexcept
18101 {
18102 return m_type;
18103 }
18104
18131 constexpr bool is_primitive() const noexcept
18132 {
18133 return is_null() or is_string() or is_boolean() or is_number() or is_binary();
18134 }
18135
18158 constexpr bool is_structured() const noexcept
18159 {
18160 return is_array() or is_object();
18161 }
18162
18180 constexpr bool is_null() const noexcept
18181 {
18182 return m_type == value_t::null;
18183 }
18184
18202 constexpr bool is_boolean() const noexcept
18203 {
18204 return m_type == value_t::boolean;
18205 }
18206
18232 constexpr bool is_number() const noexcept
18233 {
18234 return is_number_integer() or is_number_float();
18235 }
18236
18261 constexpr bool is_number_integer() const noexcept
18262 {
18263 return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
18264 }
18265
18289 constexpr bool is_number_unsigned() const noexcept
18290 {
18291 return m_type == value_t::number_unsigned;
18292 }
18293
18317 constexpr bool is_number_float() const noexcept
18318 {
18319 return m_type == value_t::number_float;
18320 }
18321
18339 constexpr bool is_object() const noexcept
18340 {
18341 return m_type == value_t::object;
18342 }
18343
18361 constexpr bool is_array() const noexcept
18362 {
18363 return m_type == value_t::array;
18364 }
18365
18383 constexpr bool is_string() const noexcept
18384 {
18385 return m_type == value_t::string;
18386 }
18387
18405 constexpr bool is_binary() const noexcept
18406 {
18407 return m_type == value_t::binary;
18408 }
18409
18432 constexpr bool is_discarded() const noexcept
18433 {
18434 return m_type == value_t::discarded;
18435 }
18436
18458 constexpr operator value_t() const noexcept
18459 {
18460 return m_type;
18461 }
18462
18464
18465 private:
18467 // value access //
18469
18471 boolean_t get_impl(boolean_t* /*unused*/) const
18472 {
18473 if (JSON_HEDLEY_LIKELY(is_boolean()))
18474 {
18475 return m_value.boolean;
18476 }
18477
18478 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
18479 }
18480
18482 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
18483 {
18484 return is_object() ? m_value.object : nullptr;
18485 }
18486
18488 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
18489 {
18490 return is_object() ? m_value.object : nullptr;
18491 }
18492
18494 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
18495 {
18496 return is_array() ? m_value.array : nullptr;
18497 }
18498
18500 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
18501 {
18502 return is_array() ? m_value.array : nullptr;
18503 }
18504
18506 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
18507 {
18508 return is_string() ? m_value.string : nullptr;
18509 }
18510
18512 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
18513 {
18514 return is_string() ? m_value.string : nullptr;
18515 }
18516
18518 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
18519 {
18520 return is_boolean() ? &m_value.boolean : nullptr;
18521 }
18522
18524 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
18525 {
18526 return is_boolean() ? &m_value.boolean : nullptr;
18527 }
18528
18530 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
18531 {
18532 return is_number_integer() ? &m_value.number_integer : nullptr;
18533 }
18534
18536 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
18537 {
18538 return is_number_integer() ? &m_value.number_integer : nullptr;
18539 }
18540
18542 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
18543 {
18544 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
18545 }
18546
18548 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
18549 {
18550 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
18551 }
18552
18554 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
18555 {
18556 return is_number_float() ? &m_value.number_float : nullptr;
18557 }
18558
18560 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
18561 {
18562 return is_number_float() ? &m_value.number_float : nullptr;
18563 }
18564
18566 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
18567 {
18568 return is_binary() ? m_value.binary : nullptr;
18569 }
18570
18572 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
18573 {
18574 return is_binary() ? m_value.binary : nullptr;
18575 }
18576
18588 template<typename ReferenceType, typename ThisType>
18589 static ReferenceType get_ref_impl(ThisType& obj)
18590 {
18591 // delegate the call to get_ptr<>()
18592 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
18593
18594 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
18595 {
18596 return *ptr;
18597 }
18598
18599 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
18600 }
18601
18602 public:
18606
18621 template<typename BasicJsonType, detail::enable_if_t<
18622 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
18623 int> = 0>
18624 basic_json get() const
18625 {
18626 return *this;
18627 }
18628
18644 template<typename BasicJsonType, detail::enable_if_t<
18645 not std::is_same<BasicJsonType, basic_json>::value and
18646 detail::is_basic_json<BasicJsonType>::value, int> = 0>
18647 BasicJsonType get() const
18648 {
18649 return *this;
18650 }
18651
18691 template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
18692 detail::enable_if_t <
18693 not detail::is_basic_json<ValueType>::value and
18694 detail::has_from_json<basic_json_t, ValueType>::value and
18695 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
18696 int> = 0>
18697 ValueType get() const noexcept(noexcept(
18698 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
18699 {
18700 // we cannot static_assert on ValueTypeCV being non-const, because
18701 // there is support for get<const basic_json_t>(), which is why we
18702 // still need the uncvref
18703 static_assert(not std::is_reference<ValueTypeCV>::value,
18704 "get() cannot be used with reference types, you might want to use get_ref()");
18705 static_assert(std::is_default_constructible<ValueType>::value,
18706 "types must be DefaultConstructible when used with get()");
18707
18708 ValueType ret;
18709 JSONSerializer<ValueType>::from_json(*this, ret);
18710 return ret;
18711 }
18712
18744 template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
18745 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
18746 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
18747 int> = 0>
18748 ValueType get() const noexcept(noexcept(
18749 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
18750 {
18751 static_assert(not std::is_reference<ValueTypeCV>::value,
18752 "get() cannot be used with reference types, you might want to use get_ref()");
18753 return JSONSerializer<ValueType>::from_json(*this);
18754 }
18755
18789 template<typename ValueType,
18790 detail::enable_if_t <
18791 not detail::is_basic_json<ValueType>::value and
18792 detail::has_from_json<basic_json_t, ValueType>::value,
18793 int> = 0>
18794 ValueType & get_to(ValueType& v) const noexcept(noexcept(
18795 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
18796 {
18797 JSONSerializer<ValueType>::from_json(*this, v);
18798 return v;
18799 }
18800
18801 template <
18802 typename T, std::size_t N,
18803 typename Array = T (&)[N],
18804 detail::enable_if_t <
18805 detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
18806 Array get_to(T (&v)[N]) const
18807 noexcept(noexcept(JSONSerializer<Array>::from_json(
18808 std::declval<const basic_json_t&>(), v)))
18809 {
18810 JSONSerializer<Array>::from_json(*this, v);
18811 return v;
18812 }
18813
18814
18841 template<typename PointerType, typename std::enable_if<
18842 std::is_pointer<PointerType>::value, int>::type = 0>
18843 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
18844 {
18845 // delegate the call to get_impl_ptr<>()
18846 return get_impl_ptr(static_cast<PointerType>(nullptr));
18847 }
18848
18853 template<typename PointerType, typename std::enable_if<
18854 std::is_pointer<PointerType>::value and
18855 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
18856 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
18857 {
18858 // delegate the call to get_impl_ptr<>() const
18859 return get_impl_ptr(static_cast<PointerType>(nullptr));
18860 }
18861
18889 template<typename PointerType, typename std::enable_if<
18890 std::is_pointer<PointerType>::value, int>::type = 0>
18891 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
18892 {
18893 // delegate the call to get_ptr
18894 return get_ptr<PointerType>();
18895 }
18896
18901 template<typename PointerType, typename std::enable_if<
18902 std::is_pointer<PointerType>::value, int>::type = 0>
18903 constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
18904 {
18905 // delegate the call to get_ptr
18906 return get_ptr<PointerType>();
18907 }
18908
18935 template<typename ReferenceType, typename std::enable_if<
18936 std::is_reference<ReferenceType>::value, int>::type = 0>
18937 ReferenceType get_ref()
18938 {
18939 // delegate call to get_ref_impl
18940 return get_ref_impl<ReferenceType>(*this);
18941 }
18942
18947 template<typename ReferenceType, typename std::enable_if<
18948 std::is_reference<ReferenceType>::value and
18949 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
18950 ReferenceType get_ref() const
18951 {
18952 // delegate call to get_ref_impl
18953 return get_ref_impl<ReferenceType>(*this);
18954 }
18955
18985 template < typename ValueType, typename std::enable_if <
18986 not std::is_pointer<ValueType>::value and
18987 not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
18988 not std::is_same<ValueType, typename string_t::value_type>::value and
18989 not detail::is_basic_json<ValueType>::value
18990 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
18991 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) and _MSC_VER >= 1910 and _MSC_VER <= 1914))
18992 and not std::is_same<ValueType, typename std::string_view>::value
18993 #endif
18994 and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
18995 , int >::type = 0 >
18996 operator ValueType() const
18997 {
18998 // delegate the call to get<>() const
18999 return get<ValueType>();
19000 }
19001
19011 binary_t& get_binary()
19012 {
19013 if (not is_binary())
19014 {
19015 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19016 }
19017
19018 return *get_ptr<binary_t*>();
19019 }
19020
19022 const binary_t& get_binary() const
19023 {
19024 if (not is_binary())
19025 {
19026 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19027 }
19028
19029 return *get_ptr<const binary_t*>();
19030 }
19031
19033
19034
19036 // element access //
19038
19042
19069 reference at(size_type idx)
19070 {
19071 // at only works for arrays
19072 if (JSON_HEDLEY_LIKELY(is_array()))
19073 {
19074 JSON_TRY
19075 {
19076 return m_value.array->at(idx);
19077 }
19078 JSON_CATCH (std::out_of_range&)
19079 {
19080 // create better exception explanation
19081 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19082 }
19083 }
19084 else
19085 {
19086 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19087 }
19088 }
19089
19116 const_reference at(size_type idx) const
19117 {
19118 // at only works for arrays
19119 if (JSON_HEDLEY_LIKELY(is_array()))
19120 {
19121 JSON_TRY
19122 {
19123 return m_value.array->at(idx);
19124 }
19125 JSON_CATCH (std::out_of_range&)
19126 {
19127 // create better exception explanation
19128 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19129 }
19130 }
19131 else
19132 {
19133 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19134 }
19135 }
19136
19167 reference at(const typename object_t::key_type& key)
19168 {
19169 // at only works for objects
19170 if (JSON_HEDLEY_LIKELY(is_object()))
19171 {
19172 JSON_TRY
19173 {
19174 return m_value.object->at(key);
19175 }
19176 JSON_CATCH (std::out_of_range&)
19177 {
19178 // create better exception explanation
19179 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19180 }
19181 }
19182 else
19183 {
19184 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19185 }
19186 }
19187
19218 const_reference at(const typename object_t::key_type& key) const
19219 {
19220 // at only works for objects
19221 if (JSON_HEDLEY_LIKELY(is_object()))
19222 {
19223 JSON_TRY
19224 {
19225 return m_value.object->at(key);
19226 }
19227 JSON_CATCH (std::out_of_range&)
19228 {
19229 // create better exception explanation
19230 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19231 }
19232 }
19233 else
19234 {
19235 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19236 }
19237 }
19238
19264 reference operator[](size_type idx)
19265 {
19266 // implicitly convert null value to an empty array
19267 if (is_null())
19268 {
19269 m_type = value_t::array;
19270 m_value.array = create<array_t>();
19271 assert_invariant();
19272 }
19273
19274 // operator[] only works for arrays
19275 if (JSON_HEDLEY_LIKELY(is_array()))
19276 {
19277 // fill up array with null values if given idx is outside range
19278 if (idx >= m_value.array->size())
19279 {
19280 m_value.array->insert(m_value.array->end(),
19281 idx - m_value.array->size() + 1,
19282 basic_json());
19283 }
19284
19285 return m_value.array->operator[](idx);
19286 }
19287
19288 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
19289 }
19290
19310 const_reference operator[](size_type idx) const
19311 {
19312 // const operator[] only works for arrays
19313 if (JSON_HEDLEY_LIKELY(is_array()))
19314 {
19315 return m_value.array->operator[](idx);
19316 }
19317
19318 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
19319 }
19320
19348 reference operator[](const typename object_t::key_type& key)
19349 {
19350 // implicitly convert null value to an empty object
19351 if (is_null())
19352 {
19353 m_type = value_t::object;
19354 m_value.object = create<object_t>();
19355 assert_invariant();
19356 }
19357
19358 // operator[] only works for objects
19359 if (JSON_HEDLEY_LIKELY(is_object()))
19360 {
19361 return m_value.object->operator[](key);
19362 }
19363
19364 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
19365 }
19366
19397 const_reference operator[](const typename object_t::key_type& key) const
19398 {
19399 // const operator[] only works for objects
19400 if (JSON_HEDLEY_LIKELY(is_object()))
19401 {
19402 assert(m_value.object->find(key) != m_value.object->end());
19403 return m_value.object->find(key)->second;
19404 }
19405
19406 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
19407 }
19408
19436 template<typename T>
19437 JSON_HEDLEY_NON_NULL(2)
19438 reference operator[](T* key)
19439 {
19440 // implicitly convert null to object
19441 if (is_null())
19442 {
19443 m_type = value_t::object;
19444 m_value = value_t::object;
19445 assert_invariant();
19446 }
19447
19448 // at only works for objects
19449 if (JSON_HEDLEY_LIKELY(is_object()))
19450 {
19451 return m_value.object->operator[](key);
19452 }
19453
19454 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
19455 }
19456
19487 template<typename T>
19488 JSON_HEDLEY_NON_NULL(2)
19489 const_reference operator[](T* key) const
19490 {
19491 // at only works for objects
19492 if (JSON_HEDLEY_LIKELY(is_object()))
19493 {
19494 assert(m_value.object->find(key) != m_value.object->end());
19495 return m_value.object->find(key)->second;
19496 }
19497
19498 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
19499 }
19500
19551 template<class ValueType, typename std::enable_if<
19552 std::is_convertible<basic_json_t, ValueType>::value
19553 and not std::is_same<value_t, ValueType>::value, int>::type = 0>
19554 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
19555 {
19556 // at only works for objects
19557 if (JSON_HEDLEY_LIKELY(is_object()))
19558 {
19559 // if key is found, return value and given default value otherwise
19560 const auto it = find(key);
19561 if (it != end())
19562 {
19563 return *it;
19564 }
19565
19566 return default_value;
19567 }
19568
19569 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
19570 }
19571
19576 string_t value(const typename object_t::key_type& key, const char* default_value) const
19577 {
19578 return value(key, string_t(default_value));
19579 }
19580
19624 template<class ValueType, typename std::enable_if<
19625 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
19626 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
19627 {
19628 // at only works for objects
19629 if (JSON_HEDLEY_LIKELY(is_object()))
19630 {
19631 // if pointer resolves a value, return it or use default value
19632 JSON_TRY
19633 {
19634 return ptr.get_checked(this);
19635 }
19636 JSON_INTERNAL_CATCH (out_of_range&)
19637 {
19638 return default_value;
19639 }
19640 }
19641
19642 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
19643 }
19644
19649 JSON_HEDLEY_NON_NULL(3)
19650 string_t value(const json_pointer& ptr, const char* default_value) const
19651 {
19652 return value(ptr, string_t(default_value));
19653 }
19654
19680 reference front()
19681 {
19682 return *begin();
19683 }
19684
19688 const_reference front() const
19689 {
19690 return *cbegin();
19691 }
19692
19724 reference back()
19725 {
19726 auto tmp = end();
19727 --tmp;
19728 return *tmp;
19729 }
19730
19734 const_reference back() const
19735 {
19736 auto tmp = cend();
19737 --tmp;
19738 return *tmp;
19739 }
19740
19787 template<class IteratorType, typename std::enable_if<
19788 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
19789 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
19790 = 0>
19791 IteratorType erase(IteratorType pos)
19792 {
19793 // make sure iterator fits the current value
19794 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
19795 {
19796 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
19797 }
19798
19799 IteratorType result = end();
19800
19801 switch (m_type)
19802 {
19803 case value_t::boolean:
19804 case value_t::number_float:
19805 case value_t::number_integer:
19806 case value_t::number_unsigned:
19807 case value_t::string:
19808 case value_t::binary:
19809 {
19810 if (JSON_HEDLEY_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
19811 {
19812 JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
19813 }
19814
19815 if (is_string())
19816 {
19817 AllocatorType<string_t> alloc;
19818 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
19819 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
19820 m_value.string = nullptr;
19821 }
19822 else if (is_binary())
19823 {
19824 AllocatorType<binary_t> alloc;
19825 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
19826 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
19827 m_value.binary = nullptr;
19828 }
19829
19830 m_type = value_t::null;
19831 assert_invariant();
19832 break;
19833 }
19834
19835 case value_t::object:
19836 {
19837 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
19838 break;
19839 }
19840
19841 case value_t::array:
19842 {
19843 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
19844 break;
19845 }
19846
19847 default:
19848 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
19849 }
19850
19851 return result;
19852 }
19853
19900 template<class IteratorType, typename std::enable_if<
19901 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
19902 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
19903 = 0>
19904 IteratorType erase(IteratorType first, IteratorType last)
19905 {
19906 // make sure iterator fits the current value
19907 if (JSON_HEDLEY_UNLIKELY(this != first.m_object or this != last.m_object))
19908 {
19909 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
19910 }
19911
19912 IteratorType result = end();
19913
19914 switch (m_type)
19915 {
19916 case value_t::boolean:
19917 case value_t::number_float:
19918 case value_t::number_integer:
19919 case value_t::number_unsigned:
19920 case value_t::string:
19921 case value_t::binary:
19922 {
19923 if (JSON_HEDLEY_LIKELY(not first.m_it.primitive_iterator.is_begin()
19924 or not last.m_it.primitive_iterator.is_end()))
19925 {
19926 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
19927 }
19928
19929 if (is_string())
19930 {
19931 AllocatorType<string_t> alloc;
19932 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
19933 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
19934 m_value.string = nullptr;
19935 }
19936 else if (is_binary())
19937 {
19938 AllocatorType<binary_t> alloc;
19939 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
19940 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
19941 m_value.binary = nullptr;
19942 }
19943
19944 m_type = value_t::null;
19945 assert_invariant();
19946 break;
19947 }
19948
19949 case value_t::object:
19950 {
19951 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
19952 last.m_it.object_iterator);
19953 break;
19954 }
19955
19956 case value_t::array:
19957 {
19958 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
19959 last.m_it.array_iterator);
19960 break;
19961 }
19962
19963 default:
19964 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
19965 }
19966
19967 return result;
19968 }
19969
19999 size_type erase(const typename object_t::key_type& key)
20000 {
20001 // this erase only works for objects
20002 if (JSON_HEDLEY_LIKELY(is_object()))
20003 {
20004 return m_value.object->erase(key);
20005 }
20006
20007 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20008 }
20009
20034 void erase(const size_type idx)
20035 {
20036 // this erase only works for arrays
20037 if (JSON_HEDLEY_LIKELY(is_array()))
20038 {
20039 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
20040 {
20041 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
20042 }
20043
20044 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
20045 }
20046 else
20047 {
20048 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20049 }
20050 }
20051
20053
20054
20056 // lookup //
20058
20061
20086 template<typename KeyT>
20087 iterator find(KeyT&& key)
20088 {
20089 auto result = end();
20090
20091 if (is_object())
20092 {
20093 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20094 }
20095
20096 return result;
20097 }
20098
20103 template<typename KeyT>
20104 const_iterator find(KeyT&& key) const
20105 {
20106 auto result = cend();
20107
20108 if (is_object())
20109 {
20110 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20111 }
20112
20113 return result;
20114 }
20115
20137 template<typename KeyT>
20138 size_type count(KeyT&& key) const
20139 {
20140 // return 0 for all nonobject types
20141 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
20142 }
20143
20169 template<typename KeyT, typename std::enable_if<
20170 not std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int>::type = 0>
20171 bool contains(KeyT && key) const
20172 {
20173 return is_object() and m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
20174 }
20175
20202 bool contains(const json_pointer& ptr) const
20203 {
20204 return ptr.contains(this);
20205 }
20206
20208
20209
20211 // iterators //
20213
20216
20241 iterator begin() noexcept
20242 {
20243 iterator result(this);
20244 result.set_begin();
20245 return result;
20246 }
20247
20251 const_iterator begin() const noexcept
20252 {
20253 return cbegin();
20254 }
20255
20281 const_iterator cbegin() const noexcept
20282 {
20283 const_iterator result(this);
20284 result.set_begin();
20285 return result;
20286 }
20287
20312 iterator end() noexcept
20313 {
20314 iterator result(this);
20315 result.set_end();
20316 return result;
20317 }
20318
20322 const_iterator end() const noexcept
20323 {
20324 return cend();
20325 }
20326
20352 const_iterator cend() const noexcept
20353 {
20354 const_iterator result(this);
20355 result.set_end();
20356 return result;
20357 }
20358
20382 reverse_iterator rbegin() noexcept
20383 {
20384 return reverse_iterator(end());
20385 }
20386
20390 const_reverse_iterator rbegin() const noexcept
20391 {
20392 return crbegin();
20393 }
20394
20419 reverse_iterator rend() noexcept
20420 {
20421 return reverse_iterator(begin());
20422 }
20423
20427 const_reverse_iterator rend() const noexcept
20428 {
20429 return crend();
20430 }
20431
20456 const_reverse_iterator crbegin() const noexcept
20457 {
20458 return const_reverse_iterator(cend());
20459 }
20460
20485 const_reverse_iterator crend() const noexcept
20486 {
20487 return const_reverse_iterator(cbegin());
20488 }
20489
20490 public:
20548 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
20549 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
20550 {
20551 return ref.items();
20552 }
20553
20557 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
20558 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
20559 {
20560 return ref.items();
20561 }
20562
20631 iteration_proxy<iterator> items() noexcept
20632 {
20633 return iteration_proxy<iterator>(*this);
20634 }
20635
20639 iteration_proxy<const_iterator> items() const noexcept
20640 {
20641 return iteration_proxy<const_iterator>(*this);
20642 }
20643
20645
20646
20648 // capacity //
20650
20653
20696 bool empty() const noexcept
20697 {
20698 switch (m_type)
20699 {
20700 case value_t::null:
20701 {
20702 // null values are empty
20703 return true;
20704 }
20705
20706 case value_t::array:
20707 {
20708 // delegate call to array_t::empty()
20709 return m_value.array->empty();
20710 }
20711
20712 case value_t::object:
20713 {
20714 // delegate call to object_t::empty()
20715 return m_value.object->empty();
20716 }
20717
20718 default:
20719 {
20720 // all other types are nonempty
20721 return false;
20722 }
20723 }
20724 }
20725
20769 size_type size() const noexcept
20770 {
20771 switch (m_type)
20772 {
20773 case value_t::null:
20774 {
20775 // null values are empty
20776 return 0;
20777 }
20778
20779 case value_t::array:
20780 {
20781 // delegate call to array_t::size()
20782 return m_value.array->size();
20783 }
20784
20785 case value_t::object:
20786 {
20787 // delegate call to object_t::size()
20788 return m_value.object->size();
20789 }
20790
20791 default:
20792 {
20793 // all other types have size 1
20794 return 1;
20795 }
20796 }
20797 }
20798
20840 size_type max_size() const noexcept
20841 {
20842 switch (m_type)
20843 {
20844 case value_t::array:
20845 {
20846 // delegate call to array_t::max_size()
20847 return m_value.array->max_size();
20848 }
20849
20850 case value_t::object:
20851 {
20852 // delegate call to object_t::max_size()
20853 return m_value.object->max_size();
20854 }
20855
20856 default:
20857 {
20858 // all other types have max_size() == size()
20859 return size();
20860 }
20861 }
20862 }
20863
20865
20866
20868 // modifiers //
20870
20873
20911 void clear() noexcept
20912 {
20913 switch (m_type)
20914 {
20915 case value_t::number_integer:
20916 {
20917 m_value.number_integer = 0;
20918 break;
20919 }
20920
20921 case value_t::number_unsigned:
20922 {
20923 m_value.number_unsigned = 0;
20924 break;
20925 }
20926
20927 case value_t::number_float:
20928 {
20929 m_value.number_float = 0.0;
20930 break;
20931 }
20932
20933 case value_t::boolean:
20934 {
20935 m_value.boolean = false;
20936 break;
20937 }
20938
20939 case value_t::string:
20940 {
20941 m_value.string->clear();
20942 break;
20943 }
20944
20945 case value_t::binary:
20946 {
20947 m_value.binary->clear();
20948 break;
20949 }
20950
20951 case value_t::array:
20952 {
20953 m_value.array->clear();
20954 break;
20955 }
20956
20957 case value_t::object:
20958 {
20959 m_value.object->clear();
20960 break;
20961 }
20962
20963 default:
20964 break;
20965 }
20966 }
20967
20988 void push_back(basic_json&& val)
20989 {
20990 // push_back only works for null objects or arrays
20991 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
20992 {
20993 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
20994 }
20995
20996 // transform null object into an array
20997 if (is_null())
20998 {
20999 m_type = value_t::array;
21000 m_value = value_t::array;
21001 assert_invariant();
21002 }
21003
21004 // add element to array (move semantics)
21005 m_value.array->push_back(std::move(val));
21006 // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
21007 }
21008
21013 reference operator+=(basic_json&& val)
21014 {
21015 push_back(std::move(val));
21016 return *this;
21017 }
21018
21023 void push_back(const basic_json& val)
21024 {
21025 // push_back only works for null objects or arrays
21026 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
21027 {
21028 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21029 }
21030
21031 // transform null object into an array
21032 if (is_null())
21033 {
21034 m_type = value_t::array;
21035 m_value = value_t::array;
21036 assert_invariant();
21037 }
21038
21039 // add element to array
21040 m_value.array->push_back(val);
21041 }
21042
21047 reference operator+=(const basic_json& val)
21048 {
21049 push_back(val);
21050 return *this;
21051 }
21052
21073 void push_back(const typename object_t::value_type& val)
21074 {
21075 // push_back only works for null objects or objects
21076 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_object())))
21077 {
21078 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21079 }
21080
21081 // transform null object into an object
21082 if (is_null())
21083 {
21084 m_type = value_t::object;
21085 m_value = value_t::object;
21086 assert_invariant();
21087 }
21088
21089 // add element to array
21090 m_value.object->insert(val);
21091 }
21092
21097 reference operator+=(const typename object_t::value_type& val)
21098 {
21099 push_back(val);
21100 return *this;
21101 }
21102
21128 void push_back(initializer_list_t init)
21129 {
21130 if (is_object() and init.size() == 2 and (*init.begin())->is_string())
21131 {
21132 basic_json&& key = init.begin()->moved_or_copied();
21133 push_back(typename object_t::value_type(
21134 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
21135 }
21136 else
21137 {
21138 push_back(basic_json(init));
21139 }
21140 }
21141
21146 reference operator+=(initializer_list_t init)
21147 {
21148 push_back(init);
21149 return *this;
21150 }
21151
21175 template<class... Args>
21176 reference emplace_back(Args&& ... args)
21177 {
21178 // emplace_back only works for null objects or arrays
21179 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
21180 {
21181 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
21182 }
21183
21184 // transform null object into an array
21185 if (is_null())
21186 {
21187 m_type = value_t::array;
21188 m_value = value_t::array;
21189 assert_invariant();
21190 }
21191
21192 // add element to array (perfect forwarding)
21193 #ifdef JSON_HAS_CPP_17
21194 return m_value.array->emplace_back(std::forward<Args>(args)...);
21195 #else
21196 m_value.array->emplace_back(std::forward<Args>(args)...);
21197 return m_value.array->back();
21198 #endif
21199 }
21200
21228 template<class... Args>
21229 std::pair<iterator, bool> emplace(Args&& ... args)
21230 {
21231 // emplace only works for null objects or arrays
21232 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_object())))
21233 {
21234 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
21235 }
21236
21237 // transform null object into an object
21238 if (is_null())
21239 {
21240 m_type = value_t::object;
21241 m_value = value_t::object;
21242 assert_invariant();
21243 }
21244
21245 // add element to array (perfect forwarding)
21246 auto res = m_value.object->emplace(std::forward<Args>(args)...);
21247 // create result iterator and set iterator to the result of emplace
21248 auto it = begin();
21249 it.m_it.object_iterator = res.first;
21250
21251 // return pair of iterator and boolean
21252 return {it, res.second};
21253 }
21254
21258 template<typename... Args>
21259 iterator insert_iterator(const_iterator pos, Args&& ... args)
21260 {
21261 iterator result(this);
21262 assert(m_value.array != nullptr);
21263
21264 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
21265 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
21266 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
21267
21268 // This could have been written as:
21269 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
21270 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
21271
21272 return result;
21273 }
21274
21297 iterator insert(const_iterator pos, const basic_json& val)
21298 {
21299 // insert only works for arrays
21300 if (JSON_HEDLEY_LIKELY(is_array()))
21301 {
21302 // check if iterator pos fits to this JSON value
21303 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21304 {
21305 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
21306 }
21307
21308 // insert to array and return iterator
21309 return insert_iterator(pos, val);
21310 }
21311
21312 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
21313 }
21314
21319 iterator insert(const_iterator pos, basic_json&& val)
21320 {
21321 return insert(pos, val);
21322 }
21323
21348 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
21349 {
21350 // insert only works for arrays
21351 if (JSON_HEDLEY_LIKELY(is_array()))
21352 {
21353 // check if iterator pos fits to this JSON value
21354 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21355 {
21356 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
21357 }
21358
21359 // insert to array and return iterator
21360 return insert_iterator(pos, cnt, val);
21361 }
21362
21363 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
21364 }
21365
21396 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
21397 {
21398 // insert only works for arrays
21399 if (JSON_HEDLEY_UNLIKELY(not is_array()))
21400 {
21401 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
21402 }
21403
21404 // check if iterator pos fits to this JSON value
21405 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21406 {
21407 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
21408 }
21409
21410 // check if range iterators belong to the same JSON object
21411 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21412 {
21413 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
21414 }
21415
21416 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
21417 {
21418 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
21419 }
21420
21421 // insert to array and return iterator
21422 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
21423 }
21424
21449 iterator insert(const_iterator pos, initializer_list_t ilist)
21450 {
21451 // insert only works for arrays
21452 if (JSON_HEDLEY_UNLIKELY(not is_array()))
21453 {
21454 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
21455 }
21456
21457 // check if iterator pos fits to this JSON value
21458 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21459 {
21460 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
21461 }
21462
21463 // insert to array and return iterator
21464 return insert_iterator(pos, ilist.begin(), ilist.end());
21465 }
21466
21490 void insert(const_iterator first, const_iterator last)
21491 {
21492 // insert only works for objects
21493 if (JSON_HEDLEY_UNLIKELY(not is_object()))
21494 {
21495 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
21496 }
21497
21498 // check if range iterators belong to the same JSON object
21499 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21500 {
21501 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
21502 }
21503
21504 // passed iterators must belong to objects
21505 if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object()))
21506 {
21507 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
21508 }
21509
21510 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
21511 }
21512
21532 void update(const_reference j)
21533 {
21534 // implicitly convert null value to an empty object
21535 if (is_null())
21536 {
21537 m_type = value_t::object;
21538 m_value.object = create<object_t>();
21539 assert_invariant();
21540 }
21541
21542 if (JSON_HEDLEY_UNLIKELY(not is_object()))
21543 {
21544 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
21545 }
21546 if (JSON_HEDLEY_UNLIKELY(not j.is_object()))
21547 {
21548 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
21549 }
21550
21551 for (auto it = j.cbegin(); it != j.cend(); ++it)
21552 {
21553 m_value.object->operator[](it.key()) = it.value();
21554 }
21555 }
21556
21583 void update(const_iterator first, const_iterator last)
21584 {
21585 // implicitly convert null value to an empty object
21586 if (is_null())
21587 {
21588 m_type = value_t::object;
21589 m_value.object = create<object_t>();
21590 assert_invariant();
21591 }
21592
21593 if (JSON_HEDLEY_UNLIKELY(not is_object()))
21594 {
21595 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
21596 }
21597
21598 // check if range iterators belong to the same JSON object
21599 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21600 {
21601 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
21602 }
21603
21604 // passed iterators must belong to objects
21605 if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object()
21606 or not last.m_object->is_object()))
21607 {
21608 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
21609 }
21610
21611 for (auto it = first; it != last; ++it)
21612 {
21613 m_value.object->operator[](it.key()) = it.value();
21614 }
21615 }
21616
21634 void swap(reference other) noexcept (
21635 std::is_nothrow_move_constructible<value_t>::value and
21636 std::is_nothrow_move_assignable<value_t>::value and
21637 std::is_nothrow_move_constructible<json_value>::value and
21638 std::is_nothrow_move_assignable<json_value>::value
21639 )
21640 {
21641 std::swap(m_type, other.m_type);
21642 std::swap(m_value, other.m_value);
21643 assert_invariant();
21644 }
21645
21666 void swap(array_t& other)
21667 {
21668 // swap only works for arrays
21669 if (JSON_HEDLEY_LIKELY(is_array()))
21670 {
21671 std::swap(*(m_value.array), other);
21672 }
21673 else
21674 {
21675 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
21676 }
21677 }
21678
21699 void swap(object_t& other)
21700 {
21701 // swap only works for objects
21702 if (JSON_HEDLEY_LIKELY(is_object()))
21703 {
21704 std::swap(*(m_value.object), other);
21705 }
21706 else
21707 {
21708 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
21709 }
21710 }
21711
21732 void swap(string_t& other)
21733 {
21734 // swap only works for strings
21735 if (JSON_HEDLEY_LIKELY(is_string()))
21736 {
21737 std::swap(*(m_value.string), other);
21738 }
21739 else
21740 {
21741 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
21742 }
21743 }
21744
21765 void swap(binary_t& other)
21766 {
21767 // swap only works for strings
21768 if (JSON_HEDLEY_LIKELY(is_binary()))
21769 {
21770 std::swap(*(m_value.binary), other);
21771 }
21772 else
21773 {
21774 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
21775 }
21776 }
21777
21779 void swap(typename binary_t::container_type& other)
21780 {
21781 // swap only works for strings
21782 if (JSON_HEDLEY_LIKELY(is_binary()))
21783 {
21784 std::swap(*(m_value.binary), other);
21785 }
21786 else
21787 {
21788 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
21789 }
21790 }
21791
21793
21794 public:
21796 // lexicographical comparison operators //
21798
21801
21857 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
21858 {
21859 const auto lhs_type = lhs.type();
21860 const auto rhs_type = rhs.type();
21861
21862 if (lhs_type == rhs_type)
21863 {
21864 switch (lhs_type)
21865 {
21866 case value_t::array:
21867 return *lhs.m_value.array == *rhs.m_value.array;
21868
21869 case value_t::object:
21870 return *lhs.m_value.object == *rhs.m_value.object;
21871
21872 case value_t::null:
21873 return true;
21874
21875 case value_t::string:
21876 return *lhs.m_value.string == *rhs.m_value.string;
21877
21878 case value_t::boolean:
21879 return lhs.m_value.boolean == rhs.m_value.boolean;
21880
21881 case value_t::number_integer:
21882 return lhs.m_value.number_integer == rhs.m_value.number_integer;
21883
21884 case value_t::number_unsigned:
21885 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
21886
21887 case value_t::number_float:
21888 return lhs.m_value.number_float == rhs.m_value.number_float;
21889
21890 case value_t::binary:
21891 return *lhs.m_value.binary == *rhs.m_value.binary;
21892
21893 default:
21894 return false;
21895 }
21896 }
21897 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
21898 {
21899 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
21900 }
21901 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
21902 {
21903 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
21904 }
21905 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
21906 {
21907 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
21908 }
21909 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
21910 {
21911 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
21912 }
21913 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
21914 {
21915 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
21916 }
21917 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
21918 {
21919 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
21920 }
21921
21922 return false;
21923 }
21924
21929 template<typename ScalarType, typename std::enable_if<
21930 std::is_scalar<ScalarType>::value, int>::type = 0>
21931 friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
21932 {
21933 return lhs == basic_json(rhs);
21934 }
21935
21940 template<typename ScalarType, typename std::enable_if<
21941 std::is_scalar<ScalarType>::value, int>::type = 0>
21942 friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
21943 {
21944 return basic_json(lhs) == rhs;
21945 }
21946
21965 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
21966 {
21967 return not (lhs == rhs);
21968 }
21969
21974 template<typename ScalarType, typename std::enable_if<
21975 std::is_scalar<ScalarType>::value, int>::type = 0>
21976 friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
21977 {
21978 return lhs != basic_json(rhs);
21979 }
21980
21985 template<typename ScalarType, typename std::enable_if<
21986 std::is_scalar<ScalarType>::value, int>::type = 0>
21987 friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
21988 {
21989 return basic_json(lhs) != rhs;
21990 }
21991
22018 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
22019 {
22020 const auto lhs_type = lhs.type();
22021 const auto rhs_type = rhs.type();
22022
22023 if (lhs_type == rhs_type)
22024 {
22025 switch (lhs_type)
22026 {
22027 case value_t::array:
22028 // note parentheses are necessary, see
22029 // https://github.com/nlohmann/json/issues/1530
22030 return (*lhs.m_value.array) < (*rhs.m_value.array);
22031
22032 case value_t::object:
22033 return (*lhs.m_value.object) < (*rhs.m_value.object);
22034
22035 case value_t::null:
22036 return false;
22037
22038 case value_t::string:
22039 return (*lhs.m_value.string) < (*rhs.m_value.string);
22040
22041 case value_t::boolean:
22042 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
22043
22044 case value_t::number_integer:
22045 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
22046
22047 case value_t::number_unsigned:
22048 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
22049
22050 case value_t::number_float:
22051 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
22052
22053 case value_t::binary:
22054 return (*lhs.m_value.binary) < (*rhs.m_value.binary);
22055
22056 default:
22057 return false;
22058 }
22059 }
22060 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
22061 {
22062 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
22063 }
22064 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
22065 {
22066 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
22067 }
22068 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
22069 {
22070 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
22071 }
22072 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
22073 {
22074 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
22075 }
22076 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
22077 {
22078 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22079 }
22080 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
22081 {
22082 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
22083 }
22084
22085 // We only reach this line if we cannot compare values. In that case,
22086 // we compare types. Note we have to call the operator explicitly,
22087 // because MSVC has problems otherwise.
22088 return operator<(lhs_type, rhs_type);
22089 }
22090
22095 template<typename ScalarType, typename std::enable_if<
22096 std::is_scalar<ScalarType>::value, int>::type = 0>
22097 friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
22098 {
22099 return lhs < basic_json(rhs);
22100 }
22101
22106 template<typename ScalarType, typename std::enable_if<
22107 std::is_scalar<ScalarType>::value, int>::type = 0>
22108 friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
22109 {
22110 return basic_json(lhs) < rhs;
22111 }
22112
22132 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
22133 {
22134 return not (rhs < lhs);
22135 }
22136
22141 template<typename ScalarType, typename std::enable_if<
22142 std::is_scalar<ScalarType>::value, int>::type = 0>
22143 friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
22144 {
22145 return lhs <= basic_json(rhs);
22146 }
22147
22152 template<typename ScalarType, typename std::enable_if<
22153 std::is_scalar<ScalarType>::value, int>::type = 0>
22154 friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
22155 {
22156 return basic_json(lhs) <= rhs;
22157 }
22158
22178 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
22179 {
22180 return not (lhs <= rhs);
22181 }
22182
22187 template<typename ScalarType, typename std::enable_if<
22188 std::is_scalar<ScalarType>::value, int>::type = 0>
22189 friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
22190 {
22191 return lhs > basic_json(rhs);
22192 }
22193
22198 template<typename ScalarType, typename std::enable_if<
22199 std::is_scalar<ScalarType>::value, int>::type = 0>
22200 friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
22201 {
22202 return basic_json(lhs) > rhs;
22203 }
22204
22224 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
22225 {
22226 return not (lhs < rhs);
22227 }
22228
22233 template<typename ScalarType, typename std::enable_if<
22234 std::is_scalar<ScalarType>::value, int>::type = 0>
22235 friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
22236 {
22237 return lhs >= basic_json(rhs);
22238 }
22239
22244 template<typename ScalarType, typename std::enable_if<
22245 std::is_scalar<ScalarType>::value, int>::type = 0>
22246 friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
22247 {
22248 return basic_json(lhs) >= rhs;
22249 }
22250
22252
22254 // serialization //
22256
22259
22291 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
22292 {
22293 // read width member and use it as indentation parameter if nonzero
22294 const bool pretty_print = o.width() > 0;
22295 const auto indentation = pretty_print ? o.width() : 0;
22296
22297 // reset width to 0 for subsequent calls to this stream
22298 o.width(0);
22299
22300 // do the actual serialization
22301 serializer s(detail::output_adapter<char>(o), o.fill());
22302 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
22303 return o;
22304 }
22305
22314 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
22315 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
22316 {
22317 return o << j;
22318 }
22319
22321
22322
22324 // deserialization //
22326
22329
22377 template<typename InputType>
22378
22379 static basic_json parse(InputType&& i,
22380 const parser_callback_t cb = nullptr,
22381 const bool allow_exceptions = true)
22382 {
22383 basic_json result;
22384 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions).parse(true, result);
22385 return result;
22386 }
22387
22411 template<typename IteratorType>
22412
22413 static basic_json parse(IteratorType first,
22414 IteratorType last,
22415 const parser_callback_t cb = nullptr,
22416 const bool allow_exceptions = true)
22417 {
22418 basic_json result;
22419 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions).parse(true, result);
22420 return result;
22421 }
22422
22423
22424 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
22425 static basic_json parse(detail::span_input_adapter&& i,
22426 const parser_callback_t cb = nullptr,
22427 const bool allow_exceptions = true)
22428 {
22429 basic_json result;
22430 parser(i.get(), cb, allow_exceptions).parse(true, result);
22431 return result;
22432 }
22433
22461 template<typename InputType>
22462 static bool accept(InputType&& i)
22463 {
22464 return parser(detail::input_adapter(std::forward<InputType>(i))).accept(true);
22465 }
22466
22467 template<typename IteratorType>
22468 static bool accept(IteratorType first, IteratorType last)
22469 {
22470 return parser(detail::input_adapter(std::move(first), std::move(last))).accept(true);
22471 }
22472
22473
22474 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
22475 static bool accept(detail::span_input_adapter&& i)
22476 {
22477 return parser(i.get()).accept(true);
22478 }
22479
22517 template <typename InputType, typename SAX>
22518 JSON_HEDLEY_NON_NULL(2)
22519 static bool sax_parse(InputType&& i, SAX* sax,
22520 input_format_t format = input_format_t::json,
22521 const bool strict = true)
22522 {
22523 auto ia = detail::input_adapter(std::forward<InputType>(i));
22524 return format == input_format_t::json
22525 ? parser(std::move(ia)).sax_parse(sax, strict)
22526 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
22527 }
22528
22529 template<class IteratorType, class SAX>
22530 JSON_HEDLEY_NON_NULL(3)
22531 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
22532 input_format_t format = input_format_t::json,
22533 const bool strict = true)
22534 {
22535 auto ia = detail::input_adapter(std::move(first), std::move(last));
22536 return format == input_format_t::json
22537 ? parser(std::move(ia)).sax_parse(sax, strict)
22538 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
22539 }
22540
22541 template <typename SAX>
22542 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
22543 JSON_HEDLEY_NON_NULL(2)
22544 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
22545 input_format_t format = input_format_t::json,
22546 const bool strict = true)
22547 {
22548 auto ia = i.get();
22549 return format == input_format_t::json
22550 ? parser(std::move(ia)).sax_parse(sax, strict)
22551 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
22552 }
22553
22562 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
22563 friend std::istream& operator<<(basic_json& j, std::istream& i)
22564 {
22565 return operator>>(i, j);
22566 }
22567
22593 friend std::istream& operator>>(std::istream& i, basic_json& j)
22594 {
22595 parser(detail::input_adapter(i)).parse(false, j);
22596 return i;
22597 }
22598
22600
22602 // convenience functions //
22604
22636
22637 const char* type_name() const noexcept
22638 {
22639 {
22640 switch (m_type)
22641 {
22642 case value_t::null:
22643 return "null";
22644 case value_t::object:
22645 return "object";
22646 case value_t::array:
22647 return "array";
22648 case value_t::string:
22649 return "string";
22650 case value_t::boolean:
22651 return "boolean";
22652 case value_t::binary:
22653 return "binary";
22654 case value_t::discarded:
22655 return "discarded";
22656 default:
22657 return "number";
22658 }
22659 }
22660 }
22661
22662
22663 private:
22665 // member variables //
22667
22669 value_t m_type = value_t::null;
22670
22672 json_value m_value = {};
22673
22675 // binary serialization/deserialization //
22677
22680
22681 public:
22777 static std::vector<uint8_t> to_cbor(const basic_json& j)
22778 {
22779 std::vector<uint8_t> result;
22780 to_cbor(j, result);
22781 return result;
22782 }
22783
22784 static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
22785 {
22786 binary_writer<uint8_t>(o).write_cbor(j);
22787 }
22788
22789 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
22790 {
22791 binary_writer<char>(o).write_cbor(j);
22792 }
22793
22874 static std::vector<uint8_t> to_msgpack(const basic_json& j)
22875 {
22876 std::vector<uint8_t> result;
22877 to_msgpack(j, result);
22878 return result;
22879 }
22880
22881 static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
22882 {
22883 binary_writer<uint8_t>(o).write_msgpack(j);
22884 }
22885
22886 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
22887 {
22888 binary_writer<char>(o).write_msgpack(j);
22889 }
22890
22977 static std::vector<uint8_t> to_ubjson(const basic_json& j,
22978 const bool use_size = false,
22979 const bool use_type = false)
22980 {
22981 std::vector<uint8_t> result;
22982 to_ubjson(j, result, use_size, use_type);
22983 return result;
22984 }
22985
22986 static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
22987 const bool use_size = false, const bool use_type = false)
22988 {
22989 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
22990 }
22991
22992 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
22993 const bool use_size = false, const bool use_type = false)
22994 {
22995 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
22996 }
22997
22998
23055 static std::vector<uint8_t> to_bson(const basic_json& j)
23056 {
23057 std::vector<uint8_t> result;
23058 to_bson(j, result);
23059 return result;
23060 }
23061
23070 static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
23071 {
23072 binary_writer<uint8_t>(o).write_bson(j);
23073 }
23074
23078 static void to_bson(const basic_json& j, detail::output_adapter<char> o)
23079 {
23080 binary_writer<char>(o).write_bson(j);
23081 }
23082
23083
23186 template<typename InputType>
23187
23188 static basic_json from_cbor(InputType&& i,
23189 const bool strict = true,
23190 const bool allow_exceptions = true)
23191 {
23192 basic_json result;
23193 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23194 auto ia = detail::input_adapter(std::forward<InputType>(i));
23195 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict);
23196 return res ? result : basic_json(value_t::discarded);
23197 }
23198
23202 template<typename IteratorType>
23203
23204 static basic_json from_cbor(IteratorType first, IteratorType last,
23205 const bool strict = true,
23206 const bool allow_exceptions = true)
23207 {
23208 basic_json result;
23209 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23210 auto ia = detail::input_adapter(std::move(first), std::move(last));
23211 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict);
23212 return res ? result : basic_json(value_t::discarded);
23213 }
23214
23215 template<typename T>
23216
23217 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23218 static basic_json from_cbor(const T* ptr, std::size_t len,
23219 const bool strict = true,
23220 const bool allow_exceptions = true)
23221 {
23222 return from_cbor(ptr, ptr + len, strict, allow_exceptions);
23223 }
23224
23225
23226
23227 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23228 static basic_json from_cbor(detail::span_input_adapter&& i,
23229 const bool strict = true,
23230 const bool allow_exceptions = true)
23231 {
23232 basic_json result;
23233 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23234 auto ia = i.get();
23235 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict);
23236 return res ? result : basic_json(value_t::discarded);
23237 }
23238
23325 template<typename InputType>
23326
23327 static basic_json from_msgpack(InputType&& i,
23328 const bool strict = true,
23329 const bool allow_exceptions = true)
23330 {
23331 basic_json result;
23332 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23333 auto ia = detail::input_adapter(std::forward<InputType>(i));
23334 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
23335 return res ? result : basic_json(value_t::discarded);
23336 }
23337
23341 template<typename IteratorType>
23342
23343 static basic_json from_msgpack(IteratorType first, IteratorType last,
23344 const bool strict = true,
23345 const bool allow_exceptions = true)
23346 {
23347 basic_json result;
23348 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23349 auto ia = detail::input_adapter(std::move(first), std::move(last));
23350 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
23351 return res ? result : basic_json(value_t::discarded);
23352 }
23353
23354
23355 template<typename T>
23356
23357 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
23358 static basic_json from_msgpack(const T* ptr, std::size_t len,
23359 const bool strict = true,
23360 const bool allow_exceptions = true)
23361 {
23362 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
23363 }
23364
23365
23366 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
23367 static basic_json from_msgpack(detail::span_input_adapter&& i,
23368 const bool strict = true,
23369 const bool allow_exceptions = true)
23370 {
23371 basic_json result;
23372 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23373 auto ia = i.get();
23374 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
23375 return res ? result : basic_json(value_t::discarded);
23376 }
23377
23378
23440 template<typename InputType>
23441
23442 static basic_json from_ubjson(InputType&& i,
23443 const bool strict = true,
23444 const bool allow_exceptions = true)
23445 {
23446 basic_json result;
23447 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23448 auto ia = detail::input_adapter(std::forward<InputType>(i));
23449 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
23450 return res ? result : basic_json(value_t::discarded);
23451 }
23452
23456 template<typename IteratorType>
23457
23458 static basic_json from_ubjson(IteratorType first, IteratorType last,
23459 const bool strict = true,
23460 const bool allow_exceptions = true)
23461 {
23462 basic_json result;
23463 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23464 auto ia = detail::input_adapter(std::move(first), std::move(last));
23465 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
23466 return res ? result : basic_json(value_t::discarded);
23467 }
23468
23469 template<typename T>
23470
23471 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
23472 static basic_json from_ubjson(const T* ptr, std::size_t len,
23473 const bool strict = true,
23474 const bool allow_exceptions = true)
23475 {
23476 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
23477 }
23478
23479
23480 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
23481 static basic_json from_ubjson(detail::span_input_adapter&& i,
23482 const bool strict = true,
23483 const bool allow_exceptions = true)
23484 {
23485 basic_json result;
23486 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23487 auto ia = i.get();
23488 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
23489 return res ? result : basic_json(value_t::discarded);
23490 }
23491
23492
23553 template<typename InputType>
23554
23555 static basic_json from_bson(InputType&& i,
23556 const bool strict = true,
23557 const bool allow_exceptions = true)
23558 {
23559 basic_json result;
23560 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23561 auto ia = detail::input_adapter(std::forward<InputType>(i));
23562 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
23563 return res ? result : basic_json(value_t::discarded);
23564 }
23565
23569 template<typename IteratorType>
23570
23571 static basic_json from_bson(IteratorType first, IteratorType last,
23572 const bool strict = true,
23573 const bool allow_exceptions = true)
23574 {
23575 basic_json result;
23576 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23577 auto ia = detail::input_adapter(std::move(first), std::move(last));
23578 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
23579 return res ? result : basic_json(value_t::discarded);
23580 }
23581
23582 template<typename T>
23583
23584 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
23585 static basic_json from_bson(const T* ptr, std::size_t len,
23586 const bool strict = true,
23587 const bool allow_exceptions = true)
23588 {
23589 return from_bson(ptr, ptr + len, strict, allow_exceptions);
23590 }
23591
23592
23593 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
23594 static basic_json from_bson(detail::span_input_adapter&& i,
23595 const bool strict = true,
23596 const bool allow_exceptions = true)
23597 {
23598 basic_json result;
23599 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23600 auto ia = i.get();
23601 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
23602 return res ? result : basic_json(value_t::discarded);
23603 }
23605
23607 // JSON Pointer support //
23609
23612
23646 reference operator[](const json_pointer& ptr)
23647 {
23648 return ptr.get_unchecked(this);
23649 }
23650
23674 const_reference operator[](const json_pointer& ptr) const
23675 {
23676 return ptr.get_unchecked(this);
23677 }
23678
23717 reference at(const json_pointer& ptr)
23718 {
23719 return ptr.get_checked(this);
23720 }
23721
23760 const_reference at(const json_pointer& ptr) const
23761 {
23762 return ptr.get_checked(this);
23763 }
23764
23787 basic_json flatten() const
23788 {
23789 basic_json result(value_t::object);
23790 json_pointer::flatten("", *this, result);
23791 return result;
23792 }
23793
23824 basic_json unflatten() const
23825 {
23826 return json_pointer::unflatten(*this);
23827 }
23828
23830
23832 // JSON Patch functions //
23834
23837
23885 basic_json patch(const basic_json& json_patch) const
23886 {
23887 // make a working copy to apply the patch to
23888 basic_json result = *this;
23889
23890 // the valid JSON Patch operations
23891 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
23892
23893 const auto get_op = [](const std::string & op)
23894 {
23895 if (op == "add")
23896 {
23897 return patch_operations::add;
23898 }
23899 if (op == "remove")
23900 {
23901 return patch_operations::remove;
23902 }
23903 if (op == "replace")
23904 {
23905 return patch_operations::replace;
23906 }
23907 if (op == "move")
23908 {
23909 return patch_operations::move;
23910 }
23911 if (op == "copy")
23912 {
23913 return patch_operations::copy;
23914 }
23915 if (op == "test")
23916 {
23917 return patch_operations::test;
23918 }
23919
23920 return patch_operations::invalid;
23921 };
23922
23923 // wrapper for "add" operation; add value at ptr
23924 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
23925 {
23926 // adding to the root of the target document means replacing it
23927 if (ptr.empty())
23928 {
23929 result = val;
23930 return;
23931 }
23932
23933 // make sure the top element of the pointer exists
23934 json_pointer top_pointer = ptr.top();
23935 if (top_pointer != ptr)
23936 {
23937 result.at(top_pointer);
23938 }
23939
23940 // get reference to parent of JSON pointer ptr
23941 const auto last_path = ptr.back();
23942 ptr.pop_back();
23943 basic_json& parent = result[ptr];
23944
23945 switch (parent.m_type)
23946 {
23947 case value_t::null:
23948 case value_t::object:
23949 {
23950 // use operator[] to add value
23951 parent[last_path] = val;
23952 break;
23953 }
23954
23955 case value_t::array:
23956 {
23957 if (last_path == "-")
23958 {
23959 // special case: append to back
23960 parent.push_back(val);
23961 }
23962 else
23963 {
23964 const auto idx = json_pointer::array_index(last_path);
23965 if (JSON_HEDLEY_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
23966 {
23967 // avoid undefined behavior
23968 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
23969 }
23970
23971 // default case: insert add offset
23972 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
23973 }
23974 break;
23975 }
23976
23977 // if there exists a parent it cannot be primitive
23978 default: // LCOV_EXCL_LINE
23979 assert(false); // LCOV_EXCL_LINE
23980 }
23981 };
23982
23983 // wrapper for "remove" operation; remove value at ptr
23984 const auto operation_remove = [&result](json_pointer & ptr)
23985 {
23986 // get reference to parent of JSON pointer ptr
23987 const auto last_path = ptr.back();
23988 ptr.pop_back();
23989 basic_json& parent = result.at(ptr);
23990
23991 // remove child
23992 if (parent.is_object())
23993 {
23994 // perform range check
23995 auto it = parent.find(last_path);
23996 if (JSON_HEDLEY_LIKELY(it != parent.end()))
23997 {
23998 parent.erase(it);
23999 }
24000 else
24001 {
24002 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
24003 }
24004 }
24005 else if (parent.is_array())
24006 {
24007 // note erase performs range check
24008 parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
24009 }
24010 };
24011
24012 // type check: top level value must be an array
24013 if (JSON_HEDLEY_UNLIKELY(not json_patch.is_array()))
24014 {
24015 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24016 }
24017
24018 // iterate and apply the operations
24019 for (const auto& val : json_patch)
24020 {
24021 // wrapper to get a value for an operation
24022 const auto get_value = [&val](const std::string & op,
24023 const std::string & member,
24024 bool string_type) -> basic_json &
24025 {
24026 // find value
24027 auto it = val.m_value.object->find(member);
24028
24029 // context-sensitive error message
24030 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
24031
24032 // check if desired value is present
24033 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
24034 {
24035 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
24036 }
24037
24038 // check if result is of type string
24039 if (JSON_HEDLEY_UNLIKELY(string_type and not it->second.is_string()))
24040 {
24041 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
24042 }
24043
24044 // no error: return value
24045 return it->second;
24046 };
24047
24048 // type check: every element of the array must be an object
24049 if (JSON_HEDLEY_UNLIKELY(not val.is_object()))
24050 {
24051 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24052 }
24053
24054 // collect mandatory members
24055 const std::string op = get_value("op", "op", true);
24056 const std::string path = get_value(op, "path", true);
24057 json_pointer ptr(path);
24058
24059 switch (get_op(op))
24060 {
24061 case patch_operations::add:
24062 {
24063 operation_add(ptr, get_value("add", "value", false));
24064 break;
24065 }
24066
24067 case patch_operations::remove:
24068 {
24069 operation_remove(ptr);
24070 break;
24071 }
24072
24073 case patch_operations::replace:
24074 {
24075 // the "path" location must exist - use at()
24076 result.at(ptr) = get_value("replace", "value", false);
24077 break;
24078 }
24079
24080 case patch_operations::move:
24081 {
24082 const std::string from_path = get_value("move", "from", true);
24083 json_pointer from_ptr(from_path);
24084
24085 // the "from" location must exist - use at()
24086 basic_json v = result.at(from_ptr);
24087
24088 // The move operation is functionally identical to a
24089 // "remove" operation on the "from" location, followed
24090 // immediately by an "add" operation at the target
24091 // location with the value that was just removed.
24092 operation_remove(from_ptr);
24093 operation_add(ptr, v);
24094 break;
24095 }
24096
24097 case patch_operations::copy:
24098 {
24099 const std::string from_path = get_value("copy", "from", true);
24100 const json_pointer from_ptr(from_path);
24101
24102 // the "from" location must exist - use at()
24103 basic_json v = result.at(from_ptr);
24104
24105 // The copy is functionally identical to an "add"
24106 // operation at the target location using the value
24107 // specified in the "from" member.
24108 operation_add(ptr, v);
24109 break;
24110 }
24111
24112 case patch_operations::test:
24113 {
24114 bool success = false;
24115 JSON_TRY
24116 {
24117 // check if "value" matches the one at "path"
24118 // the "path" location must exist - use at()
24119 success = (result.at(ptr) == get_value("test", "value", false));
24120 }
24121 JSON_INTERNAL_CATCH (out_of_range&)
24122 {
24123 // ignore out of range errors: success remains false
24124 }
24125
24126 // throw an exception if test fails
24127 if (JSON_HEDLEY_UNLIKELY(not success))
24128 {
24129 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
24130 }
24131
24132 break;
24133 }
24134
24135 default:
24136 {
24137 // op must be "add", "remove", "replace", "move", "copy", or
24138 // "test"
24139 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
24140 }
24141 }
24142 }
24143
24144 return result;
24145 }
24146
24180
24181 static basic_json diff(const basic_json& source, const basic_json& target,
24182 const std::string& path = "")
24183 {
24184 // the patch
24185 basic_json result(value_t::array);
24186
24187 // if the values are the same, return empty patch
24188 if (source == target)
24189 {
24190 return result;
24191 }
24192
24193 if (source.type() != target.type())
24194 {
24195 // different types: replace value
24196 result.push_back(
24197 {
24198 {"op", "replace"}, {"path", path}, {"value", target}
24199 });
24200 return result;
24201 }
24202
24203 switch (source.type())
24204 {
24205 case value_t::array:
24206 {
24207 // first pass: traverse common elements
24208 std::size_t i = 0;
24209 while (i < source.size() and i < target.size())
24210 {
24211 // recursive call to compare array values at index i
24212 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
24213 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24214 ++i;
24215 }
24216
24217 // i now reached the end of at least one array
24218 // in a second pass, traverse the remaining elements
24219
24220 // remove my remaining elements
24221 const auto end_index = static_cast<difference_type>(result.size());
24222 while (i < source.size())
24223 {
24224 // add operations in reverse order to avoid invalid
24225 // indices
24226 result.insert(result.begin() + end_index, object(
24227 {
24228 {"op", "remove"},
24229 {"path", path + "/" + std::to_string(i)}
24230 }));
24231 ++i;
24232 }
24233
24234 // add other remaining elements
24235 while (i < target.size())
24236 {
24237 result.push_back(
24238 {
24239 {"op", "add"},
24240 {"path", path + "/-"},
24241 {"value", target[i]}
24242 });
24243 ++i;
24244 }
24245
24246 break;
24247 }
24248
24249 case value_t::object:
24250 {
24251 // first pass: traverse this object's elements
24252 for (auto it = source.cbegin(); it != source.cend(); ++it)
24253 {
24254 // escape the key name to be used in a JSON patch
24255 const auto key = json_pointer::escape(it.key());
24256
24257 if (target.find(it.key()) != target.end())
24258 {
24259 // recursive call to compare object values at key it
24260 auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
24261 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24262 }
24263 else
24264 {
24265 // found a key that is not in o -> remove it
24266 result.push_back(object(
24267 {
24268 {"op", "remove"}, {"path", path + "/" + key}
24269 }));
24270 }
24271 }
24272
24273 // second pass: traverse other object's elements
24274 for (auto it = target.cbegin(); it != target.cend(); ++it)
24275 {
24276 if (source.find(it.key()) == source.end())
24277 {
24278 // found a key that is not in this -> add it
24279 const auto key = json_pointer::escape(it.key());
24280 result.push_back(
24281 {
24282 {"op", "add"}, {"path", path + "/" + key},
24283 {"value", it.value()}
24284 });
24285 }
24286 }
24287
24288 break;
24289 }
24290
24291 default:
24292 {
24293 // both primitive type: replace value
24294 result.push_back(
24295 {
24296 {"op", "replace"}, {"path", path}, {"value", target}
24297 });
24298 break;
24299 }
24300 }
24301
24302 return result;
24303 }
24304
24306
24308 // JSON Merge Patch functions //
24310
24313
24356 void merge_patch(const basic_json& apply_patch)
24357 {
24358 if (apply_patch.is_object())
24359 {
24360 if (not is_object())
24361 {
24362 *this = object();
24363 }
24364 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
24365 {
24366 if (it.value().is_null())
24367 {
24368 erase(it.key());
24369 }
24370 else
24371 {
24372 operator[](it.key()).merge_patch(it.value());
24373 }
24374 }
24375 }
24376 else
24377 {
24378 *this = apply_patch;
24379 }
24380 }
24381
24383 };
24384
24394 NLOHMANN_BASIC_JSON_TPL_DECLARATION
24395 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
24396 {
24397 return j.dump();
24398 }
24399 } // namespace nlohmann
24400
24402 // nonmember support //
24404
24405 // specialization of std::swap, and std::hash
24406 namespace std
24407 {
24408
24410 template<>
24411 struct hash<nlohmann::json>
24412 {
24418 std::size_t operator()(const nlohmann::json& j) const
24419 {
24420 // a naive hashing via the string representation
24421 const auto& h = hash<nlohmann::json::string_t>();
24422 return h(j.dump());
24423 }
24424 };
24425
24429 template<>
24430 struct less<::nlohmann::detail::value_t>
24431 {
24436 bool operator()(nlohmann::detail::value_t lhs,
24437 nlohmann::detail::value_t rhs) const noexcept
24438 {
24439 return nlohmann::detail::operator<(lhs, rhs);
24440 }
24441 };
24442
24448 template<>
24449 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
24450 is_nothrow_move_constructible<nlohmann::json>::value and
24451 is_nothrow_move_assignable<nlohmann::json>::value
24452 )
24453 {
24454 j1.swap(j2);
24455 }
24456
24457 } // namespace std
24458
24472 JSON_HEDLEY_NON_NULL(1)
24473 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
24474 {
24475 return nlohmann::json::parse(s, s + n);
24476 }
24477
24491 JSON_HEDLEY_NON_NULL(1)
24492 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
24493 {
24494 return nlohmann::json::json_pointer(std::string(s, n));
24495 }
24496
24497 // #include <nlohmann/detail/macro_unscope.hpp>
24498
24499
24500 // restore GCC/clang diagnostic settings
24501 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
24502 #pragma GCC diagnostic pop
24503 #endif
24504 #if defined(__clang__)
24505 #pragma GCC diagnostic pop
24506 #endif
24507
24508 // clean up
24509 #undef JSON_INTERNAL_CATCH
24510 #undef JSON_CATCH
24511 #undef JSON_THROW
24512 #undef JSON_TRY
24513 #undef JSON_HAS_CPP_14
24514 #undef JSON_HAS_CPP_17
24515 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
24516 #undef NLOHMANN_BASIC_JSON_TPL
24517
24518 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
24519 #undef JSON_HEDLEY_ALWAYS_INLINE
24520 #undef JSON_HEDLEY_ARM_VERSION
24521 #undef JSON_HEDLEY_ARM_VERSION_CHECK
24522 #undef JSON_HEDLEY_ARRAY_PARAM
24523 #undef JSON_HEDLEY_ASSUME
24524 #undef JSON_HEDLEY_BEGIN_C_DECLS
24525 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
24526 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
24527 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
24528 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
24529 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
24530 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
24531 #undef JSON_HEDLEY_CLANG_HAS_WARNING
24532 #undef JSON_HEDLEY_COMPCERT_VERSION
24533 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
24534 #undef JSON_HEDLEY_CONCAT
24535 #undef JSON_HEDLEY_CONCAT3
24536 #undef JSON_HEDLEY_CONCAT3_EX
24537 #undef JSON_HEDLEY_CONCAT_EX
24538 #undef JSON_HEDLEY_CONST
24539 #undef JSON_HEDLEY_CONSTEXPR
24540 #undef JSON_HEDLEY_CONST_CAST
24541 #undef JSON_HEDLEY_CPP_CAST
24542 #undef JSON_HEDLEY_CRAY_VERSION
24543 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
24544 #undef JSON_HEDLEY_C_DECL
24545 #undef JSON_HEDLEY_DEPRECATED
24546 #undef JSON_HEDLEY_DEPRECATED_FOR
24547 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
24548 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
24549 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
24550 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
24551 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
24552 #undef JSON_HEDLEY_DIAGNOSTIC_POP
24553 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
24554 #undef JSON_HEDLEY_DMC_VERSION
24555 #undef JSON_HEDLEY_DMC_VERSION_CHECK
24556 #undef JSON_HEDLEY_EMPTY_BASES
24557 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
24558 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
24559 #undef JSON_HEDLEY_END_C_DECLS
24560 #undef JSON_HEDLEY_FLAGS
24561 #undef JSON_HEDLEY_FLAGS_CAST
24562 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
24563 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
24564 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
24565 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
24566 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
24567 #undef JSON_HEDLEY_GCC_HAS_FEATURE
24568 #undef JSON_HEDLEY_GCC_HAS_WARNING
24569 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
24570 #undef JSON_HEDLEY_GCC_VERSION
24571 #undef JSON_HEDLEY_GCC_VERSION_CHECK
24572 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
24573 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
24574 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
24575 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
24576 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
24577 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
24578 #undef JSON_HEDLEY_GNUC_HAS_WARNING
24579 #undef JSON_HEDLEY_GNUC_VERSION
24580 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
24581 #undef JSON_HEDLEY_HAS_ATTRIBUTE
24582 #undef JSON_HEDLEY_HAS_BUILTIN
24583 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
24584 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
24585 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
24586 #undef JSON_HEDLEY_HAS_EXTENSION
24587 #undef JSON_HEDLEY_HAS_FEATURE
24588 #undef JSON_HEDLEY_HAS_WARNING
24589 #undef JSON_HEDLEY_IAR_VERSION
24590 #undef JSON_HEDLEY_IAR_VERSION_CHECK
24591 #undef JSON_HEDLEY_IBM_VERSION
24592 #undef JSON_HEDLEY_IBM_VERSION_CHECK
24593 #undef JSON_HEDLEY_IMPORT
24594 #undef JSON_HEDLEY_INLINE
24595 #undef JSON_HEDLEY_INTEL_VERSION
24596 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
24597 #undef JSON_HEDLEY_IS_CONSTANT
24598 #undef JSON_HEDLEY_IS_CONSTEXPR_
24599 #undef JSON_HEDLEY_LIKELY
24600 #undef JSON_HEDLEY_MALLOC
24601 #undef JSON_HEDLEY_MESSAGE
24602 #undef JSON_HEDLEY_MSVC_VERSION
24603 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
24604 #undef JSON_HEDLEY_NEVER_INLINE
24605 #undef JSON_HEDLEY_NON_NULL
24606 #undef JSON_HEDLEY_NO_ESCAPE
24607 #undef JSON_HEDLEY_NO_RETURN
24608 #undef JSON_HEDLEY_NO_THROW
24609 #undef JSON_HEDLEY_NULL
24610 #undef JSON_HEDLEY_PELLES_VERSION
24611 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
24612 #undef JSON_HEDLEY_PGI_VERSION
24613 #undef JSON_HEDLEY_PGI_VERSION_CHECK
24614 #undef JSON_HEDLEY_PREDICT
24615 #undef JSON_HEDLEY_PRINTF_FORMAT
24616 #undef JSON_HEDLEY_PRIVATE
24617 #undef JSON_HEDLEY_PUBLIC
24618 #undef JSON_HEDLEY_PURE
24619 #undef JSON_HEDLEY_REINTERPRET_CAST
24620 #undef JSON_HEDLEY_REQUIRE
24621 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
24622 #undef JSON_HEDLEY_REQUIRE_MSG
24623 #undef JSON_HEDLEY_RESTRICT
24624 #undef
24625 #undef JSON_HEDLEY_SENTINEL
24626 #undef JSON_HEDLEY_STATIC_ASSERT
24627 #undef JSON_HEDLEY_STATIC_CAST
24628 #undef JSON_HEDLEY_STRINGIFY
24629 #undef JSON_HEDLEY_STRINGIFY_EX
24630 #undef JSON_HEDLEY_SUNPRO_VERSION
24631 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
24632 #undef JSON_HEDLEY_TINYC_VERSION
24633 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
24634 #undef JSON_HEDLEY_TI_ARMCL_VERSION
24635 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
24636 #undef JSON_HEDLEY_TI_CL2000_VERSION
24637 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
24638 #undef JSON_HEDLEY_TI_CL430_VERSION
24639 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
24640 #undef JSON_HEDLEY_TI_CL6X_VERSION
24641 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
24642 #undef JSON_HEDLEY_TI_CL7X_VERSION
24643 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
24644 #undef JSON_HEDLEY_TI_CLPRU_VERSION
24645 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
24646 #undef JSON_HEDLEY_TI_VERSION
24647 #undef JSON_HEDLEY_TI_VERSION_CHECK
24648 #undef JSON_HEDLEY_UNAVAILABLE
24649 #undef JSON_HEDLEY_UNLIKELY
24650 #undef JSON_HEDLEY_UNPREDICTABLE
24651 #undef JSON_HEDLEY_UNREACHABLE
24652 #undef JSON_HEDLEY_UNREACHABLE_RETURN
24653 #undef JSON_HEDLEY_VERSION
24654 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
24655 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
24656 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
24657 #undef JSON_HEDLEY_VERSION_ENCODE
24658 #undef JSON_HEDLEY_WARNING
24659 #undef
24660 #undef _MSG
24661 #undef JSON_HEDLEY_FALL_THROUGH
24662
24663
24664
24665 #endif // INCLUDE_NLOHMANN_JSON_HPP_
nlohmann::basic_json::to_msgpack
static std::vector< uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:22884
nlohmann::basic_json::erase
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:19801
nlohmann::basic_json::value_t
detail::value_t value_t
Definition: json.hpp:16005
nlohmann::json_sax::boolean
virtual bool boolean(bool val)=0
a boolean value was read
nlohmann::basic_json::begin
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:20251
nlohmann::json_sax::number_integer
virtual bool number_integer(number_integer_t val)=0
an integer number was read
nlohmann::byte_container_with_subtype::operator==
bool operator==(const byte_container_with_subtype &rhs) const
Definition: json.hpp:4280
nlohmann::basic_json::dump
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition: json.hpp:18047
nlohmann::basic_json::contains
bool contains(KeyT &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:20181
nlohmann::basic_json::basic_json
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:17630
nlohmann::basic_json::const_iterator
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.hpp:16076
nlohmann::basic_json::from_msgpack
static basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:23337
nlohmann::basic_json::get
ValueType get() const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >())))
get a value (explicit); special case
Definition: json.hpp:18748
nlohmann::basic_json::meta
static basic_json meta()
returns version information on the library
Definition: json.hpp:16120
nlohmann::basic_json::number_unsigned_t
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:16548
nlohmann::basic_json::unflatten
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:23834
nlohmann::basic_json::operator>>
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:22325
nlohmann::byte_container_with_subtype::set_subtype
void set_subtype(std::uint8_t subtype) noexcept
sets the binary subtype
Definition: json.hpp:4309
nlohmann::basic_json::other_error
detail::other_error other_error
exception indicating other library errors
Definition: json.hpp:16038
nlohmann::basic_json::number_integer_t
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:16477
nlohmann::basic_json::allocator_type
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:16066
nlohmann::basic_json::object
static basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:17603
nlohmann::basic_json::array_t
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:16326
nlohmann::basic_json::basic_json
basic_json(const JsonRef &ref)
Definition: json.hpp:17798
nlohmann::basic_json::operator>
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:22188
nlohmann::basic_json::size
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:20779
nlohmann::basic_json::basic_json
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:17253
nlohmann::json_sax::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:4911
nlohmann::basic_json::invalid_iterator
detail::invalid_iterator invalid_iterator
exception indicating errors with iterators
Definition: json.hpp:16032
nlohmann::json_pointer::back
const std::string & back() const
return last reference token
Definition: json.hpp:11302
nlohmann::json_sax::start_object
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
nlohmann::json_pointer::to_string
std::string to_string() const
return a string representation of the JSON pointer
Definition: json.hpp:11096
nlohmann::basic_json::operator==
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:21867
nlohmann::basic_json::difference_type
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:16061
nlohmann::basic_json::at
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:19069
nlohmann::basic_json::get_to
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
Definition: json.hpp:18794
nlohmann::basic_json::object_t
ObjectType< StringType, basic_json, object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > >> object_t
a type for an object
Definition: json.hpp:16280
nlohmann::basic_json::type_name
const char * type_name() const noexcept
return the type as string
Definition: json.hpp:22647
nlohmann::basic_json::to_ubjson
static std::vector< uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:22987
nlohmann::basic_json::input_format_t
detail::input_format_t input_format_t
Definition: json.hpp:16015
nlohmann::basic_json::parse
static basic_json parse(InputType &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true)
deserialize from a compatible input
Definition: json.hpp:22389
nlohmann::basic_json::is_primitive
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:18131
nlohmann::basic_json::rend
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:20429
nlohmann::basic_json::crbegin
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:20466
nlohmann::basic_json::accept
static bool accept(InputType &&i)
check if the input is valid JSON
Definition: json.hpp:22472
nlohmann
namespace for Niels Lohmann
Definition: json.hpp:93
nlohmann::basic_json::find
iterator find(KeyT &&key)
find an element in a JSON object
Definition: json.hpp:20097
nlohmann::byte_container_with_subtype::has_subtype
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:4357
nlohmann::basic_json::basic_json
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:17825
nlohmann::basic_json::value
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:19564
nlohmann::basic_json::get_allocator
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:16088
nlohmann::json_sax::parse_error
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
nlohmann::basic_json::is_number_integer
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:18261
nlohmann::json_pointer
JSON Pointer.
Definition: json.hpp:11051
nlohmann::basic_json::size_type
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:16063
nlohmann::basic_json::sax_parse
static bool sax_parse(InputType &&i, SAX *sax, input_format_t format=input_format_t::json, const bool strict=true)
generate SAX events
Definition: json.hpp:22529
nlohmann::byte_container_with_subtype::operator!=
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:4286
nlohmann::basic_json::operator!=
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:21975
nlohmann::basic_json::basic_json
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.hpp:17376
nlohmann::json_pointer::empty
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:11349
nlohmann::basic_json::get
constexpr auto get() const noexcept -> decltype(std::declval< const basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:18903
nlohmann::basic_json::type_error
detail::type_error type_error
exception indicating executing a member function with a wrong type
Definition: json.hpp:16034
nlohmann::anonymous_namespace{json.hpp}::from_json
constexpr const auto & from_json
Definition: json.hpp:3618
nlohmann::basic_json::swap
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:21644
nlohmann::basic_json::is_boolean
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:18202
nlohmann::basic_json::object_comparator_t
std::less< StringType > object_comparator_t
Definition: json.hpp:16190
nlohmann::basic_json::crend
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:20495
nlohmann::basic_json::rbegin
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:20392
nlohmann::basic_json::is_discarded
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:18432
nlohmann::basic_json::get_binary
binary_t & get_binary()
Definition: json.hpp:19011
nlohmann::basic_json::binary
static basic_json binary(typename binary_t::container_type &&init, std::uint8_t subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:17513
nlohmann::json_pointer::operator==
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for equality
Definition: json.hpp:11977
nlohmann::basic_json::initializer_list_t
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:16013
nlohmann::basic_json::is_number_float
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:18317
nlohmann::basic_json::boolean_t
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:16405
nlohmann::basic_json::external_constructor
friend struct detail::external_constructor
Definition: json.hpp:15953
nlohmann::basic_json::binary_t
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:16687
nlohmann::basic_json::from_bson
static basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
Definition: json.hpp:23565
nlohmann::basic_json::back
reference back()
access the last element
Definition: json.hpp:19734
nlohmann::basic_json::const_reference
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:16058
nlohmann::byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype(container_type &&b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:4274
nlohmann::adl_serializer
default JSONSerializer template argument
Definition: json.hpp:4188
nlohmann::to_string
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:24405
nlohmann::basic_json::cbegin
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:20291
nlohmann::basic_json::array
static basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:17559
nlohmann::adl_serializer::from_json
static auto from_json(BasicJsonType &&j, ValueType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), val), void())
convert a JSON value to any value type
Definition: json.hpp:4199
nlohmann::basic_json::emplace
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:21239
nlohmann::basic_json::json_pointer
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:16007
nlohmann::basic_json::get
BasicJsonType get() const
get special-case overload
Definition: json.hpp:18647
nlohmann::basic_json::operator>=
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:22234
nlohmann::json_sax::string
virtual bool string(string_t &val)=0
a string was read
nlohmann::json_sax::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:4907
nlohmann::basic_json::reverse_iterator
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:16078
nlohmann::basic_json::count
size_type count(KeyT &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:20148
nlohmann::basic_json::parser_callback_t
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:17078
nlohmann::basic_json::is_null
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:18180
nlohmann::basic_json::operator<=
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:22142
nlohmann::basic_json::cend
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:20362
nlohmann::basic_json::flatten
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:23797
nlohmann::basic_json::empty
bool empty() const noexcept
checks whether the container is empty.
Definition: json.hpp:20706
nlohmann::basic_json::diff
static basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition: json.hpp:24191
nlohmann::json_pointer::operator/
friend json_pointer operator/(const json_pointer &lhs, const json_pointer &rhs)
create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
Definition: json.hpp:11194
nlohmann::basic_json::basic_json
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:17143
nlohmann::basic_json::operator+=
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:21023
nlohmann::basic_json::get_ref
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:18950
nlohmann::json_sax::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:4909
nlohmann::basic_json::const_pointer
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:16071
nlohmann::basic_json::is_string
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:18383
nlohmann::basic_json::get
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:18891
nlohmann::basic_json::is_array
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:18361
nlohmann::basic_json::operator<<
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:22301
nlohmann::json_sax::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:4908
nlohmann::basic_json::out_of_range
detail::out_of_range out_of_range
exception indicating access out of the defined range
Definition: json.hpp:16036
nlohmann::basic_json::front
reference front()
access the first element
Definition: json.hpp:19690
nlohmann::json_sax::start_array
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
nlohmann::basic_json::pointer
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:16069
nlohmann::basic_json::string_t
StringType string_t
a type for a string
Definition: json.hpp:16379
nlohmann::json_sax::~json_sax
virtual ~json_sax()=default
nlohmann::basic_json::type
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:18100
nlohmann::basic_json::binary
static basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition: json.hpp:17456
nlohmann::byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:4264
nlohmann::basic_json::insert
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:21307
nlohmann::basic_json::get_ref
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:18937
nlohmann::basic_json::is_number
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:18232
nlohmann::json_pointer::push_back
void push_back(const std::string &token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:11324
nlohmann::json_sax::key
virtual bool key(string_t &val)=0
an object key was read
nlohmann::json_sax::number_float
virtual bool number_float(number_float_t val, const string_t &s)=0
an floating-point number was read
nlohmann::json_pointer::operator/=
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition: json.hpp:11174
nlohmann::basic_json::clear
void clear() noexcept
clears the contents
Definition: json.hpp:20921
nlohmann::basic_json::basic_json
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:17695
nlohmann::basic_json::number_float_t
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:16616
nlohmann::basic_json::items
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:20641
nlohmann::basic_json::is_structured
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:18158
nlohmann::json_sax::end_array
virtual bool end_array()=0
the end of an array was read
nlohmann::json_pointer::operator/=
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: json.hpp:11128
nlohmann::json_pointer::push_back
void push_back(std::string &&token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:11330
nlohmann::basic_json::to_bson
static std::vector< uint8_t > to_bson(const basic_json &j)
Serializes the given JSON object j to BSON and returns a vector containing the corresponding BSON-rep...
Definition: json.hpp:23065
nlohmann::basic_json::update
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:21542
nlohmann::basic_json::basic_json
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:17914
nlohmann::json_sax::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:4910
nlohmann::basic_json
a class to store JSON values
Definition: json.hpp:15951
nlohmann::json_sax::end_object
virtual bool end_object()=0
the end of an object was read
nlohmann::basic_json::operator[]
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:19274
nlohmann::byte_container_with_subtype::clear_subtype
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:4381
nlohmann::basic_json::basic_json
basic_json(CompatibleType &&val) noexcept(noexcept(JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value
Definition: json.hpp:17216
nlohmann::json_pointer::operator/
friend json_pointer operator/(const json_pointer &ptr, std::size_t array_idx)
create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
Definition: json.hpp:11235
nlohmann::json_pointer::operator!=
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for inequality
Definition: json.hpp:11994
nlohmann::json_sax::number_unsigned
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
nlohmann::json_sax::binary
virtual bool binary(binary_t &val)=0
a binary string was read
nlohmann::basic_json::push_back
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:20998
nlohmann::basic_json::get
ValueType get() const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), std::declval< ValueType & >())))
get a value (explicit)
Definition: json.hpp:18697
nlohmann::byte_container_with_subtype::subtype
constexpr std::uint8_t subtype() const noexcept
return the binary subtype
Definition: json.hpp:4336
nlohmann::basic_json::end
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:20322
nlohmann::basic_json::merge_patch
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:24366
nlohmann::basic_json::get_ptr
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:18843
nlohmann::basic_json::parse_error
detail::parse_error parse_error
exception indicating a parse error
Definition: json.hpp:16030
nlohmann::basic_json::insert_iterator
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.hpp:21269
nlohmann::basic_json::get_ptr
constexpr auto get_ptr() const noexcept -> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:18856
nlohmann::anonymous_namespace{json.hpp}::to_json
constexpr const auto & to_json
Definition: json.hpp:4178
nlohmann::byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:4256
nlohmann::basic_json::exception
detail::exception exception
general exception of the basic_json class
Definition: json.hpp:16028
nlohmann::byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition: json.hpp:4260
nlohmann::basic_json::get_to
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition: json.hpp:18806
nlohmann::json_pointer::json_pointer
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.hpp:11078
nlohmann::json_pointer::pop_back
void pop_back()
remove last reference token
Definition: json.hpp:11278
nlohmann::basic_json::reference
value_type & reference
the type of an element reference
Definition: json.hpp:16056
nlohmann::basic_json::operator=
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:17951
nlohmann::json_pointer::operator/=
json_pointer & operator/=(std::string token)
append an unescaped reference token at the end of this JSON pointer
Definition: json.hpp:11152
nlohmann::basic_json::iterator_wrapper
static iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition: json.hpp:20559
nlohmann::basic_json::json_serializer
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:16009
nlohmann::basic_json::iterator
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.hpp:16074
nlohmann::basic_json::const_reverse_iterator
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:16080
nlohmann::basic_json::from_cbor
static basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in CBOR format
Definition: json.hpp:23198
nlohmann::json_pointer::parent_pointer
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:11253
nlohmann::json_pointer::operator/
friend json_pointer operator/(const json_pointer &ptr, std::string token)
create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
Definition: json.hpp:11215
nlohmann::basic_json::max_size
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:20850
nlohmann::basic_json::binary
static basic_json binary(const typename binary_t::container_type &init, std::uint8_t subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:17493
nlohmann::json
basic_json<> json
default JSON class
Definition: json.hpp:2774
nlohmann::json_sax
SAX interface.
Definition: json.hpp:4906
nlohmann::basic_json::is_number_unsigned
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:18289
nlohmann::byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype(const container_type &b, std::uint8_t subtype) noexcept(noexcept(container_type(b)))
Definition: json.hpp:4268
nlohmann::basic_json::get
basic_json get() const
get special-case overload
Definition: json.hpp:18624
nlohmann::basic_json::push_back
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:21138
nlohmann::basic_json::from_ubjson
static basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:23452
nlohmann::adl_serializer::to_json
static auto to_json(BasicJsonType &j, ValueType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< ValueType >(val)))) -> decltype(::nlohmann::to_json(j, std::forward< ValueType >(val)), void())
convert any value type to a JSON value
Definition: json.hpp:4216
nlohmann::byte_container_with_subtype
an internal type for a backed binary type
Definition: json.hpp:4251
nlohmann::basic_json::operator<
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:22028
nlohmann::basic_json::get_binary
const binary_t & get_binary() const
Definition: json.hpp:19022
nlohmann::basic_json::basic_json
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:17119
nlohmann::basic_json::emplace_back
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:21186
nlohmann::basic_json::to_cbor
static std::vector< uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:22787
nlohmann::basic_json::is_binary
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:18405
nlohmann::basic_json::~basic_json
~basic_json() noexcept
destructor
Definition: json.hpp:17984
nlohmann::basic_json::binary
static basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array (without subtype)
Definition: json.hpp:17503
nlohmann::basic_json::patch
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:23895
nlohmann::basic_json::is_object
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:18339
nlohmann::byte_container_with_subtype::container_type
BinaryType container_type
the type of the underlying container
Definition: json.hpp:4254