JSON for Modern C++ 3.7.3

json.hpp
1 /*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.7.3
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
6
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
17
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29
30 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
31 #define INCLUDE_NLOHMANN_JSON_HPP_
32
33 #define NLOHMANN_JSON_VERSION_MAJOR 3
34 #define NLOHMANN_JSON_VERSION_MINOR 7
35 #define NLOHMANN_JSON_VERSION_PATCH 3
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 JSON_HEDLEY_NON_NULL(2)
4460 explicit file_input_adapter(std::FILE* f) noexcept
4461 : m_file(f)
4462 {}
4463
4464 // make class move-only
4465 file_input_adapter(const file_input_adapter&) = delete;
4466 file_input_adapter(file_input_adapter&&) = default;
4467 file_input_adapter& operator=(const file_input_adapter&) = delete;
4468 file_input_adapter& operator=(file_input_adapter&&) = delete;
4469
4470 std::char_traits<char>::int_type get_character() noexcept
4471 {
4472 return std::fgetc(m_file);
4473 }
4474
4475 private:
4477 std::FILE* m_file;
4478 };
4479
4480
4490 class input_stream_adapter
4491 {
4492 public:
4493 ~input_stream_adapter()
4494 {
4495 // clear stream flags; we use underlying streambuf I/O, do not
4496 // maintain ifstream flags, except eof
4497 if (is)
4498 {
4499 is->clear(is->rdstate() & std::ios::eofbit);
4500 }
4501 }
4502
4503 explicit input_stream_adapter(std::istream& i)
4504 : is(&i), sb(i.rdbuf())
4505 {}
4506
4507 // delete because of pointer members
4508 input_stream_adapter(const input_stream_adapter&) = delete;
4509 input_stream_adapter& operator=(input_stream_adapter&) = delete;
4510 input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
4511
4512 input_stream_adapter(input_stream_adapter&& rhs) : is(rhs.is), sb(rhs.sb)
4513 {
4514 rhs.is = nullptr;
4515 rhs.sb = nullptr;
4516 }
4517
4518 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
4519 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
4520 // end up as the same value, eg. 0xFFFFFFFF.
4521 std::char_traits<char>::int_type get_character()
4522 {
4523 auto res = sb->sbumpc();
4524 // set eof manually, as we don't use the istream interface.
4525 if (res == EOF)
4526 {
4527 is->clear(is->rdstate() | std::ios::eofbit);
4528 }
4529 return res;
4530 }
4531
4532 private:
4534 std::istream* is = nullptr;
4535 std::streambuf* sb = nullptr;
4536 };
4537
4539 class input_buffer_adapter
4540 {
4541 public:
4542 input_buffer_adapter(const char* b, const std::size_t l) noexcept
4543 : cursor(b), limit(b == nullptr ? nullptr : (b + l))
4544 {}
4545
4546 // delete because of pointer members
4547 input_buffer_adapter(const input_buffer_adapter&) = delete;
4548 input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
4549 input_buffer_adapter(input_buffer_adapter&&) = default;
4550 input_buffer_adapter& operator=(input_buffer_adapter&&) = delete;
4551
4552 std::char_traits<char>::int_type get_character() noexcept
4553 {
4554 if (JSON_HEDLEY_LIKELY(cursor < limit))
4555 {
4556 assert(cursor != nullptr and limit != nullptr);
4557 return std::char_traits<char>::to_int_type(*(cursor++));
4558 }
4559
4560 return std::char_traits<char>::eof();
4561 }
4562
4563 private:
4565 const char* cursor;
4567 const char* const limit;
4568 };
4569
4570 template<typename WideStringType, size_t T>
4571 struct wide_string_input_helper
4572 {
4573 // UTF-32
4574 static void fill_buffer(const WideStringType& str,
4575 size_t& current_wchar,
4576 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4577 size_t& utf8_bytes_index,
4578 size_t& utf8_bytes_filled)
4579 {
4580 utf8_bytes_index = 0;
4581
4582 if (current_wchar == str.size())
4583 {
4584 utf8_bytes[0] = std::char_traits<char>::eof();
4585 utf8_bytes_filled = 1;
4586 }
4587 else
4588 {
4589 // get the current character
4590 const auto wc = static_cast<unsigned int>(str[current_wchar++]);
4591
4592 // UTF-32 to UTF-8 encoding
4593 if (wc < 0x80)
4594 {
4595 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4596 utf8_bytes_filled = 1;
4597 }
4598 else if (wc <= 0x7FF)
4599 {
4600 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u) & 0x1Fu));
4601 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
4602 utf8_bytes_filled = 2;
4603 }
4604 else if (wc <= 0xFFFF)
4605 {
4606 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u) & 0x0Fu));
4607 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
4608 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
4609 utf8_bytes_filled = 3;
4610 }
4611 else if (wc <= 0x10FFFF)
4612 {
4613 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((wc >> 18u) & 0x07u));
4614 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 12u) & 0x3Fu));
4615 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
4616 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
4617 utf8_bytes_filled = 4;
4618 }
4619 else
4620 {
4621 // unknown character
4622 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4623 utf8_bytes_filled = 1;
4624 }
4625 }
4626 }
4627 };
4628
4629 template<typename WideStringType>
4630 struct wide_string_input_helper<WideStringType, 2>
4631 {
4632 // UTF-16
4633 static void fill_buffer(const WideStringType& str,
4634 size_t& current_wchar,
4635 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4636 size_t& utf8_bytes_index,
4637 size_t& utf8_bytes_filled)
4638 {
4639 utf8_bytes_index = 0;
4640
4641 if (current_wchar == str.size())
4642 {
4643 utf8_bytes[0] = std::char_traits<char>::eof();
4644 utf8_bytes_filled = 1;
4645 }
4646 else
4647 {
4648 // get the current character
4649 const auto wc = static_cast<unsigned int>(str[current_wchar++]);
4650
4651 // UTF-16 to UTF-8 encoding
4652 if (wc < 0x80)
4653 {
4654 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4655 utf8_bytes_filled = 1;
4656 }
4657 else if (wc <= 0x7FF)
4658 {
4659 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u)));
4660 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
4661 utf8_bytes_filled = 2;
4662 }
4663 else if (0xD800 > wc or wc >= 0xE000)
4664 {
4665 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u)));
4666 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
4667 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
4668 utf8_bytes_filled = 3;
4669 }
4670 else
4671 {
4672 if (current_wchar < str.size())
4673 {
4674 const auto wc2 = static_cast<unsigned int>(str[current_wchar++]);
4675 const auto charcode = 0x10000u + (((wc & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
4676 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
4677 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
4678 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
4679 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
4680 utf8_bytes_filled = 4;
4681 }
4682 else
4683 {
4684 // unknown character
4685 ++current_wchar;
4686 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4687 utf8_bytes_filled = 1;
4688 }
4689 }
4690 }
4691 }
4692 };
4693
4694 template<typename WideStringType>
4695 class wide_string_input_adapter
4696 {
4697 public:
4698 explicit wide_string_input_adapter(const WideStringType& w) noexcept
4699 : str(w)
4700 {}
4701
4702 std::char_traits<char>::int_type get_character() noexcept
4703 {
4704 // check if buffer needs to be filled
4705 if (utf8_bytes_index == utf8_bytes_filled)
4706 {
4707 fill_buffer<sizeof(typename WideStringType::value_type)>();
4708
4709 assert(utf8_bytes_filled > 0);
4710 assert(utf8_bytes_index == 0);
4711 }
4712
4713 // use buffer
4714 assert(utf8_bytes_filled > 0);
4715 assert(utf8_bytes_index < utf8_bytes_filled);
4716 return utf8_bytes[utf8_bytes_index++];
4717 }
4718
4719 private:
4720 template<size_t T>
4721 void fill_buffer()
4722 {
4723 wide_string_input_helper<WideStringType, T>::fill_buffer(str, current_wchar, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
4724 }
4725
4727 const WideStringType& str;
4728
4730 std::size_t current_wchar = 0;
4731
4733 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
4734
4736 std::size_t utf8_bytes_index = 0;
4738 std::size_t utf8_bytes_filled = 0;
4739 };
4740
4741 inline file_input_adapter input_adapter(std::FILE* file)
4742 {
4743 return file_input_adapter(file);
4744 }
4745
4746 inline input_stream_adapter input_adapter(std::istream& stream)
4747 {
4748 return input_stream_adapter(stream);
4749 }
4750
4751 inline input_stream_adapter input_adapter(std::istream&& stream)
4752 {
4753 return input_stream_adapter(stream);
4754 }
4755
4756 template<typename CharT,
4757 typename std::enable_if<
4758 std::is_pointer<CharT>::value and
4759 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
4760 sizeof(typename std::remove_pointer<CharT>::type) == 1,
4761 int>::type = 0>
4762 input_buffer_adapter input_adapter(CharT b, std::size_t l)
4763 {
4764 return input_buffer_adapter(reinterpret_cast<const char*>(b), l);
4765 }
4766
4767 template<typename CharT,
4768 typename std::enable_if<
4769 std::is_pointer<CharT>::value and
4770 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
4771 sizeof(typename std::remove_pointer<CharT>::type) == 1,
4772 int>::type = 0>
4773 input_buffer_adapter input_adapter(CharT b)
4774 {
4775 return input_adapter(reinterpret_cast<const char*>(b),
4776 std::strlen(reinterpret_cast<const char*>(b)));
4777 }
4778
4779 template<class IteratorType,
4780 typename std::enable_if<
4781 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
4782 int>::type = 0>
4783 input_buffer_adapter input_adapter(IteratorType first, IteratorType last)
4784 {
4785 #ifndef NDEBUG
4786 // assertion to check that the iterator range is indeed contiguous,
4787 // see https://stackoverflow.com/a/35008842/266378 for more discussion
4788 const auto is_contiguous = std::accumulate(
4789 first, last, std::pair<bool, int>(true, 0),
4790 [&first](std::pair<bool, int> res, decltype(*first) val)
4791 {
4792 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
4793 return res;
4794 }).first;
4795 assert(is_contiguous);
4796 #endif
4797
4798 // assertion to check that each element is 1 byte long
4799 static_assert(
4800 sizeof(typename iterator_traits<IteratorType>::value_type) == 1,
4801 "each element in the iterator range must have the size of 1 byte");
4802
4803 const auto len = static_cast<size_t>(std::distance(first, last));
4804 if (JSON_HEDLEY_LIKELY(len > 0))
4805 {
4806 // there is at least one element: use the address of first
4807 return input_buffer_adapter(reinterpret_cast<const char*>(&(*first)), len);
4808 }
4809 else
4810 {
4811 // the address of first cannot be used: use nullptr
4812 return input_buffer_adapter(nullptr, len);
4813 }
4814 }
4815
4816 inline wide_string_input_adapter<std::wstring> input_adapter(const std::wstring& ws)
4817 {
4818 return wide_string_input_adapter<std::wstring>(ws);
4819 }
4820
4821
4822 inline wide_string_input_adapter<std::u16string> input_adapter(const std::u16string& ws)
4823 {
4824 return wide_string_input_adapter<std::u16string>(ws);
4825 }
4826
4827 inline wide_string_input_adapter<std::u32string> input_adapter(const std::u32string& ws)
4828 {
4829 return wide_string_input_adapter<std::u32string>(ws);
4830 }
4831
4832 template<class ContiguousContainer, typename
4833 std::enable_if<not std::is_pointer<ContiguousContainer>::value and
4834 std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
4835 int>::type = 0>
4836 input_buffer_adapter input_adapter(const ContiguousContainer& c)
4837 {
4838 return input_adapter(std::begin(c), std::end(c));
4839 }
4840
4841
4842 template<class T, std::size_t N>
4843 input_buffer_adapter input_adapter(T (&array)[N])
4844 {
4845 return input_adapter(std::begin(array), std::end(array));
4846 }
4847
4848 // This class only handles inputs of input_buffer_adapter type.
4849 // It's required so that expressions like {ptr, len} can be implicitely casted
4850 // to the correct adapter.
4851 class span_input_adapter
4852 {
4853 public:
4854 template<typename CharT,
4855 typename std::enable_if<
4856 std::is_pointer<CharT>::value and
4857 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
4858 sizeof(typename std::remove_pointer<CharT>::type) == 1,
4859 int>::type = 0>
4860 span_input_adapter(CharT b, std::size_t l)
4861 : ia(reinterpret_cast<const char*>(b), l) {}
4862
4863 template<typename CharT,
4864 typename std::enable_if<
4865 std::is_pointer<CharT>::value and
4866 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
4867 sizeof(typename std::remove_pointer<CharT>::type) == 1,
4868 int>::type = 0>
4869 span_input_adapter(CharT b)
4870 : span_input_adapter(reinterpret_cast<const char*>(b),
4871 std::strlen(reinterpret_cast<const char*>(b))) {}
4872
4873 template<class IteratorType,
4874 typename std::enable_if<
4875 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
4876 int>::type = 0>
4877 span_input_adapter(IteratorType first, IteratorType last)
4878 : ia(input_adapter(first, last)) {}
4879
4880 template<class T, std::size_t N>
4881 span_input_adapter(T (&array)[N])
4882 : span_input_adapter(std::begin(array), std::end(array)) {}
4883
4885 template<class ContiguousContainer, typename
4886 std::enable_if<not std::is_pointer<ContiguousContainer>::value and
4887 std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
4888 int>::type = 0>
4889 span_input_adapter(const ContiguousContainer& c)
4890 : span_input_adapter(std::begin(c), std::end(c)) {}
4891
4892 input_buffer_adapter&& get()
4893 {
4894 return std::move(ia);
4895 }
4896
4897 private:
4898 input_buffer_adapter ia;
4899 };
4900 } // namespace detail
4901 } // namespace nlohmann
4902
4903 // #include <nlohmann/detail/input/json_sax.hpp>
4904
4905
4906 #include <cassert> // assert
4907 #include <cstddef>
4908 #include <string> // string
4909 #include <utility> // move
4910 #include <vector> // vector
4911
4912 // #include <nlohmann/detail/exceptions.hpp>
4913
4914 // #include <nlohmann/detail/macro_scope.hpp>
4915
4916
4917 namespace nlohmann
4918 {
4919
4928 template<typename BasicJsonType>
4929 struct json_sax
4930 {
4931 using number_integer_t = typename BasicJsonType::number_integer_t;
4932 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4933 using number_float_t = typename BasicJsonType::number_float_t;
4934 using string_t = typename BasicJsonType::string_t;
4935 using binary_t = typename BasicJsonType::binary_t;
4936
4941 virtual bool null() = 0;
4942
4948 virtual bool boolean(bool val) = 0;
4949
4955 virtual bool number_integer(number_integer_t val) = 0;
4956
4962 virtual bool number_unsigned(number_unsigned_t val) = 0;
4963
4970 virtual bool number_float(number_float_t val, const string_t& s) = 0;
4971
4978 virtual bool string(string_t& val) = 0;
4979
4986 virtual bool binary(binary_t& val) = 0;
4987
4994 virtual bool start_object(std::size_t elements) = 0;
4995
5002 virtual bool key(string_t& val) = 0;
5003
5008 virtual bool end_object() = 0;
5009
5016 virtual bool start_array(std::size_t elements) = 0;
5017
5022 virtual bool end_array() = 0;
5023
5031 virtual bool parse_error(std::size_t position,
5032 const std::string& last_token,
5033 const detail::exception& ex) = 0;
5034
5035 virtual ~json_sax() = default;
5036 };
5037
5038
5039 namespace detail
5040 {
5054 template<typename BasicJsonType>
5055 class json_sax_dom_parser
5056 {
5057 public:
5058 using number_integer_t = typename BasicJsonType::number_integer_t;
5059 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5060 using number_float_t = typename BasicJsonType::number_float_t;
5061 using string_t = typename BasicJsonType::string_t;
5062 using binary_t = typename BasicJsonType::binary_t;
5063
5069 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
5070 : root(r), allow_exceptions(allow_exceptions_)
5071 {}
5072
5073 // make class move-only
5074 json_sax_dom_parser(const json_sax_dom_parser&) = delete;
5075 json_sax_dom_parser(json_sax_dom_parser&&) = default;
5076 json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
5077 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
5078 ~json_sax_dom_parser() = default;
5079
5080 bool null()
5081 {
5082 handle_value(nullptr);
5083 return true;
5084 }
5085
5086 bool boolean(bool val)
5087 {
5088 handle_value(val);
5089 return true;
5090 }
5091
5092 bool number_integer(number_integer_t val)
5093 {
5094 handle_value(val);
5095 return true;
5096 }
5097
5098 bool number_unsigned(number_unsigned_t val)
5099 {
5100 handle_value(val);
5101 return true;
5102 }
5103
5104 bool number_float(number_float_t val, const string_t& /*unused*/)
5105 {
5106 handle_value(val);
5107 return true;
5108 }
5109
5110 bool string(string_t& val)
5111 {
5112 handle_value(val);
5113 return true;
5114 }
5115
5116 bool binary(binary_t& val)
5117 {
5118 handle_value(std::move(val));
5119 return true;
5120 }
5121
5122 bool start_object(std::size_t len)
5123 {
5124 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
5125
5126 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
5127 {
5128 JSON_THROW(out_of_range::create(408,
5129 "excessive object size: " + std::to_string(len)));
5130 }
5131
5132 return true;
5133 }
5134
5135 bool key(string_t& val)
5136 {
5137 // add null at given key and store the reference for later
5138 object_element = &(ref_stack.back()->m_value.object->operator[](val));
5139 return true;
5140 }
5141
5142 bool end_object()
5143 {
5144 ref_stack.pop_back();
5145 return true;
5146 }
5147
5148 bool start_array(std::size_t len)
5149 {
5150 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
5151
5152 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
5153 {
5154 JSON_THROW(out_of_range::create(408,
5155 "excessive array size: " + std::to_string(len)));
5156 }
5157
5158 return true;
5159 }
5160
5161 bool end_array()
5162 {
5163 ref_stack.pop_back();
5164 return true;
5165 }
5166
5167 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5168 const detail::exception& ex)
5169 {
5170 errored = true;
5171 if (allow_exceptions)
5172 {
5173 // determine the proper exception type from the id
5174 switch ((ex.id / 100) % 100)
5175 {
5176 case 1:
5177 JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
5178 case 4:
5179 JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
5180 // LCOV_EXCL_START
5181 case 2:
5182 JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
5183 case 3:
5184 JSON_THROW(*static_cast<const detail::type_error*>(&ex));
5185 case 5:
5186 JSON_THROW(*static_cast<const detail::other_error*>(&ex));
5187 default:
5188 assert(false);
5189 // LCOV_EXCL_STOP
5190 }
5191 }
5192 return false;
5193 }
5194
5195 constexpr bool is_errored() const
5196 {
5197 return errored;
5198 }
5199
5200 private:
5207 template<typename Value>
5208
5209 BasicJsonType* handle_value(Value&& v)
5210 {
5211 if (ref_stack.empty())
5212 {
5213 root = BasicJsonType(std::forward<Value>(v));
5214 return &root;
5215 }
5216
5217 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
5218
5219 if (ref_stack.back()->is_array())
5220 {
5221 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
5222 return &(ref_stack.back()->m_value.array->back());
5223 }
5224
5225 assert(ref_stack.back()->is_object());
5226 assert(object_element);
5227 *object_element = BasicJsonType(std::forward<Value>(v));
5228 return object_element;
5229 }
5230
5232 BasicJsonType& root;
5234 std::vector<BasicJsonType*> ref_stack {};
5236 BasicJsonType* object_element = nullptr;
5238 bool errored = false;
5240 const bool allow_exceptions = true;
5241 };
5242
5243 template<typename BasicJsonType>
5244 class json_sax_dom_callback_parser
5245 {
5246 public:
5247 using number_integer_t = typename BasicJsonType::number_integer_t;
5248 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5249 using number_float_t = typename BasicJsonType::number_float_t;
5250 using string_t = typename BasicJsonType::string_t;
5251 using binary_t = typename BasicJsonType::binary_t;
5252 using parser_callback_t = typename BasicJsonType::parser_callback_t;
5253 using parse_event_t = typename BasicJsonType::parse_event_t;
5254
5255 json_sax_dom_callback_parser(BasicJsonType& r,
5256 const parser_callback_t cb,
5257 const bool allow_exceptions_ = true)
5258 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
5259 {
5260 keep_stack.push_back(true);
5261 }
5262
5263 // make class move-only
5264 json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
5265 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default;
5266 json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
5267 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default;
5268 ~json_sax_dom_callback_parser() = default;
5269
5270 bool null()
5271 {
5272 handle_value(nullptr);
5273 return true;
5274 }
5275
5276 bool boolean(bool val)
5277 {
5278 handle_value(val);
5279 return true;
5280 }
5281
5282 bool number_integer(number_integer_t val)
5283 {
5284 handle_value(val);
5285 return true;
5286 }
5287
5288 bool number_unsigned(number_unsigned_t val)
5289 {
5290 handle_value(val);
5291 return true;
5292 }
5293
5294 bool number_float(number_float_t val, const string_t& /*unused*/)
5295 {
5296 handle_value(val);
5297 return true;
5298 }
5299
5300 bool string(string_t& val)
5301 {
5302 handle_value(val);
5303 return true;
5304 }
5305
5306 bool binary(binary_t& val)
5307 {
5308 handle_value(std::move(val));
5309 return true;
5310 }
5311
5312 bool start_object(std::size_t len)
5313 {
5314 // check callback for object start
5315 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
5316 keep_stack.push_back(keep);
5317
5318 auto val = handle_value(BasicJsonType::value_t::object, true);
5319 ref_stack.push_back(val.second);
5320
5321 // check object limit
5322 if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
5323 {
5324 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
5325 }
5326
5327 return true;
5328 }
5329
5330 bool key(string_t& val)
5331 {
5332 BasicJsonType k = BasicJsonType(val);
5333
5334 // check callback for key
5335 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
5336 key_keep_stack.push_back(keep);
5337
5338 // add discarded value at given key and store the reference for later
5339 if (keep and ref_stack.back())
5340 {
5341 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
5342 }
5343
5344 return true;
5345 }
5346
5347 bool end_object()
5348 {
5349 if (ref_stack.back() and not callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
5350 {
5351 // discard object
5352 *ref_stack.back() = discarded;
5353 }
5354
5355 assert(not ref_stack.empty());
5356 assert(not keep_stack.empty());
5357 ref_stack.pop_back();
5358 keep_stack.pop_back();
5359
5360 if (not ref_stack.empty() and ref_stack.back() and ref_stack.back()->is_object())
5361 {
5362 // remove discarded value
5363 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
5364 {
5365 if (it->is_discarded())
5366 {
5367 ref_stack.back()->erase(it);
5368 break;
5369 }
5370 }
5371 }
5372
5373 return true;
5374 }
5375
5376 bool start_array(std::size_t len)
5377 {
5378 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
5379 keep_stack.push_back(keep);
5380
5381 auto val = handle_value(BasicJsonType::value_t::array, true);
5382 ref_stack.push_back(val.second);
5383
5384 // check array limit
5385 if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
5386 {
5387 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
5388 }
5389
5390 return true;
5391 }
5392
5393 bool end_array()
5394 {
5395 bool keep = true;
5396
5397 if (ref_stack.back())
5398 {
5399 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
5400 if (not keep)
5401 {
5402 // discard array
5403 *ref_stack.back() = discarded;
5404 }
5405 }
5406
5407 assert(not ref_stack.empty());
5408 assert(not keep_stack.empty());
5409 ref_stack.pop_back();
5410 keep_stack.pop_back();
5411
5412 // remove discarded value
5413 if (not keep and not ref_stack.empty() and ref_stack.back()->is_array())
5414 {
5415 ref_stack.back()->m_value.array->pop_back();
5416 }
5417
5418 return true;
5419 }
5420
5421 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5422 const detail::exception& ex)
5423 {
5424 errored = true;
5425 if (allow_exceptions)
5426 {
5427 // determine the proper exception type from the id
5428 switch ((ex.id / 100) % 100)
5429 {
5430 case 1:
5431 JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
5432 case 4:
5433 JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
5434 // LCOV_EXCL_START
5435 case 2:
5436 JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
5437 case 3:
5438 JSON_THROW(*static_cast<const detail::type_error*>(&ex));
5439 case 5:
5440 JSON_THROW(*static_cast<const detail::other_error*>(&ex));
5441 default:
5442 assert(false);
5443 // LCOV_EXCL_STOP
5444 }
5445 }
5446 return false;
5447 }
5448
5449 constexpr bool is_errored() const
5450 {
5451 return errored;
5452 }
5453
5454 private:
5470 template<typename Value>
5471 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
5472 {
5473 assert(not keep_stack.empty());
5474
5475 // do not handle this value if we know it would be added to a discarded
5476 // container
5477 if (not keep_stack.back())
5478 {
5479 return {false, nullptr};
5480 }
5481
5482 // create value
5483 auto value = BasicJsonType(std::forward<Value>(v));
5484
5485 // check callback
5486 const bool keep = skip_callback or callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
5487
5488 // do not handle this value if we just learnt it shall be discarded
5489 if (not keep)
5490 {
5491 return {false, nullptr};
5492 }
5493
5494 if (ref_stack.empty())
5495 {
5496 root = std::move(value);
5497 return {true, &root};
5498 }
5499
5500 // skip this value if we already decided to skip the parent
5501 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
5502 if (not ref_stack.back())
5503 {
5504 return {false, nullptr};
5505 }
5506
5507 // we now only expect arrays and objects
5508 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
5509
5510 // array
5511 if (ref_stack.back()->is_array())
5512 {
5513 ref_stack.back()->m_value.array->push_back(std::move(value));
5514 return {true, &(ref_stack.back()->m_value.array->back())};
5515 }
5516
5517 // object
5518 assert(ref_stack.back()->is_object());
5519 // check if we should store an element for the current key
5520 assert(not key_keep_stack.empty());
5521 const bool store_element = key_keep_stack.back();
5522 key_keep_stack.pop_back();
5523
5524 if (not store_element)
5525 {
5526 return {false, nullptr};
5527 }
5528
5529 assert(object_element);
5530 *object_element = std::move(value);
5531 return {true, object_element};
5532 }
5533
5535 BasicJsonType& root;
5537 std::vector<BasicJsonType*> ref_stack {};
5539 std::vector<bool> keep_stack {};
5541 std::vector<bool> key_keep_stack {};
5543 BasicJsonType* object_element = nullptr;
5545 bool errored = false;
5547 const parser_callback_t callback = nullptr;
5549 const bool allow_exceptions = true;
5551 BasicJsonType discarded = BasicJsonType::value_t::discarded;
5552 };
5553
5554 template<typename BasicJsonType>
5555 class json_sax_acceptor
5556 {
5557 public:
5558 using number_integer_t = typename BasicJsonType::number_integer_t;
5559 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5560 using number_float_t = typename BasicJsonType::number_float_t;
5561 using string_t = typename BasicJsonType::string_t;
5562 using binary_t = typename BasicJsonType::binary_t;
5563
5564 bool null()
5565 {
5566 return true;
5567 }
5568
5569 bool boolean(bool /*unused*/)
5570 {
5571 return true;
5572 }
5573
5574 bool number_integer(number_integer_t /*unused*/)
5575 {
5576 return true;
5577 }
5578
5579 bool number_unsigned(number_unsigned_t /*unused*/)
5580 {
5581 return true;
5582 }
5583
5584 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
5585 {
5586 return true;
5587 }
5588
5589 bool string(string_t& /*unused*/)
5590 {
5591 return true;
5592 }
5593
5594 bool binary(binary_t& /*unused*/)
5595 {
5596 return true;
5597 }
5598
5599 bool start_object(std::size_t /*unused*/ = std::size_t(-1))
5600 {
5601 return true;
5602 }
5603
5604 bool key(string_t& /*unused*/)
5605 {
5606 return true;
5607 }
5608
5609 bool end_object()
5610 {
5611 return true;
5612 }
5613
5614 bool start_array(std::size_t /*unused*/ = std::size_t(-1))
5615 {
5616 return true;
5617 }
5618
5619 bool end_array()
5620 {
5621 return true;
5622 }
5623
5624 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
5625 {
5626 return false;
5627 }
5628 };
5629 } // namespace detail
5630
5631 } // namespace nlohmann
5632
5633 // #include <nlohmann/detail/macro_scope.hpp>
5634
5635 // #include <nlohmann/detail/meta/is_sax.hpp>
5636
5637
5638 #include <cstdint> // size_t
5639 #include <utility> // declval
5640 #include <string> // string
5641
5642 // #include <nlohmann/detail/meta/detected.hpp>
5643
5644 // #include <nlohmann/detail/meta/type_traits.hpp>
5645
5646
5647 namespace nlohmann
5648 {
5649 namespace detail
5650 {
5651 template <typename T>
5652 using null_function_t = decltype(std::declval<T&>().null());
5653
5654 template <typename T>
5655 using boolean_function_t =
5656 decltype(std::declval<T&>().boolean(std::declval<bool>()));
5657
5658 template <typename T, typename Integer>
5659 using number_integer_function_t =
5660 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
5661
5662 template <typename T, typename Unsigned>
5663 using number_unsigned_function_t =
5664 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
5665
5666 template <typename T, typename Float, typename String>
5667 using number_float_function_t = decltype(std::declval<T&>().number_float(
5668 std::declval<Float>(), std::declval<const String&>()));
5669
5670 template <typename T, typename String>
5671 using string_function_t =
5672 decltype(std::declval<T&>().string(std::declval<String&>()));
5673
5674 template <typename T>
5675 using start_object_function_t =
5676 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
5677
5678 template <typename T, typename String>
5679 using key_function_t =
5680 decltype(std::declval<T&>().key(std::declval<String&>()));
5681
5682 template <typename T>
5683 using end_object_function_t = decltype(std::declval<T&>().end_object());
5684
5685 template <typename T>
5686 using start_array_function_t =
5687 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
5688
5689 template <typename T>
5690 using end_array_function_t = decltype(std::declval<T&>().end_array());
5691
5692 template <typename T, typename Exception>
5693 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
5694 std::declval<std::size_t>(), std::declval<const std::string&>(),
5695 std::declval<const Exception&>()));
5696
5697 template <typename SAX, typename BasicJsonType>
5698 struct is_sax
5699 {
5700 private:
5701 static_assert(is_basic_json<BasicJsonType>::value,
5702 "BasicJsonType must be of type basic_json<...>");
5703
5704 using number_integer_t = typename BasicJsonType::number_integer_t;
5705 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5706 using number_float_t = typename BasicJsonType::number_float_t;
5707 using string_t = typename BasicJsonType::string_t;
5708 using exception_t = typename BasicJsonType::exception;
5709
5710 public:
5711 static constexpr bool value =
5712 is_detected_exact<bool, null_function_t, SAX>::value &&
5713 is_detected_exact<bool, boolean_function_t, SAX>::value &&
5714 is_detected_exact<bool, number_integer_function_t, SAX,
5715 number_integer_t>::value &&
5716 is_detected_exact<bool, number_unsigned_function_t, SAX,
5717 number_unsigned_t>::value &&
5718 is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
5719 string_t>::value &&
5720 is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
5721 is_detected_exact<bool, start_object_function_t, SAX>::value &&
5722 is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
5723 is_detected_exact<bool, end_object_function_t, SAX>::value &&
5724 is_detected_exact<bool, start_array_function_t, SAX>::value &&
5725 is_detected_exact<bool, end_array_function_t, SAX>::value &&
5726 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
5727 };
5728
5729 template <typename SAX, typename BasicJsonType>
5730 struct is_sax_static_asserts
5731 {
5732 private:
5733 static_assert(is_basic_json<BasicJsonType>::value,
5734 "BasicJsonType must be of type basic_json<...>");
5735
5736 using number_integer_t = typename BasicJsonType::number_integer_t;
5737 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5738 using number_float_t = typename BasicJsonType::number_float_t;
5739 using string_t = typename BasicJsonType::string_t;
5740 using exception_t = typename BasicJsonType::exception;
5741
5742 public:
5743 static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
5744 "Missing/invalid function: bool null()");
5745 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
5746 "Missing/invalid function: bool boolean(bool)");
5747 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
5748 "Missing/invalid function: bool boolean(bool)");
5749 static_assert(
5750 is_detected_exact<bool, number_integer_function_t, SAX,
5751 number_integer_t>::value,
5752 "Missing/invalid function: bool number_integer(number_integer_t)");
5753 static_assert(
5754 is_detected_exact<bool, number_unsigned_function_t, SAX,
5755 number_unsigned_t>::value,
5756 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
5757 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
5758 number_float_t, string_t>::value,
5759 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
5760 static_assert(
5761 is_detected_exact<bool, string_function_t, SAX, string_t>::value,
5762 "Missing/invalid function: bool string(string_t&)");
5763 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
5764 "Missing/invalid function: bool start_object(std::size_t)");
5765 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
5766 "Missing/invalid function: bool key(string_t&)");
5767 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
5768 "Missing/invalid function: bool end_object()");
5769 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
5770 "Missing/invalid function: bool start_array(std::size_t)");
5771 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
5772 "Missing/invalid function: bool end_array()");
5773 static_assert(
5774 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
5775 "Missing/invalid function: bool parse_error(std::size_t, const "
5776 "std::string&, const exception&)");
5777 };
5778 } // namespace detail
5779 } // namespace nlohmann
5780
5781 // #include <nlohmann/detail/value_t.hpp>
5782
5783
5784 namespace nlohmann
5785 {
5786 namespace detail
5787 {
5788
5796 static inline bool little_endianess(int num = 1) noexcept
5797 {
5798 return *reinterpret_cast<char*>(&num) == 1;
5799 }
5800
5801
5803 // binary reader //
5805
5809 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
5810 class binary_reader
5811 {
5812 using number_integer_t = typename BasicJsonType::number_integer_t;
5813 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5814 using number_float_t = typename BasicJsonType::number_float_t;
5815 using string_t = typename BasicJsonType::string_t;
5816 using binary_t = typename BasicJsonType::binary_t;
5817 using json_sax_t = SAX;
5818
5819 public:
5825 explicit binary_reader(InputAdapterType&& adapter) : ia(std::move(adapter))
5826 {
5827 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
5828 }
5829
5830 // make class move-only
5831 binary_reader(const binary_reader&) = delete;
5832 binary_reader(binary_reader&&) = default;
5833 binary_reader& operator=(const binary_reader&) = delete;
5834 binary_reader& operator=(binary_reader&&) = default;
5835 ~binary_reader() = default;
5836
5844 JSON_HEDLEY_NON_NULL(3)
5845 bool sax_parse(const input_format_t format,
5846 json_sax_t* sax_,
5847 const bool strict = true)
5848 {
5849 sax = sax_;
5850 bool result = false;
5851
5852 switch (format)
5853 {
5854 case input_format_t::bson:
5855 result = parse_bson_internal();
5856 break;
5857
5858 case input_format_t::cbor:
5859 result = parse_cbor_internal();
5860 break;
5861
5862 case input_format_t::msgpack:
5863 result = parse_msgpack_internal();
5864 break;
5865
5866 case input_format_t::ubjson:
5867 result = parse_ubjson_internal();
5868 break;
5869
5870 default: // LCOV_EXCL_LINE
5871 assert(false); // LCOV_EXCL_LINE
5872 }
5873
5874 // strict mode: next byte must be EOF
5875 if (result and strict)
5876 {
5877 if (format == input_format_t::ubjson)
5878 {
5879 get_ignore_noop();
5880 }
5881 else
5882 {
5883 get();
5884 }
5885
5886 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char>::eof()))
5887 {
5888 return sax->parse_error(chars_read, get_token_string(),
5889 parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
5890 }
5891 }
5892
5893 return result;
5894 }
5895
5896 private:
5898 // BSON //
5900
5905 bool parse_bson_internal()
5906 {
5907 std::int32_t document_size;
5908 get_number<std::int32_t, true>(input_format_t::bson, document_size);
5909
5910 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
5911 {
5912 return false;
5913 }
5914
5915 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(/*is_array*/false)))
5916 {
5917 return false;
5918 }
5919
5920 return sax->end_object();
5921 }
5922
5930 bool get_bson_cstr(string_t& result)
5931 {
5932 auto out = std::back_inserter(result);
5933 while (true)
5934 {
5935 get();
5936 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "cstring")))
5937 {
5938 return false;
5939 }
5940 if (current == 0x00)
5941 {
5942 return true;
5943 }
5944 *out++ = static_cast<char>(current);
5945 }
5946
5947 return true;
5948 }
5949
5961 template<typename NumberType>
5962 bool get_bson_string(const NumberType len, string_t& result)
5963 {
5964 if (JSON_HEDLEY_UNLIKELY(len < 1))
5965 {
5966 auto last_token = get_token_string();
5967 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string")));
5968 }
5969
5970 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) and get() != std::char_traits<char>::eof();
5971 }
5972
5982 template<typename NumberType>
5983 bool get_bson_binary(const NumberType len, binary_t& result)
5984 {
5985 if (JSON_HEDLEY_UNLIKELY(len < 0))
5986 {
5987 auto last_token = get_token_string();
5988 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary")));
5989 }
5990
5991 // All BSON binary values have a subtype
5992 std::uint8_t subtype;
5993 get_number<std::uint8_t>(input_format_t::bson, subtype);
5994 result.set_subtype(subtype);
5995
5996 return get_binary(input_format_t::bson, len, result);
5997 }
5998
6009 bool parse_bson_element_internal(const int element_type,
6010 const std::size_t element_type_parse_position)
6011 {
6012 switch (element_type)
6013 {
6014 case 0x01: // double
6015 {
6016 double number;
6017 return get_number<double, true>(input_format_t::bson, number) and sax->number_float(static_cast<number_float_t>(number), "");
6018 }
6019
6020 case 0x02: // string
6021 {
6022 std::int32_t len;
6023 string_t value;
6024 return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_string(len, value) and sax->string(value);
6025 }
6026
6027 case 0x03: // object
6028 {
6029 return parse_bson_internal();
6030 }
6031
6032 case 0x04: // array
6033 {
6034 return parse_bson_array();
6035 }
6036
6037 case 0x05: // binary
6038 {
6039 std::int32_t len;
6040 binary_t value;
6041 return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_binary(len, value) and sax->binary(value);
6042 }
6043
6044 case 0x08: // boolean
6045 {
6046 return sax->boolean(get() != 0);
6047 }
6048
6049 case 0x0A: // null
6050 {
6051 return sax->null();
6052 }
6053
6054 case 0x10: // int32
6055 {
6056 std::int32_t value;
6057 return get_number<std::int32_t, true>(input_format_t::bson, value) and sax->number_integer(value);
6058 }
6059
6060 case 0x12: // int64
6061 {
6062 std::int64_t value;
6063 return get_number<std::int64_t, true>(input_format_t::bson, value) and sax->number_integer(value);
6064 }
6065
6066 default: // anything else not supported (yet)
6067 {
6068 std::array<char, 3> cr{{}};
6069 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type));
6070 return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data())));
6071 }
6072 }
6073 }
6074
6087 bool parse_bson_element_list(const bool is_array)
6088 {
6089 string_t key;
6090
6091 while (int element_type = get())
6092 {
6093 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list")))
6094 {
6095 return false;
6096 }
6097
6098 const std::size_t element_type_parse_position = chars_read;
6099 if (JSON_HEDLEY_UNLIKELY(not get_bson_cstr(key)))
6100 {
6101 return false;
6102 }
6103
6104 if (not is_array and not sax->key(key))
6105 {
6106 return false;
6107 }
6108
6109 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
6110 {
6111 return false;
6112 }
6113
6114 // get_bson_cstr only appends
6115 key.clear();
6116 }
6117
6118 return true;
6119 }
6120
6125 bool parse_bson_array()
6126 {
6127 std::int32_t document_size;
6128 get_number<std::int32_t, true>(input_format_t::bson, document_size);
6129
6130 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
6131 {
6132 return false;
6133 }
6134
6135 if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(/*is_array*/true)))
6136 {
6137 return false;
6138 }
6139
6140 return sax->end_array();
6141 }
6142
6144 // CBOR //
6146
6154 bool parse_cbor_internal(const bool get_char = true)
6155 {
6156 switch (get_char ? get() : current)
6157 {
6158 // EOF
6159 case std::char_traits<char>::eof():
6160 return unexpect_eof(input_format_t::cbor, "value");
6161
6162 // Integer 0x00..0x17 (0..23)
6163 case 0x00:
6164 case 0x01:
6165 case 0x02:
6166 case 0x03:
6167 case 0x04:
6168 case 0x05:
6169 case 0x06:
6170 case 0x07:
6171 case 0x08:
6172 case 0x09:
6173 case 0x0A:
6174 case 0x0B:
6175 case 0x0C:
6176 case 0x0D:
6177 case 0x0E:
6178 case 0x0F:
6179 case 0x10:
6180 case 0x11:
6181 case 0x12:
6182 case 0x13:
6183 case 0x14:
6184 case 0x15:
6185 case 0x16:
6186 case 0x17:
6187 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
6188
6189 case 0x18: // Unsigned integer (one-byte uint8_t follows)
6190 {
6191 std::uint8_t number;
6192 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6193 }
6194
6195 case 0x19: // Unsigned integer (two-byte uint16_t follows)
6196 {
6197 std::uint16_t number;
6198 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6199 }
6200
6201 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
6202 {
6203 std::uint32_t number;
6204 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6205 }
6206
6207 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
6208 {
6209 std::uint64_t number;
6210 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6211 }
6212
6213 // Negative integer -1-0x00..-1-0x17 (-1..-24)
6214 case 0x20:
6215 case 0x21:
6216 case 0x22:
6217 case 0x23:
6218 case 0x24:
6219 case 0x25:
6220 case 0x26:
6221 case 0x27:
6222 case 0x28:
6223 case 0x29:
6224 case 0x2A:
6225 case 0x2B:
6226 case 0x2C:
6227 case 0x2D:
6228 case 0x2E:
6229 case 0x2F:
6230 case 0x30:
6231 case 0x31:
6232 case 0x32:
6233 case 0x33:
6234 case 0x34:
6235 case 0x35:
6236 case 0x36:
6237 case 0x37:
6238 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
6239
6240 case 0x38: // Negative integer (one-byte uint8_t follows)
6241 {
6242 std::uint8_t number;
6243 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6244 }
6245
6246 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
6247 {
6248 std::uint16_t number;
6249 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6250 }
6251
6252 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
6253 {
6254 std::uint32_t number;
6255 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6256 }
6257
6258 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
6259 {
6260 std::uint64_t number;
6261 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1)
6262 - static_cast<number_integer_t>(number));
6263 }
6264
6265 // Binary data (0x00..0x17 bytes follow)
6266 case 0x40:
6267 case 0x41:
6268 case 0x42:
6269 case 0x43:
6270 case 0x44:
6271 case 0x45:
6272 case 0x46:
6273 case 0x47:
6274 case 0x48:
6275 case 0x49:
6276 case 0x4A:
6277 case 0x4B:
6278 case 0x4C:
6279 case 0x4D:
6280 case 0x4E:
6281 case 0x4F:
6282 case 0x50:
6283 case 0x51:
6284 case 0x52:
6285 case 0x53:
6286 case 0x54:
6287 case 0x55:
6288 case 0x56:
6289 case 0x57:
6290 case 0x58: // Binary data (one-byte uint8_t for n follows)
6291 case 0x59: // Binary data (two-byte uint16_t for n follow)
6292 case 0x5A: // Binary data (four-byte uint32_t for n follow)
6293 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
6294 case 0x5F: // Binary data (indefinite length)
6295 {
6296 binary_t b;
6297 return get_cbor_binary(b) and sax->binary(b);
6298 }
6299
6300 // UTF-8 string (0x00..0x17 bytes follow)
6301 case 0x60:
6302 case 0x61:
6303 case 0x62:
6304 case 0x63:
6305 case 0x64:
6306 case 0x65:
6307 case 0x66:
6308 case 0x67:
6309 case 0x68:
6310 case 0x69:
6311 case 0x6A:
6312 case 0x6B:
6313 case 0x6C:
6314 case 0x6D:
6315 case 0x6E:
6316 case 0x6F:
6317 case 0x70:
6318 case 0x71:
6319 case 0x72:
6320 case 0x73:
6321 case 0x74:
6322 case 0x75:
6323 case 0x76:
6324 case 0x77:
6325 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
6326 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
6327 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
6328 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
6329 case 0x7F: // UTF-8 string (indefinite length)
6330 {
6331 string_t s;
6332 return get_cbor_string(s) and sax->string(s);
6333 }
6334
6335 // array (0x00..0x17 data items follow)
6336 case 0x80:
6337 case 0x81:
6338 case 0x82:
6339 case 0x83:
6340 case 0x84:
6341 case 0x85:
6342 case 0x86:
6343 case 0x87:
6344 case 0x88:
6345 case 0x89:
6346 case 0x8A:
6347 case 0x8B:
6348 case 0x8C:
6349 case 0x8D:
6350 case 0x8E:
6351 case 0x8F:
6352 case 0x90:
6353 case 0x91:
6354 case 0x92:
6355 case 0x93:
6356 case 0x94:
6357 case 0x95:
6358 case 0x96:
6359 case 0x97:
6360 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
6361
6362 case 0x98: // array (one-byte uint8_t for n follows)
6363 {
6364 std::uint8_t len;
6365 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6366 }
6367
6368 case 0x99: // array (two-byte uint16_t for n follow)
6369 {
6370 std::uint16_t len;
6371 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6372 }
6373
6374 case 0x9A: // array (four-byte uint32_t for n follow)
6375 {
6376 std::uint32_t len;
6377 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6378 }
6379
6380 case 0x9B: // array (eight-byte uint64_t for n follow)
6381 {
6382 std::uint64_t len;
6383 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6384 }
6385
6386 case 0x9F: // array (indefinite length)
6387 return get_cbor_array(std::size_t(-1));
6388
6389 // map (0x00..0x17 pairs of data items follow)
6390 case 0xA0:
6391 case 0xA1:
6392 case 0xA2:
6393 case 0xA3:
6394 case 0xA4:
6395 case 0xA5:
6396 case 0xA6:
6397 case 0xA7:
6398 case 0xA8:
6399 case 0xA9:
6400 case 0xAA:
6401 case 0xAB:
6402 case 0xAC:
6403 case 0xAD:
6404 case 0xAE:
6405 case 0xAF:
6406 case 0xB0:
6407 case 0xB1:
6408 case 0xB2:
6409 case 0xB3:
6410 case 0xB4:
6411 case 0xB5:
6412 case 0xB6:
6413 case 0xB7:
6414 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
6415
6416 case 0xB8: // map (one-byte uint8_t for n follows)
6417 {
6418 std::uint8_t len;
6419 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
6420 }
6421
6422 case 0xB9: // map (two-byte uint16_t for n follow)
6423 {
6424 std::uint16_t len;
6425 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
6426 }
6427
6428 case 0xBA: // map (four-byte uint32_t for n follow)
6429 {
6430 std::uint32_t len;
6431 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
6432 }
6433
6434 case 0xBB: // map (eight-byte uint64_t for n follow)
6435 {
6436 std::uint64_t len;
6437 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
6438 }
6439
6440 case 0xBF: // map (indefinite length)
6441 return get_cbor_object(std::size_t(-1));
6442
6443 case 0xF4: // false
6444 return sax->boolean(false);
6445
6446 case 0xF5: // true
6447 return sax->boolean(true);
6448
6449 case 0xF6: // null
6450 return sax->null();
6451
6452 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
6453 {
6454 const int byte1_raw = get();
6455 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
6456 {
6457 return false;
6458 }
6459 const int byte2_raw = get();
6460 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
6461 {
6462 return false;
6463 }
6464
6465 const auto byte1 = static_cast<unsigned char>(byte1_raw);
6466 const auto byte2 = static_cast<unsigned char>(byte2_raw);
6467
6468 // code from RFC 7049, Appendix D, Figure 3:
6469 // As half-precision floating-point numbers were only added
6470 // to IEEE 754 in 2008, today's programming platforms often
6471 // still only have limited support for them. It is very
6472 // easy to include at least decoding support for them even
6473 // without such support. An example of a small decoder for
6474 // half-precision floating-point numbers in the C language
6475 // is shown in Fig. 3.
6476 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
6477 const double val = [&half]
6478 {
6479 const int exp = (half >> 10u) & 0x1Fu;
6480 const unsigned int mant = half & 0x3FFu;
6481 assert(0 <= exp and exp <= 32);
6482 assert(mant <= 1024);
6483 switch (exp)
6484 {
6485 case 0:
6486 return std::ldexp(mant, -24);
6487 case 31:
6488 return (mant == 0)
6489 ? std::numeric_limits<double>::infinity()
6490 : std::numeric_limits<double>::quiet_NaN();
6491 default:
6492 return std::ldexp(mant + 1024, exp - 25);
6493 }
6494 }();
6495 return sax->number_float((half & 0x8000u) != 0
6496 ? static_cast<number_float_t>(-val)
6497 : static_cast<number_float_t>(val), "");
6498 }
6499
6500 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
6501 {
6502 float number;
6503 return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
6504 }
6505
6506 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
6507 {
6508 double number;
6509 return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
6510 }
6511
6512 default: // anything else (0xFF is handled inside the other types)
6513 {
6514 auto last_token = get_token_string();
6515 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));
6516 }
6517 }
6518 }
6519
6531 bool get_cbor_string(string_t& result)
6532 {
6533 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "string")))
6534 {
6535 return false;
6536 }
6537
6538 switch (current)
6539 {
6540 // UTF-8 string (0x00..0x17 bytes follow)
6541 case 0x60:
6542 case 0x61:
6543 case 0x62:
6544 case 0x63:
6545 case 0x64:
6546 case 0x65:
6547 case 0x66:
6548 case 0x67:
6549 case 0x68:
6550 case 0x69:
6551 case 0x6A:
6552 case 0x6B:
6553 case 0x6C:
6554 case 0x6D:
6555 case 0x6E:
6556 case 0x6F:
6557 case 0x70:
6558 case 0x71:
6559 case 0x72:
6560 case 0x73:
6561 case 0x74:
6562 case 0x75:
6563 case 0x76:
6564 case 0x77:
6565 {
6566 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
6567 }
6568
6569 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
6570 {
6571 std::uint8_t len;
6572 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
6573 }
6574
6575 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
6576 {
6577 std::uint16_t len;
6578 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
6579 }
6580
6581 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
6582 {
6583 std::uint32_t len;
6584 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
6585 }
6586
6587 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
6588 {
6589 std::uint64_t len;
6590 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
6591 }
6592
6593 case 0x7F: // UTF-8 string (indefinite length)
6594 {
6595 while (get() != 0xFF)
6596 {
6597 string_t chunk;
6598 if (not get_cbor_string(chunk))
6599 {
6600 return false;
6601 }
6602 result.append(chunk);
6603 }
6604 return true;
6605 }
6606
6607 default:
6608 {
6609 auto last_token = get_token_string();
6610 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string")));
6611 }
6612 }
6613 }
6614
6626 bool get_cbor_binary(binary_t& result)
6627 {
6628 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "binary")))
6629 {
6630 return false;
6631 }
6632
6633 switch (current)
6634 {
6635 // Binary data (0x00..0x17 bytes follow)
6636 case 0x40:
6637 case 0x41:
6638 case 0x42:
6639 case 0x43:
6640 case 0x44:
6641 case 0x45:
6642 case 0x46:
6643 case 0x47:
6644 case 0x48:
6645 case 0x49:
6646 case 0x4A:
6647 case 0x4B:
6648 case 0x4C:
6649 case 0x4D:
6650 case 0x4E:
6651 case 0x4F:
6652 case 0x50:
6653 case 0x51:
6654 case 0x52:
6655 case 0x53:
6656 case 0x54:
6657 case 0x55:
6658 case 0x56:
6659 case 0x57:
6660 {
6661 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
6662 }
6663
6664 case 0x58: // Binary data (one-byte uint8_t for n follows)
6665 {
6666 std::uint8_t len;
6667 return get_number(input_format_t::cbor, len) and
6668 get_binary(input_format_t::cbor, len, result);
6669 }
6670
6671 case 0x59: // Binary data (two-byte uint16_t for n follow)
6672 {
6673 std::uint16_t len;
6674 return get_number(input_format_t::cbor, len) and
6675 get_binary(input_format_t::cbor, len, result);
6676 }
6677
6678 case 0x5A: // Binary data (four-byte uint32_t for n follow)
6679 {
6680 std::uint32_t len;
6681 return get_number(input_format_t::cbor, len) and
6682 get_binary(input_format_t::cbor, len, result);
6683 }
6684
6685 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
6686 {
6687 std::uint64_t len;
6688 return get_number(input_format_t::cbor, len) and
6689 get_binary(input_format_t::cbor, len, result);
6690 }
6691
6692 case 0x5F: // Binary data (indefinite length)
6693 {
6694 while (get() != 0xFF)
6695 {
6696 binary_t chunk;
6697 if (not get_cbor_binary(chunk))
6698 {
6699 return false;
6700 }
6701 result.insert(result.end(), chunk.begin(), chunk.end());
6702 }
6703 return true;
6704 }
6705
6706 default:
6707 {
6708 auto last_token = get_token_string();
6709 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token, "binary")));
6710 }
6711 }
6712 }
6713
6719 bool get_cbor_array(const std::size_t len)
6720 {
6721 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len)))
6722 {
6723 return false;
6724 }
6725
6726 if (len != std::size_t(-1))
6727 {
6728 for (std::size_t i = 0; i < len; ++i)
6729 {
6730 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
6731 {
6732 return false;
6733 }
6734 }
6735 }
6736 else
6737 {
6738 while (get() != 0xFF)
6739 {
6740 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal(false)))
6741 {
6742 return false;
6743 }
6744 }
6745 }
6746
6747 return sax->end_array();
6748 }
6749
6755 bool get_cbor_object(const std::size_t len)
6756 {
6757 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len)))
6758 {
6759 return false;
6760 }
6761
6762 string_t key;
6763 if (len != std::size_t(-1))
6764 {
6765 for (std::size_t i = 0; i < len; ++i)
6766 {
6767 get();
6768 if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
6769 {
6770 return false;
6771 }
6772
6773 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
6774 {
6775 return false;
6776 }
6777 key.clear();
6778 }
6779 }
6780 else
6781 {
6782 while (get() != 0xFF)
6783 {
6784 if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
6785 {
6786 return false;
6787 }
6788
6789 if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
6790 {
6791 return false;
6792 }
6793 key.clear();
6794 }
6795 }
6796
6797 return sax->end_object();
6798 }
6799
6801 // MsgPack //
6803
6807 bool parse_msgpack_internal()
6808 {
6809 switch (get())
6810 {
6811 // EOF
6812 case std::char_traits<char>::eof():
6813 return unexpect_eof(input_format_t::msgpack, "value");
6814
6815 // positive fixint
6816 case 0x00:
6817 case 0x01:
6818 case 0x02:
6819 case 0x03:
6820 case 0x04:
6821 case 0x05:
6822 case 0x06:
6823 case 0x07:
6824 case 0x08:
6825 case 0x09:
6826 case 0x0A:
6827 case 0x0B:
6828 case 0x0C:
6829 case 0x0D:
6830 case 0x0E:
6831 case 0x0F:
6832 case 0x10:
6833 case 0x11:
6834 case 0x12:
6835 case 0x13:
6836 case 0x14:
6837 case 0x15:
6838 case 0x16:
6839 case 0x17:
6840 case 0x18:
6841 case 0x19:
6842 case 0x1A:
6843 case 0x1B:
6844 case 0x1C:
6845 case 0x1D:
6846 case 0x1E:
6847 case 0x1F:
6848 case 0x20:
6849 case 0x21:
6850 case 0x22:
6851 case 0x23:
6852 case 0x24:
6853 case 0x25:
6854 case 0x26:
6855 case 0x27:
6856 case 0x28:
6857 case 0x29:
6858 case 0x2A:
6859 case 0x2B:
6860 case 0x2C:
6861 case 0x2D:
6862 case 0x2E:
6863 case 0x2F:
6864 case 0x30:
6865 case 0x31:
6866 case 0x32:
6867 case 0x33:
6868 case 0x34:
6869 case 0x35:
6870 case 0x36:
6871 case 0x37:
6872 case 0x38:
6873 case 0x39:
6874 case 0x3A:
6875 case 0x3B:
6876 case 0x3C:
6877 case 0x3D:
6878 case 0x3E:
6879 case 0x3F:
6880 case 0x40:
6881 case 0x41:
6882 case 0x42:
6883 case 0x43:
6884 case 0x44:
6885 case 0x45:
6886 case 0x46:
6887 case 0x47:
6888 case 0x48:
6889 case 0x49:
6890 case 0x4A:
6891 case 0x4B:
6892 case 0x4C:
6893 case 0x4D:
6894 case 0x4E:
6895 case 0x4F:
6896 case 0x50:
6897 case 0x51:
6898 case 0x52:
6899 case 0x53:
6900 case 0x54:
6901 case 0x55:
6902 case 0x56:
6903 case 0x57:
6904 case 0x58:
6905 case 0x59:
6906 case 0x5A:
6907 case 0x5B:
6908 case 0x5C:
6909 case 0x5D:
6910 case 0x5E:
6911 case 0x5F:
6912 case 0x60:
6913 case 0x61:
6914 case 0x62:
6915 case 0x63:
6916 case 0x64:
6917 case 0x65:
6918 case 0x66:
6919 case 0x67:
6920 case 0x68:
6921 case 0x69:
6922 case 0x6A:
6923 case 0x6B:
6924 case 0x6C:
6925 case 0x6D:
6926 case 0x6E:
6927 case 0x6F:
6928 case 0x70:
6929 case 0x71:
6930 case 0x72:
6931 case 0x73:
6932 case 0x74:
6933 case 0x75:
6934 case 0x76:
6935 case 0x77:
6936 case 0x78:
6937 case 0x79:
6938 case 0x7A:
6939 case 0x7B:
6940 case 0x7C:
6941 case 0x7D:
6942 case 0x7E:
6943 case 0x7F:
6944 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
6945
6946 // fixmap
6947 case 0x80:
6948 case 0x81:
6949 case 0x82:
6950 case 0x83:
6951 case 0x84:
6952 case 0x85:
6953 case 0x86:
6954 case 0x87:
6955 case 0x88:
6956 case 0x89:
6957 case 0x8A:
6958 case 0x8B:
6959 case 0x8C:
6960 case 0x8D:
6961 case 0x8E:
6962 case 0x8F:
6963 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
6964
6965 // fixarray
6966 case 0x90:
6967 case 0x91:
6968 case 0x92:
6969 case 0x93:
6970 case 0x94:
6971 case 0x95:
6972 case 0x96:
6973 case 0x97:
6974 case 0x98:
6975 case 0x99:
6976 case 0x9A:
6977 case 0x9B:
6978 case 0x9C:
6979 case 0x9D:
6980 case 0x9E:
6981 case 0x9F:
6982 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
6983
6984 // fixstr
6985 case 0xA0:
6986 case 0xA1:
6987 case 0xA2:
6988 case 0xA3:
6989 case 0xA4:
6990 case 0xA5:
6991 case 0xA6:
6992 case 0xA7:
6993 case 0xA8:
6994 case 0xA9:
6995 case 0xAA:
6996 case 0xAB:
6997 case 0xAC:
6998 case 0xAD:
6999 case 0xAE:
7000 case 0xAF:
7001 case 0xB0:
7002 case 0xB1:
7003 case 0xB2:
7004 case 0xB3:
7005 case 0xB4:
7006 case 0xB5:
7007 case 0xB6:
7008 case 0xB7:
7009 case 0xB8:
7010 case 0xB9:
7011 case 0xBA:
7012 case 0xBB:
7013 case 0xBC:
7014 case 0xBD:
7015 case 0xBE:
7016 case 0xBF:
7017 case 0xD9: // str 8
7018 case 0xDA: // str 16
7019 case 0xDB: // str 32
7020 {
7021 string_t s;
7022 return get_msgpack_string(s) and sax->string(s);
7023 }
7024
7025 case 0xC0: // nil
7026 return sax->null();
7027
7028 case 0xC2: // false
7029 return sax->boolean(false);
7030
7031 case 0xC3: // true
7032 return sax->boolean(true);
7033
7034 case 0xC4: // bin 8
7035 case 0xC5: // bin 16
7036 case 0xC6: // bin 32
7037 case 0xC7: // ext 8
7038 case 0xC8: // ext 16
7039 case 0xC9: // ext 32
7040 case 0xD4: // fixext 1
7041 case 0xD5: // fixext 2
7042 case 0xD6: // fixext 4
7043 case 0xD7: // fixext 8
7044 case 0xD8: // fixext 16
7045 {
7046 binary_t b;
7047 return get_msgpack_binary(b) and sax->binary(b);
7048 }
7049
7050 case 0xCA: // float 32
7051 {
7052 float number;
7053 return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
7054 }
7055
7056 case 0xCB: // float 64
7057 {
7058 double number;
7059 return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
7060 }
7061
7062 case 0xCC: // uint 8
7063 {
7064 std::uint8_t number;
7065 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7066 }
7067
7068 case 0xCD: // uint 16
7069 {
7070 std::uint16_t number;
7071 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7072 }
7073
7074 case 0xCE: // uint 32
7075 {
7076 std::uint32_t number;
7077 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7078 }
7079
7080 case 0xCF: // uint 64
7081 {
7082 std::uint64_t number;
7083 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7084 }
7085
7086 case 0xD0: // int 8
7087 {
7088 std::int8_t number;
7089 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7090 }
7091
7092 case 0xD1: // int 16
7093 {
7094 std::int16_t number;
7095 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7096 }
7097
7098 case 0xD2: // int 32
7099 {
7100 std::int32_t number;
7101 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7102 }
7103
7104 case 0xD3: // int 64
7105 {
7106 std::int64_t number;
7107 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7108 }
7109
7110 case 0xDC: // array 16
7111 {
7112 std::uint16_t len;
7113 return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
7114 }
7115
7116 case 0xDD: // array 32
7117 {
7118 std::uint32_t len;
7119 return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
7120 }
7121
7122 case 0xDE: // map 16
7123 {
7124 std::uint16_t len;
7125 return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
7126 }
7127
7128 case 0xDF: // map 32
7129 {
7130 std::uint32_t len;
7131 return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
7132 }
7133
7134 // negative fixint
7135 case 0xE0:
7136 case 0xE1:
7137 case 0xE2:
7138 case 0xE3:
7139 case 0xE4:
7140 case 0xE5:
7141 case 0xE6:
7142 case 0xE7:
7143 case 0xE8:
7144 case 0xE9:
7145 case 0xEA:
7146 case 0xEB:
7147 case 0xEC:
7148 case 0xED:
7149 case 0xEE:
7150 case 0xEF:
7151 case 0xF0:
7152 case 0xF1:
7153 case 0xF2:
7154 case 0xF3:
7155 case 0xF4:
7156 case 0xF5:
7157 case 0xF6:
7158 case 0xF7:
7159 case 0xF8:
7160 case 0xF9:
7161 case 0xFA:
7162 case 0xFB:
7163 case 0xFC:
7164 case 0xFD:
7165 case 0xFE:
7166 case 0xFF:
7167 return sax->number_integer(static_cast<std::int8_t>(current));
7168
7169 default: // anything else
7170 {
7171 auto last_token = get_token_string();
7172 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value")));
7173 }
7174 }
7175 }
7176
7187 bool get_msgpack_string(string_t& result)
7188 {
7189 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string")))
7190 {
7191 return false;
7192 }
7193
7194 switch (current)
7195 {
7196 // fixstr
7197 case 0xA0:
7198 case 0xA1:
7199 case 0xA2:
7200 case 0xA3:
7201 case 0xA4:
7202 case 0xA5:
7203 case 0xA6:
7204 case 0xA7:
7205 case 0xA8:
7206 case 0xA9:
7207 case 0xAA:
7208 case 0xAB:
7209 case 0xAC:
7210 case 0xAD:
7211 case 0xAE:
7212 case 0xAF:
7213 case 0xB0:
7214 case 0xB1:
7215 case 0xB2:
7216 case 0xB3:
7217 case 0xB4:
7218 case 0xB5:
7219 case 0xB6:
7220 case 0xB7:
7221 case 0xB8:
7222 case 0xB9:
7223 case 0xBA:
7224 case 0xBB:
7225 case 0xBC:
7226 case 0xBD:
7227 case 0xBE:
7228 case 0xBF:
7229 {
7230 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
7231 }
7232
7233 case 0xD9: // str 8
7234 {
7235 std::uint8_t len;
7236 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7237 }
7238
7239 case 0xDA: // str 16
7240 {
7241 std::uint16_t len;
7242 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7243 }
7244
7245 case 0xDB: // str 32
7246 {
7247 std::uint32_t len;
7248 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7249 }
7250
7251 default:
7252 {
7253 auto last_token = get_token_string();
7254 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string")));
7255 }
7256 }
7257 }
7258
7269 bool get_msgpack_binary(binary_t& result)
7270 {
7271 // helper function to set the subtype
7272 auto assign_and_return_true = [&result](std::int8_t subtype)
7273 {
7274 result.set_subtype(static_cast<std::uint8_t>(subtype));
7275 return true;
7276 };
7277
7278 switch (current)
7279 {
7280 case 0xC4: // bin 8
7281 {
7282 std::uint8_t len;
7283 return get_number(input_format_t::msgpack, len) and
7284 get_binary(input_format_t::msgpack, len, result);
7285 }
7286
7287 case 0xC5: // bin 16
7288 {
7289 std::uint16_t len;
7290 return get_number(input_format_t::msgpack, len) and
7291 get_binary(input_format_t::msgpack, len, result);
7292 }
7293
7294 case 0xC6: // bin 32
7295 {
7296 std::uint32_t len;
7297 return get_number(input_format_t::msgpack, len) and
7298 get_binary(input_format_t::msgpack, len, result);
7299 }
7300
7301 case 0xC7: // ext 8
7302 {
7303 std::uint8_t len;
7304 std::int8_t subtype;
7305 return get_number(input_format_t::msgpack, len) and
7306 get_number(input_format_t::msgpack, subtype) and
7307 get_binary(input_format_t::msgpack, len, result) and
7308 assign_and_return_true(subtype);
7309 }
7310
7311 case 0xC8: // ext 16
7312 {
7313 std::uint16_t len;
7314 std::int8_t subtype;
7315 return get_number(input_format_t::msgpack, len) and
7316 get_number(input_format_t::msgpack, subtype) and
7317 get_binary(input_format_t::msgpack, len, result) and
7318 assign_and_return_true(subtype);
7319 }
7320
7321 case 0xC9: // ext 32
7322 {
7323 std::uint32_t len;
7324 std::int8_t subtype;
7325 return get_number(input_format_t::msgpack, len) and
7326 get_number(input_format_t::msgpack, subtype) and
7327 get_binary(input_format_t::msgpack, len, result) and
7328 assign_and_return_true(subtype);
7329 }
7330
7331 case 0xD4: // fixext 1
7332 {
7333 std::int8_t subtype;
7334 return get_number(input_format_t::msgpack, subtype) and
7335 get_binary(input_format_t::msgpack, 1, result) and
7336 assign_and_return_true(subtype);
7337 }
7338
7339 case 0xD5: // fixext 2
7340 {
7341 std::int8_t subtype;
7342 return get_number(input_format_t::msgpack, subtype) and
7343 get_binary(input_format_t::msgpack, 2, result) and
7344 assign_and_return_true(subtype);
7345 }
7346
7347 case 0xD6: // fixext 4
7348 {
7349 std::int8_t subtype;
7350 return get_number(input_format_t::msgpack, subtype) and
7351 get_binary(input_format_t::msgpack, 4, result) and
7352 assign_and_return_true(subtype);
7353 }
7354
7355 case 0xD7: // fixext 8
7356 {
7357 std::int8_t subtype;
7358 return get_number(input_format_t::msgpack, subtype) and
7359 get_binary(input_format_t::msgpack, 8, result) and
7360 assign_and_return_true(subtype);
7361 }
7362
7363 case 0xD8: // fixext 16
7364 {
7365 std::int8_t subtype;
7366 return get_number(input_format_t::msgpack, subtype) and
7367 get_binary(input_format_t::msgpack, 16, result) and
7368 assign_and_return_true(subtype);
7369 }
7370
7371 default: // LCOV_EXCL_LINE
7372 return false; // LCOV_EXCL_LINE
7373 }
7374 }
7375
7380 bool get_msgpack_array(const std::size_t len)
7381 {
7382 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len)))
7383 {
7384 return false;
7385 }
7386
7387 for (std::size_t i = 0; i < len; ++i)
7388 {
7389 if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal()))
7390 {
7391 return false;
7392 }
7393 }
7394
7395 return sax->end_array();
7396 }
7397
7402 bool get_msgpack_object(const std::size_t len)
7403 {
7404 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len)))
7405 {
7406 return false;
7407 }
7408
7409 string_t key;
7410 for (std::size_t i = 0; i < len; ++i)
7411 {
7412 get();
7413 if (JSON_HEDLEY_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
7414 {
7415 return false;
7416 }
7417
7418 if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal()))
7419 {
7420 return false;
7421 }
7422 key.clear();
7423 }
7424
7425 return sax->end_object();
7426 }
7427
7429 // UBJSON //
7431
7439 bool parse_ubjson_internal(const bool get_char = true)
7440 {
7441 return get_ubjson_value(get_char ? get_ignore_noop() : current);
7442 }
7443
7458 bool get_ubjson_string(string_t& result, const bool get_char = true)
7459 {
7460 if (get_char)
7461 {
7462 get(); // TODO(niels): may we ignore N here?
7463 }
7464
7465 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
7466 {
7467 return false;
7468 }
7469
7470 switch (current)
7471 {
7472 case 'U':
7473 {
7474 std::uint8_t len;
7475 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7476 }
7477
7478 case 'i':
7479 {
7480 std::int8_t len;
7481 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7482 }
7483
7484 case 'I':
7485 {
7486 std::int16_t len;
7487 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7488 }
7489
7490 case 'l':
7491 {
7492 std::int32_t len;
7493 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7494 }
7495
7496 case 'L':
7497 {
7498 std::int64_t len;
7499 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7500 }
7501
7502 default:
7503 auto last_token = get_token_string();
7504 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string")));
7505 }
7506 }
7507
7512 bool get_ubjson_size_value(std::size_t& result)
7513 {
7514 switch (get_ignore_noop())
7515 {
7516 case 'U':
7517 {
7518 std::uint8_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 'i':
7528 {
7529 std::int8_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 'I':
7539 {
7540 std::int16_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 case 'l':
7550 {
7551 std::int32_t number;
7552 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7553 {
7554 return false;
7555 }
7556 result = static_cast<std::size_t>(number);
7557 return true;
7558 }
7559
7560 case 'L':
7561 {
7562 std::int64_t number;
7563 if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7564 {
7565 return false;
7566 }
7567 result = static_cast<std::size_t>(number);
7568 return true;
7569 }
7570
7571 default:
7572 {
7573 auto last_token = get_token_string();
7574 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size")));
7575 }
7576 }
7577 }
7578
7589 bool get_ubjson_size_type(std::pair<std::size_t, int>& result)
7590 {
7591 result.first = string_t::npos; // size
7592 result.second = 0; // type
7593
7594 get_ignore_noop();
7595
7596 if (current == '$')
7597 {
7598 result.second = get(); // must not ignore 'N', because 'N' maybe the type
7599 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "type")))
7600 {
7601 return false;
7602 }
7603
7604 get_ignore_noop();
7605 if (JSON_HEDLEY_UNLIKELY(current != '#'))
7606 {
7607 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
7608 {
7609 return false;
7610 }
7611 auto last_token = get_token_string();
7612 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size")));
7613 }
7614
7615 return get_ubjson_size_value(result.first);
7616 }
7617
7618 if (current == '#')
7619 {
7620 return get_ubjson_size_value(result.first);
7621 }
7622
7623 return true;
7624 }
7625
7630 bool get_ubjson_value(const int prefix)
7631 {
7632 switch (prefix)
7633 {
7634 case std::char_traits<char>::eof(): // EOF
7635 return unexpect_eof(input_format_t::ubjson, "value");
7636
7637 case 'T': // true
7638 return sax->boolean(true);
7639 case 'F': // false
7640 return sax->boolean(false);
7641
7642 case 'Z': // null
7643 return sax->null();
7644
7645 case 'U':
7646 {
7647 std::uint8_t number;
7648 return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number);
7649 }
7650
7651 case 'i':
7652 {
7653 std::int8_t number;
7654 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7655 }
7656
7657 case 'I':
7658 {
7659 std::int16_t number;
7660 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7661 }
7662
7663 case 'l':
7664 {
7665 std::int32_t number;
7666 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7667 }
7668
7669 case 'L':
7670 {
7671 std::int64_t number;
7672 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7673 }
7674
7675 case 'd':
7676 {
7677 float number;
7678 return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
7679 }
7680
7681 case 'D':
7682 {
7683 double number;
7684 return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
7685 }
7686
7687 case 'C': // char
7688 {
7689 get();
7690 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char")))
7691 {
7692 return false;
7693 }
7694 if (JSON_HEDLEY_UNLIKELY(current > 127))
7695 {
7696 auto last_token = get_token_string();
7697 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char")));
7698 }
7699 string_t s(1, static_cast<char>(current));
7700 return sax->string(s);
7701 }
7702
7703 case 'S': // string
7704 {
7705 string_t s;
7706 return get_ubjson_string(s) and sax->string(s);
7707 }
7708
7709 case '[': // array
7710 return get_ubjson_array();
7711
7712 case '{': // object
7713 return get_ubjson_object();
7714
7715 default: // anything else
7716 {
7717 auto last_token = get_token_string();
7718 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value")));
7719 }
7720 }
7721 }
7722
7726 bool get_ubjson_array()
7727 {
7728 std::pair<std::size_t, int> size_and_type;
7729 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
7730 {
7731 return false;
7732 }
7733
7734 if (size_and_type.first != string_t::npos)
7735 {
7736 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(size_and_type.first)))
7737 {
7738 return false;
7739 }
7740
7741 if (size_and_type.second != 0)
7742 {
7743 if (size_and_type.second != 'N')
7744 {
7745 for (std::size_t i = 0; i < size_and_type.first; ++i)
7746 {
7747 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second)))
7748 {
7749 return false;
7750 }
7751 }
7752 }
7753 }
7754 else
7755 {
7756 for (std::size_t i = 0; i < size_and_type.first; ++i)
7757 {
7758 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
7759 {
7760 return false;
7761 }
7762 }
7763 }
7764 }
7765 else
7766 {
7767 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
7768 {
7769 return false;
7770 }
7771
7772 while (current != ']')
7773 {
7774 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal(false)))
7775 {
7776 return false;
7777 }
7778 get_ignore_noop();
7779 }
7780 }
7781
7782 return sax->end_array();
7783 }
7784
7788 bool get_ubjson_object()
7789 {
7790 std::pair<std::size_t, int> size_and_type;
7791 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
7792 {
7793 return false;
7794 }
7795
7796 string_t key;
7797 if (size_and_type.first != string_t::npos)
7798 {
7799 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(size_and_type.first)))
7800 {
7801 return false;
7802 }
7803
7804 if (size_and_type.second != 0)
7805 {
7806 for (std::size_t i = 0; i < size_and_type.first; ++i)
7807 {
7808 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
7809 {
7810 return false;
7811 }
7812 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second)))
7813 {
7814 return false;
7815 }
7816 key.clear();
7817 }
7818 }
7819 else
7820 {
7821 for (std::size_t i = 0; i < size_and_type.first; ++i)
7822 {
7823 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
7824 {
7825 return false;
7826 }
7827 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
7828 {
7829 return false;
7830 }
7831 key.clear();
7832 }
7833 }
7834 }
7835 else
7836 {
7837 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
7838 {
7839 return false;
7840 }
7841
7842 while (current != '}')
7843 {
7844 if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key, false) or not sax->key(key)))
7845 {
7846 return false;
7847 }
7848 if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
7849 {
7850 return false;
7851 }
7852 get_ignore_noop();
7853 key.clear();
7854 }
7855 }
7856
7857 return sax->end_object();
7858 }
7859
7860 // Note, no reader for UBJSON binary types is implemented because they do
7861 // not exist
7862
7864 // Utility functions //
7866
7876 int get()
7877 {
7878 ++chars_read;
7879 return current = ia.get_character();
7880 }
7881
7885 int get_ignore_noop()
7886 {
7887 do
7888 {
7889 get();
7890 }
7891 while (current == 'N');
7892
7893 return current;
7894 }
7895
7896 /*
7897 @brief read a number from the input
7898
7899 @tparam NumberType the type of the number
7900 @param[in] format the current format (for diagnostics)
7901 @param[out] result number of type @a NumberType
7902
7903 @return whether conversion completed
7904
7905 @note This function needs to respect the system's endianess, because
7906 bytes in CBOR, MessagePack, and UBJSON are stored in network order
7907 (big endian) and therefore need reordering on little endian systems.
7908 */
7909 template<typename NumberType, bool InputIsLittleEndian = false>
7910 bool get_number(const input_format_t format, NumberType& result)
7911 {
7912 // step 1: read input into array with system's byte order
7913 std::array<std::uint8_t, sizeof(NumberType)> vec;
7914 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
7915 {
7916 get();
7917 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format, "number")))
7918 {
7919 return false;
7920 }
7921
7922 // reverse byte order prior to conversion if necessary
7923 if (is_little_endian != InputIsLittleEndian)
7924 {
7925 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
7926 }
7927 else
7928 {
7929 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
7930 }
7931 }
7932
7933 // step 2: convert array into number of type T and return
7934 std::memcpy(&result, vec.data(), sizeof(NumberType));
7935 return true;
7936 }
7937
7952 template<typename NumberType>
7953 bool get_string(const input_format_t format,
7954 const NumberType len,
7955 string_t& result)
7956 {
7957 bool success = true;
7958 std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
7959 {
7960 get();
7961 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format, "string")))
7962 {
7963 success = false;
7964 }
7965 return static_cast<char>(current);
7966 });
7967 return success;
7968 }
7969
7984 template<typename NumberType>
7985 bool get_binary(const input_format_t format,
7986 const NumberType len,
7987 binary_t& result)
7988 {
7989 bool success = true;
7990 std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
7991 {
7992 get();
7993 if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format, "binary")))
7994 {
7995 success = false;
7996 }
7997 return static_cast<std::uint8_t>(current);
7998 });
7999 return success;
8000 }
8001
8007 JSON_HEDLEY_NON_NULL(3)
8008 bool unexpect_eof(const input_format_t format, const char* context) const
8009 {
8010 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char>::eof()))
8011 {
8012 return sax->parse_error(chars_read, "<end of file>",
8013 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
8014 }
8015 return true;
8016 }
8017
8021 std::string get_token_string() const
8022 {
8023 std::array<char, 3> cr{{}};
8024 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current));
8025 return std::string{cr.data()};
8026 }
8027
8034 std::string exception_message(const input_format_t format,
8035 const std::string& detail,
8036 const std::string& context) const
8037 {
8038 std::string error_msg = "syntax error while parsing ";
8039
8040 switch (format)
8041 {
8042 case input_format_t::cbor:
8043 error_msg += "CBOR";
8044 break;
8045
8046 case input_format_t::msgpack:
8047 error_msg += "MessagePack";
8048 break;
8049
8050 case input_format_t::ubjson:
8051 error_msg += "UBJSON";
8052 break;
8053
8054 case input_format_t::bson:
8055 error_msg += "BSON";
8056 break;
8057
8058 default: // LCOV_EXCL_LINE
8059 assert(false); // LCOV_EXCL_LINE
8060 }
8061
8062 return error_msg + " " + context + ": " + detail;
8063 }
8064
8065 private:
8067 InputAdapterType ia;
8068
8070 int current = std::char_traits<char>::eof();
8071
8073 std::size_t chars_read = 0;
8074
8076 const bool is_little_endian = little_endianess();
8077
8079 json_sax_t* sax = nullptr;
8080 };
8081 } // namespace detail
8082 } // namespace nlohmann
8083
8084 // #include <nlohmann/detail/input/input_adapters.hpp>
8085
8086 // #include <nlohmann/detail/input/lexer.hpp>
8087
8088
8089 #include <array> // array
8090 #include <clocale> // localeconv
8091 #include <cstddef> // size_t
8092 #include <cstdio> // snprintf
8093 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
8094 #include <initializer_list> // initializer_list
8095 #include <string> // char_traits, string
8096 #include <utility> // move
8097 #include <vector> // vector
8098
8099 // #include <nlohmann/detail/input/input_adapters.hpp>
8100
8101 // #include <nlohmann/detail/input/position_t.hpp>
8102
8103 // #include <nlohmann/detail/macro_scope.hpp>
8104
8105
8106 namespace nlohmann
8107 {
8108 namespace detail
8109 {
8111 // lexer //
8113
8114 template<typename BasicJsonType>
8115 class lexer_base
8116 {
8117 public:
8119 enum class token_type
8120 {
8121 uninitialized,
8122 literal_true,
8123 literal_false,
8124 literal_null,
8125 value_string,
8126 value_unsigned,
8127 value_integer,
8128 value_float,
8129 begin_array,
8130 begin_object,
8131 end_array,
8132 end_object,
8133 name_separator,
8134 value_separator,
8135 parse_error,
8136 end_of_input,
8137 literal_or_value
8138 };
8139
8141
8142 JSON_HEDLEY_CONST
8143 static const char* token_type_name(const token_type t) noexcept
8144 {
8145 switch (t)
8146 {
8147 case token_type::uninitialized:
8148 return "<uninitialized>";
8149 case token_type::literal_true:
8150 return "true literal";
8151 case token_type::literal_false:
8152 return "false literal";
8153 case token_type::literal_null:
8154 return "null literal";
8155 case token_type::value_string:
8156 return "string literal";
8157 case token_type::value_unsigned:
8158 case token_type::value_integer:
8159 case token_type::value_float:
8160 return "number literal";
8161 case token_type::begin_array:
8162 return "'['";
8163 case token_type::begin_object:
8164 return "'{'";
8165 case token_type::end_array:
8166 return "']'";
8167 case token_type::end_object:
8168 return "'}'";
8169 case token_type::name_separator:
8170 return "':'";
8171 case token_type::value_separator:
8172 return "','";
8173 case token_type::parse_error:
8174 return "<parse error>";
8175 case token_type::end_of_input:
8176 return "end of input";
8177 case token_type::literal_or_value:
8178 return "'[', '{', or a literal";
8179 // LCOV_EXCL_START
8180 default: // catch non-enum values
8181 return "unknown token";
8182 // LCOV_EXCL_STOP
8183 }
8184 }
8185 };
8191 template<typename BasicJsonType, typename InputAdapterType>
8192 class lexer : public lexer_base<BasicJsonType>
8193 {
8194 using number_integer_t = typename BasicJsonType::number_integer_t;
8195 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8196 using number_float_t = typename BasicJsonType::number_float_t;
8197 using string_t = typename BasicJsonType::string_t;
8198
8199 public:
8200 using token_type = typename lexer_base<BasicJsonType>::token_type;
8201
8202 explicit lexer(InputAdapterType&& adapter)
8203 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
8204
8205 // delete because of pointer members
8206 lexer(const lexer&) = delete;
8207 lexer(lexer&&) = default;
8208 lexer& operator=(lexer&) = delete;
8209 lexer& operator=(lexer&&) = default;
8210 ~lexer() = default;
8211
8212 private:
8214 // locales
8216
8218 JSON_HEDLEY_PURE
8219 static char get_decimal_point() noexcept
8220 {
8221 const auto loc = localeconv();
8222 assert(loc != nullptr);
8223 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
8224 }
8225
8227 // scan functions
8229
8245 int get_codepoint()
8246 {
8247 // this function only makes sense after reading `\u`
8248 assert(current == 'u');
8249 int codepoint = 0;
8250
8251 const auto factors = { 12u, 8u, 4u, 0u };
8252 for (const auto factor : factors)
8253 {
8254 get();
8255
8256 if (current >= '0' and current <= '9')
8257 {
8258 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
8259 }
8260 else if (current >= 'A' and current <= 'F')
8261 {
8262 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
8263 }
8264 else if (current >= 'a' and current <= 'f')
8265 {
8266 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
8267 }
8268 else
8269 {
8270 return -1;
8271 }
8272 }
8273
8274 assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
8275 return codepoint;
8276 }
8277
8293 bool next_byte_in_range(std::initializer_list<int> ranges)
8294 {
8295 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
8296 add(current);
8297
8298 for (auto range = ranges.begin(); range != ranges.end(); ++range)
8299 {
8300 get();
8301 if (JSON_HEDLEY_LIKELY(*range <= current and current <= *(++range)))
8302 {
8303 add(current);
8304 }
8305 else
8306 {
8307 error_message = "invalid string: ill-formed UTF-8 byte";
8308 return false;
8309 }
8310 }
8311
8312 return true;
8313 }
8314
8330 token_type scan_string()
8331 {
8332 // reset token_buffer (ignore opening quote)
8333 reset();
8334
8335 // we entered the function by reading an open quote
8336 assert(current == '\"');
8337
8338 while (true)
8339 {
8340 // get next character
8341 switch (get())
8342 {
8343 // end of file while parsing string
8344 case std::char_traits<char>::eof():
8345 {
8346 error_message = "invalid string: missing closing quote";
8347 return token_type::parse_error;
8348 }
8349
8350 // closing quote
8351 case '\"':
8352 {
8353 return token_type::value_string;
8354 }
8355
8356 // escapes
8357 case '\\':
8358 {
8359 switch (get())
8360 {
8361 // quotation mark
8362 case '\"':
8363 add('\"');
8364 break;
8365 // reverse solidus
8366 case '\\':
8367 add('\\');
8368 break;
8369 // solidus
8370 case '/':
8371 add('/');
8372 break;
8373 // backspace
8374 case 'b':
8375 add('\b');
8376 break;
8377 // form feed
8378 case 'f':
8379 add('\f');
8380 break;
8381 // line feed
8382 case 'n':
8383 add('\n');
8384 break;
8385 // carriage return
8386 case 'r':
8387 add('\r');
8388 break;
8389 // tab
8390 case 't':
8391 add('\t');
8392 break;
8393
8394 // unicode escapes
8395 case 'u':
8396 {
8397 const int codepoint1 = get_codepoint();
8398 int codepoint = codepoint1; // start with codepoint1
8399
8400 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
8401 {
8402 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
8403 return token_type::parse_error;
8404 }
8405
8406 // check if code point is a high surrogate
8407 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
8408 {
8409 // expect next \uxxxx entry
8410 if (JSON_HEDLEY_LIKELY(get() == '\\' and get() == 'u'))
8411 {
8412 const int codepoint2 = get_codepoint();
8413
8414 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
8415 {
8416 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
8417 return token_type::parse_error;
8418 }
8419
8420 // check if codepoint2 is a low surrogate
8421 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
8422 {
8423 // overwrite codepoint
8424 codepoint = static_cast<int>(
8425 // high surrogate occupies the most significant 22 bits
8426 (static_cast<unsigned int>(codepoint1) << 10u)
8427 // low surrogate occupies the least significant 15 bits
8428 + static_cast<unsigned int>(codepoint2)
8429 // there is still the 0xD800, 0xDC00 and 0x10000 noise
8430 // in the result so we have to subtract with:
8431 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
8432 - 0x35FDC00u);
8433 }
8434 else
8435 {
8436 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
8437 return token_type::parse_error;
8438 }
8439 }
8440 else
8441 {
8442 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
8443 return token_type::parse_error;
8444 }
8445 }
8446 else
8447 {
8448 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
8449 {
8450 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
8451 return token_type::parse_error;
8452 }
8453 }
8454
8455 // result of the above calculation yields a proper codepoint
8456 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
8457
8458 // translate codepoint into bytes
8459 if (codepoint < 0x80)
8460 {
8461 // 1-byte characters: 0xxxxxxx (ASCII)
8462 add(codepoint);
8463 }
8464 else if (codepoint <= 0x7FF)
8465 {
8466 // 2-byte characters: 110xxxxx 10xxxxxx
8467 add(static_cast<int>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
8468 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
8469 }
8470 else if (codepoint <= 0xFFFF)
8471 {
8472 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
8473 add(static_cast<int>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
8474 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
8475 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
8476 }
8477 else
8478 {
8479 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
8480 add(static_cast<int>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
8481 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
8482 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
8483 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
8484 }
8485
8486 break;
8487 }
8488
8489 // other characters after escape
8490 default:
8491 error_message = "invalid string: forbidden character after backslash";
8492 return token_type::parse_error;
8493 }
8494
8495 break;
8496 }
8497
8498 // invalid control characters
8499 case 0x00:
8500 {
8501 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
8502 return token_type::parse_error;
8503 }
8504
8505 case 0x01:
8506 {
8507 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
8508 return token_type::parse_error;
8509 }
8510
8511 case 0x02:
8512 {
8513 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
8514 return token_type::parse_error;
8515 }
8516
8517 case 0x03:
8518 {
8519 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
8520 return token_type::parse_error;
8521 }
8522
8523 case 0x04:
8524 {
8525 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
8526 return token_type::parse_error;
8527 }
8528
8529 case 0x05:
8530 {
8531 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
8532 return token_type::parse_error;
8533 }
8534
8535 case 0x06:
8536 {
8537 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
8538 return token_type::parse_error;
8539 }
8540
8541 case 0x07:
8542 {
8543 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
8544 return token_type::parse_error;
8545 }
8546
8547 case 0x08:
8548 {
8549 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
8550 return token_type::parse_error;
8551 }
8552
8553 case 0x09:
8554 {
8555 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
8556 return token_type::parse_error;
8557 }
8558
8559 case 0x0A:
8560 {
8561 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
8562 return token_type::parse_error;
8563 }
8564
8565 case 0x0B:
8566 {
8567 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
8568 return token_type::parse_error;
8569 }
8570
8571 case 0x0C:
8572 {
8573 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
8574 return token_type::parse_error;
8575 }
8576
8577 case 0x0D:
8578 {
8579 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
8580 return token_type::parse_error;
8581 }
8582
8583 case 0x0E:
8584 {
8585 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
8586 return token_type::parse_error;
8587 }
8588
8589 case 0x0F:
8590 {
8591 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
8592 return token_type::parse_error;
8593 }
8594
8595 case 0x10:
8596 {
8597 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
8598 return token_type::parse_error;
8599 }
8600
8601 case 0x11:
8602 {
8603 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
8604 return token_type::parse_error;
8605 }
8606
8607 case 0x12:
8608 {
8609 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
8610 return token_type::parse_error;
8611 }
8612
8613 case 0x13:
8614 {
8615 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
8616 return token_type::parse_error;
8617 }
8618
8619 case 0x14:
8620 {
8621 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
8622 return token_type::parse_error;
8623 }
8624
8625 case 0x15:
8626 {
8627 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
8628 return token_type::parse_error;
8629 }
8630
8631 case 0x16:
8632 {
8633 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
8634 return token_type::parse_error;
8635 }
8636
8637 case 0x17:
8638 {
8639 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
8640 return token_type::parse_error;
8641 }
8642
8643 case 0x18:
8644 {
8645 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
8646 return token_type::parse_error;
8647 }
8648
8649 case 0x19:
8650 {
8651 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
8652 return token_type::parse_error;
8653 }
8654
8655 case 0x1A:
8656 {
8657 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
8658 return token_type::parse_error;
8659 }
8660
8661 case 0x1B:
8662 {
8663 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
8664 return token_type::parse_error;
8665 }
8666
8667 case 0x1C:
8668 {
8669 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
8670 return token_type::parse_error;
8671 }
8672
8673 case 0x1D:
8674 {
8675 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
8676 return token_type::parse_error;
8677 }
8678
8679 case 0x1E:
8680 {
8681 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
8682 return token_type::parse_error;
8683 }
8684
8685 case 0x1F:
8686 {
8687 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
8688 return token_type::parse_error;
8689 }
8690
8691 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
8692 case 0x20:
8693 case 0x21:
8694 case 0x23:
8695 case 0x24:
8696 case 0x25:
8697 case 0x26:
8698 case 0x27:
8699 case 0x28:
8700 case 0x29:
8701 case 0x2A:
8702 case 0x2B:
8703 case 0x2C:
8704 case 0x2D:
8705 case 0x2E:
8706 case 0x2F:
8707 case 0x30:
8708 case 0x31:
8709 case 0x32:
8710 case 0x33:
8711 case 0x34:
8712 case 0x35:
8713 case 0x36:
8714 case 0x37:
8715 case 0x38:
8716 case 0x39:
8717 case 0x3A:
8718 case 0x3B:
8719 case 0x3C:
8720 case 0x3D:
8721 case 0x3E:
8722 case 0x3F:
8723 case 0x40:
8724 case 0x41:
8725 case 0x42:
8726 case 0x43:
8727 case 0x44:
8728 case 0x45:
8729 case 0x46:
8730 case 0x47:
8731 case 0x48:
8732 case 0x49:
8733 case 0x4A:
8734 case 0x4B:
8735 case 0x4C:
8736 case 0x4D:
8737 case 0x4E:
8738 case 0x4F:
8739 case 0x50:
8740 case 0x51:
8741 case 0x52:
8742 case 0x53:
8743 case 0x54:
8744 case 0x55:
8745 case 0x56:
8746 case 0x57:
8747 case 0x58:
8748 case 0x59:
8749 case 0x5A:
8750 case 0x5B:
8751 case 0x5D:
8752 case 0x5E:
8753 case 0x5F:
8754 case 0x60:
8755 case 0x61:
8756 case 0x62:
8757 case 0x63:
8758 case 0x64:
8759 case 0x65:
8760 case 0x66:
8761 case 0x67:
8762 case 0x68:
8763 case 0x69:
8764 case 0x6A:
8765 case 0x6B:
8766 case 0x6C:
8767 case 0x6D:
8768 case 0x6E:
8769 case 0x6F:
8770 case 0x70:
8771 case 0x71:
8772 case 0x72:
8773 case 0x73:
8774 case 0x74:
8775 case 0x75:
8776 case 0x76:
8777 case 0x77:
8778 case 0x78:
8779 case 0x79:
8780 case 0x7A:
8781 case 0x7B:
8782 case 0x7C:
8783 case 0x7D:
8784 case 0x7E:
8785 case 0x7F:
8786 {
8787 add(current);
8788 break;
8789 }
8790
8791 // U+0080..U+07FF: bytes C2..DF 80..BF
8792 case 0xC2:
8793 case 0xC3:
8794 case 0xC4:
8795 case 0xC5:
8796 case 0xC6:
8797 case 0xC7:
8798 case 0xC8:
8799 case 0xC9:
8800 case 0xCA:
8801 case 0xCB:
8802 case 0xCC:
8803 case 0xCD:
8804 case 0xCE:
8805 case 0xCF:
8806 case 0xD0:
8807 case 0xD1:
8808 case 0xD2:
8809 case 0xD3:
8810 case 0xD4:
8811 case 0xD5:
8812 case 0xD6:
8813 case 0xD7:
8814 case 0xD8:
8815 case 0xD9:
8816 case 0xDA:
8817 case 0xDB:
8818 case 0xDC:
8819 case 0xDD:
8820 case 0xDE:
8821 case 0xDF:
8822 {
8823 if (JSON_HEDLEY_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
8824 {
8825 return token_type::parse_error;
8826 }
8827 break;
8828 }
8829
8830 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
8831 case 0xE0:
8832 {
8833 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
8834 {
8835 return token_type::parse_error;
8836 }
8837 break;
8838 }
8839
8840 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
8841 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
8842 case 0xE1:
8843 case 0xE2:
8844 case 0xE3:
8845 case 0xE4:
8846 case 0xE5:
8847 case 0xE6:
8848 case 0xE7:
8849 case 0xE8:
8850 case 0xE9:
8851 case 0xEA:
8852 case 0xEB:
8853 case 0xEC:
8854 case 0xEE:
8855 case 0xEF:
8856 {
8857 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
8858 {
8859 return token_type::parse_error;
8860 }
8861 break;
8862 }
8863
8864 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
8865 case 0xED:
8866 {
8867 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
8868 {
8869 return token_type::parse_error;
8870 }
8871 break;
8872 }
8873
8874 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
8875 case 0xF0:
8876 {
8877 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
8878 {
8879 return token_type::parse_error;
8880 }
8881 break;
8882 }
8883
8884 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
8885 case 0xF1:
8886 case 0xF2:
8887 case 0xF3:
8888 {
8889 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
8890 {
8891 return token_type::parse_error;
8892 }
8893 break;
8894 }
8895
8896 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
8897 case 0xF4:
8898 {
8899 if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
8900 {
8901 return token_type::parse_error;
8902 }
8903 break;
8904 }
8905
8906 // remaining bytes (80..C1 and F5..FF) are ill-formed
8907 default:
8908 {
8909 error_message = "invalid string: ill-formed UTF-8 byte";
8910 return token_type::parse_error;
8911 }
8912 }
8913 }
8914 }
8915
8916 JSON_HEDLEY_NON_NULL(2)
8917 static void strtof(float& f, const char* str, char** endptr) noexcept
8918 {
8919 f = std::strtof(str, endptr);
8920 }
8921
8922 JSON_HEDLEY_NON_NULL(2)
8923 static void strtof(double& f, const char* str, char** endptr) noexcept
8924 {
8925 f = std::strtod(str, endptr);
8926 }
8927
8928 JSON_HEDLEY_NON_NULL(2)
8929 static void strtof(long double& f, const char* str, char** endptr) noexcept
8930 {
8931 f = std::strtold(str, endptr);
8932 }
8933
8974 token_type scan_number() // lgtm [cpp/use-of-goto]
8975 {
8976 // reset token_buffer to store the number's bytes
8977 reset();
8978
8979 // the type of the parsed number; initially set to unsigned; will be
8980 // changed if minus sign, decimal point or exponent is read
8981 token_type number_type = token_type::value_unsigned;
8982
8983 // state (init): we just found out we need to scan a number
8984 switch (current)
8985 {
8986 case '-':
8987 {
8988 add(current);
8989 goto scan_number_minus;
8990 }
8991
8992 case '0':
8993 {
8994 add(current);
8995 goto scan_number_zero;
8996 }
8997
8998 case '1':
8999 case '2':
9000 case '3':
9001 case '4':
9002 case '5':
9003 case '6':
9004 case '7':
9005 case '8':
9006 case '9':
9007 {
9008 add(current);
9009 goto scan_number_any1;
9010 }
9011
9012 // all other characters are rejected outside scan_number()
9013 default: // LCOV_EXCL_LINE
9014 assert(false); // LCOV_EXCL_LINE
9015 }
9016
9017 scan_number_minus:
9018 // state: we just parsed a leading minus sign
9019 number_type = token_type::value_integer;
9020 switch (get())
9021 {
9022 case '0':
9023 {
9024 add(current);
9025 goto scan_number_zero;
9026 }
9027
9028 case '1':
9029 case '2':
9030 case '3':
9031 case '4':
9032 case '5':
9033 case '6':
9034 case '7':
9035 case '8':
9036 case '9':
9037 {
9038 add(current);
9039 goto scan_number_any1;
9040 }
9041
9042 default:
9043 {
9044 error_message = "invalid number; expected digit after '-'";
9045 return token_type::parse_error;
9046 }
9047 }
9048
9049 scan_number_zero:
9050 // state: we just parse a zero (maybe with a leading minus sign)
9051 switch (get())
9052 {
9053 case '.':
9054 {
9055 add(decimal_point_char);
9056 goto scan_number_decimal1;
9057 }
9058
9059 case 'e':
9060 case 'E':
9061 {
9062 add(current);
9063 goto scan_number_exponent;
9064 }
9065
9066 default:
9067 goto scan_number_done;
9068 }
9069
9070 scan_number_any1:
9071 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
9072 switch (get())
9073 {
9074 case '0':
9075 case '1':
9076 case '2':
9077 case '3':
9078 case '4':
9079 case '5':
9080 case '6':
9081 case '7':
9082 case '8':
9083 case '9':
9084 {
9085 add(current);
9086 goto scan_number_any1;
9087 }
9088
9089 case '.':
9090 {
9091 add(decimal_point_char);
9092 goto scan_number_decimal1;
9093 }
9094
9095 case 'e':
9096 case 'E':
9097 {
9098 add(current);
9099 goto scan_number_exponent;
9100 }
9101
9102 default:
9103 goto scan_number_done;
9104 }
9105
9106 scan_number_decimal1:
9107 // state: we just parsed a decimal point
9108 number_type = token_type::value_float;
9109 switch (get())
9110 {
9111 case '0':
9112 case '1':
9113 case '2':
9114 case '3':
9115 case '4':
9116 case '5':
9117 case '6':
9118 case '7':
9119 case '8':
9120 case '9':
9121 {
9122 add(current);
9123 goto scan_number_decimal2;
9124 }
9125
9126 default:
9127 {
9128 error_message = "invalid number; expected digit after '.'";
9129 return token_type::parse_error;
9130 }
9131 }
9132
9133 scan_number_decimal2:
9134 // we just parsed at least one number after a decimal point
9135 switch (get())
9136 {
9137 case '0':
9138 case '1':
9139 case '2':
9140 case '3':
9141 case '4':
9142 case '5':
9143 case '6':
9144 case '7':
9145 case '8':
9146 case '9':
9147 {
9148 add(current);
9149 goto scan_number_decimal2;
9150 }
9151
9152 case 'e':
9153 case 'E':
9154 {
9155 add(current);
9156 goto scan_number_exponent;
9157 }
9158
9159 default:
9160 goto scan_number_done;
9161 }
9162
9163 scan_number_exponent:
9164 // we just parsed an exponent
9165 number_type = token_type::value_float;
9166 switch (get())
9167 {
9168 case '+':
9169 case '-':
9170 {
9171 add(current);
9172 goto scan_number_sign;
9173 }
9174
9175 case '0':
9176 case '1':
9177 case '2':
9178 case '3':
9179 case '4':
9180 case '5':
9181 case '6':
9182 case '7':
9183 case '8':
9184 case '9':
9185 {
9186 add(current);
9187 goto scan_number_any2;
9188 }
9189
9190 default:
9191 {
9192 error_message =
9193 "invalid number; expected '+', '-', or digit after exponent";
9194 return token_type::parse_error;
9195 }
9196 }
9197
9198 scan_number_sign:
9199 // we just parsed an exponent sign
9200 switch (get())
9201 {
9202 case '0':
9203 case '1':
9204 case '2':
9205 case '3':
9206 case '4':
9207 case '5':
9208 case '6':
9209 case '7':
9210 case '8':
9211 case '9':
9212 {
9213 add(current);
9214 goto scan_number_any2;
9215 }
9216
9217 default:
9218 {
9219 error_message = "invalid number; expected digit after exponent sign";
9220 return token_type::parse_error;
9221 }
9222 }
9223
9224 scan_number_any2:
9225 // we just parsed a number after the exponent or exponent sign
9226 switch (get())
9227 {
9228 case '0':
9229 case '1':
9230 case '2':
9231 case '3':
9232 case '4':
9233 case '5':
9234 case '6':
9235 case '7':
9236 case '8':
9237 case '9':
9238 {
9239 add(current);
9240 goto scan_number_any2;
9241 }
9242
9243 default:
9244 goto scan_number_done;
9245 }
9246
9247 scan_number_done:
9248 // unget the character after the number (we only read it to know that
9249 // we are done scanning a number)
9250 unget();
9251
9252 char* endptr = nullptr;
9253 errno = 0;
9254
9255 // try to parse integers first and fall back to floats
9256 if (number_type == token_type::value_unsigned)
9257 {
9258 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
9259
9260 // we checked the number format before
9261 assert(endptr == token_buffer.data() + token_buffer.size());
9262
9263 if (errno == 0)
9264 {
9265 value_unsigned = static_cast<number_unsigned_t>(x);
9266 if (value_unsigned == x)
9267 {
9268 return token_type::value_unsigned;
9269 }
9270 }
9271 }
9272 else if (number_type == token_type::value_integer)
9273 {
9274 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
9275
9276 // we checked the number format before
9277 assert(endptr == token_buffer.data() + token_buffer.size());
9278
9279 if (errno == 0)
9280 {
9281 value_integer = static_cast<number_integer_t>(x);
9282 if (value_integer == x)
9283 {
9284 return token_type::value_integer;
9285 }
9286 }
9287 }
9288
9289 // this code is reached if we parse a floating-point number or if an
9290 // integer conversion above failed
9291 strtof(value_float, token_buffer.data(), &endptr);
9292
9293 // we checked the number format before
9294 assert(endptr == token_buffer.data() + token_buffer.size());
9295
9296 return token_type::value_float;
9297 }
9298
9304 JSON_HEDLEY_NON_NULL(2)
9305 token_type scan_literal(const char* literal_text, const std::size_t length,
9306 token_type return_type)
9307 {
9308 assert(current == literal_text[0]);
9309 for (std::size_t i = 1; i < length; ++i)
9310 {
9311 if (JSON_HEDLEY_UNLIKELY(get() != literal_text[i]))
9312 {
9313 error_message = "invalid literal";
9314 return token_type::parse_error;
9315 }
9316 }
9317 return return_type;
9318 }
9319
9321 // input management
9323
9325 void reset() noexcept
9326 {
9327 token_buffer.clear();
9328 token_string.clear();
9329 token_string.push_back(std::char_traits<char>::to_char_type(current));
9330 }
9331
9332 /*
9333 @brief get next character from the input
9334
9335 This function provides the interface to the used input adapter. It does
9336 not throw in case the input reached EOF, but returns a
9337 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
9338 for use in error messages.
9339
9340 @return character read from the input
9341 */
9342 std::char_traits<char>::int_type get()
9343 {
9344 ++position.chars_read_total;
9345 ++position.chars_read_current_line;
9346
9347 if (next_unget)
9348 {
9349 // just reset the next_unget variable and work with current
9350 next_unget = false;
9351 }
9352 else
9353 {
9354 current = ia.get_character();
9355 }
9356
9357 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char>::eof()))
9358 {
9359 token_string.push_back(std::char_traits<char>::to_char_type(current));
9360 }
9361
9362 if (current == '\n')
9363 {
9364 ++position.lines_read;
9365 position.chars_read_current_line = 0;
9366 }
9367
9368 return current;
9369 }
9370
9379 void unget()
9380 {
9381 next_unget = true;
9382
9383 --position.chars_read_total;
9384
9385 // in case we "unget" a newline, we have to also decrement the lines_read
9386 if (position.chars_read_current_line == 0)
9387 {
9388 if (position.lines_read > 0)
9389 {
9390 --position.lines_read;
9391 }
9392 }
9393 else
9394 {
9395 --position.chars_read_current_line;
9396 }
9397
9398 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char>::eof()))
9399 {
9400 assert(not token_string.empty());
9401 token_string.pop_back();
9402 }
9403 }
9404
9406 void add(int c)
9407 {
9408 token_buffer.push_back(std::char_traits<char>::to_char_type(c));
9409 }
9410
9411 public:
9413 // value getters
9415
9417 constexpr number_integer_t get_number_integer() const noexcept
9418 {
9419 return value_integer;
9420 }
9421
9423 constexpr number_unsigned_t get_number_unsigned() const noexcept
9424 {
9425 return value_unsigned;
9426 }
9427
9429 constexpr number_float_t get_number_float() const noexcept
9430 {
9431 return value_float;
9432 }
9433
9435 string_t& get_string()
9436 {
9437 return token_buffer;
9438 }
9439
9441 // diagnostics
9443
9445 constexpr position_t get_position() const noexcept
9446 {
9447 return position;
9448 }
9449
9453 std::string get_token_string() const
9454 {
9455 // escape control characters
9456 std::string result;
9457 for (const auto c : token_string)
9458 {
9459 if ('\x00' <= c and c <= '\x1F')
9460 {
9461 // escape control characters
9462 std::array<char, 9> cs{{}};
9463 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c));
9464 result += cs.data();
9465 }
9466 else
9467 {
9468 // add character as is
9469 result.push_back(c);
9470 }
9471 }
9472
9473 return result;
9474 }
9475
9477
9478 constexpr const char* get_error_message() const noexcept
9479 {
9480 return error_message;
9481 }
9482
9484 // actual scanner
9486
9491 bool skip_bom()
9492 {
9493 if (get() == 0xEF)
9494 {
9495 // check if we completely parse the BOM
9496 return get() == 0xBB and get() == 0xBF;
9497 }
9498
9499 // the first character is not the beginning of the BOM; unget it to
9500 // process is later
9501 unget();
9502 return true;
9503 }
9504
9505 token_type scan()
9506 {
9507 // initially, skip the BOM
9508 if (position.chars_read_total == 0 and not skip_bom())
9509 {
9510 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
9511 return token_type::parse_error;
9512 }
9513
9514 // read next character and ignore whitespace
9515 do
9516 {
9517 get();
9518 }
9519 while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
9520
9521 switch (current)
9522 {
9523 // structural characters
9524 case '[':
9525 return token_type::begin_array;
9526 case ']':
9527 return token_type::end_array;
9528 case '{':
9529 return token_type::begin_object;
9530 case '}':
9531 return token_type::end_object;
9532 case ':':
9533 return token_type::name_separator;
9534 case ',':
9535 return token_type::value_separator;
9536
9537 // literals
9538 case 't':
9539 return scan_literal("true", 4, token_type::literal_true);
9540 case 'f':
9541 return scan_literal("false", 5, token_type::literal_false);
9542 case 'n':
9543 return scan_literal("null", 4, token_type::literal_null);
9544
9545 // string
9546 case '\"':
9547 return scan_string();
9548
9549 // number
9550 case '-':
9551 case '0':
9552 case '1':
9553 case '2':
9554 case '3':
9555 case '4':
9556 case '5':
9557 case '6':
9558 case '7':
9559 case '8':
9560 case '9':
9561 return scan_number();
9562
9563 // end of input (the null byte is needed when parsing from
9564 // string literals)
9565 case '\0':
9566 case std::char_traits<char>::eof():
9567 return token_type::end_of_input;
9568
9569 // error
9570 default:
9571 error_message = "invalid literal";
9572 return token_type::parse_error;
9573 }
9574 }
9575
9576 private:
9578 InputAdapterType ia;
9579
9581 std::char_traits<char>::int_type current = std::char_traits<char>::eof();
9582
9584 bool next_unget = false;
9585
9587 position_t position {};
9588
9590 std::vector<char> token_string {};
9591
9593 string_t token_buffer {};
9594
9596 const char* error_message = "";
9597
9598 // number values
9599 number_integer_t value_integer = 0;
9600 number_unsigned_t value_unsigned = 0;
9601 number_float_t value_float = 0;
9602
9604 const char decimal_point_char = '.';
9605 };
9606 } // namespace detail
9607 } // namespace nlohmann
9608
9609 // #include <nlohmann/detail/input/parser.hpp>
9610
9611
9612 #include <cassert> // assert
9613 #include <cmath> // isfinite
9614 #include <cstdint> // uint8_t
9615 #include <functional> // function
9616 #include <string> // string
9617 #include <utility> // move
9618 #include <vector> // vector
9619
9620 // #include <nlohmann/detail/exceptions.hpp>
9621
9622 // #include <nlohmann/detail/input/input_adapters.hpp>
9623
9624 // #include <nlohmann/detail/input/json_sax.hpp>
9625
9626 // #include <nlohmann/detail/input/lexer.hpp>
9627
9628 // #include <nlohmann/detail/macro_scope.hpp>
9629
9630 // #include <nlohmann/detail/meta/is_sax.hpp>
9631
9632 // #include <nlohmann/detail/value_t.hpp>
9633
9634
9635 namespace nlohmann
9636 {
9637 namespace detail
9638 {
9640 // parser //
9642
9643 enum class parse_event_t : uint8_t
9644 {
9646 object_start,
9648 object_end,
9650 array_start,
9652 array_end,
9654 key,
9656 value
9657 };
9658
9659 template<typename BasicJsonType>
9660 using parser_callback_t =
9661 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
9662
9668 template<typename BasicJsonType, typename InputAdapterType>
9669 class parser
9670 {
9671 using number_integer_t = typename BasicJsonType::number_integer_t;
9672 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9673 using number_float_t = typename BasicJsonType::number_float_t;
9674 using string_t = typename BasicJsonType::string_t;
9675 using lexer_t = lexer<BasicJsonType, InputAdapterType>;
9676 using token_type = typename lexer_t::token_type;
9677
9678 public:
9680 explicit parser(InputAdapterType&& adapter,
9681 const parser_callback_t<BasicJsonType> cb = nullptr,
9682 const bool allow_exceptions_ = true)
9683 : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
9684 {
9685 // read first token
9686 get_token();
9687 }
9688
9699 void parse(const bool strict, BasicJsonType& result)
9700 {
9701 if (callback)
9702 {
9703 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
9704 sax_parse_internal(&sdp);
9705 result.assert_invariant();
9706
9707 // in strict mode, input must be completely read
9708 if (strict and (get_token() != token_type::end_of_input))
9709 {
9710 sdp.parse_error(m_lexer.get_position(),
9711 m_lexer.get_token_string(),
9712 parse_error::create(101, m_lexer.get_position(),
9713 exception_message(token_type::end_of_input, "value")));
9714 }
9715
9716 // in case of an error, return discarded value
9717 if (sdp.is_errored())
9718 {
9719 result = value_t::discarded;
9720 return;
9721 }
9722
9723 // set top-level value to null if it was discarded by the callback
9724 // function
9725 if (result.is_discarded())
9726 {
9727 result = nullptr;
9728 }
9729 }
9730 else
9731 {
9732 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
9733 sax_parse_internal(&sdp);
9734 result.assert_invariant();
9735
9736 // in strict mode, input must be completely read
9737 if (strict and (get_token() != token_type::end_of_input))
9738 {
9739 sdp.parse_error(m_lexer.get_position(),
9740 m_lexer.get_token_string(),
9741 parse_error::create(101, m_lexer.get_position(),
9742 exception_message(token_type::end_of_input, "value")));
9743 }
9744
9745 // in case of an error, return discarded value
9746 if (sdp.is_errored())
9747 {
9748 result = value_t::discarded;
9749 return;
9750 }
9751 }
9752 }
9753
9760 bool accept(const bool strict = true)
9761 {
9762 json_sax_acceptor<BasicJsonType> sax_acceptor;
9763 return sax_parse(&sax_acceptor, strict);
9764 }
9765
9766 template <typename SAX>
9767 JSON_HEDLEY_NON_NULL(2)
9768 bool sax_parse(SAX* sax, const bool strict = true)
9769 {
9770 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
9771 const bool result = sax_parse_internal(sax);
9772
9773 // strict mode: next byte must be EOF
9774 if (result and strict and (get_token() != token_type::end_of_input))
9775 {
9776 return sax->parse_error(m_lexer.get_position(),
9777 m_lexer.get_token_string(),
9778 parse_error::create(101, m_lexer.get_position(),
9779 exception_message(token_type::end_of_input, "value")));
9780 }
9781
9782 return result;
9783 }
9784
9785 private:
9786 template <typename SAX>
9787 JSON_HEDLEY_NON_NULL(2)
9788 bool sax_parse_internal(SAX* sax)
9789 {
9790 // stack to remember the hierarchy of structured values we are parsing
9791 // true = array; false = object
9792 std::vector<bool> states;
9793 // value to avoid a goto (see comment where set to true)
9794 bool skip_to_state_evaluation = false;
9795
9796 while (true)
9797 {
9798 if (not skip_to_state_evaluation)
9799 {
9800 // invariant: get_token() was called before each iteration
9801 switch (last_token)
9802 {
9803 case token_type::begin_object:
9804 {
9805 if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
9806 {
9807 return false;
9808 }
9809
9810 // closing } -> we are done
9811 if (get_token() == token_type::end_object)
9812 {
9813 if (JSON_HEDLEY_UNLIKELY(not sax->end_object()))
9814 {
9815 return false;
9816 }
9817 break;
9818 }
9819
9820 // parse key
9821 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
9822 {
9823 return sax->parse_error(m_lexer.get_position(),
9824 m_lexer.get_token_string(),
9825 parse_error::create(101, m_lexer.get_position(),
9826 exception_message(token_type::value_string, "object key")));
9827 }
9828 if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
9829 {
9830 return false;
9831 }
9832
9833 // parse separator (:)
9834 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
9835 {
9836 return sax->parse_error(m_lexer.get_position(),
9837 m_lexer.get_token_string(),
9838 parse_error::create(101, m_lexer.get_position(),
9839 exception_message(token_type::name_separator, "object separator")));
9840 }
9841
9842 // remember we are now inside an object
9843 states.push_back(false);
9844
9845 // parse values
9846 get_token();
9847 continue;
9848 }
9849
9850 case token_type::begin_array:
9851 {
9852 if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
9853 {
9854 return false;
9855 }
9856
9857 // closing ] -> we are done
9858 if (get_token() == token_type::end_array)
9859 {
9860 if (JSON_HEDLEY_UNLIKELY(not sax->end_array()))
9861 {
9862 return false;
9863 }
9864 break;
9865 }
9866
9867 // remember we are now inside an array
9868 states.push_back(true);
9869
9870 // parse values (no need to call get_token)
9871 continue;
9872 }
9873
9874 case token_type::value_float:
9875 {
9876 const auto res = m_lexer.get_number_float();
9877
9878 if (JSON_HEDLEY_UNLIKELY(not std::isfinite(res)))
9879 {
9880 return sax->parse_error(m_lexer.get_position(),
9881 m_lexer.get_token_string(),
9882 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
9883 }
9884
9885 if (JSON_HEDLEY_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
9886 {
9887 return false;
9888 }
9889
9890 break;
9891 }
9892
9893 case token_type::literal_false:
9894 {
9895 if (JSON_HEDLEY_UNLIKELY(not sax->boolean(false)))
9896 {
9897 return false;
9898 }
9899 break;
9900 }
9901
9902 case token_type::literal_null:
9903 {
9904 if (JSON_HEDLEY_UNLIKELY(not sax->null()))
9905 {
9906 return false;
9907 }
9908 break;
9909 }
9910
9911 case token_type::literal_true:
9912 {
9913 if (JSON_HEDLEY_UNLIKELY(not sax->boolean(true)))
9914 {
9915 return false;
9916 }
9917 break;
9918 }
9919
9920 case token_type::value_integer:
9921 {
9922 if (JSON_HEDLEY_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
9923 {
9924 return false;
9925 }
9926 break;
9927 }
9928
9929 case token_type::value_string:
9930 {
9931 if (JSON_HEDLEY_UNLIKELY(not sax->string(m_lexer.get_string())))
9932 {
9933 return false;
9934 }
9935 break;
9936 }
9937
9938 case token_type::value_unsigned:
9939 {
9940 if (JSON_HEDLEY_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
9941 {
9942 return false;
9943 }
9944 break;
9945 }
9946
9947 case token_type::parse_error:
9948 {
9949 // using "uninitialized" to avoid "expected" message
9950 return sax->parse_error(m_lexer.get_position(),
9951 m_lexer.get_token_string(),
9952 parse_error::create(101, m_lexer.get_position(),
9953 exception_message(token_type::uninitialized, "value")));
9954 }
9955
9956 default: // the last token was unexpected
9957 {
9958 return sax->parse_error(m_lexer.get_position(),
9959 m_lexer.get_token_string(),
9960 parse_error::create(101, m_lexer.get_position(),
9961 exception_message(token_type::literal_or_value, "value")));
9962 }
9963 }
9964 }
9965 else
9966 {
9967 skip_to_state_evaluation = false;
9968 }
9969
9970 // we reached this line after we successfully parsed a value
9971 if (states.empty())
9972 {
9973 // empty stack: we reached the end of the hierarchy: done
9974 return true;
9975 }
9976
9977 if (states.back()) // array
9978 {
9979 // comma -> next value
9980 if (get_token() == token_type::value_separator)
9981 {
9982 // parse a new value
9983 get_token();
9984 continue;
9985 }
9986
9987 // closing ]
9988 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
9989 {
9990 if (JSON_HEDLEY_UNLIKELY(not sax->end_array()))
9991 {
9992 return false;
9993 }
9994
9995 // We are done with this array. Before we can parse a
9996 // new value, we need to evaluate the new state first.
9997 // By setting skip_to_state_evaluation to false, we
9998 // are effectively jumping to the beginning of this if.
9999 assert(not states.empty());
10000 states.pop_back();
10001 skip_to_state_evaluation = true;
10002 continue;
10003 }
10004
10005 return sax->parse_error(m_lexer.get_position(),
10006 m_lexer.get_token_string(),
10007 parse_error::create(101, m_lexer.get_position(),
10008 exception_message(token_type::end_array, "array")));
10009 }
10010 else // object
10011 {
10012 // comma -> next value
10013 if (get_token() == token_type::value_separator)
10014 {
10015 // parse key
10016 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
10017 {
10018 return sax->parse_error(m_lexer.get_position(),
10019 m_lexer.get_token_string(),
10020 parse_error::create(101, m_lexer.get_position(),
10021 exception_message(token_type::value_string, "object key")));
10022 }
10023
10024 if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
10025 {
10026 return false;
10027 }
10028
10029 // parse separator (:)
10030 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10031 {
10032 return sax->parse_error(m_lexer.get_position(),
10033 m_lexer.get_token_string(),
10034 parse_error::create(101, m_lexer.get_position(),
10035 exception_message(token_type::name_separator, "object separator")));
10036 }
10037
10038 // parse values
10039 get_token();
10040 continue;
10041 }
10042
10043 // closing }
10044 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
10045 {
10046 if (JSON_HEDLEY_UNLIKELY(not sax->end_object()))
10047 {
10048 return false;
10049 }
10050
10051 // We are done with this object. Before we can parse a
10052 // new value, we need to evaluate the new state first.
10053 // By setting skip_to_state_evaluation to false, we
10054 // are effectively jumping to the beginning of this if.
10055 assert(not states.empty());
10056 states.pop_back();
10057 skip_to_state_evaluation = true;
10058 continue;
10059 }
10060
10061 return sax->parse_error(m_lexer.get_position(),
10062 m_lexer.get_token_string(),
10063 parse_error::create(101, m_lexer.get_position(),
10064 exception_message(token_type::end_object, "object")));
10065 }
10066 }
10067 }
10068
10070 token_type get_token()
10071 {
10072 return last_token = m_lexer.scan();
10073 }
10074
10075 std::string exception_message(const token_type expected, const std::string& context)
10076 {
10077 std::string error_msg = "syntax error ";
10078
10079 if (not context.empty())
10080 {
10081 error_msg += "while parsing " + context + " ";
10082 }
10083
10084 error_msg += "- ";
10085
10086 if (last_token == token_type::parse_error)
10087 {
10088 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
10089 m_lexer.get_token_string() + "'";
10090 }
10091 else
10092 {
10093 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
10094 }
10095
10096 if (expected != token_type::uninitialized)
10097 {
10098 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
10099 }
10100
10101 return error_msg;
10102 }
10103
10104 private:
10106 const parser_callback_t<BasicJsonType> callback = nullptr;
10108 token_type last_token = token_type::uninitialized;
10110 lexer_t m_lexer;
10112 const bool allow_exceptions = true;
10113 };
10114 } // namespace detail
10115 } // namespace nlohmann
10116
10117 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
10118
10119
10120 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10121
10122
10123 #include <cstddef> // ptrdiff_t
10124 #include <limits> // numeric_limits
10125
10126 namespace nlohmann
10127 {
10128 namespace detail
10129 {
10130 /*
10131 @brief an iterator for primitive JSON types
10132
10133 This class models an iterator for primitive JSON types (boolean, number,
10134 string). It's only purpose is to allow the iterator/const_iterator classes
10135 to "iterate" over primitive values. Internally, the iterator is modeled by
10136 a `difference_type` variable. Value begin_value (`0`) models the begin,
10137 end_value (`1`) models past the end.
10138 */
10139 class primitive_iterator_t
10140 {
10141 private:
10142 using difference_type = std::ptrdiff_t;
10143 static constexpr difference_type begin_value = 0;
10144 static constexpr difference_type end_value = begin_value + 1;
10145
10147 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
10148
10149 public:
10150 constexpr difference_type get_value() const noexcept
10151 {
10152 return m_it;
10153 }
10154
10156 void set_begin() noexcept
10157 {
10158 m_it = begin_value;
10159 }
10160
10162 void set_end() noexcept
10163 {
10164 m_it = end_value;
10165 }
10166
10168 constexpr bool is_begin() const noexcept
10169 {
10170 return m_it == begin_value;
10171 }
10172
10174 constexpr bool is_end() const noexcept
10175 {
10176 return m_it == end_value;
10177 }
10178
10179 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10180 {
10181 return lhs.m_it == rhs.m_it;
10182 }
10183
10184 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10185 {
10186 return lhs.m_it < rhs.m_it;
10187 }
10188
10189 primitive_iterator_t operator+(difference_type n) noexcept
10190 {
10191 auto result = *this;
10192 result += n;
10193 return result;
10194 }
10195
10196 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10197 {
10198 return lhs.m_it - rhs.m_it;
10199 }
10200
10201 primitive_iterator_t& operator++() noexcept
10202 {
10203 ++m_it;
10204 return *this;
10205 }
10206
10207 primitive_iterator_t const operator++(int) noexcept
10208 {
10209 auto result = *this;
10210 ++m_it;
10211 return result;
10212 }
10213
10214 primitive_iterator_t& operator--() noexcept
10215 {
10216 --m_it;
10217 return *this;
10218 }
10219
10220 primitive_iterator_t const operator--(int) noexcept
10221 {
10222 auto result = *this;
10223 --m_it;
10224 return result;
10225 }
10226
10227 primitive_iterator_t& operator+=(difference_type n) noexcept
10228 {
10229 m_it += n;
10230 return *this;
10231 }
10232
10233 primitive_iterator_t& operator-=(difference_type n) noexcept
10234 {
10235 m_it -= n;
10236 return *this;
10237 }
10238 };
10239 } // namespace detail
10240 } // namespace nlohmann
10241
10242
10243 namespace nlohmann
10244 {
10245 namespace detail
10246 {
10253 template<typename BasicJsonType> struct internal_iterator
10254 {
10256 typename BasicJsonType::object_t::iterator object_iterator {};
10258 typename BasicJsonType::array_t::iterator array_iterator {};
10260 typename BasicJsonType::binary_t::container_type::iterator binary_iterator {};
10262 primitive_iterator_t primitive_iterator {};
10263 };
10264 } // namespace detail
10265 } // namespace nlohmann
10266
10267 // #include <nlohmann/detail/iterators/iter_impl.hpp>
10268
10269
10270 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
10271 #include <type_traits> // conditional, is_const, remove_const
10272
10273 // #include <nlohmann/detail/boolean_operators.hpp>
10274
10275 // #include <nlohmann/detail/exceptions.hpp>
10276
10277 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
10278
10279 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10280
10281 // #include <nlohmann/detail/macro_scope.hpp>
10282
10283 // #include <nlohmann/detail/meta/cpp_future.hpp>
10284
10285 // #include <nlohmann/detail/meta/type_traits.hpp>
10286
10287 // #include <nlohmann/detail/value_t.hpp>
10288
10289
10290 namespace nlohmann
10291 {
10292 namespace detail
10293 {
10294 // forward declare, to be able to friend it later on
10295 template<typename IteratorType> class iteration_proxy;
10296 template<typename IteratorType> class iteration_proxy_value;
10297
10314 template<typename BasicJsonType>
10315 class iter_impl
10316 {
10318 friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
10319 friend BasicJsonType;
10320 friend iteration_proxy<iter_impl>;
10321 friend iteration_proxy_value<iter_impl>;
10322
10323 using object_t = typename BasicJsonType::object_t;
10324 using array_t = typename BasicJsonType::array_t;
10325 // make sure BasicJsonType is basic_json or const basic_json
10326 static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
10327 "iter_impl only accepts (const) basic_json");
10328
10329 public:
10330
10336 using iterator_category = std::bidirectional_iterator_tag;
10337
10339 using value_type = typename BasicJsonType::value_type;
10341 using difference_type = typename BasicJsonType::difference_type;
10343 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
10344 typename BasicJsonType::const_pointer,
10345 typename BasicJsonType::pointer>::type;
10347 using reference =
10348 typename std::conditional<std::is_const<BasicJsonType>::value,
10349 typename BasicJsonType::const_reference,
10350 typename BasicJsonType::reference>::type;
10351
10353 iter_impl() = default;
10354
10361 explicit iter_impl(pointer object) noexcept : m_object(object)
10362 {
10363 assert(m_object != nullptr);
10364
10365 switch (m_object->m_type)
10366 {
10367 case value_t::object:
10368 {
10369 m_it.object_iterator = typename object_t::iterator();
10370 break;
10371 }
10372
10373 case value_t::array:
10374 {
10375 m_it.array_iterator = typename array_t::iterator();
10376 break;
10377 }
10378
10379 default:
10380 {
10381 m_it.primitive_iterator = primitive_iterator_t();
10382 break;
10383 }
10384 }
10385 }
10386
10403 iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
10404 : m_object(other.m_object), m_it(other.m_it)
10405 {}
10406
10413 iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
10414 {
10415 m_object = other.m_object;
10416 m_it = other.m_it;
10417 return *this;
10418 }
10419
10425 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
10426 : m_object(other.m_object), m_it(other.m_it)
10427 {}
10428
10435 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
10436 {
10437 m_object = other.m_object;
10438 m_it = other.m_it;
10439 return *this;
10440 }
10441
10442 private:
10447 void set_begin() noexcept
10448 {
10449 assert(m_object != nullptr);
10450
10451 switch (m_object->m_type)
10452 {
10453 case value_t::object:
10454 {
10455 m_it.object_iterator = m_object->m_value.object->begin();
10456 break;
10457 }
10458
10459 case value_t::array:
10460 {
10461 m_it.array_iterator = m_object->m_value.array->begin();
10462 break;
10463 }
10464
10465 case value_t::null:
10466 {
10467 // set to end so begin()==end() is true: null is empty
10468 m_it.primitive_iterator.set_end();
10469 break;
10470 }
10471
10472 default:
10473 {
10474 m_it.primitive_iterator.set_begin();
10475 break;
10476 }
10477 }
10478 }
10479
10484 void set_end() noexcept
10485 {
10486 assert(m_object != nullptr);
10487
10488 switch (m_object->m_type)
10489 {
10490 case value_t::object:
10491 {
10492 m_it.object_iterator = m_object->m_value.object->end();
10493 break;
10494 }
10495
10496 case value_t::array:
10497 {
10498 m_it.array_iterator = m_object->m_value.array->end();
10499 break;
10500 }
10501
10502 default:
10503 {
10504 m_it.primitive_iterator.set_end();
10505 break;
10506 }
10507 }
10508 }
10509
10510 public:
10515 reference operator*() const
10516 {
10517 assert(m_object != nullptr);
10518
10519 switch (m_object->m_type)
10520 {
10521 case value_t::object:
10522 {
10523 assert(m_it.object_iterator != m_object->m_value.object->end());
10524 return m_it.object_iterator->second;
10525 }
10526
10527 case value_t::array:
10528 {
10529 assert(m_it.array_iterator != m_object->m_value.array->end());
10530 return *m_it.array_iterator;
10531 }
10532
10533 case value_t::null:
10534 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
10535
10536 default:
10537 {
10538 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
10539 {
10540 return *m_object;
10541 }
10542
10543 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
10544 }
10545 }
10546 }
10547
10552 pointer operator->() const
10553 {
10554 assert(m_object != nullptr);
10555
10556 switch (m_object->m_type)
10557 {
10558 case value_t::object:
10559 {
10560 assert(m_it.object_iterator != m_object->m_value.object->end());
10561 return &(m_it.object_iterator->second);
10562 }
10563
10564 case value_t::array:
10565 {
10566 assert(m_it.array_iterator != m_object->m_value.array->end());
10567 return &*m_it.array_iterator;
10568 }
10569
10570 default:
10571 {
10572 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
10573 {
10574 return m_object;
10575 }
10576
10577 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
10578 }
10579 }
10580 }
10581
10586 iter_impl const operator++(int)
10587 {
10588 auto result = *this;
10589 ++(*this);
10590 return result;
10591 }
10592
10597 iter_impl& operator++()
10598 {
10599 assert(m_object != nullptr);
10600
10601 switch (m_object->m_type)
10602 {
10603 case value_t::object:
10604 {
10605 std::advance(m_it.object_iterator, 1);
10606 break;
10607 }
10608
10609 case value_t::array:
10610 {
10611 std::advance(m_it.array_iterator, 1);
10612 break;
10613 }
10614
10615 default:
10616 {
10617 ++m_it.primitive_iterator;
10618 break;
10619 }
10620 }
10621
10622 return *this;
10623 }
10624
10629 iter_impl const operator--(int)
10630 {
10631 auto result = *this;
10632 --(*this);
10633 return result;
10634 }
10635
10640 iter_impl& operator--()
10641 {
10642 assert(m_object != nullptr);
10643
10644 switch (m_object->m_type)
10645 {
10646 case value_t::object:
10647 {
10648 std::advance(m_it.object_iterator, -1);
10649 break;
10650 }
10651
10652 case value_t::array:
10653 {
10654 std::advance(m_it.array_iterator, -1);
10655 break;
10656 }
10657
10658 default:
10659 {
10660 --m_it.primitive_iterator;
10661 break;
10662 }
10663 }
10664
10665 return *this;
10666 }
10667
10672 bool operator==(const iter_impl& other) const
10673 {
10674 // if objects are not the same, the comparison is undefined
10675 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
10676 {
10677 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
10678 }
10679
10680 assert(m_object != nullptr);
10681
10682 switch (m_object->m_type)
10683 {
10684 case value_t::object:
10685 return (m_it.object_iterator == other.m_it.object_iterator);
10686
10687 case value_t::array:
10688 return (m_it.array_iterator == other.m_it.array_iterator);
10689
10690 default:
10691 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
10692 }
10693 }
10694
10699 bool operator!=(const iter_impl& other) const
10700 {
10701 return not operator==(other);
10702 }
10703
10708 bool operator<(const iter_impl& other) const
10709 {
10710 // if objects are not the same, the comparison is undefined
10711 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
10712 {
10713 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
10714 }
10715
10716 assert(m_object != nullptr);
10717
10718 switch (m_object->m_type)
10719 {
10720 case value_t::object:
10721 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
10722
10723 case value_t::array:
10724 return (m_it.array_iterator < other.m_it.array_iterator);
10725
10726 default:
10727 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
10728 }
10729 }
10730
10735 bool operator<=(const iter_impl& other) const
10736 {
10737 return not other.operator < (*this);
10738 }
10739
10744 bool operator>(const iter_impl& other) const
10745 {
10746 return not operator<=(other);
10747 }
10748
10753 bool operator>=(const iter_impl& other) const
10754 {
10755 return not operator<(other);
10756 }
10757
10762 iter_impl& operator+=(difference_type i)
10763 {
10764 assert(m_object != nullptr);
10765
10766 switch (m_object->m_type)
10767 {
10768 case value_t::object:
10769 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
10770
10771 case value_t::array:
10772 {
10773 std::advance(m_it.array_iterator, i);
10774 break;
10775 }
10776
10777 default:
10778 {
10779 m_it.primitive_iterator += i;
10780 break;
10781 }
10782 }
10783
10784 return *this;
10785 }
10786
10791 iter_impl& operator-=(difference_type i)
10792 {
10793 return operator+=(-i);
10794 }
10795
10800 iter_impl operator+(difference_type i) const
10801 {
10802 auto result = *this;
10803 result += i;
10804 return result;
10805 }
10806
10811 friend iter_impl operator+(difference_type i, const iter_impl& it)
10812 {
10813 auto result = it;
10814 result += i;
10815 return result;
10816 }
10817
10822 iter_impl operator-(difference_type i) const
10823 {
10824 auto result = *this;
10825 result -= i;
10826 return result;
10827 }
10828
10833 difference_type operator-(const iter_impl& other) const
10834 {
10835 assert(m_object != nullptr);
10836
10837 switch (m_object->m_type)
10838 {
10839 case value_t::object:
10840 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
10841
10842 case value_t::array:
10843 return m_it.array_iterator - other.m_it.array_iterator;
10844
10845 default:
10846 return m_it.primitive_iterator - other.m_it.primitive_iterator;
10847 }
10848 }
10849
10854 reference operator[](difference_type n) const
10855 {
10856 assert(m_object != nullptr);
10857
10858 switch (m_object->m_type)
10859 {
10860 case value_t::object:
10861 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
10862
10863 case value_t::array:
10864 return *std::next(m_it.array_iterator, n);
10865
10866 case value_t::null:
10867 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
10868
10869 default:
10870 {
10871 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
10872 {
10873 return *m_object;
10874 }
10875
10876 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
10877 }
10878 }
10879 }
10880
10885 const typename object_t::key_type& key() const
10886 {
10887 assert(m_object != nullptr);
10888
10889 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
10890 {
10891 return m_it.object_iterator->first;
10892 }
10893
10894 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
10895 }
10896
10901 reference value() const
10902 {
10903 return operator*();
10904 }
10905
10906 private:
10908 pointer m_object = nullptr;
10910 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
10911 };
10912 } // namespace detail
10913 } // namespace nlohmann
10914
10915 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
10916
10917 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
10918
10919
10920 #include <cstddef> // ptrdiff_t
10921 #include <iterator> // reverse_iterator
10922 #include <utility> // declval
10923
10924 namespace nlohmann
10925 {
10926 namespace detail
10927 {
10929 // reverse_iterator //
10931
10950 template<typename Base>
10951 class json_reverse_iterator : public std::reverse_iterator<Base>
10952 {
10953 public:
10954 using difference_type = std::ptrdiff_t;
10956 using base_iterator = std::reverse_iterator<Base>;
10958 using reference = typename Base::reference;
10959
10961 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
10962 : base_iterator(it) {}
10963
10965 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
10966
10968 json_reverse_iterator const operator++(int)
10969 {
10970 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
10971 }
10972
10974 json_reverse_iterator& operator++()
10975 {
10976 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
10977 }
10978
10980 json_reverse_iterator const operator--(int)
10981 {
10982 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
10983 }
10984
10986 json_reverse_iterator& operator--()
10987 {
10988 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
10989 }
10990
10992 json_reverse_iterator& operator+=(difference_type i)
10993 {
10994 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
10995 }
10996
10998 json_reverse_iterator operator+(difference_type i) const
10999 {
11000 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
11001 }
11002
11004 json_reverse_iterator operator-(difference_type i) const
11005 {
11006 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
11007 }
11008
11010 difference_type operator-(const json_reverse_iterator& other) const
11011 {
11012 return base_iterator(*this) - base_iterator(other);
11013 }
11014
11016 reference operator[](difference_type n) const
11017 {
11018 return *(this->operator+(n));
11019 }
11020
11022 auto key() const -> decltype(std::declval<Base>().key())
11023 {
11024 auto it = --this->base();
11025 return it.key();
11026 }
11027
11029 reference value() const
11030 {
11031 auto it = --this->base();
11032 return it.operator * ();
11033 }
11034 };
11035 } // namespace detail
11036 } // namespace nlohmann
11037
11038 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11039
11040 // #include <nlohmann/detail/json_pointer.hpp>
11041
11042
11043 #include <algorithm> // all_of
11044 #include <cassert> // assert
11045 #include <cctype> // isdigit
11046 #include <numeric> // accumulate
11047 #include <string> // string
11048 #include <utility> // move
11049 #include <vector> // vector
11050
11051 // #include <nlohmann/detail/exceptions.hpp>
11052
11053 // #include <nlohmann/detail/macro_scope.hpp>
11054
11055 // #include <nlohmann/detail/value_t.hpp>
11056
11057
11058 namespace nlohmann
11059 {
11060 template<typename BasicJsonType>
11061 class json_pointer
11062 {
11063 // allow basic_json to access private members
11064 NLOHMANN_BASIC_JSON_TPL_DECLARATION
11065 friend class basic_json;
11066
11067 public:
11089 explicit json_pointer(const std::string& s = "")
11090 : reference_tokens(split(s))
11091 {}
11092
11107 std::string to_string() const
11108 {
11109 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
11110 std::string{},
11111 [](const std::string & a, const std::string & b)
11112 {
11113 return a + "/" + escape(b);
11114 });
11115 }
11116
11118 operator std::string() const
11119 {
11120 return to_string();
11121 }
11122
11139 json_pointer& operator/=(const json_pointer& ptr)
11140 {
11141 reference_tokens.insert(reference_tokens.end(),
11142 ptr.reference_tokens.begin(),
11143 ptr.reference_tokens.end());
11144 return *this;
11145 }
11146
11163 json_pointer& operator/=(std::string token)
11164 {
11165 push_back(std::move(token));
11166 return *this;
11167 }
11168
11185 json_pointer& operator/=(std::size_t array_idx)
11186 {
11187 return *this /= std::to_string(array_idx);
11188 }
11189
11205 friend json_pointer operator/(const json_pointer& lhs,
11206 const json_pointer& rhs)
11207 {
11208 return json_pointer(lhs) /= rhs;
11209 }
11210
11226 friend json_pointer operator/(const json_pointer& ptr, std::string token)
11227 {
11228 return json_pointer(ptr) /= std::move(token);
11229 }
11230
11246 friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
11247 {
11248 return json_pointer(ptr) /= array_idx;
11249 }
11250
11264 json_pointer parent_pointer() const
11265 {
11266 if (empty())
11267 {
11268 return *this;
11269 }
11270
11271 json_pointer res = *this;
11272 res.pop_back();
11273 return res;
11274 }
11275
11289 void pop_back()
11290 {
11291 if (JSON_HEDLEY_UNLIKELY(empty()))
11292 {
11293 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11294 }
11295
11296 reference_tokens.pop_back();
11297 }
11298
11313 const std::string& back() const
11314 {
11315 if (JSON_HEDLEY_UNLIKELY(empty()))
11316 {
11317 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11318 }
11319
11320 return reference_tokens.back();
11321 }
11322
11335 void push_back(const std::string& token)
11336 {
11337 reference_tokens.push_back(token);
11338 }
11339
11341 void push_back(std::string&& token)
11342 {
11343 reference_tokens.push_back(std::move(token));
11344 }
11345
11360 bool empty() const noexcept
11361 {
11362 return reference_tokens.empty();
11363 }
11364
11365 private:
11373 static int array_index(const std::string& s)
11374 {
11375 // error condition (cf. RFC 6901, Sect. 4)
11376 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 and s[0] == '0'))
11377 {
11378 JSON_THROW(detail::parse_error::create(106, 0,
11379 "array index '" + s +
11380 "' must not begin with '0'"));
11381 }
11382
11383 // error condition (cf. RFC 6901, Sect. 4)
11384 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 and not (s[0] >= '1' and s[0] <= '9')))
11385 {
11386 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number"));
11387 }
11388
11389 std::size_t processed_chars = 0;
11390 int res = 0;
11391 JSON_TRY
11392 {
11393 res = std::stoi(s, &processed_chars);
11394 }
11395 JSON_CATCH(std::out_of_range&)
11396 {
11397 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11398 }
11399
11400 // check if the string was completely read
11401 if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
11402 {
11403 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11404 }
11405
11406 return res;
11407 }
11408
11409 json_pointer top() const
11410 {
11411 if (JSON_HEDLEY_UNLIKELY(empty()))
11412 {
11413 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11414 }
11415
11416 json_pointer result = *this;
11417 result.reference_tokens = {reference_tokens[0]};
11418 return result;
11419 }
11420
11429 BasicJsonType& get_and_create(BasicJsonType& j) const
11430 {
11431 using size_type = typename BasicJsonType::size_type;
11432 auto result = &j;
11433
11434 // in case no reference tokens exist, return a reference to the JSON value
11435 // j which will be overwritten by a primitive value
11436 for (const auto& reference_token : reference_tokens)
11437 {
11438 switch (result->type())
11439 {
11440 case detail::value_t::null:
11441 {
11442 if (reference_token == "0")
11443 {
11444 // start a new array if reference token is 0
11445 result = &result->operator[](0);
11446 }
11447 else
11448 {
11449 // start a new object otherwise
11450 result = &result->operator[](reference_token);
11451 }
11452 break;
11453 }
11454
11455 case detail::value_t::object:
11456 {
11457 // create an entry in the object
11458 result = &result->operator[](reference_token);
11459 break;
11460 }
11461
11462 case detail::value_t::array:
11463 {
11464 // create an entry in the array
11465 result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
11466 break;
11467 }
11468
11469 /*
11470 The following code is only reached if there exists a reference
11471 token _and_ the current value is primitive. In this case, we have
11472 an error situation, because primitive values may only occur as
11473 single value; that is, with an empty list of reference tokens.
11474 */
11475 default:
11476 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
11477 }
11478 }
11479
11480 return *result;
11481 }
11482
11502 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
11503 {
11504 using size_type = typename BasicJsonType::size_type;
11505 for (const auto& reference_token : reference_tokens)
11506 {
11507 // convert null values to arrays or objects before continuing
11508 if (ptr->is_null())
11509 {
11510 // check if reference token is a number
11511 const bool nums =
11512 std::all_of(reference_token.begin(), reference_token.end(),
11513 [](const unsigned char x)
11514 {
11515 return std::isdigit(x);
11516 });
11517
11518 // change value to array for numbers or "-" or to object otherwise
11519 *ptr = (nums or reference_token == "-")
11520 ? detail::value_t::array
11521 : detail::value_t::object;
11522 }
11523
11524 switch (ptr->type())
11525 {
11526 case detail::value_t::object:
11527 {
11528 // use unchecked object access
11529 ptr = &ptr->operator[](reference_token);
11530 break;
11531 }
11532
11533 case detail::value_t::array:
11534 {
11535 if (reference_token == "-")
11536 {
11537 // explicitly treat "-" as index beyond the end
11538 ptr = &ptr->operator[](ptr->m_value.array->size());
11539 }
11540 else
11541 {
11542 // convert array index to number; unchecked access
11543 ptr = &ptr->operator[](
11544 static_cast<size_type>(array_index(reference_token)));
11545 }
11546 break;
11547 }
11548
11549 default:
11550 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
11551 }
11552 }
11553
11554 return *ptr;
11555 }
11556
11563 BasicJsonType& get_checked(BasicJsonType* ptr) const
11564 {
11565 using size_type = typename BasicJsonType::size_type;
11566 for (const auto& reference_token : reference_tokens)
11567 {
11568 switch (ptr->type())
11569 {
11570 case detail::value_t::object:
11571 {
11572 // note: at performs range check
11573 ptr = &ptr->at(reference_token);
11574 break;
11575 }
11576
11577 case detail::value_t::array:
11578 {
11579 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
11580 {
11581 // "-" always fails the range check
11582 JSON_THROW(detail::out_of_range::create(402,
11583 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
11584 ") is out of range"));
11585 }
11586
11587 // note: at performs range check
11588 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
11589 break;
11590 }
11591
11592 default:
11593 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
11594 }
11595 }
11596
11597 return *ptr;
11598 }
11599
11613 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
11614 {
11615 using size_type = typename BasicJsonType::size_type;
11616 for (const auto& reference_token : reference_tokens)
11617 {
11618 switch (ptr->type())
11619 {
11620 case detail::value_t::object:
11621 {
11622 // use unchecked object access
11623 ptr = &ptr->operator[](reference_token);
11624 break;
11625 }
11626
11627 case detail::value_t::array:
11628 {
11629 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
11630 {
11631 // "-" cannot be used for const access
11632 JSON_THROW(detail::out_of_range::create(402,
11633 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
11634 ") is out of range"));
11635 }
11636
11637 // use unchecked array access
11638 ptr = &ptr->operator[](
11639 static_cast<size_type>(array_index(reference_token)));
11640 break;
11641 }
11642
11643 default:
11644 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
11645 }
11646 }
11647
11648 return *ptr;
11649 }
11650
11657 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
11658 {
11659 using size_type = typename BasicJsonType::size_type;
11660 for (const auto& reference_token : reference_tokens)
11661 {
11662 switch (ptr->type())
11663 {
11664 case detail::value_t::object:
11665 {
11666 // note: at performs range check
11667 ptr = &ptr->at(reference_token);
11668 break;
11669 }
11670
11671 case detail::value_t::array:
11672 {
11673 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
11674 {
11675 // "-" always fails the range check
11676 JSON_THROW(detail::out_of_range::create(402,
11677 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
11678 ") is out of range"));
11679 }
11680
11681 // note: at performs range check
11682 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
11683 break;
11684 }
11685
11686 default:
11687 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
11688 }
11689 }
11690
11691 return *ptr;
11692 }
11693
11698 bool contains(const BasicJsonType* ptr) const
11699 {
11700 using size_type = typename BasicJsonType::size_type;
11701 for (const auto& reference_token : reference_tokens)
11702 {
11703 switch (ptr->type())
11704 {
11705 case detail::value_t::object:
11706 {
11707 if (not ptr->contains(reference_token))
11708 {
11709 // we did not find the key in the object
11710 return false;
11711 }
11712
11713 ptr = &ptr->operator[](reference_token);
11714 break;
11715 }
11716
11717 case detail::value_t::array:
11718 {
11719 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
11720 {
11721 // "-" always fails the range check
11722 return false;
11723 }
11724 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 and not ("0" <= reference_token and reference_token <= "9")))
11725 {
11726 // invalid char
11727 return false;
11728 }
11729 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
11730 {
11731 if (JSON_HEDLEY_UNLIKELY(not ('1' <= reference_token[0] and reference_token[0] <= '9')))
11732 {
11733 // first char should be between '1' and '9'
11734 return false;
11735 }
11736 for (std::size_t i = 1; i < reference_token.size(); i++)
11737 {
11738 if (JSON_HEDLEY_UNLIKELY(not ('0' <= reference_token[i] and reference_token[i] <= '9')))
11739 {
11740 // other char should be between '0' and '9'
11741 return false;
11742 }
11743 }
11744 }
11745
11746 const auto idx = static_cast<size_type>(array_index(reference_token));
11747 if (idx >= ptr->size())
11748 {
11749 // index out of range
11750 return false;
11751 }
11752
11753 ptr = &ptr->operator[](idx);
11754 break;
11755 }
11756
11757 default:
11758 {
11759 // we do not expect primitive values if there is still a
11760 // reference token to process
11761 return false;
11762 }
11763 }
11764 }
11765
11766 // no reference token left means we found a primitive value
11767 return true;
11768 }
11769
11779 static std::vector<std::string> split(const std::string& reference_string)
11780 {
11781 std::vector<std::string> result;
11782
11783 // special case: empty reference string -> no reference tokens
11784 if (reference_string.empty())
11785 {
11786 return result;
11787 }
11788
11789 // check if nonempty reference string begins with slash
11790 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
11791 {
11792 JSON_THROW(detail::parse_error::create(107, 1,
11793 "JSON pointer must be empty or begin with '/' - was: '" +
11794 reference_string + "'"));
11795 }
11796
11797 // extract the reference tokens:
11798 // - slash: position of the last read slash (or end of string)
11799 // - start: position after the previous slash
11800 for (
11801 // search for the first slash after the first character
11802 std::size_t slash = reference_string.find_first_of('/', 1),
11803 // set the beginning of the first reference token
11804 start = 1;
11805 // we can stop if start == 0 (if slash == std::string::npos)
11806 start != 0;
11807 // set the beginning of the next reference token
11808 // (will eventually be 0 if slash == std::string::npos)
11809 start = (slash == std::string::npos) ? 0 : slash + 1,
11810 // find next slash
11811 slash = reference_string.find_first_of('/', start))
11812 {
11813 // use the text between the beginning of the reference token
11814 // (start) and the last slash (slash).
11815 auto reference_token = reference_string.substr(start, slash - start);
11816
11817 // check reference tokens are properly escaped
11818 for (std::size_t pos = reference_token.find_first_of('~');
11819 pos != std::string::npos;
11820 pos = reference_token.find_first_of('~', pos + 1))
11821 {
11822 assert(reference_token[pos] == '~');
11823
11824 // ~ must be followed by 0 or 1
11825 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 or
11826 (reference_token[pos + 1] != '0' and
11827 reference_token[pos + 1] != '1')))
11828 {
11829 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
11830 }
11831 }
11832
11833 // finally, store the reference token
11834 unescape(reference_token);
11835 result.push_back(reference_token);
11836 }
11837
11838 return result;
11839 }
11840
11854 static void replace_substring(std::string& s, const std::string& f,
11855 const std::string& t)
11856 {
11857 assert(not f.empty());
11858 for (auto pos = s.find(f); // find first occurrence of f
11859 pos != std::string::npos; // make sure f was found
11860 s.replace(pos, f.size(), t), // replace with t, and
11861 pos = s.find(f, pos + t.size())) // find next occurrence of f
11862 {}
11863 }
11864
11866 static std::string escape(std::string s)
11867 {
11868 replace_substring(s, "~", "~0");
11869 replace_substring(s, "/", "~1");
11870 return s;
11871 }
11872
11874 static void unescape(std::string& s)
11875 {
11876 replace_substring(s, "~1", "/");
11877 replace_substring(s, "~0", "~");
11878 }
11879
11887 static void flatten(const std::string& reference_string,
11888 const BasicJsonType& value,
11889 BasicJsonType& result)
11890 {
11891 switch (value.type())
11892 {
11893 case detail::value_t::array:
11894 {
11895 if (value.m_value.array->empty())
11896 {
11897 // flatten empty array as null
11898 result[reference_string] = nullptr;
11899 }
11900 else
11901 {
11902 // iterate array and use index as reference string
11903 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
11904 {
11905 flatten(reference_string + "/" + std::to_string(i),
11906 value.m_value.array->operator[](i), result);
11907 }
11908 }
11909 break;
11910 }
11911
11912 case detail::value_t::object:
11913 {
11914 if (value.m_value.object->empty())
11915 {
11916 // flatten empty object as null
11917 result[reference_string] = nullptr;
11918 }
11919 else
11920 {
11921 // iterate object and use keys as reference string
11922 for (const auto& element : *value.m_value.object)
11923 {
11924 flatten(reference_string + "/" + escape(element.first), element.second, result);
11925 }
11926 }
11927 break;
11928 }
11929
11930 default:
11931 {
11932 // add primitive value with its reference string
11933 result[reference_string] = value;
11934 break;
11935 }
11936 }
11937 }
11938
11949 static BasicJsonType
11950 unflatten(const BasicJsonType& value)
11951 {
11952 if (JSON_HEDLEY_UNLIKELY(not value.is_object()))
11953 {
11954 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
11955 }
11956
11957 BasicJsonType result;
11958
11959 // iterate the JSON object values
11960 for (const auto& element : *value.m_value.object)
11961 {
11962 if (JSON_HEDLEY_UNLIKELY(not element.second.is_primitive()))
11963 {
11964 JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
11965 }
11966
11967 // assign value to reference pointed to by JSON pointer; Note that if
11968 // the JSON pointer is "" (i.e., points to the whole value), function
11969 // get_and_create returns a reference to result itself. An assignment
11970 // will then create a primitive value.
11971 json_pointer(element.first).get_and_create(result) = element.second;
11972 }
11973
11974 return result;
11975 }
11976
11988 friend bool operator==(json_pointer const& lhs,
11989 json_pointer const& rhs) noexcept
11990 {
11991 return lhs.reference_tokens == rhs.reference_tokens;
11992 }
11993
12005 friend bool operator!=(json_pointer const& lhs,
12006 json_pointer const& rhs) noexcept
12007 {
12008 return not (lhs == rhs);
12009 }
12010
12012 std::vector<std::string> reference_tokens;
12013 };
12014 } // namespace nlohmann
12015
12016 // #include <nlohmann/detail/json_ref.hpp>
12017
12018
12019 #include <initializer_list>
12020 #include <utility>
12021
12022 // #include <nlohmann/detail/meta/type_traits.hpp>
12023
12024
12025 namespace nlohmann
12026 {
12027 namespace detail
12028 {
12029 template<typename BasicJsonType>
12030 class json_ref
12031 {
12032 public:
12033 using value_type = BasicJsonType;
12034
12035 json_ref(value_type&& value)
12036 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
12037 {}
12038
12039 json_ref(const value_type& value)
12040 : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
12041 {}
12042
12043 json_ref(std::initializer_list<json_ref> init)
12044 : owned_value(init), value_ref(&owned_value), is_rvalue(true)
12045 {}
12046
12047 template <
12048 class... Args,
12049 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
12050 json_ref(Args && ... args)
12051 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value),
12052 is_rvalue(true) {}
12053
12054 // class should be movable only
12055 json_ref(json_ref&&) = default;
12056 json_ref(const json_ref&) = delete;
12057 json_ref& operator=(const json_ref&) = delete;
12058 json_ref& operator=(json_ref&&) = delete;
12059 ~json_ref() = default;
12060
12061 value_type moved_or_copied() const
12062 {
12063 if (is_rvalue)
12064 {
12065 return std::move(*value_ref);
12066 }
12067 return *value_ref;
12068 }
12069
12070 value_type const& operator*() const
12071 {
12072 return *static_cast<value_type const*>(value_ref);
12073 }
12074
12075 value_type const* operator->() const
12076 {
12077 return static_cast<value_type const*>(value_ref);
12078 }
12079
12080 private:
12081 mutable value_type owned_value = nullptr;
12082 value_type* value_ref = nullptr;
12083 const bool is_rvalue;
12084 };
12085 } // namespace detail
12086 } // namespace nlohmann
12087
12088 // #include <nlohmann/detail/macro_scope.hpp>
12089
12090 // #include <nlohmann/detail/meta/cpp_future.hpp>
12091
12092 // #include <nlohmann/detail/meta/type_traits.hpp>
12093
12094 // #include <nlohmann/detail/output/binary_writer.hpp>
12095
12096
12097 #include <algorithm> // reverse
12098 #include <array> // array
12099 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
12100 #include <cstring> // memcpy
12101 #include <limits> // numeric_limits
12102 #include <string> // string
12103 #include <cmath> // isnan, isinf
12104
12105 // #include <nlohmann/detail/input/binary_reader.hpp>
12106
12107 // #include <nlohmann/detail/macro_scope.hpp>
12108
12109 // #include <nlohmann/detail/output/output_adapters.hpp>
12110
12111
12112 #include <algorithm> // copy
12113 #include <cstddef> // size_t
12114 #include <ios> // streamsize
12115 #include <iterator> // back_inserter
12116 #include <memory> // shared_ptr, make_shared
12117 #include <ostream> // basic_ostream
12118 #include <string> // basic_string
12119 #include <vector> // vector
12120 // #include <nlohmann/detail/macro_scope.hpp>
12121
12122
12123 namespace nlohmann
12124 {
12125 namespace detail
12126 {
12128 template<typename CharType> struct output_adapter_protocol
12129 {
12130 virtual void write_character(CharType c) = 0;
12131 virtual void write_characters(const CharType* s, std::size_t length) = 0;
12132 virtual ~output_adapter_protocol() = default;
12133 };
12134
12136 template<typename CharType>
12137 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
12138
12140 template<typename CharType>
12141 class output_vector_adapter : public output_adapter_protocol<CharType>
12142 {
12143 public:
12144 explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
12145 : v(vec)
12146 {}
12147
12148 void write_character(CharType c) override
12149 {
12150 v.push_back(c);
12151 }
12152
12153 JSON_HEDLEY_NON_NULL(2)
12154 void write_characters(const CharType* s, std::size_t length) override
12155 {
12156 std::copy(s, s + length, std::back_inserter(v));
12157 }
12158
12159 private:
12160 std::vector<CharType>& v;
12161 };
12162
12164 template<typename CharType>
12165 class output_stream_adapter : public output_adapter_protocol<CharType>
12166 {
12167 public:
12168 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
12169 : stream(s)
12170 {}
12171
12172 void write_character(CharType c) override
12173 {
12174 stream.put(c);
12175 }
12176
12177 JSON_HEDLEY_NON_NULL(2)
12178 void write_characters(const CharType* s, std::size_t length) override
12179 {
12180 stream.write(s, static_cast<std::streamsize>(length));
12181 }
12182
12183 private:
12184 std::basic_ostream<CharType>& stream;
12185 };
12186
12188 template<typename CharType, typename StringType = std::basic_string<CharType>>
12189 class output_string_adapter : public output_adapter_protocol<CharType>
12190 {
12191 public:
12192 explicit output_string_adapter(StringType& s) noexcept
12193 : str(s)
12194 {}
12195
12196 void write_character(CharType c) override
12197 {
12198 str.push_back(c);
12199 }
12200
12201 JSON_HEDLEY_NON_NULL(2)
12202 void write_characters(const CharType* s, std::size_t length) override
12203 {
12204 str.append(s, length);
12205 }
12206
12207 private:
12208 StringType& str;
12209 };
12210
12211 template<typename CharType, typename StringType = std::basic_string<CharType>>
12212 class output_adapter
12213 {
12214 public:
12215 output_adapter(std::vector<CharType>& vec)
12216 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
12217
12218 output_adapter(std::basic_ostream<CharType>& s)
12219 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
12220
12221 output_adapter(StringType& s)
12222 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
12223
12224 operator output_adapter_t<CharType>()
12225 {
12226 return oa;
12227 }
12228
12229 private:
12230 output_adapter_t<CharType> oa = nullptr;
12231 };
12232 } // namespace detail
12233 } // namespace nlohmann
12234
12235
12236 namespace nlohmann
12237 {
12238 namespace detail
12239 {
12241 // binary writer //
12243
12247 template<typename BasicJsonType, typename CharType>
12248 class binary_writer
12249 {
12250 using string_t = typename BasicJsonType::string_t;
12251 using binary_t = typename BasicJsonType::binary_t;
12252
12253 public:
12259 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
12260 {
12261 assert(oa);
12262 }
12263
12268 void write_bson(const BasicJsonType& j)
12269 {
12270 switch (j.type())
12271 {
12272 case value_t::object:
12273 {
12274 write_bson_object(*j.m_value.object);
12275 break;
12276 }
12277
12278 default:
12279 {
12280 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
12281 }
12282 }
12283 }
12284
12288 void write_cbor(const BasicJsonType& j)
12289 {
12290 switch (j.type())
12291 {
12292 case value_t::null:
12293 {
12294 oa->write_character(to_char_type(0xF6));
12295 break;
12296 }
12297
12298 case value_t::boolean:
12299 {
12300 oa->write_character(j.m_value.boolean
12301 ? to_char_type(0xF5)
12302 : to_char_type(0xF4));
12303 break;
12304 }
12305
12306 case value_t::number_integer:
12307 {
12308 if (j.m_value.number_integer >= 0)
12309 {
12310 // CBOR does not differentiate between positive signed
12311 // integers and unsigned integers. Therefore, we used the
12312 // code from the value_t::number_unsigned case here.
12313 if (j.m_value.number_integer <= 0x17)
12314 {
12315 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12316 }
12317 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
12318 {
12319 oa->write_character(to_char_type(0x18));
12320 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12321 }
12322 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
12323 {
12324 oa->write_character(to_char_type(0x19));
12325 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
12326 }
12327 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
12328 {
12329 oa->write_character(to_char_type(0x1A));
12330 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
12331 }
12332 else
12333 {
12334 oa->write_character(to_char_type(0x1B));
12335 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
12336 }
12337 }
12338 else
12339 {
12340 // The conversions below encode the sign in the first
12341 // byte, and the value is converted to a positive number.
12342 const auto positive_number = -1 - j.m_value.number_integer;
12343 if (j.m_value.number_integer >= -24)
12344 {
12345 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
12346 }
12347 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
12348 {
12349 oa->write_character(to_char_type(0x38));
12350 write_number(static_cast<std::uint8_t>(positive_number));
12351 }
12352 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
12353 {
12354 oa->write_character(to_char_type(0x39));
12355 write_number(static_cast<std::uint16_t>(positive_number));
12356 }
12357 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
12358 {
12359 oa->write_character(to_char_type(0x3A));
12360 write_number(static_cast<std::uint32_t>(positive_number));
12361 }
12362 else
12363 {
12364 oa->write_character(to_char_type(0x3B));
12365 write_number(static_cast<std::uint64_t>(positive_number));
12366 }
12367 }
12368 break;
12369 }
12370
12371 case value_t::number_unsigned:
12372 {
12373 if (j.m_value.number_unsigned <= 0x17)
12374 {
12375 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
12376 }
12377 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12378 {
12379 oa->write_character(to_char_type(0x18));
12380 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
12381 }
12382 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12383 {
12384 oa->write_character(to_char_type(0x19));
12385 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
12386 }
12387 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12388 {
12389 oa->write_character(to_char_type(0x1A));
12390 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
12391 }
12392 else
12393 {
12394 oa->write_character(to_char_type(0x1B));
12395 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
12396 }
12397 break;
12398 }
12399
12400 case value_t::number_float:
12401 {
12402 if (std::isnan(j.m_value.number_float))
12403 {
12404 // NaN is 0xf97e00 in CBOR
12405 oa->write_character(to_char_type(0xF9));
12406 oa->write_character(to_char_type(0x7E));
12407 oa->write_character(to_char_type(0x00));
12408 }
12409 else if (std::isinf(j.m_value.number_float))
12410 {
12411 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
12412 oa->write_character(to_char_type(0xf9));
12413 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
12414 oa->write_character(to_char_type(0x00));
12415 }
12416 else
12417 {
12418 if (static_cast<double>(j.m_value.number_float) >= static_cast<double>(std::numeric_limits<float>::lowest()) and
12419 static_cast<double>(j.m_value.number_float) <= static_cast<double>((std::numeric_limits<float>::max)()) and
12420 static_cast<double>(static_cast<float>(j.m_value.number_float)) == static_cast<double>(j.m_value.number_float))
12421 {
12422 oa->write_character(get_cbor_float_prefix(static_cast<float>(j.m_value.number_float)));
12423 write_number(static_cast<float>(j.m_value.number_float));
12424 }
12425 else
12426 {
12427 oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
12428 write_number(j.m_value.number_float);
12429 }
12430 }
12431 break;
12432 }
12433
12434 case value_t::string:
12435 {
12436 // step 1: write control byte and the string length
12437 const auto N = j.m_value.string->size();
12438 if (N <= 0x17)
12439 {
12440 write_number(static_cast<std::uint8_t>(0x60 + N));
12441 }
12442 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12443 {
12444 oa->write_character(to_char_type(0x78));
12445 write_number(static_cast<std::uint8_t>(N));
12446 }
12447 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12448 {
12449 oa->write_character(to_char_type(0x79));
12450 write_number(static_cast<std::uint16_t>(N));
12451 }
12452 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12453 {
12454 oa->write_character(to_char_type(0x7A));
12455 write_number(static_cast<std::uint32_t>(N));
12456 }
12457 // LCOV_EXCL_START
12458 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12459 {
12460 oa->write_character(to_char_type(0x7B));
12461 write_number(static_cast<std::uint64_t>(N));
12462 }
12463 // LCOV_EXCL_STOP
12464
12465 // step 2: write the string
12466 oa->write_characters(
12467 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
12468 j.m_value.string->size());
12469 break;
12470 }
12471
12472 case value_t::array:
12473 {
12474 // step 1: write control byte and the array size
12475 const auto N = j.m_value.array->size();
12476 if (N <= 0x17)
12477 {
12478 write_number(static_cast<std::uint8_t>(0x80 + N));
12479 }
12480 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12481 {
12482 oa->write_character(to_char_type(0x98));
12483 write_number(static_cast<std::uint8_t>(N));
12484 }
12485 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12486 {
12487 oa->write_character(to_char_type(0x99));
12488 write_number(static_cast<std::uint16_t>(N));
12489 }
12490 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12491 {
12492 oa->write_character(to_char_type(0x9A));
12493 write_number(static_cast<std::uint32_t>(N));
12494 }
12495 // LCOV_EXCL_START
12496 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12497 {
12498 oa->write_character(to_char_type(0x9B));
12499 write_number(static_cast<std::uint64_t>(N));
12500 }
12501 // LCOV_EXCL_STOP
12502
12503 // step 2: write each element
12504 for (const auto& el : *j.m_value.array)
12505 {
12506 write_cbor(el);
12507 }
12508 break;
12509 }
12510
12511 case value_t::binary:
12512 {
12513 // step 1: write control byte and the binary array size
12514 const auto N = j.m_value.binary->size();
12515 if (N <= 0x17)
12516 {
12517 write_number(static_cast<std::uint8_t>(0x40 + N));
12518 }
12519 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12520 {
12521 oa->write_character(to_char_type(0x58));
12522 write_number(static_cast<std::uint8_t>(N));
12523 }
12524 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12525 {
12526 oa->write_character(to_char_type(0x59));
12527 write_number(static_cast<std::uint16_t>(N));
12528 }
12529 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12530 {
12531 oa->write_character(to_char_type(0x5A));
12532 write_number(static_cast<std::uint32_t>(N));
12533 }
12534 // LCOV_EXCL_START
12535 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12536 {
12537 oa->write_character(to_char_type(0x5B));
12538 write_number(static_cast<std::uint64_t>(N));
12539 }
12540 // LCOV_EXCL_STOP
12541
12542 // step 2: write each element
12543 oa->write_characters(
12544 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
12545 N);
12546
12547 break;
12548 }
12549
12550 case value_t::object:
12551 {
12552 // step 1: write control byte and the object size
12553 const auto N = j.m_value.object->size();
12554 if (N <= 0x17)
12555 {
12556 write_number(static_cast<std::uint8_t>(0xA0 + N));
12557 }
12558 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12559 {
12560 oa->write_character(to_char_type(0xB8));
12561 write_number(static_cast<std::uint8_t>(N));
12562 }
12563 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12564 {
12565 oa->write_character(to_char_type(0xB9));
12566 write_number(static_cast<std::uint16_t>(N));
12567 }
12568 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12569 {
12570 oa->write_character(to_char_type(0xBA));
12571 write_number(static_cast<std::uint32_t>(N));
12572 }
12573 // LCOV_EXCL_START
12574 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12575 {
12576 oa->write_character(to_char_type(0xBB));
12577 write_number(static_cast<std::uint64_t>(N));
12578 }
12579 // LCOV_EXCL_STOP
12580
12581 // step 2: write each element
12582 for (const auto& el : *j.m_value.object)
12583 {
12584 write_cbor(el.first);
12585 write_cbor(el.second);
12586 }
12587 break;
12588 }
12589
12590 default:
12591 break;
12592 }
12593 }
12594
12598 void write_msgpack(const BasicJsonType& j)
12599 {
12600 switch (j.type())
12601 {
12602 case value_t::null: // nil
12603 {
12604 oa->write_character(to_char_type(0xC0));
12605 break;
12606 }
12607
12608 case value_t::boolean: // true and false
12609 {
12610 oa->write_character(j.m_value.boolean
12611 ? to_char_type(0xC3)
12612 : to_char_type(0xC2));
12613 break;
12614 }
12615
12616 case value_t::number_integer:
12617 {
12618 if (j.m_value.number_integer >= 0)
12619 {
12620 // MessagePack does not differentiate between positive
12621 // signed integers and unsigned integers. Therefore, we used
12622 // the code from the value_t::number_unsigned case here.
12623 if (j.m_value.number_unsigned < 128)
12624 {
12625 // positive fixnum
12626 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12627 }
12628 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12629 {
12630 // uint 8
12631 oa->write_character(to_char_type(0xCC));
12632 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12633 }
12634 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12635 {
12636 // uint 16
12637 oa->write_character(to_char_type(0xCD));
12638 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
12639 }
12640 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12641 {
12642 // uint 32
12643 oa->write_character(to_char_type(0xCE));
12644 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
12645 }
12646 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
12647 {
12648 // uint 64
12649 oa->write_character(to_char_type(0xCF));
12650 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
12651 }
12652 }
12653 else
12654 {
12655 if (j.m_value.number_integer >= -32)
12656 {
12657 // negative fixnum
12658 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
12659 }
12660 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() and
12661 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
12662 {
12663 // int 8
12664 oa->write_character(to_char_type(0xD0));
12665 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
12666 }
12667 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() and
12668 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
12669 {
12670 // int 16
12671 oa->write_character(to_char_type(0xD1));
12672 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
12673 }
12674 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() and
12675 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
12676 {
12677 // int 32
12678 oa->write_character(to_char_type(0xD2));
12679 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
12680 }
12681 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() and
12682 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
12683 {
12684 // int 64
12685 oa->write_character(to_char_type(0xD3));
12686 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
12687 }
12688 }
12689 break;
12690 }
12691
12692 case value_t::number_unsigned:
12693 {
12694 if (j.m_value.number_unsigned < 128)
12695 {
12696 // positive fixnum
12697 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12698 }
12699 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12700 {
12701 // uint 8
12702 oa->write_character(to_char_type(0xCC));
12703 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12704 }
12705 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12706 {
12707 // uint 16
12708 oa->write_character(to_char_type(0xCD));
12709 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
12710 }
12711 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12712 {
12713 // uint 32
12714 oa->write_character(to_char_type(0xCE));
12715 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
12716 }
12717 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
12718 {
12719 // uint 64
12720 oa->write_character(to_char_type(0xCF));
12721 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
12722 }
12723 break;
12724 }
12725
12726 case value_t::number_float:
12727 {
12728 oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
12729 write_number(j.m_value.number_float);
12730 break;
12731 }
12732
12733 case value_t::string:
12734 {
12735 // step 1: write control byte and the string length
12736 const auto N = j.m_value.string->size();
12737 if (N <= 31)
12738 {
12739 // fixstr
12740 write_number(static_cast<std::uint8_t>(0xA0 | N));
12741 }
12742 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12743 {
12744 // str 8
12745 oa->write_character(to_char_type(0xD9));
12746 write_number(static_cast<std::uint8_t>(N));
12747 }
12748 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12749 {
12750 // str 16
12751 oa->write_character(to_char_type(0xDA));
12752 write_number(static_cast<std::uint16_t>(N));
12753 }
12754 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12755 {
12756 // str 32
12757 oa->write_character(to_char_type(0xDB));
12758 write_number(static_cast<std::uint32_t>(N));
12759 }
12760
12761 // step 2: write the string
12762 oa->write_characters(
12763 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
12764 j.m_value.string->size());
12765 break;
12766 }
12767
12768 case value_t::array:
12769 {
12770 // step 1: write control byte and the array size
12771 const auto N = j.m_value.array->size();
12772 if (N <= 15)
12773 {
12774 // fixarray
12775 write_number(static_cast<std::uint8_t>(0x90 | N));
12776 }
12777 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12778 {
12779 // array 16
12780 oa->write_character(to_char_type(0xDC));
12781 write_number(static_cast<std::uint16_t>(N));
12782 }
12783 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12784 {
12785 // array 32
12786 oa->write_character(to_char_type(0xDD));
12787 write_number(static_cast<std::uint32_t>(N));
12788 }
12789
12790 // step 2: write each element
12791 for (const auto& el : *j.m_value.array)
12792 {
12793 write_msgpack(el);
12794 }
12795 break;
12796 }
12797
12798 case value_t::binary:
12799 {
12800 // step 0: determine if the binary type has a set subtype to
12801 // determine whether or not to use the ext or fixext types
12802 const bool use_ext = j.m_value.binary->has_subtype();
12803
12804 // step 1: write control byte and the byte string length
12805 const auto N = j.m_value.binary->size();
12806 if (N <= (std::numeric_limits<std::uint8_t>::max)())
12807 {
12808 std::uint8_t output_type;
12809 bool fixed = true;
12810 if (use_ext)
12811 {
12812 switch (N)
12813 {
12814 case 1:
12815 output_type = 0xD4; // fixext 1
12816 break;
12817 case 2:
12818 output_type = 0xD5; // fixext 2
12819 break;
12820 case 4:
12821 output_type = 0xD6; // fixext 4
12822 break;
12823 case 8:
12824 output_type = 0xD7; // fixext 8
12825 break;
12826 case 16:
12827 output_type = 0xD8; // fixext 16
12828 break;
12829 default:
12830 output_type = 0xC7; // ext 8
12831 fixed = false;
12832 break;
12833 }
12834
12835 }
12836 else
12837 {
12838 output_type = 0xC4; // bin 8
12839 fixed = false;
12840 }
12841
12842 oa->write_character(to_char_type(output_type));
12843 if (not fixed)
12844 {
12845 write_number(static_cast<std::uint8_t>(N));
12846 }
12847 }
12848 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12849 {
12850 std::uint8_t output_type;
12851 if (use_ext)
12852 {
12853 output_type = 0xC8; // ext 16
12854 }
12855 else
12856 {
12857 output_type = 0xC5; // bin 16
12858 }
12859
12860 oa->write_character(to_char_type(output_type));
12861 write_number(static_cast<std::uint16_t>(N));
12862 }
12863 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12864 {
12865 std::uint8_t output_type;
12866 if (use_ext)
12867 {
12868 output_type = 0xC9; // ext 32
12869 }
12870 else
12871 {
12872 output_type = 0xC6; // bin 32
12873 }
12874
12875 oa->write_character(to_char_type(output_type));
12876 write_number(static_cast<std::uint32_t>(N));
12877 }
12878
12879 // step 1.5: if this is an ext type, write the subtype
12880 if (use_ext)
12881 {
12882 write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
12883 }
12884
12885 // step 2: write the byte string
12886 oa->write_characters(
12887 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
12888 N);
12889
12890 break;
12891 }
12892
12893 case value_t::object:
12894 {
12895 // step 1: write control byte and the object size
12896 const auto N = j.m_value.object->size();
12897 if (N <= 15)
12898 {
12899 // fixmap
12900 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
12901 }
12902 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12903 {
12904 // map 16
12905 oa->write_character(to_char_type(0xDE));
12906 write_number(static_cast<std::uint16_t>(N));
12907 }
12908 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12909 {
12910 // map 32
12911 oa->write_character(to_char_type(0xDF));
12912 write_number(static_cast<std::uint32_t>(N));
12913 }
12914
12915 // step 2: write each element
12916 for (const auto& el : *j.m_value.object)
12917 {
12918 write_msgpack(el.first);
12919 write_msgpack(el.second);
12920 }
12921 break;
12922 }
12923
12924 default:
12925 break;
12926 }
12927 }
12928
12935 void write_ubjson(const BasicJsonType& j, const bool use_count,
12936 const bool use_type, const bool add_prefix = true)
12937 {
12938 switch (j.type())
12939 {
12940 case value_t::null:
12941 {
12942 if (add_prefix)
12943 {
12944 oa->write_character(to_char_type('Z'));
12945 }
12946 break;
12947 }
12948
12949 case value_t::boolean:
12950 {
12951 if (add_prefix)
12952 {
12953 oa->write_character(j.m_value.boolean
12954 ? to_char_type('T')
12955 : to_char_type('F'));
12956 }
12957 break;
12958 }
12959
12960 case value_t::number_integer:
12961 {
12962 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
12963 break;
12964 }
12965
12966 case value_t::number_unsigned:
12967 {
12968 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
12969 break;
12970 }
12971
12972 case value_t::number_float:
12973 {
12974 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
12975 break;
12976 }
12977
12978 case value_t::string:
12979 {
12980 if (add_prefix)
12981 {
12982 oa->write_character(to_char_type('S'));
12983 }
12984 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
12985 oa->write_characters(
12986 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
12987 j.m_value.string->size());
12988 break;
12989 }
12990
12991 case value_t::array:
12992 {
12993 if (add_prefix)
12994 {
12995 oa->write_character(to_char_type('['));
12996 }
12997
12998 bool prefix_required = true;
12999 if (use_type and not j.m_value.array->empty())
13000 {
13001 assert(use_count);
13002 const CharType first_prefix = ubjson_prefix(j.front());
13003 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
13004 [this, first_prefix](const BasicJsonType & v)
13005 {
13006 return ubjson_prefix(v) == first_prefix;
13007 });
13008
13009 if (same_prefix)
13010 {
13011 prefix_required = false;
13012 oa->write_character(to_char_type('$'));
13013 oa->write_character(first_prefix);
13014 }
13015 }
13016
13017 if (use_count)
13018 {
13019 oa->write_character(to_char_type('#'));
13020 write_number_with_ubjson_prefix(j.m_value.array->size(), true);
13021 }
13022
13023 for (const auto& el : *j.m_value.array)
13024 {
13025 write_ubjson(el, use_count, use_type, prefix_required);
13026 }
13027
13028 if (not use_count)
13029 {
13030 oa->write_character(to_char_type(']'));
13031 }
13032
13033 break;
13034 }
13035
13036 case value_t::binary:
13037 {
13038 if (add_prefix)
13039 {
13040 oa->write_character(to_char_type('['));
13041 }
13042
13043 if (use_type and not j.m_value.binary->empty())
13044 {
13045 assert(use_count);
13046 oa->write_character(to_char_type('$'));
13047 oa->write_character('U');
13048 }
13049
13050 if (use_count)
13051 {
13052 oa->write_character(to_char_type('#'));
13053 write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
13054 }
13055
13056 if (use_type)
13057 {
13058 oa->write_characters(
13059 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13060 j.m_value.binary->size());
13061 }
13062 else
13063 {
13064 for (size_t i = 0; i < j.m_value.binary->size(); ++i)
13065 {
13066 oa->write_character(to_char_type('U'));
13067 oa->write_character(j.m_value.binary->data()[i]);
13068 }
13069 }
13070
13071 if (not use_count)
13072 {
13073 oa->write_character(to_char_type(']'));
13074 }
13075
13076 break;
13077 }
13078
13079 case value_t::object:
13080 {
13081 if (add_prefix)
13082 {
13083 oa->write_character(to_char_type('{'));
13084 }
13085
13086 bool prefix_required = true;
13087 if (use_type and not j.m_value.object->empty())
13088 {
13089 assert(use_count);
13090 const CharType first_prefix = ubjson_prefix(j.front());
13091 const bool same_prefix = std::all_of(j.begin(), j.end(),
13092 [this, first_prefix](const BasicJsonType & v)
13093 {
13094 return ubjson_prefix(v) == first_prefix;
13095 });
13096
13097 if (same_prefix)
13098 {
13099 prefix_required = false;
13100 oa->write_character(to_char_type('$'));
13101 oa->write_character(first_prefix);
13102 }
13103 }
13104
13105 if (use_count)
13106 {
13107 oa->write_character(to_char_type('#'));
13108 write_number_with_ubjson_prefix(j.m_value.object->size(), true);
13109 }
13110
13111 for (const auto& el : *j.m_value.object)
13112 {
13113 write_number_with_ubjson_prefix(el.first.size(), true);
13114 oa->write_characters(
13115 reinterpret_cast<const CharType*>(el.first.c_str()),
13116 el.first.size());
13117 write_ubjson(el.second, use_count, use_type, prefix_required);
13118 }
13119
13120 if (not use_count)
13121 {
13122 oa->write_character(to_char_type('}'));
13123 }
13124
13125 break;
13126 }
13127
13128 default:
13129 break;
13130 }
13131 }
13132
13133 private:
13135 // BSON //
13137
13142 static std::size_t calc_bson_entry_header_size(const string_t& name)
13143 {
13144 const auto it = name.find(static_cast<typename string_t::value_type>(0));
13145 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
13146 {
13147 JSON_THROW(out_of_range::create(409,
13148 "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
13149 }
13150
13151 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
13152 }
13153
13157 void write_bson_entry_header(const string_t& name,
13158 const std::uint8_t element_type)
13159 {
13160 oa->write_character(to_char_type(element_type)); // boolean
13161 oa->write_characters(
13162 reinterpret_cast<const CharType*>(name.c_str()),
13163 name.size() + 1u);
13164 }
13165
13169 void write_bson_boolean(const string_t& name,
13170 const bool value)
13171 {
13172 write_bson_entry_header(name, 0x08);
13173 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
13174 }
13175
13179 void write_bson_double(const string_t& name,
13180 const double value)
13181 {
13182 write_bson_entry_header(name, 0x01);
13183 write_number<double, true>(value);
13184 }
13185
13189 static std::size_t calc_bson_string_size(const string_t& value)
13190 {
13191 return sizeof(std::int32_t) + value.size() + 1ul;
13192 }
13193
13197 void write_bson_string(const string_t& name,
13198 const string_t& value)
13199 {
13200 write_bson_entry_header(name, 0x02);
13201
13202 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
13203 oa->write_characters(
13204 reinterpret_cast<const CharType*>(value.c_str()),
13205 value.size() + 1);
13206 }
13207
13211 void write_bson_null(const string_t& name)
13212 {
13213 write_bson_entry_header(name, 0x0A);
13214 }
13215
13219 static std::size_t calc_bson_integer_size(const std::int64_t value)
13220 {
13221 return (std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)()
13222 ? sizeof(std::int32_t)
13223 : sizeof(std::int64_t);
13224 }
13225
13229 void write_bson_integer(const string_t& name,
13230 const std::int64_t value)
13231 {
13232 if ((std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)())
13233 {
13234 write_bson_entry_header(name, 0x10); // int32
13235 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
13236 }
13237 else
13238 {
13239 write_bson_entry_header(name, 0x12); // int64
13240 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
13241 }
13242 }
13243
13247 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
13248 {
13249 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13250 ? sizeof(std::int32_t)
13251 : sizeof(std::int64_t);
13252 }
13253
13257 void write_bson_unsigned(const string_t& name,
13258 const std::uint64_t value)
13259 {
13260 if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13261 {
13262 write_bson_entry_header(name, 0x10 /* int32 */);
13263 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
13264 }
13265 else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
13266 {
13267 write_bson_entry_header(name, 0x12 /* int64 */);
13268 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
13269 }
13270 else
13271 {
13272 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
13273 }
13274 }
13275
13279 void write_bson_object_entry(const string_t& name,
13280 const typename BasicJsonType::object_t& value)
13281 {
13282 write_bson_entry_header(name, 0x03); // object
13283 write_bson_object(value);
13284 }
13285
13289 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
13290 {
13291 std::size_t array_index = 0ul;
13292
13293 const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
13294 {
13295 return result + calc_bson_element_size(std::to_string(array_index++), el);
13296 });
13297
13298 return sizeof(std::int32_t) + embedded_document_size + 1ul;
13299 }
13300
13304 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
13305 {
13306 return sizeof(std::int32_t) + value.size() + 1ul;
13307 }
13308
13312 void write_bson_array(const string_t& name,
13313 const typename BasicJsonType::array_t& value)
13314 {
13315 write_bson_entry_header(name, 0x04); // array
13316 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
13317
13318 std::size_t array_index = 0ul;
13319
13320 for (const auto& el : value)
13321 {
13322 write_bson_element(std::to_string(array_index++), el);
13323 }
13324
13325 oa->write_character(to_char_type(0x00));
13326 }
13327
13331 void write_bson_binary(const string_t& name,
13332 const binary_t& value)
13333 {
13334 write_bson_entry_header(name, 0x05);
13335
13336 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
13337 write_number(value.has_subtype() ? value.subtype() : std::uint8_t(0x00));
13338
13339 oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
13340 }
13341
13346 static std::size_t calc_bson_element_size(const string_t& name,
13347 const BasicJsonType& j)
13348 {
13349 const auto header_size = calc_bson_entry_header_size(name);
13350 switch (j.type())
13351 {
13352 case value_t::object:
13353 return header_size + calc_bson_object_size(*j.m_value.object);
13354
13355 case value_t::array:
13356 return header_size + calc_bson_array_size(*j.m_value.array);
13357
13358 case value_t::binary:
13359 return header_size + calc_bson_binary_size(*j.m_value.binary);
13360
13361 case value_t::boolean:
13362 return header_size + 1ul;
13363
13364 case value_t::number_float:
13365 return header_size + 8ul;
13366
13367 case value_t::number_integer:
13368 return header_size + calc_bson_integer_size(j.m_value.number_integer);
13369
13370 case value_t::number_unsigned:
13371 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
13372
13373 case value_t::string:
13374 return header_size + calc_bson_string_size(*j.m_value.string);
13375
13376 case value_t::null:
13377 return header_size + 0ul;
13378
13379 // LCOV_EXCL_START
13380 default:
13381 assert(false);
13382 return 0ul;
13383 // LCOV_EXCL_STOP
13384 }
13385 }
13386
13394 void write_bson_element(const string_t& name,
13395 const BasicJsonType& j)
13396 {
13397 switch (j.type())
13398 {
13399 case value_t::object:
13400 return write_bson_object_entry(name, *j.m_value.object);
13401
13402 case value_t::array:
13403 return write_bson_array(name, *j.m_value.array);
13404
13405 case value_t::binary:
13406 return write_bson_binary(name, *j.m_value.binary);
13407
13408 case value_t::boolean:
13409 return write_bson_boolean(name, j.m_value.boolean);
13410
13411 case value_t::number_float:
13412 return write_bson_double(name, j.m_value.number_float);
13413
13414 case value_t::number_integer:
13415 return write_bson_integer(name, j.m_value.number_integer);
13416
13417 case value_t::number_unsigned:
13418 return write_bson_unsigned(name, j.m_value.number_unsigned);
13419
13420 case value_t::string:
13421 return write_bson_string(name, *j.m_value.string);
13422
13423 case value_t::null:
13424 return write_bson_null(name);
13425
13426 // LCOV_EXCL_START
13427 default:
13428 assert(false);
13429 return;
13430 // LCOV_EXCL_STOP
13431 }
13432 }
13433
13440 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
13441 {
13442 std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
13443 [](size_t result, const typename BasicJsonType::object_t::value_type & el)
13444 {
13445 return result += calc_bson_element_size(el.first, el.second);
13446 });
13447
13448 return sizeof(std::int32_t) + document_size + 1ul;
13449 }
13450
13455 void write_bson_object(const typename BasicJsonType::object_t& value)
13456 {
13457 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
13458
13459 for (const auto& el : value)
13460 {
13461 write_bson_element(el.first, el.second);
13462 }
13463
13464 oa->write_character(to_char_type(0x00));
13465 }
13466
13468 // CBOR //
13470
13471 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
13472 {
13473 return to_char_type(0xFA); // Single-Precision Float
13474 }
13475
13476 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
13477 {
13478 return to_char_type(0xFB); // Double-Precision Float
13479 }
13480
13482 // MsgPack //
13484
13485 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
13486 {
13487 return to_char_type(0xCA); // float 32
13488 }
13489
13490 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
13491 {
13492 return to_char_type(0xCB); // float 64
13493 }
13494
13496 // UBJSON //
13498
13499 // UBJSON: write number (floating point)
13500 template<typename NumberType, typename std::enable_if<
13501 std::is_floating_point<NumberType>::value, int>::type = 0>
13502 void write_number_with_ubjson_prefix(const NumberType n,
13503 const bool add_prefix)
13504 {
13505 if (add_prefix)
13506 {
13507 oa->write_character(get_ubjson_float_prefix(n));
13508 }
13509 write_number(n);
13510 }
13511
13512 // UBJSON: write number (unsigned integer)
13513 template<typename NumberType, typename std::enable_if<
13514 std::is_unsigned<NumberType>::value, int>::type = 0>
13515 void write_number_with_ubjson_prefix(const NumberType n,
13516 const bool add_prefix)
13517 {
13518 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
13519 {
13520 if (add_prefix)
13521 {
13522 oa->write_character(to_char_type('i')); // int8
13523 }
13524 write_number(static_cast<std::uint8_t>(n));
13525 }
13526 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
13527 {
13528 if (add_prefix)
13529 {
13530 oa->write_character(to_char_type('U')); // uint8
13531 }
13532 write_number(static_cast<std::uint8_t>(n));
13533 }
13534 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
13535 {
13536 if (add_prefix)
13537 {
13538 oa->write_character(to_char_type('I')); // int16
13539 }
13540 write_number(static_cast<std::int16_t>(n));
13541 }
13542 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13543 {
13544 if (add_prefix)
13545 {
13546 oa->write_character(to_char_type('l')); // int32
13547 }
13548 write_number(static_cast<std::int32_t>(n));
13549 }
13550 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
13551 {
13552 if (add_prefix)
13553 {
13554 oa->write_character(to_char_type('L')); // int64
13555 }
13556 write_number(static_cast<std::int64_t>(n));
13557 }
13558 else
13559 {
13560 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
13561 }
13562 }
13563
13564 // UBJSON: write number (signed integer)
13565 template<typename NumberType, typename std::enable_if<
13566 std::is_signed<NumberType>::value and
13567 not std::is_floating_point<NumberType>::value, int>::type = 0>
13568 void write_number_with_ubjson_prefix(const NumberType n,
13569 const bool add_prefix)
13570 {
13571 if ((std::numeric_limits<std::int8_t>::min)() <= n and n <= (std::numeric_limits<std::int8_t>::max)())
13572 {
13573 if (add_prefix)
13574 {
13575 oa->write_character(to_char_type('i')); // int8
13576 }
13577 write_number(static_cast<std::int8_t>(n));
13578 }
13579 else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n and n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
13580 {
13581 if (add_prefix)
13582 {
13583 oa->write_character(to_char_type('U')); // uint8
13584 }
13585 write_number(static_cast<std::uint8_t>(n));
13586 }
13587 else if ((std::numeric_limits<std::int16_t>::min)() <= n and n <= (std::numeric_limits<std::int16_t>::max)())
13588 {
13589 if (add_prefix)
13590 {
13591 oa->write_character(to_char_type('I')); // int16
13592 }
13593 write_number(static_cast<std::int16_t>(n));
13594 }
13595 else if ((std::numeric_limits<std::int32_t>::min)() <= n and n <= (std::numeric_limits<std::int32_t>::max)())
13596 {
13597 if (add_prefix)
13598 {
13599 oa->write_character(to_char_type('l')); // int32
13600 }
13601 write_number(static_cast<std::int32_t>(n));
13602 }
13603 else if ((std::numeric_limits<std::int64_t>::min)() <= n and n <= (std::numeric_limits<std::int64_t>::max)())
13604 {
13605 if (add_prefix)
13606 {
13607 oa->write_character(to_char_type('L')); // int64
13608 }
13609 write_number(static_cast<std::int64_t>(n));
13610 }
13611 // LCOV_EXCL_START
13612 else
13613 {
13614 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
13615 }
13616 // LCOV_EXCL_STOP
13617 }
13618
13628 CharType ubjson_prefix(const BasicJsonType& j) const noexcept
13629 {
13630 switch (j.type())
13631 {
13632 case value_t::null:
13633 return 'Z';
13634
13635 case value_t::boolean:
13636 return j.m_value.boolean ? 'T' : 'F';
13637
13638 case value_t::number_integer:
13639 {
13640 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
13641 {
13642 return 'i';
13643 }
13644 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
13645 {
13646 return 'U';
13647 }
13648 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
13649 {
13650 return 'I';
13651 }
13652 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
13653 {
13654 return 'l';
13655 }
13656 // no check and assume int64_t (see note above)
13657 return 'L';
13658 }
13659
13660 case value_t::number_unsigned:
13661 {
13662 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
13663 {
13664 return 'i';
13665 }
13666 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
13667 {
13668 return 'U';
13669 }
13670 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
13671 {
13672 return 'I';
13673 }
13674 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13675 {
13676 return 'l';
13677 }
13678 // no check and assume int64_t (see note above)
13679 return 'L';
13680 }
13681
13682 case value_t::number_float:
13683 return get_ubjson_float_prefix(j.m_value.number_float);
13684
13685 case value_t::string:
13686 return 'S';
13687
13688 case value_t::array: // fallthrough
13689 case value_t::binary:
13690 return '[';
13691
13692 case value_t::object:
13693 return '{';
13694
13695 default: // discarded values
13696 return 'N';
13697 }
13698 }
13699
13700 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
13701 {
13702 return 'd'; // float 32
13703 }
13704
13705 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
13706 {
13707 return 'D'; // float 64
13708 }
13709
13711 // Utility functions //
13713
13714 /*
13715 @brief write a number to output input
13716 @param[in] n number of type @a NumberType
13717 @tparam NumberType the type of the number
13718 @tparam OutputIsLittleEndian Set to true if output data is
13719 required to be little endian
13720
13721 @note This function needs to respect the system's endianess, because bytes
13722 in CBOR, MessagePack, and UBJSON are stored in network order (big
13723 endian) and therefore need reordering on little endian systems.
13724 */
13725 template<typename NumberType, bool OutputIsLittleEndian = false>
13726 void write_number(const NumberType n)
13727 {
13728 // step 1: write number to array of length NumberType
13729 std::array<CharType, sizeof(NumberType)> vec;
13730 std::memcpy(vec.data(), &n, sizeof(NumberType));
13731
13732 // step 2: write array to output (with possible reordering)
13733 if (is_little_endian != OutputIsLittleEndian)
13734 {
13735 // reverse byte order prior to conversion if necessary
13736 std::reverse(vec.begin(), vec.end());
13737 }
13738
13739 oa->write_characters(vec.data(), sizeof(NumberType));
13740 }
13741
13742 public:
13743 // The following to_char_type functions are implement the conversion
13744 // between uint8_t and CharType. In case CharType is not unsigned,
13745 // such a conversion is required to allow values greater than 128.
13746 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
13747 template < typename C = CharType,
13748 enable_if_t < std::is_signed<C>::value and std::is_signed<char>::value > * = nullptr >
13749 static constexpr CharType to_char_type(std::uint8_t x) noexcept
13750 {
13751 return *reinterpret_cast<char*>(&x);
13752 }
13753
13754 template < typename C = CharType,
13755 enable_if_t < std::is_signed<C>::value and std::is_unsigned<char>::value > * = nullptr >
13756 static CharType to_char_type(std::uint8_t x) noexcept
13757 {
13758 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
13759 static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
13760 CharType result;
13761 std::memcpy(&result, &x, sizeof(x));
13762 return result;
13763 }
13764
13765 template<typename C = CharType,
13766 enable_if_t<std::is_unsigned<C>::value>* = nullptr>
13767 static constexpr CharType to_char_type(std::uint8_t x) noexcept
13768 {
13769 return x;
13770 }
13771
13772 template < typename InputCharType, typename C = CharType,
13773 enable_if_t <
13774 std::is_signed<C>::value and
13775 std::is_signed<char>::value and
13776 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
13777 > * = nullptr >
13778 static constexpr CharType to_char_type(InputCharType x) noexcept
13779 {
13780 return x;
13781 }
13782
13783 private:
13785 const bool is_little_endian = little_endianess();
13786
13788 output_adapter_t<CharType> oa = nullptr;
13789 };
13790 } // namespace detail
13791 } // namespace nlohmann
13792
13793 // #include <nlohmann/detail/output/output_adapters.hpp>
13794
13795 // #include <nlohmann/detail/output/serializer.hpp>
13796
13797
13798 #include <algorithm> // reverse, remove, fill, find, none_of
13799 #include <array> // array
13800 #include <cassert> // assert
13801 #include <clocale> // localeconv, lconv
13802 #include <cmath> // labs, isfinite, isnan, signbit
13803 #include <cstddef> // size_t, ptrdiff_t
13804 #include <cstdint> // uint8_t
13805 #include <cstdio> // snprintf
13806 #include <limits> // numeric_limits
13807 #include <string> // string
13808 #include <type_traits> // is_same
13809 #include <utility> // move
13810
13811 // #include <nlohmann/detail/boolean_operators.hpp>
13812
13813 // #include <nlohmann/detail/conversions/to_chars.hpp>
13814
13815
13816 #include <array> // array
13817 #include <cassert> // assert
13818 #include <cmath> // signbit, isfinite
13819 #include <cstdint> // intN_t, uintN_t
13820 #include <cstring> // memcpy, memmove
13821 #include <limits> // numeric_limits
13822 #include <type_traits> // conditional
13823
13824 // #include <nlohmann/detail/boolean_operators.hpp>
13825
13826 // #include <nlohmann/detail/macro_scope.hpp>
13827
13828
13829 namespace nlohmann
13830 {
13831 namespace detail
13832 {
13833
13853 namespace dtoa_impl
13854 {
13855
13856 template <typename Target, typename Source>
13857 Target reinterpret_bits(const Source source)
13858 {
13859 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
13860
13861 Target target;
13862 std::memcpy(&target, &source, sizeof(Source));
13863 return target;
13864 }
13865
13866 struct diyfp // f * 2^e
13867 {
13868 static constexpr int kPrecision = 64; // = q
13869
13870 std::uint64_t f = 0;
13871 int e = 0;
13872
13873 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
13874
13879 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
13880 {
13881 assert(x.e == y.e);
13882 assert(x.f >= y.f);
13883
13884 return {x.f - y.f, x.e};
13885 }
13886
13891 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
13892 {
13893 static_assert(kPrecision == 64, "internal error");
13894
13895 // Computes:
13896 // f = round((x.f * y.f) / 2^q)
13897 // e = x.e + y.e + q
13898
13899 // Emulate the 64-bit * 64-bit multiplication:
13900 //
13901 // p = u * v
13902 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
13903 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
13904 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
13905 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
13906 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
13907 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
13908 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
13909 //
13910 // (Since Q might be larger than 2^32 - 1)
13911 //
13912 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
13913 //
13914 // (Q_hi + H does not overflow a 64-bit int)
13915 //
13916 // = p_lo + 2^64 p_hi
13917
13918 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
13919 const std::uint64_t u_hi = x.f >> 32u;
13920 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
13921 const std::uint64_t v_hi = y.f >> 32u;
13922
13923 const std::uint64_t p0 = u_lo * v_lo;
13924 const std::uint64_t p1 = u_lo * v_hi;
13925 const std::uint64_t p2 = u_hi * v_lo;
13926 const std::uint64_t p3 = u_hi * v_hi;
13927
13928 const std::uint64_t p0_hi = p0 >> 32u;
13929 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
13930 const std::uint64_t p1_hi = p1 >> 32u;
13931 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
13932 const std::uint64_t p2_hi = p2 >> 32u;
13933
13934 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
13935
13936 // The full product might now be computed as
13937 //
13938 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
13939 // p_lo = p0_lo + (Q << 32)
13940 //
13941 // But in this particular case here, the full p_lo is not required.
13942 // Effectively we only need to add the highest bit in p_lo to p_hi (and
13943 // Q_hi + 1 does not overflow).
13944
13945 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
13946
13947 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
13948
13949 return {h, x.e + y.e + 64};
13950 }
13951
13956 static diyfp normalize(diyfp x) noexcept
13957 {
13958 assert(x.f != 0);
13959
13960 while ((x.f >> 63u) == 0)
13961 {
13962 x.f <<= 1u;
13963 x.e--;
13964 }
13965
13966 return x;
13967 }
13968
13973 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
13974 {
13975 const int delta = x.e - target_exponent;
13976
13977 assert(delta >= 0);
13978 assert(((x.f << delta) >> delta) == x.f);
13979
13980 return {x.f << delta, target_exponent};
13981 }
13982 };
13983
13984 struct boundaries
13985 {
13986 diyfp w;
13987 diyfp minus;
13988 diyfp plus;
13989 };
13990
13997 template <typename FloatType>
13998 boundaries compute_boundaries(FloatType value)
13999 {
14000 assert(std::isfinite(value));
14001 assert(value > 0);
14002
14003 // Convert the IEEE representation into a diyfp.
14004 //
14005 // If v is denormal:
14006 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
14007 // If v is normalized:
14008 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
14009
14010 static_assert(std::numeric_limits<FloatType>::is_iec559,
14011 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
14012
14013 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
14014 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
14015 constexpr int kMinExp = 1 - kBias;
14016 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
14017
14018 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
14019
14020 const std::uint64_t bits = reinterpret_bits<bits_type>(value);
14021 const std::uint64_t E = bits >> (kPrecision - 1);
14022 const std::uint64_t F = bits & (kHiddenBit - 1);
14023
14024 const bool is_denormal = E == 0;
14025 const diyfp v = is_denormal
14026 ? diyfp(F, kMinExp)
14027 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
14028
14029 // Compute the boundaries m- and m+ of the floating-point value
14030 // v = f * 2^e.
14031 //
14032 // Determine v- and v+, the floating-point predecessor and successor if v,
14033 // respectively.
14034 //
14035 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
14036 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
14037 //
14038 // v+ = v + 2^e
14039 //
14040 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
14041 // between m- and m+ round to v, regardless of how the input rounding
14042 // algorithm breaks ties.
14043 //
14044 // ---+-------------+-------------+-------------+-------------+--- (A)
14045 // v- m- v m+ v+
14046 //
14047 // -----------------+------+------+-------------+-------------+--- (B)
14048 // v- m- v m+ v+
14049
14050 const bool lower_boundary_is_closer = F == 0 and E > 1;
14051 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
14052 const diyfp m_minus = lower_boundary_is_closer
14053 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
14054 : diyfp(2 * v.f - 1, v.e - 1); // (A)
14055
14056 // Determine the normalized w+ = m+.
14057 const diyfp w_plus = diyfp::normalize(m_plus);
14058
14059 // Determine w- = m- such that e_(w-) = e_(w+).
14060 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
14061
14062 return {diyfp::normalize(v), w_minus, w_plus};
14063 }
14064
14065 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
14066 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
14067 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
14068 //
14069 // alpha <= e = e_c + e_w + q <= gamma
14070 //
14071 // or
14072 //
14073 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
14074 // <= f_c * f_w * 2^gamma
14075 //
14076 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
14077 //
14078 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
14079 //
14080 // or
14081 //
14082 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
14083 //
14084 // The choice of (alpha,gamma) determines the size of the table and the form of
14085 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
14086 // in practice:
14087 //
14088 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
14089 // processed independently: An integral part p1, and a fractional part p2:
14090 //
14091 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
14092 // = (f div 2^-e) + (f mod 2^-e) * 2^e
14093 // = p1 + p2 * 2^e
14094 //
14095 // The conversion of p1 into decimal form requires a series of divisions and
14096 // modulos by (a power of) 10. These operations are faster for 32-bit than for
14097 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
14098 // achieved by choosing
14099 //
14100 // -e >= 32 or e <= -32 := gamma
14101 //
14102 // In order to convert the fractional part
14103 //
14104 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
14105 //
14106 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
14107 // d[-i] are extracted in order:
14108 //
14109 // (10 * p2) div 2^-e = d[-1]
14110 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
14111 //
14112 // The multiplication by 10 must not overflow. It is sufficient to choose
14113 //
14114 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
14115 //
14116 // Since p2 = f mod 2^-e < 2^-e,
14117 //
14118 // -e <= 60 or e >= -60 := alpha
14119
14120 constexpr int kAlpha = -60;
14121 constexpr int kGamma = -32;
14122
14123 struct cached_power // c = f * 2^e ~= 10^k
14124 {
14125 std::uint64_t f;
14126 int e;
14127 int k;
14128 };
14129
14137 inline cached_power get_cached_power_for_binary_exponent(int e)
14138 {
14139 // Now
14140 //
14141 // alpha <= e_c + e + q <= gamma (1)
14142 // ==> f_c * 2^alpha <= c * 2^e * 2^q
14143 //
14144 // and since the c's are normalized, 2^(q-1) <= f_c,
14145 //
14146 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
14147 // ==> 2^(alpha - e - 1) <= c
14148 //
14149 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
14150 //
14151 // k = ceil( log_10( 2^(alpha - e - 1) ) )
14152 // = ceil( (alpha - e - 1) * log_10(2) )
14153 //
14154 // From the paper:
14155 // "In theory the result of the procedure could be wrong since c is rounded,
14156 // and the computation itself is approximated [...]. In practice, however,
14157 // this simple function is sufficient."
14158 //
14159 // For IEEE double precision floating-point numbers converted into
14160 // normalized diyfp's w = f * 2^e, with q = 64,
14161 //
14162 // e >= -1022 (min IEEE exponent)
14163 // -52 (p - 1)
14164 // -52 (p - 1, possibly normalize denormal IEEE numbers)
14165 // -11 (normalize the diyfp)
14166 // = -1137
14167 //
14168 // and
14169 //
14170 // e <= +1023 (max IEEE exponent)
14171 // -52 (p - 1)
14172 // -11 (normalize the diyfp)
14173 // = 960
14174 //
14175 // This binary exponent range [-1137,960] results in a decimal exponent
14176 // range [-307,324]. One does not need to store a cached power for each
14177 // k in this range. For each such k it suffices to find a cached power
14178 // such that the exponent of the product lies in [alpha,gamma].
14179 // This implies that the difference of the decimal exponents of adjacent
14180 // table entries must be less than or equal to
14181 //
14182 // floor( (gamma - alpha) * log_10(2) ) = 8.
14183 //
14184 // (A smaller distance gamma-alpha would require a larger table.)
14185
14186 // NB:
14187 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
14188
14189 constexpr int kCachedPowersMinDecExp = -300;
14190 constexpr int kCachedPowersDecStep = 8;
14191
14192 static constexpr std::array<cached_power, 79> kCachedPowers =
14193 {
14194 {
14195 { 0xAB70FE17C79AC6CA, -1060, -300 },
14196 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
14197 { 0xBE5691EF416BD60C, -1007, -284 },
14198 { 0x8DD01FAD907FFC3C, -980, -276 },
14199 { 0xD3515C2831559A83, -954, -268 },
14200 { 0x9D71AC8FADA6C9B5, -927, -260 },
14201 { 0xEA9C227723EE8BCB, -901, -252 },
14202 { 0xAECC49914078536D, -874, -244 },
14203 { 0x823C12795DB6CE57, -847, -236 },
14204 { 0xC21094364DFB5637, -821, -228 },
14205 { 0x9096EA6F3848984F, -794, -220 },
14206 { 0xD77485CB25823AC7, -768, -212 },
14207 { 0xA086CFCD97BF97F4, -741, -204 },
14208 { 0xEF340A98172AACE5, -715, -196 },
14209 { 0xB23867FB2A35B28E, -688, -188 },
14210 { 0x84C8D4DFD2C63F3B, -661, -180 },
14211 { 0xC5DD44271AD3CDBA, -635, -172 },
14212 { 0x936B9FCEBB25C996, -608, -164 },
14213 { 0xDBAC6C247D62A584, -582, -156 },
14214 { 0xA3AB66580D5FDAF6, -555, -148 },
14215 { 0xF3E2F893DEC3F126, -529, -140 },
14216 { 0xB5B5ADA8AAFF80B8, -502, -132 },
14217 { 0x87625F056C7C4A8B, -475, -124 },
14218 { 0xC9BCFF6034C13053, -449, -116 },
14219 { 0x964E858C91BA2655, -422, -108 },
14220 { 0xDFF9772470297EBD, -396, -100 },
14221 { 0xA6DFBD9FB8E5B88F, -369, -92 },
14222 { 0xF8A95FCF88747D94, -343, -84 },
14223 { 0xB94470938FA89BCF, -316, -76 },
14224 { 0x8A08F0F8BF0F156B, -289, -68 },
14225 { 0xCDB02555653131B6, -263, -60 },
14226 { 0x993FE2C6D07B7FAC, -236, -52 },
14227 { 0xE45C10C42A2B3B06, -210, -44 },
14228 { 0xAA242499697392D3, -183, -36 },
14229 { 0xFD87B5F28300CA0E, -157, -28 },
14230 { 0xBCE5086492111AEB, -130, -20 },
14231 { 0x8CBCCC096F5088CC, -103, -12 },
14232 { 0xD1B71758E219652C, -77, -4 },
14233 { 0x9C40000000000000, -50, 4 },
14234 { 0xE8D4A51000000000, -24, 12 },
14235 { 0xAD78EBC5AC620000, 3, 20 },
14236 { 0x813F3978F8940984, 30, 28 },
14237 { 0xC097CE7BC90715B3, 56, 36 },
14238 { 0x8F7E32CE7BEA5C70, 83, 44 },
14239 { 0xD5D238A4ABE98068, 109, 52 },
14240 { 0x9F4F2726179A2245, 136, 60 },
14241 { 0xED63A231D4C4FB27, 162, 68 },
14242 { 0xB0DE65388CC8ADA8, 189, 76 },
14243 { 0x83C7088E1AAB65DB, 216, 84 },
14244 { 0xC45D1DF942711D9A, 242, 92 },
14245 { 0x924D692CA61BE758, 269, 100 },
14246 { 0xDA01EE641A708DEA, 295, 108 },
14247 { 0xA26DA3999AEF774A, 322, 116 },
14248 { 0xF209787BB47D6B85, 348, 124 },
14249 { 0xB454E4A179DD1877, 375, 132 },
14250 { 0x865B86925B9BC5C2, 402, 140 },
14251 { 0xC83553C5C8965D3D, 428, 148 },
14252 { 0x952AB45CFA97A0B3, 455, 156 },
14253 { 0xDE469FBD99A05FE3, 481, 164 },
14254 { 0xA59BC234DB398C25, 508, 172 },
14255 { 0xF6C69A72A3989F5C, 534, 180 },
14256 { 0xB7DCBF5354E9BECE, 561, 188 },
14257 { 0x88FCF317F22241E2, 588, 196 },
14258 { 0xCC20CE9BD35C78A5, 614, 204 },
14259 { 0x98165AF37B2153DF, 641, 212 },
14260 { 0xE2A0B5DC971F303A, 667, 220 },
14261 { 0xA8D9D1535CE3B396, 694, 228 },
14262 { 0xFB9B7CD9A4A7443C, 720, 236 },
14263 { 0xBB764C4CA7A44410, 747, 244 },
14264 { 0x8BAB8EEFB6409C1A, 774, 252 },
14265 { 0xD01FEF10A657842C, 800, 260 },
14266 { 0x9B10A4E5E9913129, 827, 268 },
14267 { 0xE7109BFBA19C0C9D, 853, 276 },
14268 { 0xAC2820D9623BF429, 880, 284 },
14269 { 0x80444B5E7AA7CF85, 907, 292 },
14270 { 0xBF21E44003ACDD2D, 933, 300 },
14271 { 0x8E679C2F5E44FF8F, 960, 308 },
14272 { 0xD433179D9C8CB841, 986, 316 },
14273 { 0x9E19DB92B4E31BA9, 1013, 324 },
14274 }
14275 };
14276
14277 // This computation gives exactly the same results for k as
14278 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
14279 // for |e| <= 1500, but doesn't require floating-point operations.
14280 // NB: log_10(2) ~= 78913 / 2^18
14281 assert(e >= -1500);
14282 assert(e <= 1500);
14283 const int f = kAlpha - e - 1;
14284 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
14285
14286 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
14287 assert(index >= 0);
14288 assert(static_cast<std::size_t>(index) < kCachedPowers.size());
14289
14290 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
14291 assert(kAlpha <= cached.e + e + 64);
14292 assert(kGamma >= cached.e + e + 64);
14293
14294 return cached;
14295 }
14296
14301 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
14302 {
14303 // LCOV_EXCL_START
14304 if (n >= 1000000000)
14305 {
14306 pow10 = 1000000000;
14307 return 10;
14308 }
14309 // LCOV_EXCL_STOP
14310 else if (n >= 100000000)
14311 {
14312 pow10 = 100000000;
14313 return 9;
14314 }
14315 else if (n >= 10000000)
14316 {
14317 pow10 = 10000000;
14318 return 8;
14319 }
14320 else if (n >= 1000000)
14321 {
14322 pow10 = 1000000;
14323 return 7;
14324 }
14325 else if (n >= 100000)
14326 {
14327 pow10 = 100000;
14328 return 6;
14329 }
14330 else if (n >= 10000)
14331 {
14332 pow10 = 10000;
14333 return 5;
14334 }
14335 else if (n >= 1000)
14336 {
14337 pow10 = 1000;
14338 return 4;
14339 }
14340 else if (n >= 100)
14341 {
14342 pow10 = 100;
14343 return 3;
14344 }
14345 else if (n >= 10)
14346 {
14347 pow10 = 10;
14348 return 2;
14349 }
14350 else
14351 {
14352 pow10 = 1;
14353 return 1;
14354 }
14355 }
14356
14357 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
14358 std::uint64_t rest, std::uint64_t ten_k)
14359 {
14360 assert(len >= 1);
14361 assert(dist <= delta);
14362 assert(rest <= delta);
14363 assert(ten_k > 0);
14364
14365 // <--------------------------- delta ---->
14366 // <---- dist --------->
14367 // --------------[------------------+-------------------]--------------
14368 // M- w M+
14369 //
14370 // ten_k
14371 // <------>
14372 // <---- rest ---->
14373 // --------------[------------------+----+--------------]--------------
14374 // w V
14375 // = buf * 10^k
14376 //
14377 // ten_k represents a unit-in-the-last-place in the decimal representation
14378 // stored in buf.
14379 // Decrement buf by ten_k while this takes buf closer to w.
14380
14381 // The tests are written in this order to avoid overflow in unsigned
14382 // integer arithmetic.
14383
14384 while (rest < dist
14385 and delta - rest >= ten_k
14386 and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
14387 {
14388 assert(buf[len - 1] != '0');
14389 buf[len - 1]--;
14390 rest += ten_k;
14391 }
14392 }
14393
14398 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
14399 diyfp M_minus, diyfp w, diyfp M_plus)
14400 {
14401 static_assert(kAlpha >= -60, "internal error");
14402 static_assert(kGamma <= -32, "internal error");
14403
14404 // Generates the digits (and the exponent) of a decimal floating-point
14405 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
14406 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
14407 //
14408 // <--------------------------- delta ---->
14409 // <---- dist --------->
14410 // --------------[------------------+-------------------]--------------
14411 // M- w M+
14412 //
14413 // Grisu2 generates the digits of M+ from left to right and stops as soon as
14414 // V is in [M-,M+].
14415
14416 assert(M_plus.e >= kAlpha);
14417 assert(M_plus.e <= kGamma);
14418
14419 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
14420 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
14421
14422 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
14423 //
14424 // M+ = f * 2^e
14425 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
14426 // = ((p1 ) * 2^-e + (p2 )) * 2^e
14427 // = p1 + p2 * 2^e
14428
14429 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
14430
14431 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.)
14432 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
14433
14434 // 1)
14435 //
14436 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
14437
14438 assert(p1 > 0);
14439
14440 std::uint32_t pow10;
14441 const int k = find_largest_pow10(p1, pow10);
14442
14443 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
14444 //
14445 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
14446 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
14447 //
14448 // M+ = p1 + p2 * 2^e
14449 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
14450 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
14451 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
14452 //
14453 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
14454 //
14455 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
14456 //
14457 // but stop as soon as
14458 //
14459 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
14460
14461 int n = k;
14462 while (n > 0)
14463 {
14464 // Invariants:
14465 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
14466 // pow10 = 10^(n-1) <= p1 < 10^n
14467 //
14468 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
14469 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
14470 //
14471 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
14472 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
14473 //
14474 assert(d <= 9);
14475 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
14476 //
14477 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
14478 //
14479 p1 = r;
14480 n--;
14481 //
14482 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
14483 // pow10 = 10^n
14484 //
14485
14486 // Now check if enough digits have been generated.
14487 // Compute
14488 //
14489 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
14490 //
14491 // Note:
14492 // Since rest and delta share the same exponent e, it suffices to
14493 // compare the significands.
14494 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
14495 if (rest <= delta)
14496 {
14497 // V = buffer * 10^n, with M- <= V <= M+.
14498
14499 decimal_exponent += n;
14500
14501 // We may now just stop. But instead look if the buffer could be
14502 // decremented to bring V closer to w.
14503 //
14504 // pow10 = 10^n is now 1 ulp in the decimal representation V.
14505 // The rounding procedure works with diyfp's with an implicit
14506 // exponent of e.
14507 //
14508 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
14509 //
14510 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
14511 grisu2_round(buffer, length, dist, delta, rest, ten_n);
14512
14513 return;
14514 }
14515
14516 pow10 /= 10;
14517 //
14518 // pow10 = 10^(n-1) <= p1 < 10^n
14519 // Invariants restored.
14520 }
14521
14522 // 2)
14523 //
14524 // The digits of the integral part have been generated:
14525 //
14526 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
14527 // = buffer + p2 * 2^e
14528 //
14529 // Now generate the digits of the fractional part p2 * 2^e.
14530 //
14531 // Note:
14532 // No decimal point is generated: the exponent is adjusted instead.
14533 //
14534 // p2 actually represents the fraction
14535 //
14536 // p2 * 2^e
14537 // = p2 / 2^-e
14538 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
14539 //
14540 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
14541 //
14542 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
14543 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
14544 //
14545 // using
14546 //
14547 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
14548 // = ( d) * 2^-e + ( r)
14549 //
14550 // or
14551 // 10^m * p2 * 2^e = d + r * 2^e
14552 //
14553 // i.e.
14554 //
14555 // M+ = buffer + p2 * 2^e
14556 // = buffer + 10^-m * (d + r * 2^e)
14557 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
14558 //
14559 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
14560
14561 assert(p2 > delta);
14562
14563 int m = 0;
14564 for (;;)
14565 {
14566 // Invariant:
14567 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
14568 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
14569 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
14570 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
14571 //
14572 assert(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
14573 p2 *= 10;
14574 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
14575 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
14576 //
14577 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
14578 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
14579 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
14580 //
14581 assert(d <= 9);
14582 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
14583 //
14584 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
14585 //
14586 p2 = r;
14587 m++;
14588 //
14589 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
14590 // Invariant restored.
14591
14592 // Check if enough digits have been generated.
14593 //
14594 // 10^-m * p2 * 2^e <= delta * 2^e
14595 // p2 * 2^e <= 10^m * delta * 2^e
14596 // p2 <= 10^m * delta
14597 delta *= 10;
14598 dist *= 10;
14599 if (p2 <= delta)
14600 {
14601 break;
14602 }
14603 }
14604
14605 // V = buffer * 10^-m, with M- <= V <= M+.
14606
14607 decimal_exponent -= m;
14608
14609 // 1 ulp in the decimal representation is now 10^-m.
14610 // Since delta and dist are now scaled by 10^m, we need to do the
14611 // same with ulp in order to keep the units in sync.
14612 //
14613 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
14614 //
14615 const std::uint64_t ten_m = one.f;
14616 grisu2_round(buffer, length, dist, delta, p2, ten_m);
14617
14618 // By construction this algorithm generates the shortest possible decimal
14619 // number (Loitsch, Theorem 6.2) which rounds back to w.
14620 // For an input number of precision p, at least
14621 //
14622 // N = 1 + ceil(p * log_10(2))
14623 //
14624 // decimal digits are sufficient to identify all binary floating-point
14625 // numbers (Matula, "In-and-Out conversions").
14626 // This implies that the algorithm does not produce more than N decimal
14627 // digits.
14628 //
14629 // N = 17 for p = 53 (IEEE double precision)
14630 // N = 9 for p = 24 (IEEE single precision)
14631 }
14632
14638 JSON_HEDLEY_NON_NULL(1)
14639 inline void grisu2(char* buf, int& len, int& decimal_exponent,
14640 diyfp m_minus, diyfp v, diyfp m_plus)
14641 {
14642 assert(m_plus.e == m_minus.e);
14643 assert(m_plus.e == v.e);
14644
14645 // --------(-----------------------+-----------------------)-------- (A)
14646 // m- v m+
14647 //
14648 // --------------------(-----------+-----------------------)-------- (B)
14649 // m- v m+
14650 //
14651 // First scale v (and m- and m+) such that the exponent is in the range
14652 // [alpha, gamma].
14653
14654 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
14655
14656 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
14657
14658 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
14659 const diyfp w = diyfp::mul(v, c_minus_k);
14660 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
14661 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
14662
14663 // ----(---+---)---------------(---+---)---------------(---+---)----
14664 // w- w w+
14665 // = c*m- = c*v = c*m+
14666 //
14667 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
14668 // w+ are now off by a small amount.
14669 // In fact:
14670 //
14671 // w - v * 10^k < 1 ulp
14672 //
14673 // To account for this inaccuracy, add resp. subtract 1 ulp.
14674 //
14675 // --------+---[---------------(---+---)---------------]---+--------
14676 // w- M- w M+ w+
14677 //
14678 // Now any number in [M-, M+] (bounds included) will round to w when input,
14679 // regardless of how the input rounding algorithm breaks ties.
14680 //
14681 // And digit_gen generates the shortest possible such number in [M-, M+].
14682 // Note that this does not mean that Grisu2 always generates the shortest
14683 // possible number in the interval (m-, m+).
14684 const diyfp M_minus(w_minus.f + 1, w_minus.e);
14685 const diyfp M_plus (w_plus.f - 1, w_plus.e );
14686
14687 decimal_exponent = -cached.k; // = -(-k) = k
14688
14689 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
14690 }
14691
14697 template <typename FloatType>
14698 JSON_HEDLEY_NON_NULL(1)
14699 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
14700 {
14701 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
14702 "internal error: not enough precision");
14703
14704 assert(std::isfinite(value));
14705 assert(value > 0);
14706
14707 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
14708 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
14709 // decimal representations are not exactly "short".
14710 //
14711 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
14712 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
14713 // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
14714 // does.
14715 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
14716 // representation using the corresponding std::from_chars function recovers value exactly". That
14717 // indicates that single precision floating-point numbers should be recovered using
14718 // 'std::strtof'.
14719 //
14720 // NB: If the neighbors are computed for single-precision numbers, there is a single float
14721 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
14722 // value is off by 1 ulp.
14723 #if 0
14724 const boundaries w = compute_boundaries(static_cast<double>(value));
14725 #else
14726 const boundaries w = compute_boundaries(value);
14727 #endif
14728
14729 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
14730 }
14731
14737 JSON_HEDLEY_NON_NULL(1)
14738
14739 inline char* append_exponent(char* buf, int e)
14740 {
14741 assert(e > -1000);
14742 assert(e < 1000);
14743
14744 if (e < 0)
14745 {
14746 e = -e;
14747 *buf++ = '-';
14748 }
14749 else
14750 {
14751 *buf++ = '+';
14752 }
14753
14754 auto k = static_cast<std::uint32_t>(e);
14755 if (k < 10)
14756 {
14757 // Always print at least two digits in the exponent.
14758 // This is for compatibility with printf("%g").
14759 *buf++ = '0';
14760 *buf++ = static_cast<char>('0' + k);
14761 }
14762 else if (k < 100)
14763 {
14764 *buf++ = static_cast<char>('0' + k / 10);
14765 k %= 10;
14766 *buf++ = static_cast<char>('0' + k);
14767 }
14768 else
14769 {
14770 *buf++ = static_cast<char>('0' + k / 100);
14771 k %= 100;
14772 *buf++ = static_cast<char>('0' + k / 10);
14773 k %= 10;
14774 *buf++ = static_cast<char>('0' + k);
14775 }
14776
14777 return buf;
14778 }
14779
14789 JSON_HEDLEY_NON_NULL(1)
14790
14791 inline char* format_buffer(char* buf, int len, int decimal_exponent,
14792 int min_exp, int max_exp)
14793 {
14794 assert(min_exp < 0);
14795 assert(max_exp > 0);
14796
14797 const int k = len;
14798 const int n = len + decimal_exponent;
14799
14800 // v = buf * 10^(n-k)
14801 // k is the length of the buffer (number of decimal digits)
14802 // n is the position of the decimal point relative to the start of the buffer.
14803
14804 if (k <= n and n <= max_exp)
14805 {
14806 // digits[000]
14807 // len <= max_exp + 2
14808
14809 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
14810 // Make it look like a floating-point number (#362, #378)
14811 buf[n + 0] = '.';
14812 buf[n + 1] = '0';
14813 return buf + (static_cast<size_t>(n) + 2);
14814 }
14815
14816 if (0 < n and n <= max_exp)
14817 {
14818 // dig.its
14819 // len <= max_digits10 + 1
14820
14821 assert(k > n);
14822
14823 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
14824 buf[n] = '.';
14825 return buf + (static_cast<size_t>(k) + 1U);
14826 }
14827
14828 if (min_exp < n and n <= 0)
14829 {
14830 // 0.[000]digits
14831 // len <= 2 + (-min_exp - 1) + max_digits10
14832
14833 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
14834 buf[0] = '0';
14835 buf[1] = '.';
14836 std::memset(buf + 2, '0', static_cast<size_t>(-n));
14837 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
14838 }
14839
14840 if (k == 1)
14841 {
14842 // dE+123
14843 // len <= 1 + 5
14844
14845 buf += 1;
14846 }
14847 else
14848 {
14849 // d.igitsE+123
14850 // len <= max_digits10 + 1 + 5
14851
14852 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
14853 buf[1] = '.';
14854 buf += 1 + static_cast<size_t>(k);
14855 }
14856
14857 *buf++ = 'e';
14858 return append_exponent(buf, n - 1);
14859 }
14860
14861 } // namespace dtoa_impl
14862
14873 template <typename FloatType>
14874 JSON_HEDLEY_NON_NULL(1, 2)
14875
14876 char* to_chars(char* first, const char* last, FloatType value)
14877 {
14878 static_cast<void>(last); // maybe unused - fix warning
14879 assert(std::isfinite(value));
14880
14881 // Use signbit(value) instead of (value < 0) since signbit works for -0.
14882 if (std::signbit(value))
14883 {
14884 value = -value;
14885 *first++ = '-';
14886 }
14887
14888 if (value == 0) // +-0
14889 {
14890 *first++ = '0';
14891 // Make it look like a floating-point number (#362, #378)
14892 *first++ = '.';
14893 *first++ = '0';
14894 return first;
14895 }
14896
14897 assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
14898
14899 // Compute v = buffer * 10^decimal_exponent.
14900 // The decimal digits are stored in the buffer, which needs to be interpreted
14901 // as an unsigned decimal integer.
14902 // len is the length of the buffer, i.e. the number of decimal digits.
14903 int len = 0;
14904 int decimal_exponent = 0;
14905 dtoa_impl::grisu2(first, len, decimal_exponent, value);
14906
14907 assert(len <= std::numeric_limits<FloatType>::max_digits10);
14908
14909 // Format the buffer like printf("%.*g", prec, value)
14910 constexpr int kMinExp = -4;
14911 // Use digits10 here to increase compatibility with version 2.
14912 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
14913
14914 assert(last - first >= kMaxExp + 2);
14915 assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
14916 assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
14917
14918 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
14919 }
14920
14921 } // namespace detail
14922 } // namespace nlohmann
14923
14924 // #include <nlohmann/detail/exceptions.hpp>
14925
14926 // #include <nlohmann/detail/macro_scope.hpp>
14927
14928 // #include <nlohmann/detail/meta/cpp_future.hpp>
14929
14930 // #include <nlohmann/detail/output/binary_writer.hpp>
14931
14932 // #include <nlohmann/detail/output/output_adapters.hpp>
14933
14934 // #include <nlohmann/detail/value_t.hpp>
14935
14936
14937 namespace nlohmann
14938 {
14939 namespace detail
14940 {
14942 // serialization //
14944
14946 enum class error_handler_t
14947 {
14948 strict,
14949 replace,
14950 ignore
14951 };
14952
14953 template<typename BasicJsonType>
14954 class serializer
14955 {
14956 using string_t = typename BasicJsonType::string_t;
14957 using number_float_t = typename BasicJsonType::number_float_t;
14958 using number_integer_t = typename BasicJsonType::number_integer_t;
14959 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
14960 using binary_char_t = typename BasicJsonType::binary_t::value_type;
14961 static constexpr std::uint8_t UTF8_ACCEPT = 0;
14962 static constexpr std::uint8_t UTF8_REJECT = 1;
14963
14964 public:
14970 serializer(output_adapter_t<char> s, const char ichar,
14971 error_handler_t error_handler_ = error_handler_t::strict)
14972 : o(std::move(s))
14973 , loc(std::localeconv())
14974 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : * (loc->thousands_sep))
14975 , decimal_point(loc->decimal_point == nullptr ? '\0' : * (loc->decimal_point))
14976 , indent_char(ichar)
14977 , indent_string(512, indent_char)
14978 , error_handler(error_handler_)
14979 {}
14980
14981 // delete because of pointer members
14982 serializer(const serializer&) = delete;
14983 serializer& operator=(const serializer&) = delete;
14984 serializer(serializer&&) = delete;
14985 serializer& operator=(serializer&&) = delete;
14986 ~serializer() = default;
14987
15010 void dump(const BasicJsonType& val,
15011 const bool pretty_print,
15012 const bool ensure_ascii,
15013 const unsigned int indent_step,
15014 const unsigned int current_indent = 0)
15015 {
15016 switch (val.m_type)
15017 {
15018 case value_t::object:
15019 {
15020 if (val.m_value.object->empty())
15021 {
15022 o->write_characters("{}", 2);
15023 return;
15024 }
15025
15026 if (pretty_print)
15027 {
15028 o->write_characters("{\n", 2);
15029
15030 // variable to hold indentation for recursive calls
15031 const auto new_indent = current_indent + indent_step;
15032 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15033 {
15034 indent_string.resize(indent_string.size() * 2, ' ');
15035 }
15036
15037 // first n-1 elements
15038 auto i = val.m_value.object->cbegin();
15039 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15040 {
15041 o->write_characters(indent_string.c_str(), new_indent);
15042 o->write_character('\"');
15043 dump_escaped(i->first, ensure_ascii);
15044 o->write_characters("\": ", 3);
15045 dump(i->second, true, ensure_ascii, indent_step, new_indent);
15046 o->write_characters(",\n", 2);
15047 }
15048
15049 // last element
15050 assert(i != val.m_value.object->cend());
15051 assert(std::next(i) == val.m_value.object->cend());
15052 o->write_characters(indent_string.c_str(), new_indent);
15053 o->write_character('\"');
15054 dump_escaped(i->first, ensure_ascii);
15055 o->write_characters("\": ", 3);
15056 dump(i->second, true, ensure_ascii, indent_step, new_indent);
15057
15058 o->write_character('\n');
15059 o->write_characters(indent_string.c_str(), current_indent);
15060 o->write_character('}');
15061 }
15062 else
15063 {
15064 o->write_character('{');
15065
15066 // first n-1 elements
15067 auto i = val.m_value.object->cbegin();
15068 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15069 {
15070 o->write_character('\"');
15071 dump_escaped(i->first, ensure_ascii);
15072 o->write_characters("\":", 2);
15073 dump(i->second, false, ensure_ascii, indent_step, current_indent);
15074 o->write_character(',');
15075 }
15076
15077 // last element
15078 assert(i != val.m_value.object->cend());
15079 assert(std::next(i) == val.m_value.object->cend());
15080 o->write_character('\"');
15081 dump_escaped(i->first, ensure_ascii);
15082 o->write_characters("\":", 2);
15083 dump(i->second, false, ensure_ascii, indent_step, current_indent);
15084
15085 o->write_character('}');
15086 }
15087
15088 return;
15089 }
15090
15091 case value_t::array:
15092 {
15093 if (val.m_value.array->empty())
15094 {
15095 o->write_characters("[]", 2);
15096 return;
15097 }
15098
15099 if (pretty_print)
15100 {
15101 o->write_characters("[\n", 2);
15102
15103 // variable to hold indentation for recursive calls
15104 const auto new_indent = current_indent + indent_step;
15105 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15106 {
15107 indent_string.resize(indent_string.size() * 2, ' ');
15108 }
15109
15110 // first n-1 elements
15111 for (auto i = val.m_value.array->cbegin();
15112 i != val.m_value.array->cend() - 1; ++i)
15113 {
15114 o->write_characters(indent_string.c_str(), new_indent);
15115 dump(*i, true, ensure_ascii, indent_step, new_indent);
15116 o->write_characters(",\n", 2);
15117 }
15118
15119 // last element
15120 assert(not val.m_value.array->empty());
15121 o->write_characters(indent_string.c_str(), new_indent);
15122 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
15123
15124 o->write_character('\n');
15125 o->write_characters(indent_string.c_str(), current_indent);
15126 o->write_character(']');
15127 }
15128 else
15129 {
15130 o->write_character('[');
15131
15132 // first n-1 elements
15133 for (auto i = val.m_value.array->cbegin();
15134 i != val.m_value.array->cend() - 1; ++i)
15135 {
15136 dump(*i, false, ensure_ascii, indent_step, current_indent);
15137 o->write_character(',');
15138 }
15139
15140 // last element
15141 assert(not val.m_value.array->empty());
15142 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
15143
15144 o->write_character(']');
15145 }
15146
15147 return;
15148 }
15149
15150 case value_t::string:
15151 {
15152 o->write_character('\"');
15153 dump_escaped(*val.m_value.string, ensure_ascii);
15154 o->write_character('\"');
15155 return;
15156 }
15157
15158 case value_t::binary:
15159 {
15160 if (pretty_print)
15161 {
15162 o->write_characters("{\n", 2);
15163
15164 // variable to hold indentation for recursive calls
15165 const auto new_indent = current_indent + indent_step;
15166 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15167 {
15168 indent_string.resize(indent_string.size() * 2, ' ');
15169 }
15170
15171 o->write_characters(indent_string.c_str(), new_indent);
15172
15173 o->write_characters("\"bytes\": [", 10);
15174
15175 if (not val.m_value.binary->empty())
15176 {
15177 for (auto i = val.m_value.binary->cbegin();
15178 i != val.m_value.binary->cend() - 1; ++i)
15179 {
15180 dump_integer(*i);
15181 o->write_characters(", ", 2);
15182 }
15183 dump_integer(val.m_value.binary->back());
15184 }
15185
15186 o->write_characters("],\n", 3);
15187 o->write_characters(indent_string.c_str(), new_indent);
15188
15189 o->write_characters("\"subtype\": ", 11);
15190 if (val.m_value.binary->has_subtype())
15191 {
15192 dump_integer(val.m_value.binary->subtype());
15193 }
15194 else
15195 {
15196 o->write_characters("null", 4);
15197 }
15198 o->write_character('\n');
15199 o->write_characters(indent_string.c_str(), current_indent);
15200 o->write_character('}');
15201 }
15202 else
15203 {
15204 o->write_characters("{\"bytes\":[", 10);
15205
15206 if (not val.m_value.binary->empty())
15207 {
15208 for (auto i = val.m_value.binary->cbegin();
15209 i != val.m_value.binary->cend() - 1; ++i)
15210 {
15211 dump_integer(*i);
15212 o->write_character(',');
15213 }
15214 dump_integer(val.m_value.binary->back());
15215 }
15216
15217 o->write_characters("],\"subtype\":", 12);
15218 if (val.m_value.binary->has_subtype())
15219 {
15220 dump_integer(val.m_value.binary->subtype());
15221 o->write_character('}');
15222 }
15223 else
15224 {
15225 o->write_characters("null}", 5);
15226 }
15227 }
15228 return;
15229 }
15230
15231 case value_t::boolean:
15232 {
15233 if (val.m_value.boolean)
15234 {
15235 o->write_characters("true", 4);
15236 }
15237 else
15238 {
15239 o->write_characters("false", 5);
15240 }
15241 return;
15242 }
15243
15244 case value_t::number_integer:
15245 {
15246 dump_integer(val.m_value.number_integer);
15247 return;
15248 }
15249
15250 case value_t::number_unsigned:
15251 {
15252 dump_integer(val.m_value.number_unsigned);
15253 return;
15254 }
15255
15256 case value_t::number_float:
15257 {
15258 dump_float(val.m_value.number_float);
15259 return;
15260 }
15261
15262 case value_t::discarded:
15263 {
15264 o->write_characters("<discarded>", 11);
15265 return;
15266 }
15267
15268 case value_t::null:
15269 {
15270 o->write_characters("null", 4);
15271 return;
15272 }
15273
15274 default: // LCOV_EXCL_LINE
15275 assert(false); // LCOV_EXCL_LINE
15276 }
15277 }
15278
15279 private:
15294 void dump_escaped(const string_t& s, const bool ensure_ascii)
15295 {
15296 std::uint32_t codepoint;
15297 std::uint8_t state = UTF8_ACCEPT;
15298 std::size_t bytes = 0; // number of bytes written to string_buffer
15299
15300 // number of bytes written at the point of the last valid byte
15301 std::size_t bytes_after_last_accept = 0;
15302 std::size_t undumped_chars = 0;
15303
15304 for (std::size_t i = 0; i < s.size(); ++i)
15305 {
15306 const auto byte = static_cast<uint8_t>(s[i]);
15307
15308 switch (decode(state, codepoint, byte))
15309 {
15310 case UTF8_ACCEPT: // decode found a new code point
15311 {
15312 switch (codepoint)
15313 {
15314 case 0x08: // backspace
15315 {
15316 string_buffer[bytes++] = '\\';
15317 string_buffer[bytes++] = 'b';
15318 break;
15319 }
15320
15321 case 0x09: // horizontal tab
15322 {
15323 string_buffer[bytes++] = '\\';
15324 string_buffer[bytes++] = 't';
15325 break;
15326 }
15327
15328 case 0x0A: // newline
15329 {
15330 string_buffer[bytes++] = '\\';
15331 string_buffer[bytes++] = 'n';
15332 break;
15333 }
15334
15335 case 0x0C: // formfeed
15336 {
15337 string_buffer[bytes++] = '\\';
15338 string_buffer[bytes++] = 'f';
15339 break;
15340 }
15341
15342 case 0x0D: // carriage return
15343 {
15344 string_buffer[bytes++] = '\\';
15345 string_buffer[bytes++] = 'r';
15346 break;
15347 }
15348
15349 case 0x22: // quotation mark
15350 {
15351 string_buffer[bytes++] = '\\';
15352 string_buffer[bytes++] = '\"';
15353 break;
15354 }
15355
15356 case 0x5C: // reverse solidus
15357 {
15358 string_buffer[bytes++] = '\\';
15359 string_buffer[bytes++] = '\\';
15360 break;
15361 }
15362
15363 default:
15364 {
15365 // escape control characters (0x00..0x1F) or, if
15366 // ensure_ascii parameter is used, non-ASCII characters
15367 if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
15368 {
15369 if (codepoint <= 0xFFFF)
15370 {
15371 (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
15372 static_cast<std::uint16_t>(codepoint));
15373 bytes += 6;
15374 }
15375 else
15376 {
15377 (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
15378 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
15379 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
15380 bytes += 12;
15381 }
15382 }
15383 else
15384 {
15385 // copy byte to buffer (all previous bytes
15386 // been copied have in default case above)
15387 string_buffer[bytes++] = s[i];
15388 }
15389 break;
15390 }
15391 }
15392
15393 // write buffer and reset index; there must be 13 bytes
15394 // left, as this is the maximal number of bytes to be
15395 // written ("\uxxxx\uxxxx\0") for one code point
15396 if (string_buffer.size() - bytes < 13)
15397 {
15398 o->write_characters(string_buffer.data(), bytes);
15399 bytes = 0;
15400 }
15401
15402 // remember the byte position of this accept
15403 bytes_after_last_accept = bytes;
15404 undumped_chars = 0;
15405 break;
15406 }
15407
15408 case UTF8_REJECT: // decode found invalid UTF-8 byte
15409 {
15410 switch (error_handler)
15411 {
15412 case error_handler_t::strict:
15413 {
15414 std::string sn(3, '\0');
15415 (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
15416 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
15417 }
15418
15419 case error_handler_t::ignore:
15420 case error_handler_t::replace:
15421 {
15422 // in case we saw this character the first time, we
15423 // would like to read it again, because the byte
15424 // may be OK for itself, but just not OK for the
15425 // previous sequence
15426 if (undumped_chars > 0)
15427 {
15428 --i;
15429 }
15430
15431 // reset length buffer to the last accepted index;
15432 // thus removing/ignoring the invalid characters
15433 bytes = bytes_after_last_accept;
15434
15435 if (error_handler == error_handler_t::replace)
15436 {
15437 // add a replacement character
15438 if (ensure_ascii)
15439 {
15440 string_buffer[bytes++] = '\\';
15441 string_buffer[bytes++] = 'u';
15442 string_buffer[bytes++] = 'f';
15443 string_buffer[bytes++] = 'f';
15444 string_buffer[bytes++] = 'f';
15445 string_buffer[bytes++] = 'd';
15446 }
15447 else
15448 {
15449 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
15450 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
15451 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
15452 }
15453
15454 // write buffer and reset index; there must be 13 bytes
15455 // left, as this is the maximal number of bytes to be
15456 // written ("\uxxxx\uxxxx\0") for one code point
15457 if (string_buffer.size() - bytes < 13)
15458 {
15459 o->write_characters(string_buffer.data(), bytes);
15460 bytes = 0;
15461 }
15462
15463 bytes_after_last_accept = bytes;
15464 }
15465
15466 undumped_chars = 0;
15467
15468 // continue processing the string
15469 state = UTF8_ACCEPT;
15470 break;
15471 }
15472
15473 default: // LCOV_EXCL_LINE
15474 assert(false); // LCOV_EXCL_LINE
15475 }
15476 break;
15477 }
15478
15479 default: // decode found yet incomplete multi-byte code point
15480 {
15481 if (not ensure_ascii)
15482 {
15483 // code point will not be escaped - copy byte to buffer
15484 string_buffer[bytes++] = s[i];
15485 }
15486 ++undumped_chars;
15487 break;
15488 }
15489 }
15490 }
15491
15492 // we finished processing the string
15493 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
15494 {
15495 // write buffer
15496 if (bytes > 0)
15497 {
15498 o->write_characters(string_buffer.data(), bytes);
15499 }
15500 }
15501 else
15502 {
15503 // we finish reading, but do not accept: string was incomplete
15504 switch (error_handler)
15505 {
15506 case error_handler_t::strict:
15507 {
15508 std::string sn(3, '\0');
15509 (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
15510 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
15511 }
15512
15513 case error_handler_t::ignore:
15514 {
15515 // write all accepted bytes
15516 o->write_characters(string_buffer.data(), bytes_after_last_accept);
15517 break;
15518 }
15519
15520 case error_handler_t::replace:
15521 {
15522 // write all accepted bytes
15523 o->write_characters(string_buffer.data(), bytes_after_last_accept);
15524 // add a replacement character
15525 if (ensure_ascii)
15526 {
15527 o->write_characters("\\ufffd", 6);
15528 }
15529 else
15530 {
15531 o->write_characters("\xEF\xBF\xBD", 3);
15532 }
15533 break;
15534 }
15535
15536 default: // LCOV_EXCL_LINE
15537 assert(false); // LCOV_EXCL_LINE
15538 }
15539 }
15540 }
15541
15550 inline unsigned int count_digits(number_unsigned_t x) noexcept
15551 {
15552 unsigned int n_digits = 1;
15553 for (;;)
15554 {
15555 if (x < 10)
15556 {
15557 return n_digits;
15558 }
15559 if (x < 100)
15560 {
15561 return n_digits + 1;
15562 }
15563 if (x < 1000)
15564 {
15565 return n_digits + 2;
15566 }
15567 if (x < 10000)
15568 {
15569 return n_digits + 3;
15570 }
15571 x = x / 10000u;
15572 n_digits += 4;
15573 }
15574 }
15575
15585 template<typename NumberType, detail::enable_if_t<
15586 std::is_same<NumberType, number_unsigned_t>::value or
15587 std::is_same<NumberType, number_integer_t>::value or
15588 std::is_same<NumberType, binary_char_t>::value,
15589 int> = 0>
15590 void dump_integer(NumberType x)
15591 {
15592 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
15593 {
15594 {
15595 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
15596 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
15597 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
15598 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
15599 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
15600 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
15601 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
15602 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
15603 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
15604 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
15605 }
15606 };
15607
15608 // special case for "0"
15609 if (x == 0)
15610 {
15611 o->write_character('0');
15612 return;
15613 }
15614
15615 // use a pointer to fill the buffer
15616 auto buffer_ptr = number_buffer.begin();
15617
15618 const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not(x >= 0); // see issue #755
15619 number_unsigned_t abs_value;
15620
15621 unsigned int n_chars;
15622
15623 if (is_negative)
15624 {
15625 *buffer_ptr = '-';
15626 abs_value = remove_sign(static_cast<number_integer_t>(x));
15627
15628 // account one more byte for the minus sign
15629 n_chars = 1 + count_digits(abs_value);
15630 }
15631 else
15632 {
15633 abs_value = static_cast<number_unsigned_t>(x);
15634 n_chars = count_digits(abs_value);
15635 }
15636
15637 // spare 1 byte for '\0'
15638 assert(n_chars < number_buffer.size() - 1);
15639
15640 // jump to the end to generate the string from backward
15641 // so we later avoid reversing the result
15642 buffer_ptr += n_chars;
15643
15644 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
15645 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
15646 while (abs_value >= 100)
15647 {
15648 const auto digits_index = static_cast<unsigned>((abs_value % 100));
15649 abs_value /= 100;
15650 *(--buffer_ptr) = digits_to_99[digits_index][1];
15651 *(--buffer_ptr) = digits_to_99[digits_index][0];
15652 }
15653
15654 if (abs_value >= 10)
15655 {
15656 const auto digits_index = static_cast<unsigned>(abs_value);
15657 *(--buffer_ptr) = digits_to_99[digits_index][1];
15658 *(--buffer_ptr) = digits_to_99[digits_index][0];
15659 }
15660 else
15661 {
15662 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
15663 }
15664
15665 o->write_characters(number_buffer.data(), n_chars);
15666 }
15667
15676 void dump_float(number_float_t x)
15677 {
15678 // NaN / inf
15679 if (not std::isfinite(x))
15680 {
15681 o->write_characters("null", 4);
15682 return;
15683 }
15684
15685 // If number_float_t is an IEEE-754 single or double precision number,
15686 // use the Grisu2 algorithm to produce short numbers which are
15687 // guaranteed to round-trip, using strtof and strtod, resp.
15688 //
15689 // NB: The test below works if <long double> == <double>.
15690 static constexpr bool is_ieee_single_or_double
15691 = (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 24 and std::numeric_limits<number_float_t>::max_exponent == 128) or
15692 (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 53 and std::numeric_limits<number_float_t>::max_exponent == 1024);
15693
15694 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
15695 }
15696
15697 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
15698 {
15699 char* begin = number_buffer.data();
15700 char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
15701
15702 o->write_characters(begin, static_cast<size_t>(end - begin));
15703 }
15704
15705 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
15706 {
15707 // get number of digits for a float -> text -> float round-trip
15708 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
15709
15710 // the actual conversion
15711 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
15712
15713 // negative value indicates an error
15714 assert(len > 0);
15715 // check if buffer was large enough
15716 assert(static_cast<std::size_t>(len) < number_buffer.size());
15717
15718 // erase thousands separator
15719 if (thousands_sep != '\0')
15720 {
15721 const auto end = std::remove(number_buffer.begin(),
15722 number_buffer.begin() + len, thousands_sep);
15723 std::fill(end, number_buffer.end(), '\0');
15724 assert((end - number_buffer.begin()) <= len);
15725 len = (end - number_buffer.begin());
15726 }
15727
15728 // convert decimal point to '.'
15729 if (decimal_point != '\0' and decimal_point != '.')
15730 {
15731 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
15732 if (dec_pos != number_buffer.end())
15733 {
15734 *dec_pos = '.';
15735 }
15736 }
15737
15738 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
15739
15740 // determine if need to append ".0"
15741 const bool value_is_int_like =
15742 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
15743 [](char c)
15744 {
15745 return c == '.' or c == 'e';
15746 });
15747
15748 if (value_is_int_like)
15749 {
15750 o->write_characters(".0", 2);
15751 }
15752 }
15753
15775 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
15776 {
15777 static const std::array<std::uint8_t, 400> utf8d =
15778 {
15779 {
15780 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
15781 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
15782 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
15783 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
15784 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
15785 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
15786 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
15787 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
15788 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
15789 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
15790 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
15791 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
15792 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
15793 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
15794 }
15795 };
15796
15797 const std::uint8_t type = utf8d[byte];
15798
15799 codep = (state != UTF8_ACCEPT)
15800 ? (byte & 0x3fu) | (codep << 6u)
15801 : (0xFFu >> type) & (byte);
15802
15803 std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
15804 assert(index < 400);
15805 state = utf8d[index];
15806 return state;
15807 }
15808
15809 /*
15810 * Overload to make the compiler happy while it is instantiating
15811 * dump_integer for number_unsigned_t.
15812 * Must never be called.
15813 */
15814 number_unsigned_t remove_sign(number_unsigned_t x)
15815 {
15816 assert(false); // LCOV_EXCL_LINE
15817 return x; // LCOV_EXCL_LINE
15818 }
15819
15820 /*
15821 * Helper function for dump_integer
15822 *
15823 * This function takes a negative signed integer and returns its absolute
15824 * value as unsigned integer. The plus/minus shuffling is necessary as we can
15825 * not directly remove the sign of an arbitrary signed integer as the
15826 * absolute values of INT_MIN and INT_MAX are usually not the same. See
15827 * #1708 for details.
15828 */
15829 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
15830 {
15831 assert(x < 0 and x < (std::numeric_limits<number_integer_t>::max)());
15832 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
15833 }
15834
15835 private:
15837 output_adapter_t<char> o = nullptr;
15838
15840 std::array<char, 64> number_buffer{{}};
15841
15843 const std::lconv* loc = nullptr;
15845 const char thousands_sep = '\0';
15847 const char decimal_point = '\0';
15848
15850 std::array<char, 512> string_buffer{{}};
15851
15853 const char indent_char;
15855 string_t indent_string;
15856
15858 const error_handler_t error_handler;
15859 };
15860 } // namespace detail
15861 } // namespace nlohmann
15862
15863 // #include <nlohmann/detail/value_t.hpp>
15864
15865 // #include <nlohmann/json_fwd.hpp>
15866
15867
15873 namespace nlohmann
15874 {
15875
15960 NLOHMANN_BASIC_JSON_TPL_DECLARATION
15961 class basic_json
15962 {
15963 private:
15964 template<detail::value_t> friend struct detail::external_constructor;
15965 friend ::nlohmann::json_pointer<basic_json>;
15966
15967 template<typename BasicJsonType, typename InputType>
15968 friend class ::nlohmann::detail::parser;
15969 friend ::nlohmann::detail::serializer<basic_json>;
15970 template<typename BasicJsonType>
15971 friend class ::nlohmann::detail::iter_impl;
15972 template<typename BasicJsonType, typename CharType>
15973 friend class ::nlohmann::detail::binary_writer;
15974 template<typename BasicJsonType, typename InputType, typename SAX>
15975 friend class ::nlohmann::detail::binary_reader;
15976 template<typename BasicJsonType>
15977 friend class ::nlohmann::detail::json_sax_dom_parser;
15978 template<typename BasicJsonType>
15979 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
15980
15982 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
15983
15984 // convenience aliases for types residing in namespace detail;
15985 using lexer = ::nlohmann::detail::lexer_base<basic_json>;
15986
15987 template<typename InputAdapterType>
15988 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
15989 InputAdapterType adapter,
15990 detail::parser_callback_t<basic_json>cb = nullptr,
15991 bool allow_exceptions = true
15992 )
15993 {
15994 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter), std::move(cb), allow_exceptions);
15995 }
15996
15997 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
15998 template<typename BasicJsonType>
15999 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
16000 template<typename BasicJsonType>
16001 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
16002 template<typename Iterator>
16003 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
16004 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
16005
16006 template<typename CharType>
16007 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
16008
16009 template<typename InputType>
16010 using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
16011 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
16012
16013 using serializer = ::nlohmann::detail::serializer<basic_json>;
16014
16015 public:
16016 using value_t = detail::value_t;
16018 using json_pointer = ::nlohmann::json_pointer<basic_json>;
16019 template<typename T, typename SFINAE>
16020 using json_serializer = JSONSerializer<T, SFINAE>;
16022 using error_handler_t = detail::error_handler_t;
16024 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
16025
16026 using input_format_t = detail::input_format_t;
16028 using json_sax_t = json_sax<basic_json>;
16029
16031 // exceptions //
16033
16037
16039 using exception = detail::exception;
16041 using parse_error = detail::parse_error;
16043 using invalid_iterator = detail::invalid_iterator;
16045 using type_error = detail::type_error;
16047 using out_of_range = detail::out_of_range;
16049 using other_error = detail::other_error;
16050
16052
16053
16055 // container types //
16057
16062
16064 using value_type = basic_json;
16065
16067 using reference = value_type&;
16069 using const_reference = const value_type&;
16070
16072 using difference_type = std::ptrdiff_t;
16074 using size_type = std::size_t;
16075
16077 using allocator_type = AllocatorType<basic_json>;
16078
16080 using pointer = typename std::allocator_traits<allocator_type>::pointer;
16082 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
16083
16085 using iterator = iter_impl<basic_json>;
16087 using const_iterator = iter_impl<const basic_json>;
16089 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
16091 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
16092
16094
16095
16099 static allocator_type get_allocator()
16100 {
16101 return allocator_type();
16102 }
16103
16130
16131 static basic_json meta()
16132 {
16133 basic_json result;
16134
16135 result["copyright"] = "(C) 2013-2017 Niels Lohmann";
16136 result["name"] = "JSON for Modern C++";
16137 result["url"] = "https://github.com/nlohmann/json";
16138 result["version"]["string"] =
16139 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
16140 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
16141 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
16142 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
16143 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
16144 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
16145
16146 #ifdef _WIN32
16147 result["platform"] = "win32";
16148 #elif defined __linux__
16149 result["platform"] = "linux";
16150 #elif defined __APPLE__
16151 result["platform"] = "apple";
16152 #elif defined __unix__
16153 result["platform"] = "unix";
16154 #else
16155 result["platform"] = "unknown";
16156 #endif
16157
16158 #if defined(__ICC) || defined(__INTEL_COMPILER)
16159 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
16160 #elif defined(__clang__)
16161 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
16162 #elif defined(__GNUC__) || defined(__GNUG__)
16163 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
16164 #elif defined(__HP_cc) || defined(__HP_aCC)
16165 result["compiler"] = "hp"
16166 #elif defined(__IBMCPP__)
16167 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
16168 #elif defined(_MSC_VER)
16169 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
16170 #elif defined(__PGI)
16171 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
16172 #elif defined(__SUNPRO_CC)
16173 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
16174 #else
16175 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
16176 #endif
16177
16178 #ifdef __cplusplus
16179 result["compiler"]["c++"] = std::to_string(__cplusplus);
16180 #else
16181 result["compiler"]["c++"] = "unknown";
16182 #endif
16183 return result;
16184 }
16185
16186
16188 // JSON value data types //
16190
16195
16196 #if defined(JSON_HAS_CPP_14)
16197 // Use transparent comparator if possible, combined with perfect forwarding
16198 // on find() and count() calls prevents unnecessary string construction.
16199 using object_comparator_t = std::less<>;
16200 #else
16201 using object_comparator_t = std::less<StringType>;
16202 #endif
16203
16287 using object_t = ObjectType<StringType,
16288 basic_json,
16289 object_comparator_t,
16290 AllocatorType<std::pair<const StringType,
16291 basic_json>>>;
16292
16337 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
16338
16390 using string_t = StringType;
16391
16416 using boolean_t = BooleanType;
16417
16488 using number_integer_t = NumberIntegerType;
16489
16559 using number_unsigned_t = NumberUnsignedType;
16560
16627 using number_float_t = NumberFloatType;
16628
16698 using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
16700
16701 private:
16702
16704 template<typename T, typename... Args>
16705
16706 static T* create(Args&& ... args)
16707 {
16708 AllocatorType<T> alloc;
16709 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
16710
16711 auto deleter = [&](T * object)
16712 {
16713 AllocatorTraits::deallocate(alloc, object, 1);
16714 };
16715 std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
16716 AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
16717 assert(object != nullptr);
16718 return object.release();
16719 }
16720
16722 // JSON value storage //
16724
16750 union json_value
16751 {
16753 object_t* object;
16755 array_t* array;
16757 string_t* string;
16759 binary_t* binary;
16761 boolean_t boolean;
16763 number_integer_t number_integer;
16765 number_unsigned_t number_unsigned;
16767 number_float_t number_float;
16768
16770 json_value() = default;
16772 json_value(boolean_t v) noexcept : boolean(v) {}
16774 json_value(number_integer_t v) noexcept : number_integer(v) {}
16776 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
16778 json_value(number_float_t v) noexcept : number_float(v) {}
16780 json_value(value_t t)
16781 {
16782 switch (t)
16783 {
16784 case value_t::object:
16785 {
16786 object = create<object_t>();
16787 break;
16788 }
16789
16790 case value_t::array:
16791 {
16792 array = create<array_t>();
16793 break;
16794 }
16795
16796 case value_t::string:
16797 {
16798 string = create<string_t>("");
16799 break;
16800 }
16801
16802 case value_t::binary:
16803 {
16804 binary = create<binary_t>();
16805 break;
16806 }
16807
16808 case value_t::boolean:
16809 {
16810 boolean = boolean_t(false);
16811 break;
16812 }
16813
16814 case value_t::number_integer:
16815 {
16816 number_integer = number_integer_t(0);
16817 break;
16818 }
16819
16820 case value_t::number_unsigned:
16821 {
16822 number_unsigned = number_unsigned_t(0);
16823 break;
16824 }
16825
16826 case value_t::number_float:
16827 {
16828 number_float = number_float_t(0.0);
16829 break;
16830 }
16831
16832 case value_t::null:
16833 {
16834 object = nullptr; // silence warning, see #821
16835 break;
16836 }
16837
16838 default:
16839 {
16840 object = nullptr; // silence warning, see #821
16841 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
16842 {
16843 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.7.3")); // LCOV_EXCL_LINE
16844 }
16845 break;
16846 }
16847 }
16848 }
16849
16851 json_value(const string_t& value)
16852 {
16853 string = create<string_t>(value);
16854 }
16855
16857 json_value(string_t&& value)
16858 {
16859 string = create<string_t>(std::move(value));
16860 }
16861
16863 json_value(const object_t& value)
16864 {
16865 object = create<object_t>(value);
16866 }
16867
16869 json_value(object_t&& value)
16870 {
16871 object = create<object_t>(std::move(value));
16872 }
16873
16875 json_value(const array_t& value)
16876 {
16877 array = create<array_t>(value);
16878 }
16879
16881 json_value(array_t&& value)
16882 {
16883 array = create<array_t>(std::move(value));
16884 }
16885
16887 json_value(const typename binary_t::container_type& value)
16888 {
16889 binary = create<binary_t>(value);
16890 }
16891
16893 json_value(typename binary_t::container_type&& value)
16894 {
16895 binary = create<binary_t>(std::move(value));
16896 }
16897
16899 json_value(const binary_t& value)
16900 {
16901 binary = create<binary_t>(value);
16902 }
16903
16905 json_value(binary_t&& value)
16906 {
16907 binary = create<binary_t>(std::move(value));
16908 }
16909
16910 void destroy(value_t t) noexcept
16911 {
16912 // flatten the current json_value to a heap-allocated stack
16913 std::vector<basic_json> stack;
16914
16915 // move the top-level items to stack
16916 if (t == value_t::array)
16917 {
16918 stack.reserve(array->size());
16919 std::move(array->begin(), array->end(), std::back_inserter(stack));
16920 }
16921 else if (t == value_t::object)
16922 {
16923 stack.reserve(object->size());
16924 for (auto&& it : *object)
16925 {
16926 stack.push_back(std::move(it.second));
16927 }
16928 }
16929
16930 while (not stack.empty())
16931 {
16932 // move the last item to local variable to be processed
16933 basic_json current_item(std::move(stack.back()));
16934 stack.pop_back();
16935
16936 // if current_item is array/object, move
16937 // its children to the stack to be processed later
16938 if (current_item.is_array())
16939 {
16940 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
16941 std::back_inserter(stack));
16942
16943 current_item.m_value.array->clear();
16944 }
16945 else if (current_item.is_object())
16946 {
16947 for (auto&& it : *current_item.m_value.object)
16948 {
16949 stack.push_back(std::move(it.second));
16950 }
16951
16952 current_item.m_value.object->clear();
16953 }
16954
16955 // it's now safe that current_item get destructed
16956 // since it doesn't have any children
16957 }
16958
16959 switch (t)
16960 {
16961 case value_t::object:
16962 {
16963 AllocatorType<object_t> alloc;
16964 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
16965 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
16966 break;
16967 }
16968
16969 case value_t::array:
16970 {
16971 AllocatorType<array_t> alloc;
16972 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
16973 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
16974 break;
16975 }
16976
16977 case value_t::string:
16978 {
16979 AllocatorType<string_t> alloc;
16980 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
16981 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
16982 break;
16983 }
16984
16985 case value_t::binary:
16986 {
16987 AllocatorType<binary_t> alloc;
16988 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
16989 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
16990 break;
16991 }
16992
16993 default:
16994 {
16995 break;
16996 }
16997 }
16998 }
16999 };
17000
17010 void assert_invariant() const noexcept
17011 {
17012 assert(m_type != value_t::object or m_value.object != nullptr);
17013 assert(m_type != value_t::array or m_value.array != nullptr);
17014 assert(m_type != value_t::string or m_value.string != nullptr);
17015 assert(m_type != value_t::binary or m_value.binary != nullptr);
17016 }
17017
17018 public:
17020 // JSON parser callback //
17022
17038 using parse_event_t = detail::parse_event_t;
17039
17089 using parser_callback_t = detail::parser_callback_t<basic_json>;
17090
17092 // constructors //
17094
17099
17130 basic_json(const value_t v)
17131 : m_type(v), m_value(v)
17132 {
17133 assert_invariant();
17134 }
17135
17154 basic_json(std::nullptr_t = nullptr) noexcept
17155 : basic_json(value_t::null)
17156 {
17157 assert_invariant();
17158 }
17159
17223 template <typename CompatibleType,
17224 typename U = detail::uncvref_t<CompatibleType>,
17225 detail::enable_if_t<
17226 not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
17227 basic_json(CompatibleType && val) noexcept(noexcept(
17228 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
17229 std::forward<CompatibleType>(val))))
17230 {
17231 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
17232 assert_invariant();
17233 }
17234
17261 template <typename BasicJsonType,
17262 detail::enable_if_t<
17263 detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
17264 basic_json(const BasicJsonType& val)
17265 {
17266 using other_boolean_t = typename BasicJsonType::boolean_t;
17267 using other_number_float_t = typename BasicJsonType::number_float_t;
17268 using other_number_integer_t = typename BasicJsonType::number_integer_t;
17269 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
17270 using other_string_t = typename BasicJsonType::string_t;
17271 using other_object_t = typename BasicJsonType::object_t;
17272 using other_array_t = typename BasicJsonType::array_t;
17273 using other_binary_t = typename BasicJsonType::binary_t;
17274
17275 switch (val.type())
17276 {
17277 case value_t::boolean:
17278 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
17279 break;
17280 case value_t::number_float:
17281 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
17282 break;
17283 case value_t::number_integer:
17284 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
17285 break;
17286 case value_t::number_unsigned:
17287 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
17288 break;
17289 case value_t::string:
17290 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
17291 break;
17292 case value_t::object:
17293 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
17294 break;
17295 case value_t::array:
17296 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
17297 break;
17298 case value_t::binary:
17299 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
17300 break;
17301 case value_t::null:
17302 *this = nullptr;
17303 break;
17304 case value_t::discarded:
17305 m_type = value_t::discarded;
17306 break;
17307 default: // LCOV_EXCL_LINE
17308 assert(false); // LCOV_EXCL_LINE
17309 }
17310 assert_invariant();
17311 }
17312
17387 basic_json(initializer_list_t init,
17388 bool type_deduction = true,
17389 value_t manual_type = value_t::array)
17390 {
17391 // check if each element is an array with two elements whose first
17392 // element is a string
17393 bool is_an_object = std::all_of(init.begin(), init.end(),
17394 [](const detail::json_ref<basic_json>& element_ref)
17395 {
17396 return element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string();
17397 });
17398
17399 // adjust type if type deduction is not wanted
17400 if (not type_deduction)
17401 {
17402 // if array is wanted, do not create an object though possible
17403 if (manual_type == value_t::array)
17404 {
17405 is_an_object = false;
17406 }
17407
17408 // if object is wanted but impossible, throw an exception
17409 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object and not is_an_object))
17410 {
17411 JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
17412 }
17413 }
17414
17415 if (is_an_object)
17416 {
17417 // the initializer list is a list of pairs -> create object
17418 m_type = value_t::object;
17419 m_value = value_t::object;
17420
17421 std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
17422 {
17423 auto element = element_ref.moved_or_copied();
17424 m_value.object->emplace(
17425 std::move(*((*element.m_value.array)[0].m_value.string)),
17426 std::move((*element.m_value.array)[1]));
17427 });
17428 }
17429 else
17430 {
17431 // the initializer list describes an array -> create array
17432 m_type = value_t::array;
17433 m_value.array = create<array_t>(init.begin(), init.end());
17434 }
17435
17436 assert_invariant();
17437 }
17438
17466
17467 static basic_json binary(const typename binary_t::container_type& init)
17468 {
17469 auto res = basic_json();
17470 res.m_type = value_t::binary;
17471 res.m_value = init;
17472 return res;
17473 }
17474
17503
17504 static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype)
17505 {
17506 auto res = basic_json();
17507 res.m_type = value_t::binary;
17508 res.m_value = binary_t(init, subtype);
17509 return res;
17510 }
17511
17513
17514 static basic_json binary(typename binary_t::container_type&& init)
17515 {
17516 auto res = basic_json();
17517 res.m_type = value_t::binary;
17518 res.m_value = std::move(init);
17519 return res;
17520 }
17521
17523
17524 static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype)
17525 {
17526 auto res = basic_json();
17527 res.m_type = value_t::binary;
17528 res.m_value = binary_t(std::move(init), subtype);
17529 return res;
17530 }
17531
17569
17570 static basic_json array(initializer_list_t init = {})
17571 {
17572 return basic_json(init, false, value_t::array);
17573 }
17574
17613
17614 static basic_json object(initializer_list_t init = {})
17615 {
17616 return basic_json(init, false, value_t::object);
17617 }
17618
17641 basic_json(size_type cnt, const basic_json& val)
17642 : m_type(value_t::array)
17643 {
17644 m_value.array = create<array_t>(cnt, val);
17645 assert_invariant();
17646 }
17647
17703 template<class InputIT, typename std::enable_if<
17704 std::is_same<InputIT, typename basic_json_t::iterator>::value or
17705 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
17706 basic_json(InputIT first, InputIT last)
17707 {
17708 assert(first.m_object != nullptr);
17709 assert(last.m_object != nullptr);
17710
17711 // make sure iterator fits the current value
17712 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
17713 {
17714 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
17715 }
17716
17717 // copy type from first iterator
17718 m_type = first.m_object->m_type;
17719
17720 // check if iterator range is complete for primitive values
17721 switch (m_type)
17722 {
17723 case value_t::boolean:
17724 case value_t::number_float:
17725 case value_t::number_integer:
17726 case value_t::number_unsigned:
17727 case value_t::string:
17728 {
17729 if (JSON_HEDLEY_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
17730 or not last.m_it.primitive_iterator.is_end()))
17731 {
17732 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
17733 }
17734 break;
17735 }
17736
17737 default:
17738 break;
17739 }
17740
17741 switch (m_type)
17742 {
17743 case value_t::number_integer:
17744 {
17745 m_value.number_integer = first.m_object->m_value.number_integer;
17746 break;
17747 }
17748
17749 case value_t::number_unsigned:
17750 {
17751 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
17752 break;
17753 }
17754
17755 case value_t::number_float:
17756 {
17757 m_value.number_float = first.m_object->m_value.number_float;
17758 break;
17759 }
17760
17761 case value_t::boolean:
17762 {
17763 m_value.boolean = first.m_object->m_value.boolean;
17764 break;
17765 }
17766
17767 case value_t::string:
17768 {
17769 m_value = *first.m_object->m_value.string;
17770 break;
17771 }
17772
17773 case value_t::object:
17774 {
17775 m_value.object = create<object_t>(first.m_it.object_iterator,
17776 last.m_it.object_iterator);
17777 break;
17778 }
17779
17780 case value_t::array:
17781 {
17782 m_value.array = create<array_t>(first.m_it.array_iterator,
17783 last.m_it.array_iterator);
17784 break;
17785 }
17786
17787 case value_t::binary:
17788 {
17789 m_value = *first.m_object->m_value.binary;
17790 break;
17791 }
17792
17793 default:
17794 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
17795 std::string(first.m_object->type_name())));
17796 }
17797
17798 assert_invariant();
17799 }
17800
17801
17803 // other constructors and destructor //
17805
17806 template <typename JsonRef,
17807 detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
17808 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
17809 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
17810
17836 basic_json(const basic_json& other)
17837 : m_type(other.m_type)
17838 {
17839 // check of passed value is valid
17840 other.assert_invariant();
17841
17842 switch (m_type)
17843 {
17844 case value_t::object:
17845 {
17846 m_value = *other.m_value.object;
17847 break;
17848 }
17849
17850 case value_t::array:
17851 {
17852 m_value = *other.m_value.array;
17853 break;
17854 }
17855
17856 case value_t::string:
17857 {
17858 m_value = *other.m_value.string;
17859 break;
17860 }
17861
17862 case value_t::boolean:
17863 {
17864 m_value = other.m_value.boolean;
17865 break;
17866 }
17867
17868 case value_t::number_integer:
17869 {
17870 m_value = other.m_value.number_integer;
17871 break;
17872 }
17873
17874 case value_t::number_unsigned:
17875 {
17876 m_value = other.m_value.number_unsigned;
17877 break;
17878 }
17879
17880 case value_t::number_float:
17881 {
17882 m_value = other.m_value.number_float;
17883 break;
17884 }
17885
17886 case value_t::binary:
17887 {
17888 m_value = *other.m_value.binary;
17889 break;
17890 }
17891
17892 default:
17893 break;
17894 }
17895
17896 assert_invariant();
17897 }
17898
17925 basic_json(basic_json&& other) noexcept
17926 : m_type(std::move(other.m_type)),
17927 m_value(std::move(other.m_value))
17928 {
17929 // check that passed value is valid
17930 other.assert_invariant();
17931
17932 // invalidate payload
17933 other.m_type = value_t::null;
17934 other.m_value = {};
17935
17936 assert_invariant();
17937 }
17938
17962 basic_json& operator=(basic_json other) noexcept (
17963 std::is_nothrow_move_constructible<value_t>::value and
17964 std::is_nothrow_move_assignable<value_t>::value and
17965 std::is_nothrow_move_constructible<json_value>::value and
17966 std::is_nothrow_move_assignable<json_value>::value
17967 )
17968 {
17969 // check that passed value is valid
17970 other.assert_invariant();
17971
17972 using std::swap;
17973 swap(m_type, other.m_type);
17974 swap(m_value, other.m_value);
17975
17976 assert_invariant();
17977 return *this;
17978 }
17979
17995 ~basic_json() noexcept
17996 {
17997 assert_invariant();
17998 m_value.destroy(m_type);
17999 }
18000
18002
18003 public:
18005 // object inspection //
18007
18011
18058 string_t dump(const int indent = -1,
18059 const char indent_char = ' ',
18060 const bool ensure_ascii = false,
18061 const error_handler_t error_handler = error_handler_t::strict) const
18062 {
18063 string_t result;
18064 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
18065
18066 if (indent >= 0)
18067 {
18068 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
18069 }
18070 else
18071 {
18072 s.dump(*this, false, ensure_ascii, 0);
18073 }
18074
18075 return result;
18076 }
18077
18111 constexpr value_t type() const noexcept
18112 {
18113 return m_type;
18114 }
18115
18142 constexpr bool is_primitive() const noexcept
18143 {
18144 return is_null() or is_string() or is_boolean() or is_number() or is_binary();
18145 }
18146
18169 constexpr bool is_structured() const noexcept
18170 {
18171 return is_array() or is_object();
18172 }
18173
18191 constexpr bool is_null() const noexcept
18192 {
18193 return m_type == value_t::null;
18194 }
18195
18213 constexpr bool is_boolean() const noexcept
18214 {
18215 return m_type == value_t::boolean;
18216 }
18217
18243 constexpr bool is_number() const noexcept
18244 {
18245 return is_number_integer() or is_number_float();
18246 }
18247
18272 constexpr bool is_number_integer() const noexcept
18273 {
18274 return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
18275 }
18276
18300 constexpr bool is_number_unsigned() const noexcept
18301 {
18302 return m_type == value_t::number_unsigned;
18303 }
18304
18328 constexpr bool is_number_float() const noexcept
18329 {
18330 return m_type == value_t::number_float;
18331 }
18332
18350 constexpr bool is_object() const noexcept
18351 {
18352 return m_type == value_t::object;
18353 }
18354
18372 constexpr bool is_array() const noexcept
18373 {
18374 return m_type == value_t::array;
18375 }
18376
18394 constexpr bool is_string() const noexcept
18395 {
18396 return m_type == value_t::string;
18397 }
18398
18416 constexpr bool is_binary() const noexcept
18417 {
18418 return m_type == value_t::binary;
18419 }
18420
18443 constexpr bool is_discarded() const noexcept
18444 {
18445 return m_type == value_t::discarded;
18446 }
18447
18469 constexpr operator value_t() const noexcept
18470 {
18471 return m_type;
18472 }
18473
18475
18476 private:
18478 // value access //
18480
18482 boolean_t get_impl(boolean_t* /*unused*/) const
18483 {
18484 if (JSON_HEDLEY_LIKELY(is_boolean()))
18485 {
18486 return m_value.boolean;
18487 }
18488
18489 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
18490 }
18491
18493 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
18494 {
18495 return is_object() ? m_value.object : nullptr;
18496 }
18497
18499 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
18500 {
18501 return is_object() ? m_value.object : nullptr;
18502 }
18503
18505 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
18506 {
18507 return is_array() ? m_value.array : nullptr;
18508 }
18509
18511 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
18512 {
18513 return is_array() ? m_value.array : nullptr;
18514 }
18515
18517 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
18518 {
18519 return is_string() ? m_value.string : nullptr;
18520 }
18521
18523 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
18524 {
18525 return is_string() ? m_value.string : nullptr;
18526 }
18527
18529 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
18530 {
18531 return is_boolean() ? &m_value.boolean : nullptr;
18532 }
18533
18535 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
18536 {
18537 return is_boolean() ? &m_value.boolean : nullptr;
18538 }
18539
18541 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
18542 {
18543 return is_number_integer() ? &m_value.number_integer : nullptr;
18544 }
18545
18547 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
18548 {
18549 return is_number_integer() ? &m_value.number_integer : nullptr;
18550 }
18551
18553 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
18554 {
18555 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
18556 }
18557
18559 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
18560 {
18561 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
18562 }
18563
18565 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
18566 {
18567 return is_number_float() ? &m_value.number_float : nullptr;
18568 }
18569
18571 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
18572 {
18573 return is_number_float() ? &m_value.number_float : nullptr;
18574 }
18575
18577 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
18578 {
18579 return is_binary() ? m_value.binary : nullptr;
18580 }
18581
18583 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
18584 {
18585 return is_binary() ? m_value.binary : nullptr;
18586 }
18587
18599 template<typename ReferenceType, typename ThisType>
18600 static ReferenceType get_ref_impl(ThisType& obj)
18601 {
18602 // delegate the call to get_ptr<>()
18603 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
18604
18605 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
18606 {
18607 return *ptr;
18608 }
18609
18610 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
18611 }
18612
18613 public:
18617
18632 template<typename BasicJsonType, detail::enable_if_t<
18633 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
18634 int> = 0>
18635 basic_json get() const
18636 {
18637 return *this;
18638 }
18639
18655 template<typename BasicJsonType, detail::enable_if_t<
18656 not std::is_same<BasicJsonType, basic_json>::value and
18657 detail::is_basic_json<BasicJsonType>::value, int> = 0>
18658 BasicJsonType get() const
18659 {
18660 return *this;
18661 }
18662
18702 template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
18703 detail::enable_if_t <
18704 not detail::is_basic_json<ValueType>::value and
18705 detail::has_from_json<basic_json_t, ValueType>::value and
18706 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
18707 int> = 0>
18708 ValueType get() const noexcept(noexcept(
18709 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
18710 {
18711 // we cannot static_assert on ValueTypeCV being non-const, because
18712 // there is support for get<const basic_json_t>(), which is why we
18713 // still need the uncvref
18714 static_assert(not std::is_reference<ValueTypeCV>::value,
18715 "get() cannot be used with reference types, you might want to use get_ref()");
18716 static_assert(std::is_default_constructible<ValueType>::value,
18717 "types must be DefaultConstructible when used with get()");
18718
18719 ValueType ret;
18720 JSONSerializer<ValueType>::from_json(*this, ret);
18721 return ret;
18722 }
18723
18755 template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
18756 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
18757 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
18758 int> = 0>
18759 ValueType get() const noexcept(noexcept(
18760 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
18761 {
18762 static_assert(not std::is_reference<ValueTypeCV>::value,
18763 "get() cannot be used with reference types, you might want to use get_ref()");
18764 return JSONSerializer<ValueType>::from_json(*this);
18765 }
18766
18800 template<typename ValueType,
18801 detail::enable_if_t <
18802 not detail::is_basic_json<ValueType>::value and
18803 detail::has_from_json<basic_json_t, ValueType>::value,
18804 int> = 0>
18805 ValueType & get_to(ValueType& v) const noexcept(noexcept(
18806 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
18807 {
18808 JSONSerializer<ValueType>::from_json(*this, v);
18809 return v;
18810 }
18811
18812 template <
18813 typename T, std::size_t N,
18814 typename Array = T (&)[N],
18815 detail::enable_if_t <
18816 detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
18817 Array get_to(T (&v)[N]) const
18818 noexcept(noexcept(JSONSerializer<Array>::from_json(
18819 std::declval<const basic_json_t&>(), v)))
18820 {
18821 JSONSerializer<Array>::from_json(*this, v);
18822 return v;
18823 }
18824
18825
18852 template<typename PointerType, typename std::enable_if<
18853 std::is_pointer<PointerType>::value, int>::type = 0>
18854 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
18855 {
18856 // delegate the call to get_impl_ptr<>()
18857 return get_impl_ptr(static_cast<PointerType>(nullptr));
18858 }
18859
18864 template<typename PointerType, typename std::enable_if<
18865 std::is_pointer<PointerType>::value and
18866 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
18867 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
18868 {
18869 // delegate the call to get_impl_ptr<>() const
18870 return get_impl_ptr(static_cast<PointerType>(nullptr));
18871 }
18872
18900 template<typename PointerType, typename std::enable_if<
18901 std::is_pointer<PointerType>::value, int>::type = 0>
18902 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
18903 {
18904 // delegate the call to get_ptr
18905 return get_ptr<PointerType>();
18906 }
18907
18912 template<typename PointerType, typename std::enable_if<
18913 std::is_pointer<PointerType>::value, int>::type = 0>
18914 constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
18915 {
18916 // delegate the call to get_ptr
18917 return get_ptr<PointerType>();
18918 }
18919
18946 template<typename ReferenceType, typename std::enable_if<
18947 std::is_reference<ReferenceType>::value, int>::type = 0>
18948 ReferenceType get_ref()
18949 {
18950 // delegate call to get_ref_impl
18951 return get_ref_impl<ReferenceType>(*this);
18952 }
18953
18958 template<typename ReferenceType, typename std::enable_if<
18959 std::is_reference<ReferenceType>::value and
18960 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
18961 ReferenceType get_ref() const
18962 {
18963 // delegate call to get_ref_impl
18964 return get_ref_impl<ReferenceType>(*this);
18965 }
18966
18996 template < typename ValueType, typename std::enable_if <
18997 not std::is_pointer<ValueType>::value and
18998 not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
18999 not std::is_same<ValueType, typename string_t::value_type>::value and
19000 not detail::is_basic_json<ValueType>::value
19001 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
19002 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) and _MSC_VER <= 1914))
19003 and not std::is_same<ValueType, typename std::string_view>::value
19004 #endif
19005 and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
19006 , int >::type = 0 >
19007 operator ValueType() const
19008 {
19009 // delegate the call to get<>() const
19010 return get<ValueType>();
19011 }
19012
19022 binary_t& get_binary()
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<binary_t*>();
19030 }
19031
19033 const binary_t& get_binary() const
19034 {
19035 if (not is_binary())
19036 {
19037 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19038 }
19039
19040 return *get_ptr<const binary_t*>();
19041 }
19042
19044
19045
19047 // element access //
19049
19053
19080 reference at(size_type idx)
19081 {
19082 // at only works for arrays
19083 if (JSON_HEDLEY_LIKELY(is_array()))
19084 {
19085 JSON_TRY
19086 {
19087 return m_value.array->at(idx);
19088 }
19089 JSON_CATCH (std::out_of_range&)
19090 {
19091 // create better exception explanation
19092 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19093 }
19094 }
19095 else
19096 {
19097 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19098 }
19099 }
19100
19127 const_reference at(size_type idx) const
19128 {
19129 // at only works for arrays
19130 if (JSON_HEDLEY_LIKELY(is_array()))
19131 {
19132 JSON_TRY
19133 {
19134 return m_value.array->at(idx);
19135 }
19136 JSON_CATCH (std::out_of_range&)
19137 {
19138 // create better exception explanation
19139 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19140 }
19141 }
19142 else
19143 {
19144 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19145 }
19146 }
19147
19178 reference at(const typename object_t::key_type& key)
19179 {
19180 // at only works for objects
19181 if (JSON_HEDLEY_LIKELY(is_object()))
19182 {
19183 JSON_TRY
19184 {
19185 return m_value.object->at(key);
19186 }
19187 JSON_CATCH (std::out_of_range&)
19188 {
19189 // create better exception explanation
19190 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19191 }
19192 }
19193 else
19194 {
19195 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19196 }
19197 }
19198
19229 const_reference at(const typename object_t::key_type& key) const
19230 {
19231 // at only works for objects
19232 if (JSON_HEDLEY_LIKELY(is_object()))
19233 {
19234 JSON_TRY
19235 {
19236 return m_value.object->at(key);
19237 }
19238 JSON_CATCH (std::out_of_range&)
19239 {
19240 // create better exception explanation
19241 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19242 }
19243 }
19244 else
19245 {
19246 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19247 }
19248 }
19249
19275 reference operator[](size_type idx)
19276 {
19277 // implicitly convert null value to an empty array
19278 if (is_null())
19279 {
19280 m_type = value_t::array;
19281 m_value.array = create<array_t>();
19282 assert_invariant();
19283 }
19284
19285 // operator[] only works for arrays
19286 if (JSON_HEDLEY_LIKELY(is_array()))
19287 {
19288 // fill up array with null values if given idx is outside range
19289 if (idx >= m_value.array->size())
19290 {
19291 m_value.array->insert(m_value.array->end(),
19292 idx - m_value.array->size() + 1,
19293 basic_json());
19294 }
19295
19296 return m_value.array->operator[](idx);
19297 }
19298
19299 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
19300 }
19301
19321 const_reference operator[](size_type idx) const
19322 {
19323 // const operator[] only works for arrays
19324 if (JSON_HEDLEY_LIKELY(is_array()))
19325 {
19326 return m_value.array->operator[](idx);
19327 }
19328
19329 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
19330 }
19331
19359 reference operator[](const typename object_t::key_type& key)
19360 {
19361 // implicitly convert null value to an empty object
19362 if (is_null())
19363 {
19364 m_type = value_t::object;
19365 m_value.object = create<object_t>();
19366 assert_invariant();
19367 }
19368
19369 // operator[] only works for objects
19370 if (JSON_HEDLEY_LIKELY(is_object()))
19371 {
19372 return m_value.object->operator[](key);
19373 }
19374
19375 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
19376 }
19377
19408 const_reference operator[](const typename object_t::key_type& key) const
19409 {
19410 // const operator[] only works for objects
19411 if (JSON_HEDLEY_LIKELY(is_object()))
19412 {
19413 assert(m_value.object->find(key) != m_value.object->end());
19414 return m_value.object->find(key)->second;
19415 }
19416
19417 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
19418 }
19419
19447 template<typename T>
19448 JSON_HEDLEY_NON_NULL(2)
19449 reference operator[](T* key)
19450 {
19451 // implicitly convert null to object
19452 if (is_null())
19453 {
19454 m_type = value_t::object;
19455 m_value = value_t::object;
19456 assert_invariant();
19457 }
19458
19459 // at only works for objects
19460 if (JSON_HEDLEY_LIKELY(is_object()))
19461 {
19462 return m_value.object->operator[](key);
19463 }
19464
19465 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
19466 }
19467
19498 template<typename T>
19499 JSON_HEDLEY_NON_NULL(2)
19500 const_reference operator[](T* key) const
19501 {
19502 // at only works for objects
19503 if (JSON_HEDLEY_LIKELY(is_object()))
19504 {
19505 assert(m_value.object->find(key) != m_value.object->end());
19506 return m_value.object->find(key)->second;
19507 }
19508
19509 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
19510 }
19511
19562 template<class ValueType, typename std::enable_if<
19563 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
19564 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
19565 {
19566 // at only works for objects
19567 if (JSON_HEDLEY_LIKELY(is_object()))
19568 {
19569 // if key is found, return value and given default value otherwise
19570 const auto it = find(key);
19571 if (it != end())
19572 {
19573 return *it;
19574 }
19575
19576 return default_value;
19577 }
19578
19579 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
19580 }
19581
19586 string_t value(const typename object_t::key_type& key, const char* default_value) const
19587 {
19588 return value(key, string_t(default_value));
19589 }
19590
19634 template<class ValueType, typename std::enable_if<
19635 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
19636 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
19637 {
19638 // at only works for objects
19639 if (JSON_HEDLEY_LIKELY(is_object()))
19640 {
19641 // if pointer resolves a value, return it or use default value
19642 JSON_TRY
19643 {
19644 return ptr.get_checked(this);
19645 }
19646 JSON_INTERNAL_CATCH (out_of_range&)
19647 {
19648 return default_value;
19649 }
19650 }
19651
19652 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
19653 }
19654
19659 JSON_HEDLEY_NON_NULL(3)
19660 string_t value(const json_pointer& ptr, const char* default_value) const
19661 {
19662 return value(ptr, string_t(default_value));
19663 }
19664
19690 reference front()
19691 {
19692 return *begin();
19693 }
19694
19698 const_reference front() const
19699 {
19700 return *cbegin();
19701 }
19702
19734 reference back()
19735 {
19736 auto tmp = end();
19737 --tmp;
19738 return *tmp;
19739 }
19740
19744 const_reference back() const
19745 {
19746 auto tmp = cend();
19747 --tmp;
19748 return *tmp;
19749 }
19750
19797 template<class IteratorType, typename std::enable_if<
19798 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
19799 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
19800 = 0>
19801 IteratorType erase(IteratorType pos)
19802 {
19803 // make sure iterator fits the current value
19804 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
19805 {
19806 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
19807 }
19808
19809 IteratorType result = end();
19810
19811 switch (m_type)
19812 {
19813 case value_t::boolean:
19814 case value_t::number_float:
19815 case value_t::number_integer:
19816 case value_t::number_unsigned:
19817 case value_t::string:
19818 case value_t::binary:
19819 {
19820 if (JSON_HEDLEY_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
19821 {
19822 JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
19823 }
19824
19825 if (is_string())
19826 {
19827 AllocatorType<string_t> alloc;
19828 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
19829 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
19830 m_value.string = nullptr;
19831 }
19832 else if (is_binary())
19833 {
19834 AllocatorType<binary_t> alloc;
19835 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
19836 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
19837 m_value.binary = nullptr;
19838 }
19839
19840 m_type = value_t::null;
19841 assert_invariant();
19842 break;
19843 }
19844
19845 case value_t::object:
19846 {
19847 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
19848 break;
19849 }
19850
19851 case value_t::array:
19852 {
19853 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
19854 break;
19855 }
19856
19857 default:
19858 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
19859 }
19860
19861 return result;
19862 }
19863
19910 template<class IteratorType, typename std::enable_if<
19911 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
19912 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
19913 = 0>
19914 IteratorType erase(IteratorType first, IteratorType last)
19915 {
19916 // make sure iterator fits the current value
19917 if (JSON_HEDLEY_UNLIKELY(this != first.m_object or this != last.m_object))
19918 {
19919 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
19920 }
19921
19922 IteratorType result = end();
19923
19924 switch (m_type)
19925 {
19926 case value_t::boolean:
19927 case value_t::number_float:
19928 case value_t::number_integer:
19929 case value_t::number_unsigned:
19930 case value_t::string:
19931 case value_t::binary:
19932 {
19933 if (JSON_HEDLEY_LIKELY(not first.m_it.primitive_iterator.is_begin()
19934 or not last.m_it.primitive_iterator.is_end()))
19935 {
19936 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
19937 }
19938
19939 if (is_string())
19940 {
19941 AllocatorType<string_t> alloc;
19942 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
19943 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
19944 m_value.string = nullptr;
19945 }
19946 else if (is_binary())
19947 {
19948 AllocatorType<binary_t> alloc;
19949 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
19950 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
19951 m_value.binary = nullptr;
19952 }
19953
19954 m_type = value_t::null;
19955 assert_invariant();
19956 break;
19957 }
19958
19959 case value_t::object:
19960 {
19961 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
19962 last.m_it.object_iterator);
19963 break;
19964 }
19965
19966 case value_t::array:
19967 {
19968 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
19969 last.m_it.array_iterator);
19970 break;
19971 }
19972
19973 default:
19974 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
19975 }
19976
19977 return result;
19978 }
19979
20009 size_type erase(const typename object_t::key_type& key)
20010 {
20011 // this erase only works for objects
20012 if (JSON_HEDLEY_LIKELY(is_object()))
20013 {
20014 return m_value.object->erase(key);
20015 }
20016
20017 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20018 }
20019
20044 void erase(const size_type idx)
20045 {
20046 // this erase only works for arrays
20047 if (JSON_HEDLEY_LIKELY(is_array()))
20048 {
20049 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
20050 {
20051 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
20052 }
20053
20054 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
20055 }
20056 else
20057 {
20058 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20059 }
20060 }
20061
20063
20064
20066 // lookup //
20068
20071
20096 template<typename KeyT>
20097 iterator find(KeyT&& key)
20098 {
20099 auto result = end();
20100
20101 if (is_object())
20102 {
20103 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20104 }
20105
20106 return result;
20107 }
20108
20113 template<typename KeyT>
20114 const_iterator find(KeyT&& key) const
20115 {
20116 auto result = cend();
20117
20118 if (is_object())
20119 {
20120 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20121 }
20122
20123 return result;
20124 }
20125
20147 template<typename KeyT>
20148 size_type count(KeyT&& key) const
20149 {
20150 // return 0 for all nonobject types
20151 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
20152 }
20153
20179 template<typename KeyT, typename std::enable_if<
20180 not std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int>::type = 0>
20181 bool contains(KeyT && key) const
20182 {
20183 return is_object() and m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
20184 }
20185
20212 bool contains(const json_pointer& ptr) const
20213 {
20214 return ptr.contains(this);
20215 }
20216
20218
20219
20221 // iterators //
20223
20226
20251 iterator begin() noexcept
20252 {
20253 iterator result(this);
20254 result.set_begin();
20255 return result;
20256 }
20257
20261 const_iterator begin() const noexcept
20262 {
20263 return cbegin();
20264 }
20265
20291 const_iterator cbegin() const noexcept
20292 {
20293 const_iterator result(this);
20294 result.set_begin();
20295 return result;
20296 }
20297
20322 iterator end() noexcept
20323 {
20324 iterator result(this);
20325 result.set_end();
20326 return result;
20327 }
20328
20332 const_iterator end() const noexcept
20333 {
20334 return cend();
20335 }
20336
20362 const_iterator cend() const noexcept
20363 {
20364 const_iterator result(this);
20365 result.set_end();
20366 return result;
20367 }
20368
20392 reverse_iterator rbegin() noexcept
20393 {
20394 return reverse_iterator(end());
20395 }
20396
20400 const_reverse_iterator rbegin() const noexcept
20401 {
20402 return crbegin();
20403 }
20404
20429 reverse_iterator rend() noexcept
20430 {
20431 return reverse_iterator(begin());
20432 }
20433
20437 const_reverse_iterator rend() const noexcept
20438 {
20439 return crend();
20440 }
20441
20466 const_reverse_iterator crbegin() const noexcept
20467 {
20468 return const_reverse_iterator(cend());
20469 }
20470
20495 const_reverse_iterator crend() const noexcept
20496 {
20497 return const_reverse_iterator(cbegin());
20498 }
20499
20500 public:
20558 JSON_HEDLEY_DEPRECATED(3.1.0)
20559 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
20560 {
20561 return ref.items();
20562 }
20563
20567 JSON_HEDLEY_DEPRECATED(3.1.0)
20568 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
20569 {
20570 return ref.items();
20571 }
20572
20641 iteration_proxy<iterator> items() noexcept
20642 {
20643 return iteration_proxy<iterator>(*this);
20644 }
20645
20649 iteration_proxy<const_iterator> items() const noexcept
20650 {
20651 return iteration_proxy<const_iterator>(*this);
20652 }
20653
20655
20656
20658 // capacity //
20660
20663
20706 bool empty() const noexcept
20707 {
20708 switch (m_type)
20709 {
20710 case value_t::null:
20711 {
20712 // null values are empty
20713 return true;
20714 }
20715
20716 case value_t::array:
20717 {
20718 // delegate call to array_t::empty()
20719 return m_value.array->empty();
20720 }
20721
20722 case value_t::object:
20723 {
20724 // delegate call to object_t::empty()
20725 return m_value.object->empty();
20726 }
20727
20728 default:
20729 {
20730 // all other types are nonempty
20731 return false;
20732 }
20733 }
20734 }
20735
20779 size_type size() const noexcept
20780 {
20781 switch (m_type)
20782 {
20783 case value_t::null:
20784 {
20785 // null values are empty
20786 return 0;
20787 }
20788
20789 case value_t::array:
20790 {
20791 // delegate call to array_t::size()
20792 return m_value.array->size();
20793 }
20794
20795 case value_t::object:
20796 {
20797 // delegate call to object_t::size()
20798 return m_value.object->size();
20799 }
20800
20801 default:
20802 {
20803 // all other types have size 1
20804 return 1;
20805 }
20806 }
20807 }
20808
20850 size_type max_size() const noexcept
20851 {
20852 switch (m_type)
20853 {
20854 case value_t::array:
20855 {
20856 // delegate call to array_t::max_size()
20857 return m_value.array->max_size();
20858 }
20859
20860 case value_t::object:
20861 {
20862 // delegate call to object_t::max_size()
20863 return m_value.object->max_size();
20864 }
20865
20866 default:
20867 {
20868 // all other types have max_size() == size()
20869 return size();
20870 }
20871 }
20872 }
20873
20875
20876
20878 // modifiers //
20880
20883
20921 void clear() noexcept
20922 {
20923 switch (m_type)
20924 {
20925 case value_t::number_integer:
20926 {
20927 m_value.number_integer = 0;
20928 break;
20929 }
20930
20931 case value_t::number_unsigned:
20932 {
20933 m_value.number_unsigned = 0;
20934 break;
20935 }
20936
20937 case value_t::number_float:
20938 {
20939 m_value.number_float = 0.0;
20940 break;
20941 }
20942
20943 case value_t::boolean:
20944 {
20945 m_value.boolean = false;
20946 break;
20947 }
20948
20949 case value_t::string:
20950 {
20951 m_value.string->clear();
20952 break;
20953 }
20954
20955 case value_t::binary:
20956 {
20957 m_value.binary->clear();
20958 break;
20959 }
20960
20961 case value_t::array:
20962 {
20963 m_value.array->clear();
20964 break;
20965 }
20966
20967 case value_t::object:
20968 {
20969 m_value.object->clear();
20970 break;
20971 }
20972
20973 default:
20974 break;
20975 }
20976 }
20977
20998 void push_back(basic_json&& val)
20999 {
21000 // push_back only works for null objects or arrays
21001 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
21002 {
21003 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21004 }
21005
21006 // transform null object into an array
21007 if (is_null())
21008 {
21009 m_type = value_t::array;
21010 m_value = value_t::array;
21011 assert_invariant();
21012 }
21013
21014 // add element to array (move semantics)
21015 m_value.array->push_back(std::move(val));
21016 // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
21017 }
21018
21023 reference operator+=(basic_json&& val)
21024 {
21025 push_back(std::move(val));
21026 return *this;
21027 }
21028
21033 void push_back(const basic_json& val)
21034 {
21035 // push_back only works for null objects or arrays
21036 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
21037 {
21038 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21039 }
21040
21041 // transform null object into an array
21042 if (is_null())
21043 {
21044 m_type = value_t::array;
21045 m_value = value_t::array;
21046 assert_invariant();
21047 }
21048
21049 // add element to array
21050 m_value.array->push_back(val);
21051 }
21052
21057 reference operator+=(const basic_json& val)
21058 {
21059 push_back(val);
21060 return *this;
21061 }
21062
21083 void push_back(const typename object_t::value_type& val)
21084 {
21085 // push_back only works for null objects or objects
21086 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_object())))
21087 {
21088 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21089 }
21090
21091 // transform null object into an object
21092 if (is_null())
21093 {
21094 m_type = value_t::object;
21095 m_value = value_t::object;
21096 assert_invariant();
21097 }
21098
21099 // add element to array
21100 m_value.object->insert(val);
21101 }
21102
21107 reference operator+=(const typename object_t::value_type& val)
21108 {
21109 push_back(val);
21110 return *this;
21111 }
21112
21138 void push_back(initializer_list_t init)
21139 {
21140 if (is_object() and init.size() == 2 and (*init.begin())->is_string())
21141 {
21142 basic_json&& key = init.begin()->moved_or_copied();
21143 push_back(typename object_t::value_type(
21144 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
21145 }
21146 else
21147 {
21148 push_back(basic_json(init));
21149 }
21150 }
21151
21156 reference operator+=(initializer_list_t init)
21157 {
21158 push_back(init);
21159 return *this;
21160 }
21161
21185 template<class... Args>
21186 reference emplace_back(Args&& ... args)
21187 {
21188 // emplace_back only works for null objects or arrays
21189 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
21190 {
21191 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
21192 }
21193
21194 // transform null object into an array
21195 if (is_null())
21196 {
21197 m_type = value_t::array;
21198 m_value = value_t::array;
21199 assert_invariant();
21200 }
21201
21202 // add element to array (perfect forwarding)
21203 #ifdef JSON_HAS_CPP_17
21204 return m_value.array->emplace_back(std::forward<Args>(args)...);
21205 #else
21206 m_value.array->emplace_back(std::forward<Args>(args)...);
21207 return m_value.array->back();
21208 #endif
21209 }
21210
21238 template<class... Args>
21239 std::pair<iterator, bool> emplace(Args&& ... args)
21240 {
21241 // emplace only works for null objects or arrays
21242 if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_object())))
21243 {
21244 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
21245 }
21246
21247 // transform null object into an object
21248 if (is_null())
21249 {
21250 m_type = value_t::object;
21251 m_value = value_t::object;
21252 assert_invariant();
21253 }
21254
21255 // add element to array (perfect forwarding)
21256 auto res = m_value.object->emplace(std::forward<Args>(args)...);
21257 // create result iterator and set iterator to the result of emplace
21258 auto it = begin();
21259 it.m_it.object_iterator = res.first;
21260
21261 // return pair of iterator and boolean
21262 return {it, res.second};
21263 }
21264
21268 template<typename... Args>
21269 iterator insert_iterator(const_iterator pos, Args&& ... args)
21270 {
21271 iterator result(this);
21272 assert(m_value.array != nullptr);
21273
21274 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
21275 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
21276 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
21277
21278 // This could have been written as:
21279 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
21280 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
21281
21282 return result;
21283 }
21284
21307 iterator insert(const_iterator pos, const basic_json& val)
21308 {
21309 // insert only works for arrays
21310 if (JSON_HEDLEY_LIKELY(is_array()))
21311 {
21312 // check if iterator pos fits to this JSON value
21313 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21314 {
21315 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
21316 }
21317
21318 // insert to array and return iterator
21319 return insert_iterator(pos, val);
21320 }
21321
21322 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
21323 }
21324
21329 iterator insert(const_iterator pos, basic_json&& val)
21330 {
21331 return insert(pos, val);
21332 }
21333
21358 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
21359 {
21360 // insert only works for arrays
21361 if (JSON_HEDLEY_LIKELY(is_array()))
21362 {
21363 // check if iterator pos fits to this JSON value
21364 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21365 {
21366 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
21367 }
21368
21369 // insert to array and return iterator
21370 return insert_iterator(pos, cnt, val);
21371 }
21372
21373 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
21374 }
21375
21406 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
21407 {
21408 // insert only works for arrays
21409 if (JSON_HEDLEY_UNLIKELY(not is_array()))
21410 {
21411 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
21412 }
21413
21414 // check if iterator pos fits to this JSON value
21415 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21416 {
21417 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
21418 }
21419
21420 // check if range iterators belong to the same JSON object
21421 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21422 {
21423 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
21424 }
21425
21426 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
21427 {
21428 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
21429 }
21430
21431 // insert to array and return iterator
21432 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
21433 }
21434
21459 iterator insert(const_iterator pos, initializer_list_t ilist)
21460 {
21461 // insert only works for arrays
21462 if (JSON_HEDLEY_UNLIKELY(not is_array()))
21463 {
21464 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
21465 }
21466
21467 // check if iterator pos fits to this JSON value
21468 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21469 {
21470 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
21471 }
21472
21473 // insert to array and return iterator
21474 return insert_iterator(pos, ilist.begin(), ilist.end());
21475 }
21476
21500 void insert(const_iterator first, const_iterator last)
21501 {
21502 // insert only works for objects
21503 if (JSON_HEDLEY_UNLIKELY(not is_object()))
21504 {
21505 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
21506 }
21507
21508 // check if range iterators belong to the same JSON object
21509 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21510 {
21511 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
21512 }
21513
21514 // passed iterators must belong to objects
21515 if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object()))
21516 {
21517 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
21518 }
21519
21520 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
21521 }
21522
21542 void update(const_reference j)
21543 {
21544 // implicitly convert null value to an empty object
21545 if (is_null())
21546 {
21547 m_type = value_t::object;
21548 m_value.object = create<object_t>();
21549 assert_invariant();
21550 }
21551
21552 if (JSON_HEDLEY_UNLIKELY(not is_object()))
21553 {
21554 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
21555 }
21556 if (JSON_HEDLEY_UNLIKELY(not j.is_object()))
21557 {
21558 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
21559 }
21560
21561 for (auto it = j.cbegin(); it != j.cend(); ++it)
21562 {
21563 m_value.object->operator[](it.key()) = it.value();
21564 }
21565 }
21566
21593 void update(const_iterator first, const_iterator last)
21594 {
21595 // implicitly convert null value to an empty object
21596 if (is_null())
21597 {
21598 m_type = value_t::object;
21599 m_value.object = create<object_t>();
21600 assert_invariant();
21601 }
21602
21603 if (JSON_HEDLEY_UNLIKELY(not is_object()))
21604 {
21605 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
21606 }
21607
21608 // check if range iterators belong to the same JSON object
21609 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21610 {
21611 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
21612 }
21613
21614 // passed iterators must belong to objects
21615 if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object()
21616 or not last.m_object->is_object()))
21617 {
21618 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
21619 }
21620
21621 for (auto it = first; it != last; ++it)
21622 {
21623 m_value.object->operator[](it.key()) = it.value();
21624 }
21625 }
21626
21644 void swap(reference other) noexcept (
21645 std::is_nothrow_move_constructible<value_t>::value and
21646 std::is_nothrow_move_assignable<value_t>::value and
21647 std::is_nothrow_move_constructible<json_value>::value and
21648 std::is_nothrow_move_assignable<json_value>::value
21649 )
21650 {
21651 std::swap(m_type, other.m_type);
21652 std::swap(m_value, other.m_value);
21653 assert_invariant();
21654 }
21655
21676 void swap(array_t& other)
21677 {
21678 // swap only works for arrays
21679 if (JSON_HEDLEY_LIKELY(is_array()))
21680 {
21681 std::swap(*(m_value.array), other);
21682 }
21683 else
21684 {
21685 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
21686 }
21687 }
21688
21709 void swap(object_t& other)
21710 {
21711 // swap only works for objects
21712 if (JSON_HEDLEY_LIKELY(is_object()))
21713 {
21714 std::swap(*(m_value.object), other);
21715 }
21716 else
21717 {
21718 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
21719 }
21720 }
21721
21742 void swap(string_t& other)
21743 {
21744 // swap only works for strings
21745 if (JSON_HEDLEY_LIKELY(is_string()))
21746 {
21747 std::swap(*(m_value.string), other);
21748 }
21749 else
21750 {
21751 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
21752 }
21753 }
21754
21775 void swap(binary_t& other)
21776 {
21777 // swap only works for strings
21778 if (JSON_HEDLEY_LIKELY(is_binary()))
21779 {
21780 std::swap(*(m_value.binary), other);
21781 }
21782 else
21783 {
21784 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
21785 }
21786 }
21787
21789 void swap(typename binary_t::container_type& other)
21790 {
21791 // swap only works for strings
21792 if (JSON_HEDLEY_LIKELY(is_binary()))
21793 {
21794 std::swap(*(m_value.binary), other);
21795 }
21796 else
21797 {
21798 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
21799 }
21800 }
21801
21803
21804 public:
21806 // lexicographical comparison operators //
21808
21811
21867 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
21868 {
21869 const auto lhs_type = lhs.type();
21870 const auto rhs_type = rhs.type();
21871
21872 if (lhs_type == rhs_type)
21873 {
21874 switch (lhs_type)
21875 {
21876 case value_t::array:
21877 return *lhs.m_value.array == *rhs.m_value.array;
21878
21879 case value_t::object:
21880 return *lhs.m_value.object == *rhs.m_value.object;
21881
21882 case value_t::null:
21883 return true;
21884
21885 case value_t::string:
21886 return *lhs.m_value.string == *rhs.m_value.string;
21887
21888 case value_t::boolean:
21889 return lhs.m_value.boolean == rhs.m_value.boolean;
21890
21891 case value_t::number_integer:
21892 return lhs.m_value.number_integer == rhs.m_value.number_integer;
21893
21894 case value_t::number_unsigned:
21895 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
21896
21897 case value_t::number_float:
21898 return lhs.m_value.number_float == rhs.m_value.number_float;
21899
21900 case value_t::binary:
21901 return *lhs.m_value.binary == *rhs.m_value.binary;
21902
21903 default:
21904 return false;
21905 }
21906 }
21907 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
21908 {
21909 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
21910 }
21911 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
21912 {
21913 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
21914 }
21915 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
21916 {
21917 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
21918 }
21919 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
21920 {
21921 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
21922 }
21923 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
21924 {
21925 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
21926 }
21927 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
21928 {
21929 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
21930 }
21931
21932 return false;
21933 }
21934
21939 template<typename ScalarType, typename std::enable_if<
21940 std::is_scalar<ScalarType>::value, int>::type = 0>
21941 friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
21942 {
21943 return lhs == basic_json(rhs);
21944 }
21945
21950 template<typename ScalarType, typename std::enable_if<
21951 std::is_scalar<ScalarType>::value, int>::type = 0>
21952 friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
21953 {
21954 return basic_json(lhs) == rhs;
21955 }
21956
21975 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
21976 {
21977 return not (lhs == rhs);
21978 }
21979
21984 template<typename ScalarType, typename std::enable_if<
21985 std::is_scalar<ScalarType>::value, int>::type = 0>
21986 friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
21987 {
21988 return lhs != basic_json(rhs);
21989 }
21990
21995 template<typename ScalarType, typename std::enable_if<
21996 std::is_scalar<ScalarType>::value, int>::type = 0>
21997 friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
21998 {
21999 return basic_json(lhs) != rhs;
22000 }
22001
22028 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
22029 {
22030 const auto lhs_type = lhs.type();
22031 const auto rhs_type = rhs.type();
22032
22033 if (lhs_type == rhs_type)
22034 {
22035 switch (lhs_type)
22036 {
22037 case value_t::array:
22038 // note parentheses are necessary, see
22039 // https://github.com/nlohmann/json/issues/1530
22040 return (*lhs.m_value.array) < (*rhs.m_value.array);
22041
22042 case value_t::object:
22043 return (*lhs.m_value.object) < (*rhs.m_value.object);
22044
22045 case value_t::null:
22046 return false;
22047
22048 case value_t::string:
22049 return (*lhs.m_value.string) < (*rhs.m_value.string);
22050
22051 case value_t::boolean:
22052 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
22053
22054 case value_t::number_integer:
22055 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
22056
22057 case value_t::number_unsigned:
22058 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
22059
22060 case value_t::number_float:
22061 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
22062
22063 case value_t::binary:
22064 return (*lhs.m_value.binary) < (*rhs.m_value.binary);
22065
22066 default:
22067 return false;
22068 }
22069 }
22070 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
22071 {
22072 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
22073 }
22074 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
22075 {
22076 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
22077 }
22078 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
22079 {
22080 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
22081 }
22082 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
22083 {
22084 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
22085 }
22086 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
22087 {
22088 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22089 }
22090 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
22091 {
22092 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
22093 }
22094
22095 // We only reach this line if we cannot compare values. In that case,
22096 // we compare types. Note we have to call the operator explicitly,
22097 // because MSVC has problems otherwise.
22098 return operator<(lhs_type, rhs_type);
22099 }
22100
22105 template<typename ScalarType, typename std::enable_if<
22106 std::is_scalar<ScalarType>::value, int>::type = 0>
22107 friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
22108 {
22109 return lhs < basic_json(rhs);
22110 }
22111
22116 template<typename ScalarType, typename std::enable_if<
22117 std::is_scalar<ScalarType>::value, int>::type = 0>
22118 friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
22119 {
22120 return basic_json(lhs) < rhs;
22121 }
22122
22142 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
22143 {
22144 return not (rhs < lhs);
22145 }
22146
22151 template<typename ScalarType, typename std::enable_if<
22152 std::is_scalar<ScalarType>::value, int>::type = 0>
22153 friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
22154 {
22155 return lhs <= basic_json(rhs);
22156 }
22157
22162 template<typename ScalarType, typename std::enable_if<
22163 std::is_scalar<ScalarType>::value, int>::type = 0>
22164 friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
22165 {
22166 return basic_json(lhs) <= rhs;
22167 }
22168
22188 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
22189 {
22190 return not (lhs <= rhs);
22191 }
22192
22197 template<typename ScalarType, typename std::enable_if<
22198 std::is_scalar<ScalarType>::value, int>::type = 0>
22199 friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
22200 {
22201 return lhs > basic_json(rhs);
22202 }
22203
22208 template<typename ScalarType, typename std::enable_if<
22209 std::is_scalar<ScalarType>::value, int>::type = 0>
22210 friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
22211 {
22212 return basic_json(lhs) > rhs;
22213 }
22214
22234 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
22235 {
22236 return not (lhs < rhs);
22237 }
22238
22243 template<typename ScalarType, typename std::enable_if<
22244 std::is_scalar<ScalarType>::value, int>::type = 0>
22245 friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
22246 {
22247 return lhs >= basic_json(rhs);
22248 }
22249
22254 template<typename ScalarType, typename std::enable_if<
22255 std::is_scalar<ScalarType>::value, int>::type = 0>
22256 friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
22257 {
22258 return basic_json(lhs) >= rhs;
22259 }
22260
22262
22264 // serialization //
22266
22269
22301 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
22302 {
22303 // read width member and use it as indentation parameter if nonzero
22304 const bool pretty_print = o.width() > 0;
22305 const auto indentation = pretty_print ? o.width() : 0;
22306
22307 // reset width to 0 for subsequent calls to this stream
22308 o.width(0);
22309
22310 // do the actual serialization
22311 serializer s(detail::output_adapter<char>(o), o.fill());
22312 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
22313 return o;
22314 }
22315
22324 JSON_HEDLEY_DEPRECATED(3.0.0)
22325 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
22326 {
22327 return o << j;
22328 }
22329
22331
22332
22334 // deserialization //
22336
22339
22403 template<typename InputType>
22404
22405 static basic_json parse(InputType&& i,
22406 const parser_callback_t cb = nullptr,
22407 const bool allow_exceptions = true)
22408 {
22409 basic_json result;
22410 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions).parse(true, result);
22411 return result;
22412 }
22413
22414
22415
22416
22417 static basic_json parse(detail::span_input_adapter&& i,
22418 const parser_callback_t cb = nullptr,
22419 const bool allow_exceptions = true)
22420 {
22421 basic_json result;
22422 parser(i.get(), cb, allow_exceptions).parse(true, result);
22423 return result;
22424 }
22425
22426 template<typename InputType>
22427 static bool accept(InputType&& i)
22428 {
22429 return parser(detail::input_adapter(std::forward<InputType>(i))).accept(true);
22430 }
22431
22432 static bool accept(detail::span_input_adapter&& i)
22433 {
22434 return parser(i.get()).accept(true);
22435 }
22489 template <typename SAX, typename InputType>
22490 JSON_HEDLEY_NON_NULL(2)
22491 static bool sax_parse(InputType&& i, SAX* sax,
22492 input_format_t format = input_format_t::json,
22493 const bool strict = true)
22494 {
22495 auto ia = detail::input_adapter(std::forward<InputType>(i));
22496 return format == input_format_t::json
22497 ? parser(std::move(ia)).sax_parse(sax, strict)
22498 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
22499 }
22500
22501 template <typename SAX>
22502 JSON_HEDLEY_NON_NULL(2)
22503 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
22504 input_format_t format = input_format_t::json,
22505 const bool strict = true)
22506 {
22507 auto ia = i.get();
22508 return format == input_format_t::json
22509 ? parser(std::move(ia)).sax_parse(sax, strict)
22510 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
22511 }
22512
22513
22563 template<class IteratorType, typename std::enable_if<
22564 std::is_base_of<
22565 std::random_access_iterator_tag,
22566 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
22567 static basic_json parse(IteratorType first, IteratorType last,
22568 const parser_callback_t cb = nullptr,
22569 const bool allow_exceptions = true)
22570 {
22571 basic_json result;
22572 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
22573 return result;
22574 }
22575
22576 template<class IteratorType, typename std::enable_if<
22577 std::is_base_of<
22578 std::random_access_iterator_tag,
22579 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
22580 static bool accept(IteratorType first, IteratorType last)
22581 {
22582 return parser(detail::input_adapter(first, last)).accept(true);
22583 }
22584
22585 template<class IteratorType, class SAX, typename std::enable_if<
22586 std::is_base_of<
22587 std::random_access_iterator_tag,
22588 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
22589 JSON_HEDLEY_NON_NULL(3)
22590 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
22591 {
22592 return parser(detail::input_adapter(first, last)).sax_parse(sax);
22593 }
22594
22603 JSON_HEDLEY_DEPRECATED(3.0.0)
22604 friend std::istream& operator<<(basic_json& j, std::istream& i)
22605 {
22606 return operator>>(i, j);
22607 }
22608
22634 friend std::istream& operator>>(std::istream& i, basic_json& j)
22635 {
22636 parser(detail::input_adapter(i)).parse(false, j);
22637 return i;
22638 }
22639
22641
22643 // convenience functions //
22645
22677
22678 const char* type_name() const noexcept
22679 {
22680 {
22681 switch (m_type)
22682 {
22683 case value_t::null:
22684 return "null";
22685 case value_t::object:
22686 return "object";
22687 case value_t::array:
22688 return "array";
22689 case value_t::string:
22690 return "string";
22691 case value_t::boolean:
22692 return "boolean";
22693 case value_t::binary:
22694 return "binary";
22695 case value_t::discarded:
22696 return "discarded";
22697 default:
22698 return "number";
22699 }
22700 }
22701 }
22702
22703
22704 private:
22706 // member variables //
22708
22710 value_t m_type = value_t::null;
22711
22713 json_value m_value = {};
22714
22716 // binary serialization/deserialization //
22718
22721
22722 public:
22818 static std::vector<uint8_t> to_cbor(const basic_json& j)
22819 {
22820 std::vector<uint8_t> result;
22821 to_cbor(j, result);
22822 return result;
22823 }
22824
22825 static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
22826 {
22827 binary_writer<uint8_t>(o).write_cbor(j);
22828 }
22829
22830 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
22831 {
22832 binary_writer<char>(o).write_cbor(j);
22833 }
22834
22915 static std::vector<uint8_t> to_msgpack(const basic_json& j)
22916 {
22917 std::vector<uint8_t> result;
22918 to_msgpack(j, result);
22919 return result;
22920 }
22921
22922 static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
22923 {
22924 binary_writer<uint8_t>(o).write_msgpack(j);
22925 }
22926
22927 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
22928 {
22929 binary_writer<char>(o).write_msgpack(j);
22930 }
22931
23018 static std::vector<uint8_t> to_ubjson(const basic_json& j,
23019 const bool use_size = false,
23020 const bool use_type = false)
23021 {
23022 std::vector<uint8_t> result;
23023 to_ubjson(j, result, use_size, use_type);
23024 return result;
23025 }
23026
23027 static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
23028 const bool use_size = false, const bool use_type = false)
23029 {
23030 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
23031 }
23032
23033 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
23034 const bool use_size = false, const bool use_type = false)
23035 {
23036 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23037 }
23038
23039
23096 static std::vector<uint8_t> to_bson(const basic_json& j)
23097 {
23098 std::vector<uint8_t> result;
23099 to_bson(j, result);
23100 return result;
23101 }
23102
23111 static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
23112 {
23113 binary_writer<uint8_t>(o).write_bson(j);
23114 }
23115
23119 static void to_bson(const basic_json& j, detail::output_adapter<char> o)
23120 {
23121 binary_writer<char>(o).write_bson(j);
23122 }
23123
23124
23227 template<typename InputType>
23228
23229 static basic_json from_cbor(InputType&& i,
23230 const bool strict = true,
23231 const bool allow_exceptions = true)
23232 {
23233 basic_json result;
23234 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23235 auto ia = detail::input_adapter(std::forward<InputType>(i));
23236 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict);
23237 return res ? result : basic_json(value_t::discarded);
23238 }
23239
23243 template<typename A1, typename A2,
23244 detail::enable_if_t<std::is_constructible<detail::span_input_adapter, A1, A2>::value, int> = 0>
23245
23246 static basic_json from_cbor(A1 && a1, A2 && a2,
23247 const bool strict = true,
23248 const bool allow_exceptions = true)
23249 {
23250 basic_json result;
23251 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23252 const bool res = binary_reader<detail::input_buffer_adapter>(detail::span_input_adapter(std::forward<A1>(a1), std::forward<A2>(a2)).get()).sax_parse(input_format_t::cbor, &sdp, strict);
23253 return res ? result : basic_json(value_t::discarded);
23254 }
23255
23256
23257 static basic_json from_cbor(detail::span_input_adapter&& i,
23258 const bool strict = true,
23259 const bool allow_exceptions = true)
23260 {
23261 basic_json result;
23262 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23263 const bool res = binary_reader<detail::input_buffer_adapter>(i.get()).sax_parse(input_format_t::cbor, &sdp, strict);
23264 return res ? result : basic_json(value_t::discarded);
23265 }
23266
23353 template<typename InputType>
23354
23355 static basic_json from_msgpack(InputType&& i,
23356 const bool strict = true,
23357 const bool allow_exceptions = true)
23358 {
23359 basic_json result;
23360 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23361 auto ia = detail::input_adapter(std::forward<InputType>(i));
23362 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
23363 return res ? result : basic_json(value_t::discarded);
23364 }
23365
23369 template<typename A1, typename A2,
23370 detail::enable_if_t<std::is_constructible<detail::span_input_adapter, A1, A2>::value, int> = 0>
23371
23372 static basic_json from_msgpack(A1 && a1, A2 && a2,
23373 const bool strict = true,
23374 const bool allow_exceptions = true)
23375 {
23376 basic_json result;
23377 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23378 const bool res = binary_reader<detail::input_buffer_adapter>(detail::span_input_adapter(std::forward<A1>(a1), std::forward<A2>(a2)).get()).sax_parse(input_format_t::msgpack, &sdp, strict);
23379 return res ? result : basic_json(value_t::discarded);
23380 }
23381
23382
23383
23384 static basic_json from_msgpack(detail::span_input_adapter&& i,
23385 const bool strict = true,
23386 const bool allow_exceptions = true)
23387 {
23388 basic_json result;
23389 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23390 const bool res = binary_reader<detail::input_buffer_adapter>(i.get()).sax_parse(input_format_t::msgpack, &sdp, strict);
23391 return res ? result : basic_json(value_t::discarded);
23392 }
23393
23394
23456 template<typename InputType>
23457
23458 static basic_json from_ubjson(InputType&& i,
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::forward<InputType>(i));
23465 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
23466 return res ? result : basic_json(value_t::discarded);
23467 }
23468
23472 template<typename A1, typename A2,
23473 detail::enable_if_t<std::is_constructible<detail::span_input_adapter, A1, A2>::value, int> = 0>
23474
23475 static basic_json from_ubjson(A1 && a1, A2 && a2,
23476 const bool strict = true,
23477 const bool allow_exceptions = true)
23478 {
23479 basic_json result;
23480 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23481 const bool res = binary_reader<detail::input_buffer_adapter>(detail::span_input_adapter(std::forward<A1>(a1), std::forward<A2>(a2)).get()).sax_parse(input_format_t::ubjson, &sdp, strict);
23482 return res ? result : basic_json(value_t::discarded);
23483 }
23484
23485
23486 static basic_json from_ubjson(detail::span_input_adapter&& i,
23487 const bool strict = true,
23488 const bool allow_exceptions = true)
23489 {
23490 basic_json result;
23491 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23492 const bool res = binary_reader<detail::input_buffer_adapter>(i.get()).sax_parse(input_format_t::ubjson, &sdp, strict);
23493 return res ? result : basic_json(value_t::discarded);
23494 }
23495
23496
23557 template<typename InputType>
23558
23559 static basic_json from_bson(InputType&& i,
23560 const bool strict = true,
23561 const bool allow_exceptions = true)
23562 {
23563 basic_json result;
23564 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23565 auto ia = detail::input_adapter(std::forward<InputType>(i));
23566 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
23567 return res ? result : basic_json(value_t::discarded);
23568 }
23569
23573 template<typename A1, typename A2,
23574 detail::enable_if_t<std::is_constructible<detail::span_input_adapter, A1, A2>::value, int> = 0>
23575
23576 static basic_json from_bson(A1 && a1, A2 && a2,
23577 const bool strict = true,
23578 const bool allow_exceptions = true)
23579 {
23580 basic_json result;
23581 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23582 const bool res = binary_reader<detail::input_buffer_adapter>(detail::span_input_adapter(std::forward<A1>(a1), std::forward<A2>(a2)).get()).sax_parse(input_format_t::bson, &sdp, strict);
23583 return res ? result : basic_json(value_t::discarded);
23584 }
23585
23586
23587 static basic_json from_bson(detail::span_input_adapter&& i,
23588 const bool strict = true,
23589 const bool allow_exceptions = true)
23590 {
23591 basic_json result;
23592 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23593 const bool res = binary_reader<detail::input_buffer_adapter>(i.get()).sax_parse(input_format_t::bson, &sdp, strict);
23594 return res ? result : basic_json(value_t::discarded);
23595 }
23597
23599 // JSON Pointer support //
23601
23604
23638 reference operator[](const json_pointer& ptr)
23639 {
23640 return ptr.get_unchecked(this);
23641 }
23642
23666 const_reference operator[](const json_pointer& ptr) const
23667 {
23668 return ptr.get_unchecked(this);
23669 }
23670
23709 reference at(const json_pointer& ptr)
23710 {
23711 return ptr.get_checked(this);
23712 }
23713
23752 const_reference at(const json_pointer& ptr) const
23753 {
23754 return ptr.get_checked(this);
23755 }
23756
23779 basic_json flatten() const
23780 {
23781 basic_json result(value_t::object);
23782 json_pointer::flatten("", *this, result);
23783 return result;
23784 }
23785
23816 basic_json unflatten() const
23817 {
23818 return json_pointer::unflatten(*this);
23819 }
23820
23822
23824 // JSON Patch functions //
23826
23829
23877 basic_json patch(const basic_json& json_patch) const
23878 {
23879 // make a working copy to apply the patch to
23880 basic_json result = *this;
23881
23882 // the valid JSON Patch operations
23883 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
23884
23885 const auto get_op = [](const std::string & op)
23886 {
23887 if (op == "add")
23888 {
23889 return patch_operations::add;
23890 }
23891 if (op == "remove")
23892 {
23893 return patch_operations::remove;
23894 }
23895 if (op == "replace")
23896 {
23897 return patch_operations::replace;
23898 }
23899 if (op == "move")
23900 {
23901 return patch_operations::move;
23902 }
23903 if (op == "copy")
23904 {
23905 return patch_operations::copy;
23906 }
23907 if (op == "test")
23908 {
23909 return patch_operations::test;
23910 }
23911
23912 return patch_operations::invalid;
23913 };
23914
23915 // wrapper for "add" operation; add value at ptr
23916 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
23917 {
23918 // adding to the root of the target document means replacing it
23919 if (ptr.empty())
23920 {
23921 result = val;
23922 return;
23923 }
23924
23925 // make sure the top element of the pointer exists
23926 json_pointer top_pointer = ptr.top();
23927 if (top_pointer != ptr)
23928 {
23929 result.at(top_pointer);
23930 }
23931
23932 // get reference to parent of JSON pointer ptr
23933 const auto last_path = ptr.back();
23934 ptr.pop_back();
23935 basic_json& parent = result[ptr];
23936
23937 switch (parent.m_type)
23938 {
23939 case value_t::null:
23940 case value_t::object:
23941 {
23942 // use operator[] to add value
23943 parent[last_path] = val;
23944 break;
23945 }
23946
23947 case value_t::array:
23948 {
23949 if (last_path == "-")
23950 {
23951 // special case: append to back
23952 parent.push_back(val);
23953 }
23954 else
23955 {
23956 const auto idx = json_pointer::array_index(last_path);
23957 if (JSON_HEDLEY_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
23958 {
23959 // avoid undefined behavior
23960 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
23961 }
23962
23963 // default case: insert add offset
23964 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
23965 }
23966 break;
23967 }
23968
23969 // if there exists a parent it cannot be primitive
23970 default: // LCOV_EXCL_LINE
23971 assert(false); // LCOV_EXCL_LINE
23972 }
23973 };
23974
23975 // wrapper for "remove" operation; remove value at ptr
23976 const auto operation_remove = [&result](json_pointer & ptr)
23977 {
23978 // get reference to parent of JSON pointer ptr
23979 const auto last_path = ptr.back();
23980 ptr.pop_back();
23981 basic_json& parent = result.at(ptr);
23982
23983 // remove child
23984 if (parent.is_object())
23985 {
23986 // perform range check
23987 auto it = parent.find(last_path);
23988 if (JSON_HEDLEY_LIKELY(it != parent.end()))
23989 {
23990 parent.erase(it);
23991 }
23992 else
23993 {
23994 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
23995 }
23996 }
23997 else if (parent.is_array())
23998 {
23999 // note erase performs range check
24000 parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
24001 }
24002 };
24003
24004 // type check: top level value must be an array
24005 if (JSON_HEDLEY_UNLIKELY(not json_patch.is_array()))
24006 {
24007 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24008 }
24009
24010 // iterate and apply the operations
24011 for (const auto& val : json_patch)
24012 {
24013 // wrapper to get a value for an operation
24014 const auto get_value = [&val](const std::string & op,
24015 const std::string & member,
24016 bool string_type) -> basic_json &
24017 {
24018 // find value
24019 auto it = val.m_value.object->find(member);
24020
24021 // context-sensitive error message
24022 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
24023
24024 // check if desired value is present
24025 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
24026 {
24027 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
24028 }
24029
24030 // check if result is of type string
24031 if (JSON_HEDLEY_UNLIKELY(string_type and not it->second.is_string()))
24032 {
24033 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
24034 }
24035
24036 // no error: return value
24037 return it->second;
24038 };
24039
24040 // type check: every element of the array must be an object
24041 if (JSON_HEDLEY_UNLIKELY(not val.is_object()))
24042 {
24043 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24044 }
24045
24046 // collect mandatory members
24047 const std::string op = get_value("op", "op", true);
24048 const std::string path = get_value(op, "path", true);
24049 json_pointer ptr(path);
24050
24051 switch (get_op(op))
24052 {
24053 case patch_operations::add:
24054 {
24055 operation_add(ptr, get_value("add", "value", false));
24056 break;
24057 }
24058
24059 case patch_operations::remove:
24060 {
24061 operation_remove(ptr);
24062 break;
24063 }
24064
24065 case patch_operations::replace:
24066 {
24067 // the "path" location must exist - use at()
24068 result.at(ptr) = get_value("replace", "value", false);
24069 break;
24070 }
24071
24072 case patch_operations::move:
24073 {
24074 const std::string from_path = get_value("move", "from", true);
24075 json_pointer from_ptr(from_path);
24076
24077 // the "from" location must exist - use at()
24078 basic_json v = result.at(from_ptr);
24079
24080 // The move operation is functionally identical to a
24081 // "remove" operation on the "from" location, followed
24082 // immediately by an "add" operation at the target
24083 // location with the value that was just removed.
24084 operation_remove(from_ptr);
24085 operation_add(ptr, v);
24086 break;
24087 }
24088
24089 case patch_operations::copy:
24090 {
24091 const std::string from_path = get_value("copy", "from", true);
24092 const json_pointer from_ptr(from_path);
24093
24094 // the "from" location must exist - use at()
24095 basic_json v = result.at(from_ptr);
24096
24097 // The copy is functionally identical to an "add"
24098 // operation at the target location using the value
24099 // specified in the "from" member.
24100 operation_add(ptr, v);
24101 break;
24102 }
24103
24104 case patch_operations::test:
24105 {
24106 bool success = false;
24107 JSON_TRY
24108 {
24109 // check if "value" matches the one at "path"
24110 // the "path" location must exist - use at()
24111 success = (result.at(ptr) == get_value("test", "value", false));
24112 }
24113 JSON_INTERNAL_CATCH (out_of_range&)
24114 {
24115 // ignore out of range errors: success remains false
24116 }
24117
24118 // throw an exception if test fails
24119 if (JSON_HEDLEY_UNLIKELY(not success))
24120 {
24121 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
24122 }
24123
24124 break;
24125 }
24126
24127 default:
24128 {
24129 // op must be "add", "remove", "replace", "move", "copy", or
24130 // "test"
24131 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
24132 }
24133 }
24134 }
24135
24136 return result;
24137 }
24138
24172
24173 static basic_json diff(const basic_json& source, const basic_json& target,
24174 const std::string& path = "")
24175 {
24176 // the patch
24177 basic_json result(value_t::array);
24178
24179 // if the values are the same, return empty patch
24180 if (source == target)
24181 {
24182 return result;
24183 }
24184
24185 if (source.type() != target.type())
24186 {
24187 // different types: replace value
24188 result.push_back(
24189 {
24190 {"op", "replace"}, {"path", path}, {"value", target}
24191 });
24192 return result;
24193 }
24194
24195 switch (source.type())
24196 {
24197 case value_t::array:
24198 {
24199 // first pass: traverse common elements
24200 std::size_t i = 0;
24201 while (i < source.size() and i < target.size())
24202 {
24203 // recursive call to compare array values at index i
24204 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
24205 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24206 ++i;
24207 }
24208
24209 // i now reached the end of at least one array
24210 // in a second pass, traverse the remaining elements
24211
24212 // remove my remaining elements
24213 const auto end_index = static_cast<difference_type>(result.size());
24214 while (i < source.size())
24215 {
24216 // add operations in reverse order to avoid invalid
24217 // indices
24218 result.insert(result.begin() + end_index, object(
24219 {
24220 {"op", "remove"},
24221 {"path", path + "/" + std::to_string(i)}
24222 }));
24223 ++i;
24224 }
24225
24226 // add other remaining elements
24227 while (i < target.size())
24228 {
24229 result.push_back(
24230 {
24231 {"op", "add"},
24232 {"path", path + "/-"},
24233 {"value", target[i]}
24234 });
24235 ++i;
24236 }
24237
24238 break;
24239 }
24240
24241 case value_t::object:
24242 {
24243 // first pass: traverse this object's elements
24244 for (auto it = source.cbegin(); it != source.cend(); ++it)
24245 {
24246 // escape the key name to be used in a JSON patch
24247 const auto key = json_pointer::escape(it.key());
24248
24249 if (target.find(it.key()) != target.end())
24250 {
24251 // recursive call to compare object values at key it
24252 auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
24253 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24254 }
24255 else
24256 {
24257 // found a key that is not in o -> remove it
24258 result.push_back(object(
24259 {
24260 {"op", "remove"}, {"path", path + "/" + key}
24261 }));
24262 }
24263 }
24264
24265 // second pass: traverse other object's elements
24266 for (auto it = target.cbegin(); it != target.cend(); ++it)
24267 {
24268 if (source.find(it.key()) == source.end())
24269 {
24270 // found a key that is not in this -> add it
24271 const auto key = json_pointer::escape(it.key());
24272 result.push_back(
24273 {
24274 {"op", "add"}, {"path", path + "/" + key},
24275 {"value", it.value()}
24276 });
24277 }
24278 }
24279
24280 break;
24281 }
24282
24283 default:
24284 {
24285 // both primitive type: replace value
24286 result.push_back(
24287 {
24288 {"op", "replace"}, {"path", path}, {"value", target}
24289 });
24290 break;
24291 }
24292 }
24293
24294 return result;
24295 }
24296
24298
24300 // JSON Merge Patch functions //
24302
24305
24348 void merge_patch(const basic_json& apply_patch)
24349 {
24350 if (apply_patch.is_object())
24351 {
24352 if (not is_object())
24353 {
24354 *this = object();
24355 }
24356 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
24357 {
24358 if (it.value().is_null())
24359 {
24360 erase(it.key());
24361 }
24362 else
24363 {
24364 operator[](it.key()).merge_patch(it.value());
24365 }
24366 }
24367 }
24368 else
24369 {
24370 *this = apply_patch;
24371 }
24372 }
24373
24375 };
24376
24386 NLOHMANN_BASIC_JSON_TPL_DECLARATION
24387 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
24388 {
24389 return j.dump();
24390 }
24391 } // namespace nlohmann
24392
24394 // nonmember support //
24396
24397 // specialization of std::swap, and std::hash
24398 namespace std
24399 {
24400
24402 template<>
24403 struct hash<nlohmann::json>
24404 {
24410 std::size_t operator()(const nlohmann::json& j) const
24411 {
24412 // a naive hashing via the string representation
24413 const auto& h = hash<nlohmann::json::string_t>();
24414 return h(j.dump());
24415 }
24416 };
24417
24421 template<>
24422 struct less<::nlohmann::detail::value_t>
24423 {
24428 bool operator()(nlohmann::detail::value_t lhs,
24429 nlohmann::detail::value_t rhs) const noexcept
24430 {
24431 return nlohmann::detail::operator<(lhs, rhs);
24432 }
24433 };
24434
24440 template<>
24441 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
24442 is_nothrow_move_constructible<nlohmann::json>::value and
24443 is_nothrow_move_assignable<nlohmann::json>::value
24444 )
24445 {
24446 j1.swap(j2);
24447 }
24448
24449 } // namespace std
24450
24464 JSON_HEDLEY_NON_NULL(1)
24465 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
24466 {
24467 return nlohmann::json::parse(s, s + n);
24468 }
24469
24483 JSON_HEDLEY_NON_NULL(1)
24484 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
24485 {
24486 return nlohmann::json::json_pointer(std::string(s, n));
24487 }
24488
24489 // #include <nlohmann/detail/macro_unscope.hpp>
24490
24491
24492 // restore GCC/clang diagnostic settings
24493 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
24494 #pragma GCC diagnostic pop
24495 #endif
24496 #if defined(__clang__)
24497 #pragma GCC diagnostic pop
24498 #endif
24499
24500 // clean up
24501 #undef JSON_INTERNAL_CATCH
24502 #undef JSON_CATCH
24503 #undef JSON_THROW
24504 #undef JSON_TRY
24505 #undef JSON_HAS_CPP_14
24506 #undef JSON_HAS_CPP_17
24507 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
24508 #undef NLOHMANN_BASIC_JSON_TPL
24509
24510 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
24511 #undef JSON_HEDLEY_ALWAYS_INLINE
24512 #undef JSON_HEDLEY_ARM_VERSION
24513 #undef JSON_HEDLEY_ARM_VERSION_CHECK
24514 #undef JSON_HEDLEY_ARRAY_PARAM
24515 #undef JSON_HEDLEY_ASSUME
24516 #undef JSON_HEDLEY_BEGIN_C_DECLS
24517 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
24518 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
24519 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
24520 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
24521 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
24522 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
24523 #undef JSON_HEDLEY_CLANG_HAS_WARNING
24524 #undef JSON_HEDLEY_COMPCERT_VERSION
24525 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
24526 #undef JSON_HEDLEY_CONCAT
24527 #undef JSON_HEDLEY_CONCAT3
24528 #undef JSON_HEDLEY_CONCAT3_EX
24529 #undef JSON_HEDLEY_CONCAT_EX
24530 #undef JSON_HEDLEY_CONST
24531 #undef JSON_HEDLEY_CONSTEXPR
24532 #undef JSON_HEDLEY_CONST_CAST
24533 #undef JSON_HEDLEY_CPP_CAST
24534 #undef JSON_HEDLEY_CRAY_VERSION
24535 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
24536 #undef JSON_HEDLEY_C_DECL
24537 #undef JSON_HEDLEY_DEPRECATED
24538 #undef JSON_HEDLEY_DEPRECATED_FOR
24539 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
24540 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
24541 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
24542 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
24543 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
24544 #undef JSON_HEDLEY_DIAGNOSTIC_POP
24545 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
24546 #undef JSON_HEDLEY_DMC_VERSION
24547 #undef JSON_HEDLEY_DMC_VERSION_CHECK
24548 #undef JSON_HEDLEY_EMPTY_BASES
24549 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
24550 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
24551 #undef JSON_HEDLEY_END_C_DECLS
24552 #undef JSON_HEDLEY_FLAGS
24553 #undef JSON_HEDLEY_FLAGS_CAST
24554 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
24555 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
24556 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
24557 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
24558 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
24559 #undef JSON_HEDLEY_GCC_HAS_FEATURE
24560 #undef JSON_HEDLEY_GCC_HAS_WARNING
24561 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
24562 #undef JSON_HEDLEY_GCC_VERSION
24563 #undef JSON_HEDLEY_GCC_VERSION_CHECK
24564 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
24565 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
24566 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
24567 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
24568 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
24569 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
24570 #undef JSON_HEDLEY_GNUC_HAS_WARNING
24571 #undef JSON_HEDLEY_GNUC_VERSION
24572 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
24573 #undef JSON_HEDLEY_HAS_ATTRIBUTE
24574 #undef JSON_HEDLEY_HAS_BUILTIN
24575 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
24576 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
24577 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
24578 #undef JSON_HEDLEY_HAS_EXTENSION
24579 #undef JSON_HEDLEY_HAS_FEATURE
24580 #undef JSON_HEDLEY_HAS_WARNING
24581 #undef JSON_HEDLEY_IAR_VERSION
24582 #undef JSON_HEDLEY_IAR_VERSION_CHECK
24583 #undef JSON_HEDLEY_IBM_VERSION
24584 #undef JSON_HEDLEY_IBM_VERSION_CHECK
24585 #undef JSON_HEDLEY_IMPORT
24586 #undef JSON_HEDLEY_INLINE
24587 #undef JSON_HEDLEY_INTEL_VERSION
24588 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
24589 #undef JSON_HEDLEY_IS_CONSTANT
24590 #undef JSON_HEDLEY_IS_CONSTEXPR_
24591 #undef JSON_HEDLEY_LIKELY
24592 #undef JSON_HEDLEY_MALLOC
24593 #undef JSON_HEDLEY_MESSAGE
24594 #undef JSON_HEDLEY_MSVC_VERSION
24595 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
24596 #undef JSON_HEDLEY_NEVER_INLINE
24597 #undef JSON_HEDLEY_NON_NULL
24598 #undef JSON_HEDLEY_NO_ESCAPE
24599 #undef JSON_HEDLEY_NO_RETURN
24600 #undef JSON_HEDLEY_NO_THROW
24601 #undef JSON_HEDLEY_NULL
24602 #undef JSON_HEDLEY_PELLES_VERSION
24603 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
24604 #undef JSON_HEDLEY_PGI_VERSION
24605 #undef JSON_HEDLEY_PGI_VERSION_CHECK
24606 #undef JSON_HEDLEY_PREDICT
24607 #undef JSON_HEDLEY_PRINTF_FORMAT
24608 #undef JSON_HEDLEY_PRIVATE
24609 #undef JSON_HEDLEY_PUBLIC
24610 #undef JSON_HEDLEY_PURE
24611 #undef JSON_HEDLEY_REINTERPRET_CAST
24612 #undef JSON_HEDLEY_REQUIRE
24613 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
24614 #undef JSON_HEDLEY_REQUIRE_MSG
24615 #undef JSON_HEDLEY_RESTRICT
24616 #undef
24617 #undef JSON_HEDLEY_SENTINEL
24618 #undef JSON_HEDLEY_STATIC_ASSERT
24619 #undef JSON_HEDLEY_STATIC_CAST
24620 #undef JSON_HEDLEY_STRINGIFY
24621 #undef JSON_HEDLEY_STRINGIFY_EX
24622 #undef JSON_HEDLEY_SUNPRO_VERSION
24623 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
24624 #undef JSON_HEDLEY_TINYC_VERSION
24625 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
24626 #undef JSON_HEDLEY_TI_ARMCL_VERSION
24627 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
24628 #undef JSON_HEDLEY_TI_CL2000_VERSION
24629 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
24630 #undef JSON_HEDLEY_TI_CL430_VERSION
24631 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
24632 #undef JSON_HEDLEY_TI_CL6X_VERSION
24633 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
24634 #undef JSON_HEDLEY_TI_CL7X_VERSION
24635 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
24636 #undef JSON_HEDLEY_TI_CLPRU_VERSION
24637 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
24638 #undef JSON_HEDLEY_TI_VERSION
24639 #undef JSON_HEDLEY_TI_VERSION_CHECK
24640 #undef JSON_HEDLEY_UNAVAILABLE
24641 #undef JSON_HEDLEY_UNLIKELY
24642 #undef JSON_HEDLEY_UNPREDICTABLE
24643 #undef JSON_HEDLEY_UNREACHABLE
24644 #undef JSON_HEDLEY_UNREACHABLE_RETURN
24645 #undef JSON_HEDLEY_VERSION
24646 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
24647 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
24648 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
24649 #undef JSON_HEDLEY_VERSION_ENCODE
24650 #undef JSON_HEDLEY_WARNING
24651 #undef
24652 #undef _MSG
24653 #undef JSON_HEDLEY_FALL_THROUGH
24654
24655
24656
24657 #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:22925
nlohmann::basic_json::erase
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:19811
nlohmann::basic_json::value_t
detail::value_t value_t
Definition: json.hpp:16016
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:20261
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:18058
nlohmann::basic_json::contains
bool contains(KeyT &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:20191
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:17641
nlohmann::basic_json::const_iterator
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.hpp:16087
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:23365
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:18759
nlohmann::basic_json::meta
static basic_json meta()
returns version information on the library
Definition: json.hpp:16131
nlohmann::basic_json::number_unsigned_t
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:16559
nlohmann::basic_json::unflatten
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:23826
nlohmann::basic_json::operator>>
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:22335
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:16049
nlohmann::basic_json::number_integer_t
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:16488
nlohmann::basic_json::allocator_type
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:16077
nlohmann::basic_json::object
static basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:17614
nlohmann::basic_json::array_t
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:16337
nlohmann::basic_json::basic_json
basic_json(const JsonRef &ref)
Definition: json.hpp:17809
nlohmann::basic_json::operator>
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:22198
nlohmann::basic_json::size
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:20789
nlohmann::basic_json::basic_json
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:17264
nlohmann::json_sax::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:4935
nlohmann::basic_json::invalid_iterator
detail::invalid_iterator invalid_iterator
exception indicating errors with iterators
Definition: json.hpp:16043
nlohmann::json_pointer::back
const std::string & back() const
return last reference token
Definition: json.hpp:11313
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:11107
nlohmann::basic_json::operator==
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:21877
nlohmann::basic_json::difference_type
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:16072
nlohmann::basic_json::at
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:19080
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:18805
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:16291
nlohmann::basic_json::type_name
const char * type_name() const noexcept
return the type as string
Definition: json.hpp:22688
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:23028
nlohmann::basic_json::input_format_t
detail::input_format_t input_format_t
Definition: json.hpp:16026
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:22415
nlohmann::basic_json::is_primitive
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:18142
nlohmann::basic_json::rend
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:20439
nlohmann::basic_json::crbegin
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:20476
nlohmann::basic_json::accept
static bool accept(InputType &&i)
Definition: json.hpp:22437
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:20107
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:17836
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:19574
nlohmann::basic_json::get_allocator
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:16099
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:18272
nlohmann::json_pointer
JSON Pointer.
Definition: json.hpp:11062
nlohmann::basic_json::size_type
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:16074
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:22501
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:21985
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:17387
nlohmann::json_pointer::empty
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:11360
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:18914
nlohmann::basic_json::type_error
detail::type_error type_error
exception indicating executing a member function with a wrong type
Definition: json.hpp:16045
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:21654
nlohmann::basic_json::is_boolean
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:18213
nlohmann::basic_json::object_comparator_t
std::less< StringType > object_comparator_t
Definition: json.hpp:16201
nlohmann::basic_json::crend
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:20505
nlohmann::basic_json::rbegin
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:20402
nlohmann::basic_json::is_discarded
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:18443
nlohmann::basic_json::get_binary
binary_t & get_binary()
Definition: json.hpp:19022
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:17524
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:11988
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:16024
nlohmann::basic_json::is_number_float
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:18328
nlohmann::basic_json::boolean_t
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:16416
nlohmann::basic_json::external_constructor
friend struct detail::external_constructor
Definition: json.hpp:15964
nlohmann::basic_json::binary_t
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:16698
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:23569
nlohmann::basic_json::back
reference back()
access the last element
Definition: json.hpp:19744
nlohmann::basic_json::const_reference
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:16069
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:24397
nlohmann::basic_json::cbegin
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:20301
nlohmann::basic_json::array
static basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:17570
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:21249
nlohmann::basic_json::json_pointer
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:16018
nlohmann::basic_json::get
BasicJsonType get() const
get special-case overload
Definition: json.hpp:18658
nlohmann::basic_json::operator>=
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:22244
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:4931
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:16089
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:20158
nlohmann::basic_json::parser_callback_t
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:17089
nlohmann::basic_json::is_null
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:18191
nlohmann::basic_json::operator<=
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:22152
nlohmann::basic_json::cend
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:20372
nlohmann::basic_json::flatten
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:23789
nlohmann::basic_json::empty
bool empty() const noexcept
checks whether the container is empty.
Definition: json.hpp:20716
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:24183
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:11205
nlohmann::basic_json::basic_json
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:17154
nlohmann::basic_json::operator+=
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:21033
nlohmann::basic_json::get_ref
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:18961
nlohmann::json_sax::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:4933
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:16082
nlohmann::basic_json::is_string
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:18394
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:18902
nlohmann::basic_json::is_array
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:18372
nlohmann::basic_json::operator<<
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:22311
nlohmann::json_sax::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:4932
nlohmann::basic_json::out_of_range
detail::out_of_range out_of_range
exception indicating access out of the defined range
Definition: json.hpp:16047
nlohmann::basic_json::front
reference front()
access the first element
Definition: json.hpp:19700
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:16080
nlohmann::basic_json::string_t
StringType string_t
a type for a string
Definition: json.hpp:16390
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:18111
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:17467
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:21317
nlohmann::basic_json::get_ref
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:18948
nlohmann::basic_json::is_number
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:18243
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:11335
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:11185
nlohmann::basic_json::clear
void clear() noexcept
clears the contents
Definition: json.hpp:20931
nlohmann::basic_json::basic_json
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:17706
nlohmann::basic_json::number_float_t
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:16627
nlohmann::basic_json::items
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:20651
nlohmann::basic_json::is_structured
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:18169
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:11139
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:11341
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:23106
nlohmann::basic_json::update
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:21552
nlohmann::basic_json::basic_json
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:17925
nlohmann::json_sax::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:4934
nlohmann::basic_json
a class to store JSON values
Definition: json.hpp:15962
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:19285
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:17227
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:11246
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:12005
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:21008
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:18708
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:20332
nlohmann::basic_json::merge_patch
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:24358
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:18854
nlohmann::basic_json::parse_error
detail::parse_error parse_error
exception indicating a parse error
Definition: json.hpp:16041
nlohmann::basic_json::insert_iterator
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.hpp:21279
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:18867
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:16039
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:18817
nlohmann::json_pointer::json_pointer
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.hpp:11089
nlohmann::json_pointer::pop_back
void pop_back()
remove last reference token
Definition: json.hpp:11289
nlohmann::basic_json::reference
value_type & reference
the type of an element reference
Definition: json.hpp:16067
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:17962
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:11163
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:20569
nlohmann::basic_json::json_serializer
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:16020
nlohmann::basic_json::iterator
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.hpp:16085
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:16091
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:23239
nlohmann::json_pointer::parent_pointer
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:11264
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:11226
nlohmann::basic_json::max_size
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:20860
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:17504
nlohmann::json
basic_json<> json
default JSON class
Definition: json.hpp:2774
nlohmann::json_sax
SAX interface.
Definition: json.hpp:4930
nlohmann::basic_json::is_number_unsigned
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:18300
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:18635
nlohmann::basic_json::push_back
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:21148
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:23468
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:22038
nlohmann::basic_json::get_binary
const binary_t & get_binary() const
Definition: json.hpp:19033
nlohmann::basic_json::basic_json
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:17130
nlohmann::basic_json::emplace_back
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:21196
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:22828
nlohmann::basic_json::is_binary
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:18416
nlohmann::basic_json::~basic_json
~basic_json() noexcept
destructor
Definition: json.hpp:17995
nlohmann::basic_json::binary
static basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array (without subtype)
Definition: json.hpp:17514
nlohmann::basic_json::patch
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:23887
nlohmann::basic_json::is_object
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:18350
nlohmann::byte_container_with_subtype::container_type
BinaryType container_type
the type of the underlying container
Definition: json.hpp:4254