JSON for Modern C++ 3.9.1

json.hpp
1 /*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.9.1
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 9
35 #define NLOHMANN_JSON_VERSION_PATCH 1
36
37 #include <algorithm> // all_of, find, for_each
38 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
39 #include <functional> // hash, less
40 #include <initializer_list> // initializer_list
41 #include <iosfwd> // istream, ostream
42 #include <iterator> // random_access_iterator_tag
43 #include <memory> // unique_ptr
44 #include <numeric> // accumulate
45 #include <string> // string, stoi, to_string
46 #include <utility> // declval, forward, move, pair, swap
47 #include <vector> // vector
48
49 // #include <nlohmann/adl_serializer.hpp>
50
51
52 #include <utility>
53
54 // #include <nlohmann/detail/conversions/from_json.hpp>
55
56
57 #include <algorithm> // transform
58 #include <array> // array
59 #include <forward_list> // forward_list
60 #include <iterator> // inserter, front_inserter, end
61 #include <map> // map
62 #include <string> // string
63 #include <tuple> // tuple, make_tuple
64 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
65 #include <unordered_map> // unordered_map
66 #include <utility> // pair, declval
67 #include <valarray> // valarray
68
69 // #include <nlohmann/detail/exceptions.hpp>
70
71
72 #include <exception> // exception
73 #include <stdexcept> // runtime_error
74 #include <string> // to_string
75
76 // #include <nlohmann/detail/input/position_t.hpp>
77
78
79 #include <cstddef> // size_t
80
81 namespace nlohmann
82 {
83 namespace detail
84 {
86 struct position_t
87 {
89 std::size_t chars_read_total = 0;
91 std::size_t chars_read_current_line = 0;
93 std::size_t lines_read = 0;
94
96 constexpr operator size_t() const
97 {
98 return chars_read_total;
99 }
100 };
101
102 } // namespace detail
103 } // namespace nlohmann
104
105 // #include <nlohmann/detail/macro_scope.hpp>
106
107
108 #include <utility> // pair
109 // #include <nlohmann/thirdparty/hedley/hedley.hpp>
110 /* Hedley - https://nemequ.github.io/hedley
111 * Created by Evan Nemerson <evan@nemerson.com>
112 *
113 * To the extent possible under law, the author(s) have dedicated all
114 * copyright and related and neighboring rights to this software to
115 * the public domain worldwide. This software is distributed without
116 * any warranty.
117 *
118 * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
119 * SPDX-License-Identifier: CC0-1.0
120 */
121
122 #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 13)
123 #if defined(JSON_HEDLEY_VERSION)
124 #undef JSON_HEDLEY_VERSION
125 #endif
126 #define JSON_HEDLEY_VERSION 13
127
128 #if defined(JSON_HEDLEY_STRINGIFY_EX)
129 #undef JSON_HEDLEY_STRINGIFY_EX
130 #endif
131 #define JSON_HEDLEY_STRINGIFY_EX(x) #x
132
133 #if defined(JSON_HEDLEY_STRINGIFY)
134 #undef JSON_HEDLEY_STRINGIFY
135 #endif
136 #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
137
138 #if defined(JSON_HEDLEY_CONCAT_EX)
139 #undef JSON_HEDLEY_CONCAT_EX
140 #endif
141 #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
142
143 #if defined(JSON_HEDLEY_CONCAT)
144 #undef JSON_HEDLEY_CONCAT
145 #endif
146 #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
147
148 #if defined(JSON_HEDLEY_CONCAT3_EX)
149 #undef JSON_HEDLEY_CONCAT3_EX
150 #endif
151 #define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
152
153 #if defined(JSON_HEDLEY_CONCAT3)
154 #undef JSON_HEDLEY_CONCAT3
155 #endif
156 #define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
157
158 #if defined(JSON_HEDLEY_VERSION_ENCODE)
159 #undef JSON_HEDLEY_VERSION_ENCODE
160 #endif
161 #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
162
163 #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
164 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
165 #endif
166 #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
167
168 #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
169 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
170 #endif
171 #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
172
173 #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
174 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
175 #endif
176 #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
177
178 #if defined(JSON_HEDLEY_GNUC_VERSION)
179 #undef JSON_HEDLEY_GNUC_VERSION
180 #endif
181 #if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
182 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
183 #elif defined(__GNUC__)
184 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
185 #endif
186
187 #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
188 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
189 #endif
190 #if defined(JSON_HEDLEY_GNUC_VERSION)
191 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
192 #else
193 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
194 #endif
195
196 #if defined(JSON_HEDLEY_MSVC_VERSION)
197 #undef JSON_HEDLEY_MSVC_VERSION
198 #endif
199 #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000)
200 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
201 #elif defined(_MSC_FULL_VER)
202 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
203 #elif defined(_MSC_VER)
204 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
205 #endif
206
207 #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
208 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
209 #endif
210 #if !defined(_MSC_VER)
211 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
212 #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
213 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
214 #elif defined(_MSC_VER) && (_MSC_VER >= 1200)
215 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
216 #else
217 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
218 #endif
219
220 #if defined(JSON_HEDLEY_INTEL_VERSION)
221 #undef JSON_HEDLEY_INTEL_VERSION
222 #endif
223 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE)
224 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
225 #elif defined(__INTEL_COMPILER)
226 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
227 #endif
228
229 #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
230 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
231 #endif
232 #if defined(JSON_HEDLEY_INTEL_VERSION)
233 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
234 #else
235 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
236 #endif
237
238 #if defined(JSON_HEDLEY_PGI_VERSION)
239 #undef JSON_HEDLEY_PGI_VERSION
240 #endif
241 #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
242 #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
243 #endif
244
245 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
246 #undef JSON_HEDLEY_PGI_VERSION_CHECK
247 #endif
248 #if defined(JSON_HEDLEY_PGI_VERSION)
249 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
250 #else
251 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
252 #endif
253
254 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
255 #undef JSON_HEDLEY_SUNPRO_VERSION
256 #endif
257 #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
258 #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)
259 #elif defined(__SUNPRO_C)
260 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
261 #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
262 #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)
263 #elif defined(__SUNPRO_CC)
264 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
265 #endif
266
267 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
268 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
269 #endif
270 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
271 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
272 #else
273 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
274 #endif
275
276 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
277 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
278 #endif
279 #if defined(__EMSCRIPTEN__)
280 #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
281 #endif
282
283 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
284 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
285 #endif
286 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
287 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
288 #else
289 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
290 #endif
291
292 #if defined(JSON_HEDLEY_ARM_VERSION)
293 #undef JSON_HEDLEY_ARM_VERSION
294 #endif
295 #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
296 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
297 #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
298 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
299 #endif
300
301 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
302 #undef JSON_HEDLEY_ARM_VERSION_CHECK
303 #endif
304 #if defined(JSON_HEDLEY_ARM_VERSION)
305 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
306 #else
307 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
308 #endif
309
310 #if defined(JSON_HEDLEY_IBM_VERSION)
311 #undef JSON_HEDLEY_IBM_VERSION
312 #endif
313 #if defined(__ibmxl__)
314 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
315 #elif defined(__xlC__) && defined(__xlC_ver__)
316 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
317 #elif defined(__xlC__)
318 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
319 #endif
320
321 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
322 #undef JSON_HEDLEY_IBM_VERSION_CHECK
323 #endif
324 #if defined(JSON_HEDLEY_IBM_VERSION)
325 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
326 #else
327 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
328 #endif
329
330 #if defined(JSON_HEDLEY_TI_VERSION)
331 #undef JSON_HEDLEY_TI_VERSION
332 #endif
333 #if \
334 defined(__TI_COMPILER_VERSION__) && \
335 ( \
336 defined(__TMS470__) || defined(__TI_ARM__) || \
337 defined(__MSP430__) || \
338 defined(__TMS320C2000__) \
339 )
340 #if (__TI_COMPILER_VERSION__ >= 16000000)
341 #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
342 #endif
343 #endif
344
345 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
346 #undef JSON_HEDLEY_TI_VERSION_CHECK
347 #endif
348 #if defined(JSON_HEDLEY_TI_VERSION)
349 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
350 #else
351 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
352 #endif
353
354 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
355 #undef JSON_HEDLEY_TI_CL2000_VERSION
356 #endif
357 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
358 #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
359 #endif
360
361 #if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
362 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
363 #endif
364 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
365 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
366 #else
367 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
368 #endif
369
370 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
371 #undef JSON_HEDLEY_TI_CL430_VERSION
372 #endif
373 #if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
374 #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
375 #endif
376
377 #if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
378 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
379 #endif
380 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
381 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
382 #else
383 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
384 #endif
385
386 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
387 #undef JSON_HEDLEY_TI_ARMCL_VERSION
388 #endif
389 #if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
390 #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
391 #endif
392
393 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
394 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
395 #endif
396 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
397 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
398 #else
399 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
400 #endif
401
402 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
403 #undef JSON_HEDLEY_TI_CL6X_VERSION
404 #endif
405 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
406 #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
407 #endif
408
409 #if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
410 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
411 #endif
412 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
413 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
414 #else
415 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
416 #endif
417
418 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
419 #undef JSON_HEDLEY_TI_CL7X_VERSION
420 #endif
421 #if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
422 #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
423 #endif
424
425 #if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
426 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
427 #endif
428 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
429 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
430 #else
431 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
432 #endif
433
434 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
435 #undef JSON_HEDLEY_TI_CLPRU_VERSION
436 #endif
437 #if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
438 #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
439 #endif
440
441 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
442 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
443 #endif
444 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
445 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
446 #else
447 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
448 #endif
449
450 #if defined(JSON_HEDLEY_CRAY_VERSION)
451 #undef JSON_HEDLEY_CRAY_VERSION
452 #endif
453 #if defined(_CRAYC)
454 #if defined(_RELEASE_PATCHLEVEL)
455 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
456 #else
457 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
458 #endif
459 #endif
460
461 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
462 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
463 #endif
464 #if defined(JSON_HEDLEY_CRAY_VERSION)
465 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
466 #else
467 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
468 #endif
469
470 #if defined(JSON_HEDLEY_IAR_VERSION)
471 #undef JSON_HEDLEY_IAR_VERSION
472 #endif
473 #if defined(__IAR_SYSTEMS_ICC__)
474 #if __VER__ > 1000
475 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
476 #else
477 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(VER / 100, __VER__ % 100, 0)
478 #endif
479 #endif
480
481 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
482 #undef JSON_HEDLEY_IAR_VERSION_CHECK
483 #endif
484 #if defined(JSON_HEDLEY_IAR_VERSION)
485 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
486 #else
487 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
488 #endif
489
490 #if defined(JSON_HEDLEY_TINYC_VERSION)
491 #undef JSON_HEDLEY_TINYC_VERSION
492 #endif
493 #if defined(__TINYC__)
494 #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
495 #endif
496
497 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
498 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
499 #endif
500 #if defined(JSON_HEDLEY_TINYC_VERSION)
501 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
502 #else
503 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
504 #endif
505
506 #if defined(JSON_HEDLEY_DMC_VERSION)
507 #undef JSON_HEDLEY_DMC_VERSION
508 #endif
509 #if defined(__DMC__)
510 #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
511 #endif
512
513 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
514 #undef JSON_HEDLEY_DMC_VERSION_CHECK
515 #endif
516 #if defined(JSON_HEDLEY_DMC_VERSION)
517 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
518 #else
519 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
520 #endif
521
522 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
523 #undef JSON_HEDLEY_COMPCERT_VERSION
524 #endif
525 #if defined(__COMPCERT_VERSION__)
526 #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
527 #endif
528
529 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
530 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
531 #endif
532 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
533 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
534 #else
535 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
536 #endif
537
538 #if defined(JSON_HEDLEY_PELLES_VERSION)
539 #undef JSON_HEDLEY_PELLES_VERSION
540 #endif
541 #if defined(__POCC__)
542 #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
543 #endif
544
545 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
546 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
547 #endif
548 #if defined(JSON_HEDLEY_PELLES_VERSION)
549 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
550 #else
551 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
552 #endif
553
554 #if defined(JSON_HEDLEY_GCC_VERSION)
555 #undef JSON_HEDLEY_GCC_VERSION
556 #endif
557 #if \
558 defined(JSON_HEDLEY_GNUC_VERSION) && \
559 !defined(__clang__) && \
560 !defined(JSON_HEDLEY_INTEL_VERSION) && \
561 !defined(JSON_HEDLEY_PGI_VERSION) && \
562 !defined(JSON_HEDLEY_ARM_VERSION) && \
563 !defined(JSON_HEDLEY_TI_VERSION) && \
564 !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
565 !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
566 !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
567 !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
568 !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
569 !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
570 !defined(__COMPCERT__)
571 #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
572 #endif
573
574 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
575 #undef JSON_HEDLEY_GCC_VERSION_CHECK
576 #endif
577 #if defined(JSON_HEDLEY_GCC_VERSION)
578 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
579 #else
580 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
581 #endif
582
583 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
584 #undef JSON_HEDLEY_HAS_ATTRIBUTE
585 #endif
586 #if defined(__has_attribute)
587 #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
588 #else
589 #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
590 #endif
591
592 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
593 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
594 #endif
595 #if defined(__has_attribute)
596 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
597 #else
598 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
599 #endif
600
601 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
602 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
603 #endif
604 #if defined(__has_attribute)
605 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
606 #else
607 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
608 #endif
609
610 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
611 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
612 #endif
613 #if \
614 defined(__has_cpp_attribute) && \
615 defined(__cplusplus) && \
616 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
617 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
618 #else
619 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
620 #endif
621
622 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
623 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
624 #endif
625 #if !defined(__cplusplus) || !defined(__has_cpp_attribute)
626 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
627 #elif \
628 !defined(JSON_HEDLEY_PGI_VERSION) && \
629 !defined(JSON_HEDLEY_IAR_VERSION) && \
630 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
631 (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
632 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
633 #else
634 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
635 #endif
636
637 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
638 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
639 #endif
640 #if defined(__has_cpp_attribute) && defined(__cplusplus)
641 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
642 #else
643 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
644 #endif
645
646 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
647 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
648 #endif
649 #if defined(__has_cpp_attribute) && defined(__cplusplus)
650 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
651 #else
652 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
653 #endif
654
655 #if defined(JSON_HEDLEY_HAS_BUILTIN)
656 #undef JSON_HEDLEY_HAS_BUILTIN
657 #endif
658 #if defined(__has_builtin)
659 #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
660 #else
661 #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
662 #endif
663
664 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
665 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
666 #endif
667 #if defined(__has_builtin)
668 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
669 #else
670 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
671 #endif
672
673 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
674 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
675 #endif
676 #if defined(__has_builtin)
677 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
678 #else
679 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
680 #endif
681
682 #if defined(JSON_HEDLEY_HAS_FEATURE)
683 #undef JSON_HEDLEY_HAS_FEATURE
684 #endif
685 #if defined(__has_feature)
686 #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
687 #else
688 #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
689 #endif
690
691 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
692 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
693 #endif
694 #if defined(__has_feature)
695 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
696 #else
697 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
698 #endif
699
700 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
701 #undef JSON_HEDLEY_GCC_HAS_FEATURE
702 #endif
703 #if defined(__has_feature)
704 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
705 #else
706 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
707 #endif
708
709 #if defined(JSON_HEDLEY_HAS_EXTENSION)
710 #undef JSON_HEDLEY_HAS_EXTENSION
711 #endif
712 #if defined(__has_extension)
713 #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
714 #else
715 #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
716 #endif
717
718 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
719 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
720 #endif
721 #if defined(__has_extension)
722 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
723 #else
724 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
725 #endif
726
727 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
728 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
729 #endif
730 #if defined(__has_extension)
731 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
732 #else
733 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
734 #endif
735
736 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
737 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
738 #endif
739 #if defined(__has_declspec_attribute)
740 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
741 #else
742 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
743 #endif
744
745 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
746 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
747 #endif
748 #if defined(__has_declspec_attribute)
749 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
750 #else
751 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
752 #endif
753
754 #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
755 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
756 #endif
757 #if defined(__has_declspec_attribute)
758 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
759 #else
760 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
761 #endif
762
763 #if defined(JSON_HEDLEY_HAS_WARNING)
764 #undef JSON_HEDLEY_HAS_WARNING
765 #endif
766 #if defined(__has_warning)
767 #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
768 #else
769 #define JSON_HEDLEY_HAS_WARNING(warning) (0)
770 #endif
771
772 #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
773 #undef JSON_HEDLEY_GNUC_HAS_WARNING
774 #endif
775 #if defined(__has_warning)
776 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
777 #else
778 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
779 #endif
780
781 #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
782 #undef JSON_HEDLEY_GCC_HAS_WARNING
783 #endif
784 #if defined(__has_warning)
785 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
786 #else
787 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
788 #endif
789
790 /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
791 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
792 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
793 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
794 #endif
795 #if defined(__cplusplus)
796 # if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
797 # if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
798 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
799 JSON_HEDLEY_DIAGNOSTIC_PUSH \
800 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
801 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
802 xpr \
803 JSON_HEDLEY_DIAGNOSTIC_POP
804 # else
805 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
806 JSON_HEDLEY_DIAGNOSTIC_PUSH \
807 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
808 xpr \
809 JSON_HEDLEY_DIAGNOSTIC_POP
810 # endif
811 # endif
812 #endif
813 #if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
814 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
815 #endif
816
817 #if defined(JSON_HEDLEY_CONST_CAST)
818 #undef JSON_HEDLEY_CONST_CAST
819 #endif
820 #if defined(__cplusplus)
821 # define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
822 #elif \
823 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
824 JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
825 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
826 # define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
827 JSON_HEDLEY_DIAGNOSTIC_PUSH \
828 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
829 ((T) (expr)); \
830 JSON_HEDLEY_DIAGNOSTIC_POP \
831 }))
832 #else
833 # define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
834 #endif
835
836 #if defined(JSON_HEDLEY_REINTERPRET_CAST)
837 #undef JSON_HEDLEY_REINTERPRET_CAST
838 #endif
839 #if defined(__cplusplus)
840 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
841 #else
842 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
843 #endif
844
845 #if defined(JSON_HEDLEY_STATIC_CAST)
846 #undef JSON_HEDLEY_STATIC_CAST
847 #endif
848 #if defined(__cplusplus)
849 #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
850 #else
851 #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
852 #endif
853
854 #if defined(JSON_HEDLEY_CPP_CAST)
855 #undef JSON_HEDLEY_CPP_CAST
856 #endif
857 #if defined(__cplusplus)
858 # if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
859 # define JSON_HEDLEY_CPP_CAST(T, expr) \
860 JSON_HEDLEY_DIAGNOSTIC_PUSH \
861 _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
862 ((T) (expr)) \
863 JSON_HEDLEY_DIAGNOSTIC_POP
864 # elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
865 # define JSON_HEDLEY_CPP_CAST(T, expr) \
866 JSON_HEDLEY_DIAGNOSTIC_PUSH \
867 _Pragma("diag_suppress=Pe137") \
868 JSON_HEDLEY_DIAGNOSTIC_POP \
869 # else
870 # define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
871 # endif
872 #else
873 # define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
874 #endif
875
876 #if \
877 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
878 defined(__clang__) || \
879 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
880 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
881 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
882 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
883 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
884 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
885 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
886 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
887 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
888 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
889 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
890 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
891 JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
892 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
893 JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
894 (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
895 #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
896 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
897 #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
898 #else
899 #define JSON_HEDLEY_PRAGMA(value)
900 #endif
901
902 #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
903 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
904 #endif
905 #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
906 #undef JSON_HEDLEY_DIAGNOSTIC_POP
907 #endif
908 #if defined(__clang__)
909 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
910 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
911 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
912 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
913 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
914 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
915 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
916 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
917 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
918 #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
919 #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
920 #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
921 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
922 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
923 #elif \
924 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
925 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
926 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
927 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
928 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
929 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
930 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
931 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
932 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
933 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
934 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
935 #else
936 #define JSON_HEDLEY_DIAGNOSTIC_PUSH
937 #define JSON_HEDLEY_DIAGNOSTIC_POP
938 #endif
939
940 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
941 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
942 #endif
943 #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
944 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
945 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
946 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
947 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
948 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
949 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
950 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
951 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
952 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
953 #elif \
954 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
955 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
956 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
957 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
958 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
959 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
960 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
961 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
962 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
963 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
964 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
965 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
966 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
967 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
968 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
969 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
970 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
971 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
972 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
973 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
974 #else
975 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
976 #endif
977
978 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
979 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
980 #endif
981 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
982 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
983 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
984 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
985 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
986 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
987 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
988 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
989 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
990 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
991 #elif \
992 JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
993 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
994 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
995 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
996 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
997 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
998 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
999 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1000 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1001 #else
1002 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1003 #endif
1004
1005 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1006 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1007 #endif
1008 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1009 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1010 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1011 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1012 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1013 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1014 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1015 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1016 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1017 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1018 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1019 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1020 #elif \
1021 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1022 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1023 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1024 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1025 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1026 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1027 #else
1028 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1029 #endif
1030
1031 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1032 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1033 #endif
1034 #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1035 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1036 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1037 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1038 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1039 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1040 #else
1041 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1042 #endif
1043
1044 #if defined(JSON_HEDLEY_DEPRECATED)
1045 #undef JSON_HEDLEY_DEPRECATED
1046 #endif
1047 #if defined(JSON_HEDLEY_DEPRECATED_FOR)
1048 #undef JSON_HEDLEY_DEPRECATED_FOR
1049 #endif
1050 #if JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0)
1051 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1052 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1053 #elif defined(__cplusplus) && (__cplusplus >= 201402L)
1054 #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1055 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1056 #elif \
1057 JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) || \
1058 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1059 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1060 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1061 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1062 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1063 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1064 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1065 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1066 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1067 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1068 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1069 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1070 #elif \
1071 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1072 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1073 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1074 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1075 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1076 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1077 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1078 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1079 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1080 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1081 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1082 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1083 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1084 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1085 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1086 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1087 #elif \
1088 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1089 JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0)
1090 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1091 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1092 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1093 #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1094 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1095 #else
1096 #define JSON_HEDLEY_DEPRECATED(since)
1097 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1098 #endif
1099
1100 #if defined(JSON_HEDLEY_UNAVAILABLE)
1101 #undef JSON_HEDLEY_UNAVAILABLE
1102 #endif
1103 #if \
1104 JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1105 JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1106 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1107 #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1108 #else
1109 #define JSON_HEDLEY_UNAVAILABLE(available_since)
1110 #endif
1111
1112 #if defined()
1113 #undef
1114 #endif
1115 #if defined(_MSG)
1116 #undef _MSG
1117 #endif
1118 #if (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1119 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1120 #define _MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1121 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1122 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1123 #define _MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1124 #elif \
1125 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1126 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1127 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1128 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1129 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1130 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1131 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1132 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1133 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1134 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1135 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1136 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1137 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1138 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1139 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1140 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1141 #define __attribute__((__warn_unused_result__))
1142 #define _MSG(msg) __attribute__((__warn_unused_result__))
1143 #elif defined(_Check_return_) /* SAL */
1144 #define _Check_return_
1145 #define _MSG(msg) _Check_return_
1146 #else
1147 #define
1148 #define _MSG(msg)
1149 #endif
1150
1151 #if defined(JSON_HEDLEY_SENTINEL)
1152 #undef JSON_HEDLEY_SENTINEL
1153 #endif
1154 #if \
1155 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1156 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1157 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1158 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0)
1159 #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1160 #else
1161 #define JSON_HEDLEY_SENTINEL(position)
1162 #endif
1163
1164 #if defined(JSON_HEDLEY_NO_RETURN)
1165 #undef JSON_HEDLEY_NO_RETURN
1166 #endif
1167 #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1168 #define JSON_HEDLEY_NO_RETURN __noreturn
1169 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1170 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1171 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1172 #define JSON_HEDLEY_NO_RETURN _Noreturn
1173 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
1174 #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1175 #elif \
1176 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1177 JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1178 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1179 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1180 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1181 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1182 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1183 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1184 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1185 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1186 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1187 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1188 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1189 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1190 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1191 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1192 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1193 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1194 #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1195 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
1196 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1197 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1198 #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1199 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1200 #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1201 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1202 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1203 #else
1204 #define JSON_HEDLEY_NO_RETURN
1205 #endif
1206
1207 #if defined(JSON_HEDLEY_NO_ESCAPE)
1208 #undef JSON_HEDLEY_NO_ESCAPE
1209 #endif
1210 #if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1211 #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1212 #else
1213 #define JSON_HEDLEY_NO_ESCAPE
1214 #endif
1215
1216 #if defined(JSON_HEDLEY_UNREACHABLE)
1217 #undef JSON_HEDLEY_UNREACHABLE
1218 #endif
1219 #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1220 #undef JSON_HEDLEY_UNREACHABLE_RETURN
1221 #endif
1222 #if defined(JSON_HEDLEY_ASSUME)
1223 #undef JSON_HEDLEY_ASSUME
1224 #endif
1225 #if \
1226 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1227 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1228 #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1229 #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1230 #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1231 #elif \
1232 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1233 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1234 #if defined(__cplusplus)
1235 #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1236 #else
1237 #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1238 #endif
1239 #endif
1240 #if \
1241 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1242 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1243 JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1244 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1245 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5)
1246 #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1247 #elif defined(JSON_HEDLEY_ASSUME)
1248 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1249 #endif
1250 #if !defined(JSON_HEDLEY_ASSUME)
1251 #if defined(JSON_HEDLEY_UNREACHABLE)
1252 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1253 #else
1254 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1255 #endif
1256 #endif
1257 #if defined(JSON_HEDLEY_UNREACHABLE)
1258 #if \
1259 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1260 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1261 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1262 #else
1263 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1264 #endif
1265 #else
1266 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1267 #endif
1268 #if !defined(JSON_HEDLEY_UNREACHABLE)
1269 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1270 #endif
1271
1272 JSON_HEDLEY_DIAGNOSTIC_PUSH
1273 #if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1274 #pragma clang diagnostic ignored "-Wpedantic"
1275 #endif
1276 #if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1277 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1278 #endif
1279 #if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1280 #if defined(__clang__)
1281 #pragma clang diagnostic ignored "-Wvariadic-macros"
1282 #elif defined(JSON_HEDLEY_GCC_VERSION)
1283 #pragma GCC diagnostic ignored "-Wvariadic-macros"
1284 #endif
1285 #endif
1286 #if defined(JSON_HEDLEY_NON_NULL)
1287 #undef JSON_HEDLEY_NON_NULL
1288 #endif
1289 #if \
1290 JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1291 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1292 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1293 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1294 #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1295 #else
1296 #define JSON_HEDLEY_NON_NULL(...)
1297 #endif
1298 JSON_HEDLEY_DIAGNOSTIC_POP
1299
1300 #if defined(JSON_HEDLEY_PRINTF_FORMAT)
1301 #undef JSON_HEDLEY_PRINTF_FORMAT
1302 #endif
1303 #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1304 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1305 #elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1306 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1307 #elif \
1308 JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1309 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1310 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1311 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1312 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1313 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1314 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1315 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1316 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1317 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1318 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1319 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1320 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1321 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1322 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1323 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1324 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1325 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1326 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1327 #else
1328 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1329 #endif
1330
1331 #if defined(JSON_HEDLEY_CONSTEXPR)
1332 #undef JSON_HEDLEY_CONSTEXPR
1333 #endif
1334 #if defined(__cplusplus)
1335 #if __cplusplus >= 201103L
1336 #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1337 #endif
1338 #endif
1339 #if !defined(JSON_HEDLEY_CONSTEXPR)
1340 #define JSON_HEDLEY_CONSTEXPR
1341 #endif
1342
1343 #if defined(JSON_HEDLEY_PREDICT)
1344 #undef JSON_HEDLEY_PREDICT
1345 #endif
1346 #if defined(JSON_HEDLEY_LIKELY)
1347 #undef JSON_HEDLEY_LIKELY
1348 #endif
1349 #if defined(JSON_HEDLEY_UNLIKELY)
1350 #undef JSON_HEDLEY_UNLIKELY
1351 #endif
1352 #if defined(JSON_HEDLEY_UNPREDICTABLE)
1353 #undef JSON_HEDLEY_UNPREDICTABLE
1354 #endif
1355 #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1356 #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1357 #endif
1358 #if \
1359 JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) || \
1360 JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0)
1361 # define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1362 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1363 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1364 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1365 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1366 #elif \
1367 JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) || \
1368 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1369 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1370 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1371 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1372 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1373 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1374 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1375 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1376 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1377 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1378 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1379 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1380 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1381 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
1382 # define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1383 (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1384 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1385 (__extension__ ({ \
1386 double hedley_probability_ = (probability); \
1387 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1388 }))
1389 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1390 (__extension__ ({ \
1391 double hedley_probability_ = (probability); \
1392 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1393 }))
1394 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1395 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1396 #else
1397 # define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1398 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1399 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1400 # define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1401 # define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1402 #endif
1403 #if !defined(JSON_HEDLEY_UNPREDICTABLE)
1404 #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1405 #endif
1406
1407 #if defined(JSON_HEDLEY_MALLOC)
1408 #undef JSON_HEDLEY_MALLOC
1409 #endif
1410 #if \
1411 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1412 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1413 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1414 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1415 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1416 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1417 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1418 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1419 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1420 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1421 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1422 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1423 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1424 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1425 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1426 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1427 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1428 #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1429 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1430 #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1431 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(14, 0, 0)
1432 #define JSON_HEDLEY_MALLOC __declspec(restrict)
1433 #else
1434 #define JSON_HEDLEY_MALLOC
1435 #endif
1436
1437 #if defined(JSON_HEDLEY_PURE)
1438 #undef JSON_HEDLEY_PURE
1439 #endif
1440 #if \
1441 JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1442 JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1443 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1444 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1445 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1446 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1447 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1448 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1449 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1450 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1451 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1452 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1453 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1454 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1455 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1456 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1457 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1458 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1459 # define JSON_HEDLEY_PURE __attribute__((__pure__))
1460 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1461 # define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1462 #elif defined(__cplusplus) && \
1463 ( \
1464 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1465 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1466 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1467 )
1468 # define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1469 #else
1470 # define JSON_HEDLEY_PURE
1471 #endif
1472
1473 #if defined(JSON_HEDLEY_CONST)
1474 #undef JSON_HEDLEY_CONST
1475 #endif
1476 #if \
1477 JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1478 JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1479 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1480 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1481 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1482 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1483 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1484 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1485 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1486 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1487 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1488 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1489 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1490 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1491 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1492 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1493 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1494 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1495 #define JSON_HEDLEY_CONST __attribute__((__const__))
1496 #elif \
1497 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1498 #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1499 #else
1500 #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1501 #endif
1502
1503 #if defined(JSON_HEDLEY_RESTRICT)
1504 #undef JSON_HEDLEY_RESTRICT
1505 #endif
1506 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1507 #define JSON_HEDLEY_RESTRICT restrict
1508 #elif \
1509 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1510 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1511 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1512 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1513 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1514 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1515 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1516 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1517 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1518 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1519 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1520 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1521 defined(__clang__)
1522 #define JSON_HEDLEY_RESTRICT __restrict
1523 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1524 #define JSON_HEDLEY_RESTRICT _Restrict
1525 #else
1526 #define JSON_HEDLEY_RESTRICT
1527 #endif
1528
1529 #if defined(JSON_HEDLEY_INLINE)
1530 #undef JSON_HEDLEY_INLINE
1531 #endif
1532 #if \
1533 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1534 (defined(__cplusplus) && (__cplusplus >= 199711L))
1535 #define JSON_HEDLEY_INLINE inline
1536 #elif \
1537 defined(JSON_HEDLEY_GCC_VERSION) || \
1538 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1539 #define JSON_HEDLEY_INLINE __inline__
1540 #elif \
1541 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1542 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1543 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1544 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1545 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1546 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1547 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1548 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1549 #define JSON_HEDLEY_INLINE __inline
1550 #else
1551 #define JSON_HEDLEY_INLINE
1552 #endif
1553
1554 #if defined(JSON_HEDLEY_ALWAYS_INLINE)
1555 #undef JSON_HEDLEY_ALWAYS_INLINE
1556 #endif
1557 #if \
1558 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1559 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1560 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1561 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1562 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1563 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1564 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1565 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1566 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1567 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1568 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1569 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1570 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1571 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1572 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1573 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1574 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1575 # define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1576 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0)
1577 # define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1578 #elif defined(__cplusplus) && \
1579 ( \
1580 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1581 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1582 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1583 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1584 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1585 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1586 )
1587 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1588 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1589 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1590 #else
1591 # define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1592 #endif
1593
1594 #if defined(JSON_HEDLEY_NEVER_INLINE)
1595 #undef JSON_HEDLEY_NEVER_INLINE
1596 #endif
1597 #if \
1598 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1599 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1600 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1601 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1602 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1603 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1604 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1605 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1606 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1607 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1608 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1609 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1610 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1611 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1612 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1613 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1614 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1615 #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1616 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
1617 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1618 #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1619 #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1620 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1621 #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1622 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1623 #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1624 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1625 #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1626 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1627 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1628 #else
1629 #define JSON_HEDLEY_NEVER_INLINE
1630 #endif
1631
1632 #if defined(JSON_HEDLEY_PRIVATE)
1633 #undef JSON_HEDLEY_PRIVATE
1634 #endif
1635 #if defined(JSON_HEDLEY_PUBLIC)
1636 #undef JSON_HEDLEY_PUBLIC
1637 #endif
1638 #if defined(JSON_HEDLEY_IMPORT)
1639 #undef JSON_HEDLEY_IMPORT
1640 #endif
1641 #if defined(_WIN32) || defined(__CYGWIN__)
1642 # define JSON_HEDLEY_PRIVATE
1643 # define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1644 # define JSON_HEDLEY_IMPORT __declspec(dllimport)
1645 #else
1646 # if \
1647 JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1648 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1649 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1650 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1651 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1652 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1653 ( \
1654 defined(__TI_EABI__) && \
1655 ( \
1656 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1657 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1658 ) \
1659 )
1660 # define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1661 # define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1662 # else
1663 # define JSON_HEDLEY_PRIVATE
1664 # define JSON_HEDLEY_PUBLIC
1665 # endif
1666 # define JSON_HEDLEY_IMPORT extern
1667 #endif
1668
1669 #if defined(JSON_HEDLEY_NO_THROW)
1670 #undef JSON_HEDLEY_NO_THROW
1671 #endif
1672 #if \
1673 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1674 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1675 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1676 #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1677 #elif \
1678 JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1679 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1680 #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1681 #else
1682 #define JSON_HEDLEY_NO_THROW
1683 #endif
1684
1685 #if defined(JSON_HEDLEY_FALL_THROUGH)
1686 #undef JSON_HEDLEY_FALL_THROUGH
1687 #endif
1688 #if \
1689 JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1690 JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0)
1691 #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1692 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1693 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1694 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1695 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1696 #elif defined(__fallthrough) /* SAL */
1697 #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1698 #else
1699 #define JSON_HEDLEY_FALL_THROUGH
1700 #endif
1701
1702 #if defined()
1703 #undef
1704 #endif
1705 #if \
1706 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1707 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
1708 #define __attribute__((__returns_nonnull__))
1709 #elif defined(_Ret_notnull_) /* SAL */
1710 #define _Ret_notnull_
1711 #else
1712 #define
1713 #endif
1714
1715 #if defined(JSON_HEDLEY_ARRAY_PARAM)
1716 #undef JSON_HEDLEY_ARRAY_PARAM
1717 #endif
1718 #if \
1719 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1720 !defined(__STDC_NO_VLA__) && \
1721 !defined(__cplusplus) && \
1722 !defined(JSON_HEDLEY_PGI_VERSION) && \
1723 !defined(JSON_HEDLEY_TINYC_VERSION)
1724 #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1725 #else
1726 #define JSON_HEDLEY_ARRAY_PARAM(name)
1727 #endif
1728
1729 #if defined(JSON_HEDLEY_IS_CONSTANT)
1730 #undef JSON_HEDLEY_IS_CONSTANT
1731 #endif
1732 #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1733 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1734 #endif
1735 /* JSON_HEDLEY_IS_CONSTEXPR_ is for
1736 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1737 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1738 #undef JSON_HEDLEY_IS_CONSTEXPR_
1739 #endif
1740 #if \
1741 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1742 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1743 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1744 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1745 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1746 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1747 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1748 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1749 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
1750 #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1751 #endif
1752 #if !defined(__cplusplus)
1753 # if \
1754 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1755 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1756 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1757 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1758 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1759 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1760 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1761 #if defined(__INTPTR_TYPE__)
1762 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1763 #else
1764 #include <stdint.h>
1765 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1766 #endif
1767 # elif \
1768 ( \
1769 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1770 !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1771 !defined(JSON_HEDLEY_PGI_VERSION) && \
1772 !defined(JSON_HEDLEY_IAR_VERSION)) || \
1773 JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) || \
1774 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1775 JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1776 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1777 JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1778 #if defined(__INTPTR_TYPE__)
1779 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1780 #else
1781 #include <stdint.h>
1782 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1783 #endif
1784 # elif \
1785 defined(JSON_HEDLEY_GCC_VERSION) || \
1786 defined(JSON_HEDLEY_INTEL_VERSION) || \
1787 defined(JSON_HEDLEY_TINYC_VERSION) || \
1788 defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1789 JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1790 defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1791 defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1792 defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1793 defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1794 defined(__clang__)
1795 # define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1796 sizeof(void) != \
1797 sizeof(*( \
1798 1 ? \
1799 ((void*) ((expr) * 0L) ) : \
1800 ((struct { char v[sizeof(void) * 2]; } *) 1) \
1801 ) \
1802 ) \
1803 )
1804 # endif
1805 #endif
1806 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1807 #if !defined(JSON_HEDLEY_IS_CONSTANT)
1808 #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1809 #endif
1810 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
1811 #else
1812 #if !defined(JSON_HEDLEY_IS_CONSTANT)
1813 #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
1814 #endif
1815 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
1816 #endif
1817
1818 #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
1819 #undef JSON_HEDLEY_BEGIN_C_DECLS
1820 #endif
1821 #if defined(JSON_HEDLEY_END_C_DECLS)
1822 #undef JSON_HEDLEY_END_C_DECLS
1823 #endif
1824 #if defined(JSON_HEDLEY_C_DECL)
1825 #undef JSON_HEDLEY_C_DECL
1826 #endif
1827 #if defined(__cplusplus)
1828 #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
1829 #define JSON_HEDLEY_END_C_DECLS }
1830 #define JSON_HEDLEY_C_DECL extern "C"
1831 #else
1832 #define JSON_HEDLEY_BEGIN_C_DECLS
1833 #define JSON_HEDLEY_END_C_DECLS
1834 #define JSON_HEDLEY_C_DECL
1835 #endif
1836
1837 #if defined(JSON_HEDLEY_STATIC_ASSERT)
1838 #undef JSON_HEDLEY_STATIC_ASSERT
1839 #endif
1840 #if \
1841 !defined(__cplusplus) && ( \
1842 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
1843 JSON_HEDLEY_HAS_FEATURE(c_static_assert) || \
1844 JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
1845 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1846 defined(_Static_assert) \
1847 )
1848 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
1849 #elif \
1850 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
1851 JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0)
1852 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
1853 #else
1854 # define JSON_HEDLEY_STATIC_ASSERT(expr, message)
1855 #endif
1856
1857 #if defined(JSON_HEDLEY_NULL)
1858 #undef JSON_HEDLEY_NULL
1859 #endif
1860 #if defined(__cplusplus)
1861 #if __cplusplus >= 201103L
1862 #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
1863 #elif defined(NULL)
1864 #define JSON_HEDLEY_NULL NULL
1865 #else
1866 #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
1867 #endif
1868 #elif defined(NULL)
1869 #define JSON_HEDLEY_NULL NULL
1870 #else
1871 #define JSON_HEDLEY_NULL ((void*) 0)
1872 #endif
1873
1874 #if defined(JSON_HEDLEY_MESSAGE)
1875 #undef JSON_HEDLEY_MESSAGE
1876 #endif
1877 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1878 # define JSON_HEDLEY_MESSAGE(msg) \
1879 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1880 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1881 JSON_HEDLEY_PRAGMA(message msg) \
1882 JSON_HEDLEY_DIAGNOSTIC_POP
1883 #elif \
1884 JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
1885 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1886 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
1887 #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
1888 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
1889 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1890 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1891 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
1892 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1893 #else
1894 # define JSON_HEDLEY_MESSAGE(msg)
1895 #endif
1896
1897 #if defined(JSON_HEDLEY_WARNING)
1898 #undef JSON_HEDLEY_WARNING
1899 #endif
1900 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1901 # define JSON_HEDLEY_WARNING(msg) \
1902 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1903 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1904 JSON_HEDLEY_PRAGMA(clang warning msg) \
1905 JSON_HEDLEY_DIAGNOSTIC_POP
1906 #elif \
1907 JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
1908 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
1909 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1910 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
1911 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1912 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
1913 #else
1914 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
1915 #endif
1916
1917 #if defined(JSON_HEDLEY_REQUIRE)
1918 #undef JSON_HEDLEY_REQUIRE
1919 #endif
1920 #if defined(JSON_HEDLEY_REQUIRE_MSG)
1921 #undef JSON_HEDLEY_REQUIRE_MSG
1922 #endif
1923 #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
1924 # if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
1925 # define JSON_HEDLEY_REQUIRE(expr) \
1926 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1927 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1928 __attribute__((diagnose_if(!(expr), #expr, "error"))) \
1929 JSON_HEDLEY_DIAGNOSTIC_POP
1930 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
1931 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1932 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1933 __attribute__((diagnose_if(!(expr), msg, "error"))) \
1934 JSON_HEDLEY_DIAGNOSTIC_POP
1935 # else
1936 # define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
1937 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
1938 # endif
1939 #else
1940 # define JSON_HEDLEY_REQUIRE(expr)
1941 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
1942 #endif
1943
1944 #if defined(JSON_HEDLEY_FLAGS)
1945 #undef JSON_HEDLEY_FLAGS
1946 #endif
1947 #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum)
1948 #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
1949 #endif
1950
1951 #if defined(JSON_HEDLEY_FLAGS_CAST)
1952 #undef JSON_HEDLEY_FLAGS_CAST
1953 #endif
1954 #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
1955 # define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
1956 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1957 _Pragma("warning(disable:188)") \
1958 ((T) (expr)); \
1959 JSON_HEDLEY_DIAGNOSTIC_POP \
1960 }))
1961 #else
1962 # define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
1963 #endif
1964
1965 #if defined(JSON_HEDLEY_EMPTY_BASES)
1966 #undef JSON_HEDLEY_EMPTY_BASES
1967 #endif
1968 #if JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)
1969 #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
1970 #else
1971 #define JSON_HEDLEY_EMPTY_BASES
1972 #endif
1973
1974 /* Remaining macros are deprecated. */
1975
1976 #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
1977 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
1978 #endif
1979 #if defined(__clang__)
1980 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
1981 #else
1982 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1983 #endif
1984
1985 #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
1986 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
1987 #endif
1988 #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
1989
1990 #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
1991 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
1992 #endif
1993 #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
1994
1995 #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
1996 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
1997 #endif
1998 #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
1999
2000 #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2001 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2002 #endif
2003 #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2004
2005 #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2006 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2007 #endif
2008 #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2009
2010 #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2011 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2012 #endif
2013 #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2014
2015 #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2016 #undef JSON_HEDLEY_CLANG_HAS_WARNING
2017 #endif
2018 #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2019
2020 #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2021
2022
2023 // This file contains all internal macro definitions
2024 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2025
2026 // exclude unsupported compilers
2027 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2028 #if defined(__clang__)
2029 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2030 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2031 #endif
2032 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2033 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2034 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2035 #endif
2036 #endif
2037 #endif
2038
2039 // C++ language standard detection
2040 #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2041 #define JSON_HAS_CPP_20
2042 #define JSON_HAS_CPP_17
2043 #define JSON_HAS_CPP_14
2044 #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2045 #define JSON_HAS_CPP_17
2046 #define JSON_HAS_CPP_14
2047 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2048 #define JSON_HAS_CPP_14
2049 #endif
2050
2051 // disable float-equal warnings on GCC/clang
2052 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
2053 #pragma GCC diagnostic push
2054 #pragma GCC diagnostic ignored "-Wfloat-equal"
2055 #endif
2056
2057 // disable documentation warnings on clang
2058 #if defined(__clang__)
2059 #pragma GCC diagnostic push
2060 #pragma GCC diagnostic ignored "-Wdocumentation"
2061 #endif
2062
2063 // allow to disable exceptions
2064 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2065 #define JSON_THROW(exception) throw exception
2066 #define JSON_TRY try
2067 #define JSON_CATCH(exception) catch(exception)
2068 #define JSON_INTERNAL_CATCH(exception) catch(exception)
2069 #else
2070 #include <cstdlib>
2071 #define JSON_THROW(exception) std::abort()
2072 #define JSON_TRY if(true)
2073 #define JSON_CATCH(exception) if(false)
2074 #define JSON_INTERNAL_CATCH(exception) if(false)
2075 #endif
2076
2077 // override exception macros
2078 #if defined(JSON_THROW_USER)
2079 #undef JSON_THROW
2080 #define JSON_THROW JSON_THROW_USER
2081 #endif
2082 #if defined(JSON_TRY_USER)
2083 #undef JSON_TRY
2084 #define JSON_TRY JSON_TRY_USER
2085 #endif
2086 #if defined(JSON_CATCH_USER)
2087 #undef JSON_CATCH
2088 #define JSON_CATCH JSON_CATCH_USER
2089 #undef JSON_INTERNAL_CATCH
2090 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2091 #endif
2092 #if defined(JSON_INTERNAL_CATCH_USER)
2093 #undef JSON_INTERNAL_CATCH
2094 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2095 #endif
2096
2097 // allow to override assert
2098 #if !defined(JSON_ASSERT)
2099 #include <cassert> // assert
2100 #define JSON_ASSERT(x) assert(x)
2101 #endif
2102
2103 // allow to access some private functions (needed by the test suite)
2104 #if defined(JSON_TESTS_PRIVATE)
2105 #define JSON_PRIVATE_UNLESS_TESTED public
2106 #else
2107 #define JSON_PRIVATE_UNLESS_TESTED private
2108 #endif
2109
2115 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2116 template<typename BasicJsonType> \
2117 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2118 { \
2119 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2120 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2121 auto it = std::find_if(std::begin(m), std::end(m), \
2122 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2123 { \
2124 return ej_pair.first == e; \
2125 }); \
2126 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2127 } \
2128 template<typename BasicJsonType> \
2129 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2130 { \
2131 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2132 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2133 auto it = std::find_if(std::begin(m), std::end(m), \
2134 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2135 { \
2136 return ej_pair.second == j; \
2137 }); \
2138 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2139 }
2140
2141 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2142 // may be removed in the future once the class is split.
2143
2144 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2145 template<template<typename, typename, typename...> class ObjectType, \
2146 template<typename, typename...> class ArrayType, \
2147 class StringType, class BooleanType, class NumberIntegerType, \
2148 class NumberUnsignedType, class NumberFloatType, \
2149 template<typename> class AllocatorType, \
2150 template<typename, typename = void> class JSONSerializer, \
2151 class BinaryType>
2152
2153 #define NLOHMANN_BASIC_JSON_TPL \
2154 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2155 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2156 AllocatorType, JSONSerializer, BinaryType>
2157
2158 // Macros to simplify conversion from/to types
2159
2160 #define NLOHMANN_JSON_EXPAND( x ) x
2161 #define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
2162 #define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2163 NLOHMANN_JSON_PASTE64, \
2164 NLOHMANN_JSON_PASTE63, \
2165 NLOHMANN_JSON_PASTE62, \
2166 NLOHMANN_JSON_PASTE61, \
2167 NLOHMANN_JSON_PASTE60, \
2168 NLOHMANN_JSON_PASTE59, \
2169 NLOHMANN_JSON_PASTE58, \
2170 NLOHMANN_JSON_PASTE57, \
2171 NLOHMANN_JSON_PASTE56, \
2172 NLOHMANN_JSON_PASTE55, \
2173 NLOHMANN_JSON_PASTE54, \
2174 NLOHMANN_JSON_PASTE53, \
2175 NLOHMANN_JSON_PASTE52, \
2176 NLOHMANN_JSON_PASTE51, \
2177 NLOHMANN_JSON_PASTE50, \
2178 NLOHMANN_JSON_PASTE49, \
2179 NLOHMANN_JSON_PASTE48, \
2180 NLOHMANN_JSON_PASTE47, \
2181 NLOHMANN_JSON_PASTE46, \
2182 NLOHMANN_JSON_PASTE45, \
2183 NLOHMANN_JSON_PASTE44, \
2184 NLOHMANN_JSON_PASTE43, \
2185 NLOHMANN_JSON_PASTE42, \
2186 NLOHMANN_JSON_PASTE41, \
2187 NLOHMANN_JSON_PASTE40, \
2188 NLOHMANN_JSON_PASTE39, \
2189 NLOHMANN_JSON_PASTE38, \
2190 NLOHMANN_JSON_PASTE37, \
2191 NLOHMANN_JSON_PASTE36, \
2192 NLOHMANN_JSON_PASTE35, \
2193 NLOHMANN_JSON_PASTE34, \
2194 NLOHMANN_JSON_PASTE33, \
2195 NLOHMANN_JSON_PASTE32, \
2196 NLOHMANN_JSON_PASTE31, \
2197 NLOHMANN_JSON_PASTE30, \
2198 NLOHMANN_JSON_PASTE29, \
2199 NLOHMANN_JSON_PASTE28, \
2200 NLOHMANN_JSON_PASTE27, \
2201 NLOHMANN_JSON_PASTE26, \
2202 NLOHMANN_JSON_PASTE25, \
2203 NLOHMANN_JSON_PASTE24, \
2204 NLOHMANN_JSON_PASTE23, \
2205 NLOHMANN_JSON_PASTE22, \
2206 NLOHMANN_JSON_PASTE21, \
2207 NLOHMANN_JSON_PASTE20, \
2208 NLOHMANN_JSON_PASTE19, \
2209 NLOHMANN_JSON_PASTE18, \
2210 NLOHMANN_JSON_PASTE17, \
2211 NLOHMANN_JSON_PASTE16, \
2212 NLOHMANN_JSON_PASTE15, \
2213 NLOHMANN_JSON_PASTE14, \
2214 NLOHMANN_JSON_PASTE13, \
2215 NLOHMANN_JSON_PASTE12, \
2216 NLOHMANN_JSON_PASTE11, \
2217 NLOHMANN_JSON_PASTE10, \
2218 NLOHMANN_JSON_PASTE9, \
2219 NLOHMANN_JSON_PASTE8, \
2220 NLOHMANN_JSON_PASTE7, \
2221 NLOHMANN_JSON_PASTE6, \
2222 NLOHMANN_JSON_PASTE5, \
2223 NLOHMANN_JSON_PASTE4, \
2224 NLOHMANN_JSON_PASTE3, \
2225 NLOHMANN_JSON_PASTE2, \
2226 NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2227 #define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2228 #define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2229 #define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2230 #define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2231 #define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2232 #define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
2233 #define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
2234 #define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
2235 #define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
2236 #define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
2237 #define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
2238 #define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
2239 #define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
2240 #define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
2241 #define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
2242 #define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
2243 #define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
2244 #define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
2245 #define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
2246 #define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
2247 #define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
2248 #define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
2249 #define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
2250 #define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
2251 #define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
2252 #define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
2253 #define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
2254 #define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
2255 #define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
2256 #define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
2257 #define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
2258 #define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
2259 #define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
2260 #define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
2261 #define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
2262 #define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
2263 #define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
2264 #define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
2265 #define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
2266 #define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
2267 #define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
2268 #define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
2269 #define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
2270 #define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
2271 #define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
2272 #define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
2273 #define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
2274 #define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
2275 #define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
2276 #define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
2277 #define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
2278 #define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
2279 #define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
2280 #define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
2281 #define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
2282 #define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
2283 #define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
2284 #define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
2285 #define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
2286 #define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
2287 #define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
2288 #define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
2289 #define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
2290
2291 #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2292 #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2293
2299 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2300 friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2301 friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2302
2308 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2309 inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2310 inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2311
2312 #ifndef JSON_USE_IMPLICIT_CONVERSIONS
2313 #define JSON_USE_IMPLICIT_CONVERSIONS 1
2314 #endif
2315
2316 #if JSON_USE_IMPLICIT_CONVERSIONS
2317 #define JSON_EXPLICIT
2318 #else
2319 #define JSON_EXPLICIT explicit
2320 #endif
2321
2322
2323 namespace nlohmann
2324 {
2325 namespace detail
2326 {
2328 // exceptions //
2330
2359 class exception : public std::exception
2360 {
2361 public:
2363
2364 const char* what() const noexcept override
2365 {
2366 return m.what();
2367 }
2368
2370 const int id;
2371
2372 protected:
2373 JSON_HEDLEY_NON_NULL(3)
2374 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
2375
2376 static std::string name(const std::string& ename, int id_)
2377 {
2378 return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2379 }
2380
2381 private:
2383 std::runtime_error m;
2384 };
2385
2431 class parse_error : public exception
2432 {
2433 public:
2443 static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
2444 {
2445 std::string w = exception::name("parse_error", id_) + "parse error" +
2446 position_string(pos) + ": " + what_arg;
2447 return parse_error(id_, pos.chars_read_total, w.c_str());
2448 }
2449
2450 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
2451 {
2452 std::string w = exception::name("parse_error", id_) + "parse error" +
2453 (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2454 ": " + what_arg;
2455 return parse_error(id_, byte_, w.c_str());
2456 }
2457
2467 const std::size_t byte;
2468
2469 private:
2470 parse_error(int id_, std::size_t byte_, const char* what_arg)
2471 : exception(id_, what_arg), byte(byte_) {}
2472
2473 static std::string position_string(const position_t& pos)
2474 {
2475 return " at line " + std::to_string(pos.lines_read + 1) +
2476 ", column " + std::to_string(pos.chars_read_current_line);
2477 }
2478 };
2479
2517 class invalid_iterator : public exception
2518 {
2519 public:
2520 static invalid_iterator create(int id_, const std::string& what_arg)
2521 {
2522 std::string w = exception::name("invalid_iterator", id_) + what_arg;
2523 return invalid_iterator(id_, w.c_str());
2524 }
2525
2526 private:
2527 JSON_HEDLEY_NON_NULL(3)
2528 invalid_iterator(int id_, const char* what_arg)
2529 : exception(id_, what_arg) {}
2530 };
2531
2571 class type_error : public exception
2572 {
2573 public:
2574 static type_error create(int id_, const std::string& what_arg)
2575 {
2576 std::string w = exception::name("type_error", id_) + what_arg;
2577 return type_error(id_, w.c_str());
2578 }
2579
2580 private:
2581 JSON_HEDLEY_NON_NULL(3)
2582 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2583 };
2584
2618 class out_of_range : public exception
2619 {
2620 public:
2621 static out_of_range create(int id_, const std::string& what_arg)
2622 {
2623 std::string w = exception::name("out_of_range", id_) + what_arg;
2624 return out_of_range(id_, w.c_str());
2625 }
2626
2627 private:
2628 JSON_HEDLEY_NON_NULL(3)
2629 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
2630 };
2631
2656 class other_error : public exception
2657 {
2658 public:
2659 static other_error create(int id_, const std::string& what_arg)
2660 {
2661 std::string w = exception::name("other_error", id_) + what_arg;
2662 return other_error(id_, w.c_str());
2663 }
2664
2665 private:
2666 JSON_HEDLEY_NON_NULL(3)
2667 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2668 };
2669 } // namespace detail
2670 } // namespace nlohmann
2671
2672 // #include <nlohmann/detail/macro_scope.hpp>
2673
2674 // #include <nlohmann/detail/meta/cpp_future.hpp>
2675
2676
2677 #include <cstddef> // size_t
2678 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
2679
2680 namespace nlohmann
2681 {
2682 namespace detail
2683 {
2684 // alias templates to reduce boilerplate
2685 template<bool B, typename T = void>
2686 using enable_if_t = typename std::enable_if<B, T>::type;
2687
2688 template<typename T>
2689 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
2690
2691 // implementation of C++14 index_sequence and affiliates
2692 // source: https://stackoverflow.com/a/32223343
2693 template<std::size_t... Ints>
2694 struct index_sequence
2695 {
2696 using type = index_sequence;
2697 using value_type = std::size_t;
2698 static constexpr std::size_t size() noexcept
2699 {
2700 return sizeof...(Ints);
2701 }
2702 };
2703
2704 template<class Sequence1, class Sequence2>
2705 struct merge_and_renumber;
2706
2707 template<std::size_t... I1, std::size_t... I2>
2708 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
2709 : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
2710
2711 template<std::size_t N>
2712 struct make_index_sequence
2713 : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
2714 typename make_index_sequence < N - N / 2 >::type > {};
2715
2716 template<> struct make_index_sequence<0> : index_sequence<> {};
2717 template<> struct make_index_sequence<1> : index_sequence<0> {};
2718
2719 template<typename... Ts>
2720 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
2721
2722 // dispatch utility (taken from ranges-v3)
2723 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
2724 template<> struct priority_tag<0> {};
2725
2726 // taken from ranges-v3
2727 template<typename T>
2728 struct static_const
2729 {
2730 static constexpr T value{};
2731 };
2732
2733 template<typename T>
2734 constexpr T static_const<T>::value;
2735 } // namespace detail
2736 } // namespace nlohmann
2737
2738 // #include <nlohmann/detail/meta/type_traits.hpp>
2739
2740
2741 #include <limits> // numeric_limits
2742 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
2743 #include <utility> // declval
2744
2745 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
2746
2747
2748 #include <iterator> // random_access_iterator_tag
2749
2750 // #include <nlohmann/detail/meta/void_t.hpp>
2751
2752
2753 namespace nlohmann
2754 {
2755 namespace detail
2756 {
2757 template<typename ...Ts> struct make_void
2758 {
2759 using type = void;
2760 };
2761 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
2762 } // namespace detail
2763 } // namespace nlohmann
2764
2765 // #include <nlohmann/detail/meta/cpp_future.hpp>
2766
2767
2768 namespace nlohmann
2769 {
2770 namespace detail
2771 {
2772 template<typename It, typename = void>
2773 struct iterator_types {};
2774
2775 template<typename It>
2776 struct iterator_types <
2777 It,
2778 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
2779 typename It::reference, typename It::iterator_category >>
2780 {
2781 using difference_type = typename It::difference_type;
2782 using value_type = typename It::value_type;
2783 using pointer = typename It::pointer;
2784 using reference = typename It::reference;
2785 using iterator_category = typename It::iterator_category;
2786 };
2787
2788 // This is required as some compilers implement std::iterator_traits in a way that
2789 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
2790 template<typename T, typename = void>
2791 struct iterator_traits
2792 {
2793 };
2794
2795 template<typename T>
2796 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
2797 : iterator_types<T>
2798 {
2799 };
2800
2801 template<typename T>
2802 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
2803 {
2804 using iterator_category = std::random_access_iterator_tag;
2805 using value_type = T;
2806 using difference_type = ptrdiff_t;
2807 using pointer = T*;
2808 using reference = T&;
2809 };
2810 } // namespace detail
2811 } // namespace nlohmann
2812
2813 // #include <nlohmann/detail/macro_scope.hpp>
2814
2815 // #include <nlohmann/detail/meta/cpp_future.hpp>
2816
2817 // #include <nlohmann/detail/meta/detected.hpp>
2818
2819
2820 #include <type_traits>
2821
2822 // #include <nlohmann/detail/meta/void_t.hpp>
2823
2824
2825 // https://en.cppreference.com/w/cpp/experimental/is_detected
2826 namespace nlohmann
2827 {
2828 namespace detail
2829 {
2830 struct nonesuch
2831 {
2832 nonesuch() = delete;
2833 ~nonesuch() = delete;
2834 nonesuch(nonesuch const&) = delete;
2835 nonesuch(nonesuch const&&) = delete;
2836 void operator=(nonesuch const&) = delete;
2837 void operator=(nonesuch&&) = delete;
2838 };
2839
2840 template<class Default,
2841 class AlwaysVoid,
2842 template<class...> class Op,
2843 class... Args>
2844 struct detector
2845 {
2846 using value_t = std::false_type;
2847 using type = Default;
2848 };
2849
2850 template<class Default, template<class...> class Op, class... Args>
2851 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2852 {
2853 using value_t = std::true_type;
2854 using type = Op<Args...>;
2855 };
2856
2857 template<template<class...> class Op, class... Args>
2858 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2859
2860 template<template<class...> class Op, class... Args>
2861 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2862
2863 template<class Default, template<class...> class Op, class... Args>
2864 using detected_or = detector<Default, void, Op, Args...>;
2865
2866 template<class Default, template<class...> class Op, class... Args>
2867 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2868
2869 template<class Expected, template<class...> class Op, class... Args>
2870 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2871
2872 template<class To, template<class...> class Op, class... Args>
2873 using is_detected_convertible =
2874 std::is_convertible<detected_t<Op, Args...>, To>;
2875 } // namespace detail
2876 } // namespace nlohmann
2877
2878 // #include <nlohmann/json_fwd.hpp>
2879 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
2880 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
2881
2882 #include <cstdint> // int64_t, uint64_t
2883 #include <map> // map
2884 #include <memory> // allocator
2885 #include <string> // string
2886 #include <vector> // vector
2887
2893 namespace nlohmann
2894 {
2902 template<typename T = void, typename SFINAE = void>
2903 struct adl_serializer;
2904
2905 template<template<typename U, typename V, typename... Args> class ObjectType =
2906 std::map,
2907 template<typename U, typename... Args> class ArrayType = std::vector,
2908 class StringType = std::string, class BooleanType = bool,
2909 class NumberIntegerType = std::int64_t,
2910 class NumberUnsignedType = std::uint64_t,
2911 class NumberFloatType = double,
2912 template<typename U> class AllocatorType = std::allocator,
2913 template<typename T, typename SFINAE = void> class JSONSerializer =
2914 adl_serializer,
2915 class BinaryType = std::vector<std::uint8_t>>
2916 class basic_json;
2917
2929 template<typename BasicJsonType>
2930 class json_pointer;
2931
2940 using json = basic_json<>;
2941
2942 template<class Key, class T, class IgnoredLess, class Allocator>
2943 struct ordered_map;
2944
2952 using ordered_json = basic_json<nlohmann::ordered_map>;
2953
2954 } // namespace nlohmann
2955
2956 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
2957
2958
2959 namespace nlohmann
2960 {
2969 namespace detail
2970 {
2972 // helpers //
2974
2975 // Note to maintainers:
2976 //
2977 // Every trait in this file expects a non CV-qualified type.
2978 // The only exceptions are in the 'aliases for detected' section
2979 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
2980 //
2981 // In this case, T has to be properly CV-qualified to constraint the function arguments
2982 // (e.g. to_json(BasicJsonType&, const T&))
2983
2984 template<typename> struct is_basic_json : std::false_type {};
2985
2986 NLOHMANN_BASIC_JSON_TPL_DECLARATION
2987 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
2988
2990 // json_ref helpers //
2992
2993 template<typename>
2994 class json_ref;
2995
2996 template<typename>
2997 struct is_json_ref : std::false_type {};
2998
2999 template<typename T>
3000 struct is_json_ref<json_ref<T>> : std::true_type {};
3001
3003 // aliases for detected //
3005
3006 template<typename T>
3007 using mapped_type_t = typename T::mapped_type;
3008
3009 template<typename T>
3010 using key_type_t = typename T::key_type;
3011
3012 template<typename T>
3013 using value_type_t = typename T::value_type;
3014
3015 template<typename T>
3016 using difference_type_t = typename T::difference_type;
3017
3018 template<typename T>
3019 using pointer_t = typename T::pointer;
3020
3021 template<typename T>
3022 using reference_t = typename T::reference;
3023
3024 template<typename T>
3025 using iterator_category_t = typename T::iterator_category;
3026
3027 template<typename T>
3028 using iterator_t = typename T::iterator;
3029
3030 template<typename T, typename... Args>
3031 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3032
3033 template<typename T, typename... Args>
3034 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3035
3036 template<typename T, typename U>
3037 using get_template_function = decltype(std::declval<T>().template get<U>());
3038
3039 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3040 template<typename BasicJsonType, typename T, typename = void>
3041 struct has_from_json : std::false_type {};
3042
3043 // trait checking if j.get<T> is valid
3044 // use this trait instead of std::is_constructible or std::is_convertible,
3045 // both rely on, or make use of implicit conversions, and thus fail when T
3046 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3047 template <typename BasicJsonType, typename T>
3048 struct is_getable
3049 {
3050 static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
3051 };
3052
3053 template<typename BasicJsonType, typename T>
3054 struct has_from_json < BasicJsonType, T,
3055 enable_if_t < !is_basic_json<T>::value >>
3056 {
3057 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3058
3059 static constexpr bool value =
3060 is_detected_exact<void, from_json_function, serializer,
3061 const BasicJsonType&, T&>::value;
3062 };
3063
3064 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3065 // this overload is used for non-default-constructible user-defined-types
3066 template<typename BasicJsonType, typename T, typename = void>
3067 struct has_non_default_from_json : std::false_type {};
3068
3069 template<typename BasicJsonType, typename T>
3070 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3071 {
3072 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3073
3074 static constexpr bool value =
3075 is_detected_exact<T, from_json_function, serializer,
3076 const BasicJsonType&>::value;
3077 };
3078
3079 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3080 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3081 template<typename BasicJsonType, typename T, typename = void>
3082 struct has_to_json : std::false_type {};
3083
3084 template<typename BasicJsonType, typename T>
3085 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3086 {
3087 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3088
3089 static constexpr bool value =
3090 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3091 T>::value;
3092 };
3093
3094
3096 // is_ functions //
3098
3099 template<typename T, typename = void>
3100 struct is_iterator_traits : std::false_type {};
3101
3102 template<typename T>
3103 struct is_iterator_traits<iterator_traits<T>>
3104 {
3105 private:
3106 using traits = iterator_traits<T>;
3107
3108 public:
3109 static constexpr auto value =
3110 is_detected<value_type_t, traits>::value &&
3111 is_detected<difference_type_t, traits>::value &&
3112 is_detected<pointer_t, traits>::value &&
3113 is_detected<iterator_category_t, traits>::value &&
3114 is_detected<reference_t, traits>::value;
3115 };
3116
3117 // source: https://stackoverflow.com/a/37193089/4116453
3118
3119 template<typename T, typename = void>
3120 struct is_complete_type : std::false_type {};
3121
3122 template<typename T>
3123 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3124
3125 template<typename BasicJsonType, typename CompatibleObjectType,
3126 typename = void>
3127 struct is_compatible_object_type_impl : std::false_type {};
3128
3129 template<typename BasicJsonType, typename CompatibleObjectType>
3130 struct is_compatible_object_type_impl <
3131 BasicJsonType, CompatibleObjectType,
3132 enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3133 is_detected<key_type_t, CompatibleObjectType>::value >>
3134 {
3135
3136 using object_t = typename BasicJsonType::object_t;
3137
3138 // macOS's is_constructible does not play well with nonesuch...
3139 static constexpr bool value =
3140 std::is_constructible<typename object_t::key_type,
3141 typename CompatibleObjectType::key_type>::value &&
3142 std::is_constructible<typename object_t::mapped_type,
3143 typename CompatibleObjectType::mapped_type>::value;
3144 };
3145
3146 template<typename BasicJsonType, typename CompatibleObjectType>
3147 struct is_compatible_object_type
3148 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3149
3150 template<typename BasicJsonType, typename ConstructibleObjectType,
3151 typename = void>
3152 struct is_constructible_object_type_impl : std::false_type {};
3153
3154 template<typename BasicJsonType, typename ConstructibleObjectType>
3155 struct is_constructible_object_type_impl <
3156 BasicJsonType, ConstructibleObjectType,
3157 enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3158 is_detected<key_type_t, ConstructibleObjectType>::value >>
3159 {
3160 using object_t = typename BasicJsonType::object_t;
3161
3162 static constexpr bool value =
3163 (std::is_default_constructible<ConstructibleObjectType>::value &&
3164 (std::is_move_assignable<ConstructibleObjectType>::value ||
3165 std::is_copy_assignable<ConstructibleObjectType>::value) &&
3166 (std::is_constructible<typename ConstructibleObjectType::key_type,
3167 typename object_t::key_type>::value &&
3168 std::is_same <
3169 typename object_t::mapped_type,
3170 typename ConstructibleObjectType::mapped_type >::value)) ||
3171 (has_from_json<BasicJsonType,
3172 typename ConstructibleObjectType::mapped_type>::value ||
3173 has_non_default_from_json <
3174 BasicJsonType,
3175 typename ConstructibleObjectType::mapped_type >::value);
3176 };
3177
3178 template<typename BasicJsonType, typename ConstructibleObjectType>
3179 struct is_constructible_object_type
3180 : is_constructible_object_type_impl<BasicJsonType,
3181 ConstructibleObjectType> {};
3182
3183 template<typename BasicJsonType, typename CompatibleStringType,
3184 typename = void>
3185 struct is_compatible_string_type_impl : std::false_type {};
3186
3187 template<typename BasicJsonType, typename CompatibleStringType>
3188 struct is_compatible_string_type_impl <
3189 BasicJsonType, CompatibleStringType,
3190 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3191 value_type_t, CompatibleStringType>::value >>
3192 {
3193 static constexpr auto value =
3194 std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
3195 };
3196
3197 template<typename BasicJsonType, typename ConstructibleStringType>
3198 struct is_compatible_string_type
3199 : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3200
3201 template<typename BasicJsonType, typename ConstructibleStringType,
3202 typename = void>
3203 struct is_constructible_string_type_impl : std::false_type {};
3204
3205 template<typename BasicJsonType, typename ConstructibleStringType>
3206 struct is_constructible_string_type_impl <
3207 BasicJsonType, ConstructibleStringType,
3208 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3209 value_type_t, ConstructibleStringType>::value >>
3210 {
3211 static constexpr auto value =
3212 std::is_constructible<ConstructibleStringType,
3213 typename BasicJsonType::string_t>::value;
3214 };
3215
3216 template<typename BasicJsonType, typename ConstructibleStringType>
3217 struct is_constructible_string_type
3218 : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3219
3220 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3221 struct is_compatible_array_type_impl : std::false_type {};
3222
3223 template<typename BasicJsonType, typename CompatibleArrayType>
3224 struct is_compatible_array_type_impl <
3225 BasicJsonType, CompatibleArrayType,
3226 enable_if_t < is_detected<value_type_t, CompatibleArrayType>::value&&
3227 is_detected<iterator_t, CompatibleArrayType>::value&&
3228 // This is needed because json_reverse_iterator has a ::iterator type...
3229 // Therefore it is detected as a CompatibleArrayType.
3230 // The real fix would be to have an Iterable concept.
3231 !is_iterator_traits <
3232 iterator_traits<CompatibleArrayType >>::value >>
3233 {
3234 static constexpr bool value =
3235 std::is_constructible<BasicJsonType,
3236 typename CompatibleArrayType::value_type>::value;
3237 };
3238
3239 template<typename BasicJsonType, typename CompatibleArrayType>
3240 struct is_compatible_array_type
3241 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3242
3243 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3244 struct is_constructible_array_type_impl : std::false_type {};
3245
3246 template<typename BasicJsonType, typename ConstructibleArrayType>
3247 struct is_constructible_array_type_impl <
3248 BasicJsonType, ConstructibleArrayType,
3249 enable_if_t<std::is_same<ConstructibleArrayType,
3250 typename BasicJsonType::value_type>::value >>
3251 : std::true_type {};
3252
3253 template<typename BasicJsonType, typename ConstructibleArrayType>
3254 struct is_constructible_array_type_impl <
3255 BasicJsonType, ConstructibleArrayType,
3256 enable_if_t < !std::is_same<ConstructibleArrayType,
3257 typename BasicJsonType::value_type>::value&&
3258 std::is_default_constructible<ConstructibleArrayType>::value&&
3259 (std::is_move_assignable<ConstructibleArrayType>::value ||
3260 std::is_copy_assignable<ConstructibleArrayType>::value)&&
3261 is_detected<value_type_t, ConstructibleArrayType>::value&&
3262 is_detected<iterator_t, ConstructibleArrayType>::value&&
3263 is_complete_type <
3264 detected_t<value_type_t, ConstructibleArrayType >>::value >>
3265 {
3266 static constexpr bool value =
3267 // This is needed because json_reverse_iterator has a ::iterator type,
3268 // furthermore, std::back_insert_iterator (and other iterators) have a
3269 // base class `iterator`... Therefore it is detected as a
3270 // ConstructibleArrayType. The real fix would be to have an Iterable
3271 // concept.
3272 !is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value &&
3273
3274 (std::is_same<typename ConstructibleArrayType::value_type,
3275 typename BasicJsonType::array_t::value_type>::value ||
3276 has_from_json<BasicJsonType,
3277 typename ConstructibleArrayType::value_type>::value ||
3278 has_non_default_from_json <
3279 BasicJsonType, typename ConstructibleArrayType::value_type >::value);
3280 };
3281
3282 template<typename BasicJsonType, typename ConstructibleArrayType>
3283 struct is_constructible_array_type
3284 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3285
3286 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3287 typename = void>
3288 struct is_compatible_integer_type_impl : std::false_type {};
3289
3290 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3291 struct is_compatible_integer_type_impl <
3292 RealIntegerType, CompatibleNumberIntegerType,
3293 enable_if_t < std::is_integral<RealIntegerType>::value&&
3294 std::is_integral<CompatibleNumberIntegerType>::value&&
3295 !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3296 {
3297 // is there an assert somewhere on overflows?
3298 using RealLimits = std::numeric_limits<RealIntegerType>;
3299 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3300
3301 static constexpr auto value =
3302 std::is_constructible<RealIntegerType,
3303 CompatibleNumberIntegerType>::value &&
3304 CompatibleLimits::is_integer &&
3305 RealLimits::is_signed == CompatibleLimits::is_signed;
3306 };
3307
3308 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3309 struct is_compatible_integer_type
3310 : is_compatible_integer_type_impl<RealIntegerType,
3311 CompatibleNumberIntegerType> {};
3312
3313 template<typename BasicJsonType, typename CompatibleType, typename = void>
3314 struct is_compatible_type_impl: std::false_type {};
3315
3316 template<typename BasicJsonType, typename CompatibleType>
3317 struct is_compatible_type_impl <
3318 BasicJsonType, CompatibleType,
3319 enable_if_t<is_complete_type<CompatibleType>::value >>
3320 {
3321 static constexpr bool value =
3322 has_to_json<BasicJsonType, CompatibleType>::value;
3323 };
3324
3325 template<typename BasicJsonType, typename CompatibleType>
3326 struct is_compatible_type
3327 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3328
3329 // https://en.cppreference.com/w/cpp/types/conjunction
3330 template<class...> struct conjunction : std::true_type { };
3331 template<class B1> struct conjunction<B1> : B1 { };
3332 template<class B1, class... Bn>
3333 struct conjunction<B1, Bn...>
3334 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3335
3336 template<typename T1, typename T2>
3337 struct is_constructible_tuple : std::false_type {};
3338
3339 template<typename T1, typename... Args>
3340 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<std::is_constructible<T1, Args>...> {};
3341 } // namespace detail
3342 } // namespace nlohmann
3343
3344 // #include <nlohmann/detail/value_t.hpp>
3345
3346
3347 #include <array> // array
3348 #include <cstddef> // size_t
3349 #include <cstdint> // uint8_t
3350 #include <string> // string
3351
3352 namespace nlohmann
3353 {
3354 namespace detail
3355 {
3357 // JSON type enumeration //
3359
3384 enum class value_t : std::uint8_t
3385 {
3386 null,
3387 object,
3388 array,
3389 string,
3390 boolean,
3391 number_integer,
3392 number_unsigned,
3393 number_float,
3394 binary,
3395 discarded
3396 };
3397
3411 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
3412 {
3413 static constexpr std::array<std::uint8_t, 9> order = {{
3414 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
3415 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
3416 6 /* binary */
3417 }
3418 };
3419
3420 const auto l_index = static_cast<std::size_t>(lhs);
3421 const auto r_index = static_cast<std::size_t>(rhs);
3422 return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
3423 }
3424 } // namespace detail
3425 } // namespace nlohmann
3426
3427
3428 namespace nlohmann
3429 {
3430 namespace detail
3431 {
3432 template<typename BasicJsonType>
3433 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3434 {
3435 if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
3436 {
3437 JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
3438 }
3439 n = nullptr;
3440 }
3441
3442 // overloads for basic_json template parameters
3443 template < typename BasicJsonType, typename ArithmeticType,
3444 enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
3445 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3446 int > = 0 >
3447 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3448 {
3449 switch (static_cast<value_t>(j))
3450 {
3451 case value_t::number_unsigned:
3452 {
3453 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3454 break;
3455 }
3456 case value_t::number_integer:
3457 {
3458 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3459 break;
3460 }
3461 case value_t::number_float:
3462 {
3463 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3464 break;
3465 }
3466
3467 default:
3468 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
3469 }
3470 }
3471
3472 template<typename BasicJsonType>
3473 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
3474 {
3475 if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
3476 {
3477 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
3478 }
3479 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
3480 }
3481
3482 template<typename BasicJsonType>
3483 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
3484 {
3485 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3486 {
3487 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
3488 }
3489 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3490 }
3491
3492 template <
3493 typename BasicJsonType, typename ConstructibleStringType,
3494 enable_if_t <
3495 is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&
3496 !std::is_same<typename BasicJsonType::string_t,
3497 ConstructibleStringType>::value,
3498 int > = 0 >
3499 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
3500 {
3501 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3502 {
3503 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
3504 }
3505
3506 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3507 }
3508
3509 template<typename BasicJsonType>
3510 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
3511 {
3512 get_arithmetic_value(j, val);
3513 }
3514
3515 template<typename BasicJsonType>
3516 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
3517 {
3518 get_arithmetic_value(j, val);
3519 }
3520
3521 template<typename BasicJsonType>
3522 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
3523 {
3524 get_arithmetic_value(j, val);
3525 }
3526
3527 template<typename BasicJsonType, typename EnumType,
3528 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
3529 void from_json(const BasicJsonType& j, EnumType& e)
3530 {
3531 typename std::underlying_type<EnumType>::type val;
3532 get_arithmetic_value(j, val);
3533 e = static_cast<EnumType>(val);
3534 }
3535
3536 // forward_list doesn't have an insert method
3537 template<typename BasicJsonType, typename T, typename Allocator,
3538 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
3539 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
3540 {
3541 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3542 {
3543 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3544 }
3545 l.clear();
3546 std::transform(j.rbegin(), j.rend(),
3547 std::front_inserter(l), [](const BasicJsonType & i)
3548 {
3549 return i.template get<T>();
3550 });
3551 }
3552
3553 // valarray doesn't have an insert method
3554 template<typename BasicJsonType, typename T,
3555 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
3556 void from_json(const BasicJsonType& j, std::valarray<T>& l)
3557 {
3558 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3559 {
3560 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3561 }
3562 l.resize(j.size());
3563 std::transform(j.begin(), j.end(), std::begin(l),
3564 [](const BasicJsonType & elem)
3565 {
3566 return elem.template get<T>();
3567 });
3568 }
3569
3570 template<typename BasicJsonType, typename T, std::size_t N>
3571 auto from_json(const BasicJsonType& j, T (&arr)[N])
3572 -> decltype(j.template get<T>(), void())
3573 {
3574 for (std::size_t i = 0; i < N; ++i)
3575 {
3576 arr[i] = j.at(i).template get<T>();
3577 }
3578 }
3579
3580 template<typename BasicJsonType>
3581 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
3582 {
3583 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
3584 }
3585
3586 template<typename BasicJsonType, typename T, std::size_t N>
3587 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
3588 priority_tag<2> /*unused*/)
3589 -> decltype(j.template get<T>(), void())
3590 {
3591 for (std::size_t i = 0; i < N; ++i)
3592 {
3593 arr[i] = j.at(i).template get<T>();
3594 }
3595 }
3596
3597 template<typename BasicJsonType, typename ConstructibleArrayType>
3598 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
3599 -> decltype(
3600 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
3601 j.template get<typename ConstructibleArrayType::value_type>(),
3602 void())
3603 {
3604 using std::end;
3605
3606 ConstructibleArrayType ret;
3607 ret.reserve(j.size());
3608 std::transform(j.begin(), j.end(),
3609 std::inserter(ret, end(ret)), [](const BasicJsonType & i)
3610 {
3611 // get<BasicJsonType>() returns *this, this won't call a from_json
3612 // method when value_type is BasicJsonType
3613 return i.template get<typename ConstructibleArrayType::value_type>();
3614 });
3615 arr = std::move(ret);
3616 }
3617
3618 template<typename BasicJsonType, typename ConstructibleArrayType>
3619 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
3620 priority_tag<0> /*unused*/)
3621 {
3622 using std::end;
3623
3624 ConstructibleArrayType ret;
3625 std::transform(
3626 j.begin(), j.end(), std::inserter(ret, end(ret)),
3627 [](const BasicJsonType & i)
3628 {
3629 // get<BasicJsonType>() returns *this, this won't call a from_json
3630 // method when value_type is BasicJsonType
3631 return i.template get<typename ConstructibleArrayType::value_type>();
3632 });
3633 arr = std::move(ret);
3634 }
3635
3636 template < typename BasicJsonType, typename ConstructibleArrayType,
3637 enable_if_t <
3638 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
3639 !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
3640 !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3641 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
3642 !is_basic_json<ConstructibleArrayType>::value,
3643 int > = 0 >
3644 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
3645 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
3646 j.template get<typename ConstructibleArrayType::value_type>(),
3647 void())
3648 {
3649 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3650 {
3651 JSON_THROW(type_error::create(302, "type must be array, but is " +
3652 std::string(j.type_name())));
3653 }
3654
3655 from_json_array_impl(j, arr, priority_tag<3> {});
3656 }
3657
3658 template<typename BasicJsonType>
3659 void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
3660 {
3661 if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
3662 {
3663 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name())));
3664 }
3665
3666 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
3667 }
3668
3669 template<typename BasicJsonType, typename ConstructibleObjectType,
3670 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
3671 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
3672 {
3673 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
3674 {
3675 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
3676 }
3677
3678 ConstructibleObjectType ret;
3679 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
3680 using value_type = typename ConstructibleObjectType::value_type;
3681 std::transform(
3682 inner_object->begin(), inner_object->end(),
3683 std::inserter(ret, ret.begin()),
3684 [](typename BasicJsonType::object_t::value_type const & p)
3685 {
3686 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
3687 });
3688 obj = std::move(ret);
3689 }
3690
3691 // overload for arithmetic types, not chosen for basic_json template arguments
3692 // (BooleanType, etc..); note: Is it really necessary to provide explicit
3693 // overloads for boolean_t etc. in case of a custom BooleanType which is not
3694 // an arithmetic type?
3695 template < typename BasicJsonType, typename ArithmeticType,
3696 enable_if_t <
3697 std::is_arithmetic<ArithmeticType>::value&&
3698 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
3699 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
3700 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
3701 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3702 int > = 0 >
3703 void from_json(const BasicJsonType& j, ArithmeticType& val)
3704 {
3705 switch (static_cast<value_t>(j))
3706 {
3707 case value_t::number_unsigned:
3708 {
3709 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3710 break;
3711 }
3712 case value_t::number_integer:
3713 {
3714 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3715 break;
3716 }
3717 case value_t::number_float:
3718 {
3719 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3720 break;
3721 }
3722 case value_t::boolean:
3723 {
3724 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
3725 break;
3726 }
3727
3728 default:
3729 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
3730 }
3731 }
3732
3733 template<typename BasicJsonType, typename A1, typename A2>
3734 void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
3735 {
3736 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
3737 }
3738
3739 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
3740 void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
3741 {
3742 t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
3743 }
3744
3745 template<typename BasicJsonType, typename... Args>
3746 void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
3747 {
3748 from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
3749 }
3750
3751 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
3752 typename = enable_if_t < !std::is_constructible <
3753 typename BasicJsonType::string_t, Key >::value >>
3754 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
3755 {
3756 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3757 {
3758 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3759 }
3760 m.clear();
3761 for (const auto& p : j)
3762 {
3763 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
3764 {
3765 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3766 }
3767 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3768 }
3769 }
3770
3771 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
3772 typename = enable_if_t < !std::is_constructible <
3773 typename BasicJsonType::string_t, Key >::value >>
3774 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
3775 {
3776 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3777 {
3778 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3779 }
3780 m.clear();
3781 for (const auto& p : j)
3782 {
3783 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
3784 {
3785 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3786 }
3787 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3788 }
3789 }
3790
3791 struct from_json_fn
3792 {
3793 template<typename BasicJsonType, typename T>
3794 auto operator()(const BasicJsonType& j, T& val) const
3795 noexcept(noexcept(from_json(j, val)))
3796 -> decltype(from_json(j, val), void())
3797 {
3798 return from_json(j, val);
3799 }
3800 };
3801 } // namespace detail
3802
3806 namespace
3807 {
3808 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
3809 } // namespace
3810 } // namespace nlohmann
3811
3812 // #include <nlohmann/detail/conversions/to_json.hpp>
3813
3814
3815 #include <algorithm> // copy
3816 #include <iterator> // begin, end
3817 #include <string> // string
3818 #include <tuple> // tuple, get
3819 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
3820 #include <utility> // move, forward, declval, pair
3821 #include <valarray> // valarray
3822 #include <vector> // vector
3823
3824 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
3825
3826
3827 #include <cstddef> // size_t
3828 #include <iterator> // input_iterator_tag
3829 #include <string> // string, to_string
3830 #include <tuple> // tuple_size, get, tuple_element
3831
3832 // #include <nlohmann/detail/meta/type_traits.hpp>
3833
3834 // #include <nlohmann/detail/value_t.hpp>
3835
3836
3837 namespace nlohmann
3838 {
3839 namespace detail
3840 {
3841 template<typename string_type>
3842 void int_to_string( string_type& target, std::size_t value )
3843 {
3844 // For ADL
3845 using std::to_string;
3846 target = to_string(value);
3847 }
3848 template<typename IteratorType> class iteration_proxy_value
3849 {
3850 public:
3851 using difference_type = std::ptrdiff_t;
3852 using value_type = iteration_proxy_value;
3853 using pointer = value_type * ;
3854 using reference = value_type & ;
3855 using iterator_category = std::input_iterator_tag;
3856 using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
3857
3858 private:
3860 IteratorType anchor;
3862 std::size_t array_index = 0;
3864 mutable std::size_t array_index_last = 0;
3866 mutable string_type array_index_str = "0";
3868 const string_type empty_str = "";
3869
3870 public:
3871 explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
3872
3874 iteration_proxy_value& operator*()
3875 {
3876 return *this;
3877 }
3878
3880 iteration_proxy_value& operator++()
3881 {
3882 ++anchor;
3883 ++array_index;
3884
3885 return *this;
3886 }
3887
3889 bool operator==(const iteration_proxy_value& o) const
3890 {
3891 return anchor == o.anchor;
3892 }
3893
3895 bool operator!=(const iteration_proxy_value& o) const
3896 {
3897 return anchor != o.anchor;
3898 }
3899
3901 const string_type& key() const
3902 {
3903 JSON_ASSERT(anchor.m_object != nullptr);
3904
3905 switch (anchor.m_object->type())
3906 {
3907 // use integer array index as key
3908 case value_t::array:
3909 {
3910 if (array_index != array_index_last)
3911 {
3912 int_to_string( array_index_str, array_index );
3913 array_index_last = array_index;
3914 }
3915 return array_index_str;
3916 }
3917
3918 // use key from the object
3919 case value_t::object:
3920 return anchor.key();
3921
3922 // use an empty key for all primitive types
3923 default:
3924 return empty_str;
3925 }
3926 }
3927
3929 typename IteratorType::reference value() const
3930 {
3931 return anchor.value();
3932 }
3933 };
3934
3936 template<typename IteratorType> class iteration_proxy
3937 {
3938 private:
3940 typename IteratorType::reference container;
3941
3942 public:
3944 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
3945 : container(cont) {}
3946
3948 iteration_proxy_value<IteratorType> begin() noexcept
3949 {
3950 return iteration_proxy_value<IteratorType>(container.begin());
3951 }
3952
3954 iteration_proxy_value<IteratorType> end() noexcept
3955 {
3956 return iteration_proxy_value<IteratorType>(container.end());
3957 }
3958 };
3959 // Structured Bindings Support
3960 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3961 // And see https://github.com/nlohmann/json/pull/1391
3962 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
3963 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
3964 {
3965 return i.key();
3966 }
3967 // Structured Bindings Support
3968 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3969 // And see https://github.com/nlohmann/json/pull/1391
3970 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
3971 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
3972 {
3973 return i.value();
3974 }
3975 } // namespace detail
3976 } // namespace nlohmann
3977
3978 // The Addition to the STD Namespace is required to add
3979 // Structured Bindings Support to the iteration_proxy_value class
3980 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3981 // And see https://github.com/nlohmann/json/pull/1391
3982 namespace std
3983 {
3984 #if defined(__clang__)
3985 // Fix: https://github.com/nlohmann/json/issues/1401
3986 #pragma clang diagnostic push
3987 #pragma clang diagnostic ignored "-Wmismatched-tags"
3988 #endif
3989 template<typename IteratorType>
3990 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
3991 : public std::integral_constant<std::size_t, 2> {};
3992
3993 template<std::size_t N, typename IteratorType>
3994 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
3995 {
3996 public:
3997 using type = decltype(
3998 get<N>(std::declval <
3999 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
4000 };
4001 #if defined(__clang__)
4002 #pragma clang diagnostic pop
4003 #endif
4004 } // namespace std
4005
4006 // #include <nlohmann/detail/meta/cpp_future.hpp>
4007
4008 // #include <nlohmann/detail/meta/type_traits.hpp>
4009
4010 // #include <nlohmann/detail/value_t.hpp>
4011
4012
4013 namespace nlohmann
4014 {
4015 namespace detail
4016 {
4018 // constructors //
4020
4021 template<value_t> struct external_constructor;
4022
4023 template<>
4024 struct external_constructor<value_t::boolean>
4025 {
4026 template<typename BasicJsonType>
4027 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4028 {
4029 j.m_type = value_t::boolean;
4030 j.m_value = b;
4031 j.assert_invariant();
4032 }
4033 };
4034
4035 template<>
4036 struct external_constructor<value_t::string>
4037 {
4038 template<typename BasicJsonType>
4039 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4040 {
4041 j.m_type = value_t::string;
4042 j.m_value = s;
4043 j.assert_invariant();
4044 }
4045
4046 template<typename BasicJsonType>
4047 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4048 {
4049 j.m_type = value_t::string;
4050 j.m_value = std::move(s);
4051 j.assert_invariant();
4052 }
4053
4054 template < typename BasicJsonType, typename CompatibleStringType,
4055 enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
4056 int > = 0 >
4057 static void construct(BasicJsonType& j, const CompatibleStringType& str)
4058 {
4059 j.m_type = value_t::string;
4060 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4061 j.assert_invariant();
4062 }
4063 };
4064
4065 template<>
4066 struct external_constructor<value_t::binary>
4067 {
4068 template<typename BasicJsonType>
4069 static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4070 {
4071 j.m_type = value_t::binary;
4072 typename BasicJsonType::binary_t value{b};
4073 j.m_value = value;
4074 j.assert_invariant();
4075 }
4076
4077 template<typename BasicJsonType>
4078 static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4079 {
4080 j.m_type = value_t::binary;
4081 typename BasicJsonType::binary_t value{std::move(b)};
4082 j.m_value = value;
4083 j.assert_invariant();
4084 }
4085 };
4086
4087 template<>
4088 struct external_constructor<value_t::number_float>
4089 {
4090 template<typename BasicJsonType>
4091 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4092 {
4093 j.m_type = value_t::number_float;
4094 j.m_value = val;
4095 j.assert_invariant();
4096 }
4097 };
4098
4099 template<>
4100 struct external_constructor<value_t::number_unsigned>
4101 {
4102 template<typename BasicJsonType>
4103 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4104 {
4105 j.m_type = value_t::number_unsigned;
4106 j.m_value = val;
4107 j.assert_invariant();
4108 }
4109 };
4110
4111 template<>
4112 struct external_constructor<value_t::number_integer>
4113 {
4114 template<typename BasicJsonType>
4115 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4116 {
4117 j.m_type = value_t::number_integer;
4118 j.m_value = val;
4119 j.assert_invariant();
4120 }
4121 };
4122
4123 template<>
4124 struct external_constructor<value_t::array>
4125 {
4126 template<typename BasicJsonType>
4127 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4128 {
4129 j.m_type = value_t::array;
4130 j.m_value = arr;
4131 j.assert_invariant();
4132 }
4133
4134 template<typename BasicJsonType>
4135 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4136 {
4137 j.m_type = value_t::array;
4138 j.m_value = std::move(arr);
4139 j.assert_invariant();
4140 }
4141
4142 template < typename BasicJsonType, typename CompatibleArrayType,
4143 enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
4144 int > = 0 >
4145 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4146 {
4147 using std::begin;
4148 using std::end;
4149 j.m_type = value_t::array;
4150 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4151 j.assert_invariant();
4152 }
4153
4154 template<typename BasicJsonType>
4155 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4156 {
4157 j.m_type = value_t::array;
4158 j.m_value = value_t::array;
4159 j.m_value.array->reserve(arr.size());
4160 for (const bool x : arr)
4161 {
4162 j.m_value.array->push_back(x);
4163 }
4164 j.assert_invariant();
4165 }
4166
4167 template<typename BasicJsonType, typename T,
4168 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4169 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4170 {
4171 j.m_type = value_t::array;
4172 j.m_value = value_t::array;
4173 j.m_value.array->resize(arr.size());
4174 if (arr.size() > 0)
4175 {
4176 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4177 }
4178 j.assert_invariant();
4179 }
4180 };
4181
4182 template<>
4183 struct external_constructor<value_t::object>
4184 {
4185 template<typename BasicJsonType>
4186 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
4187 {
4188 j.m_type = value_t::object;
4189 j.m_value = obj;
4190 j.assert_invariant();
4191 }
4192
4193 template<typename BasicJsonType>
4194 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4195 {
4196 j.m_type = value_t::object;
4197 j.m_value = std::move(obj);
4198 j.assert_invariant();
4199 }
4200
4201 template < typename BasicJsonType, typename CompatibleObjectType,
4202 enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
4203 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4204 {
4205 using std::begin;
4206 using std::end;
4207
4208 j.m_type = value_t::object;
4209 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4210 j.assert_invariant();
4211 }
4212 };
4213
4215 // to_json //
4217
4218 template<typename BasicJsonType, typename T,
4219 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
4220 void to_json(BasicJsonType& j, T b) noexcept
4221 {
4222 external_constructor<value_t::boolean>::construct(j, b);
4223 }
4224
4225 template<typename BasicJsonType, typename CompatibleString,
4226 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
4227 void to_json(BasicJsonType& j, const CompatibleString& s)
4228 {
4229 external_constructor<value_t::string>::construct(j, s);
4230 }
4231
4232 template<typename BasicJsonType>
4233 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4234 {
4235 external_constructor<value_t::string>::construct(j, std::move(s));
4236 }
4237
4238 template<typename BasicJsonType, typename FloatType,
4239 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
4240 void to_json(BasicJsonType& j, FloatType val) noexcept
4241 {
4242 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4243 }
4244
4245 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4246 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
4247 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4248 {
4249 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4250 }
4251
4252 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4253 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
4254 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4255 {
4256 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4257 }
4258
4259 template<typename BasicJsonType, typename EnumType,
4260 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4261 void to_json(BasicJsonType& j, EnumType e) noexcept
4262 {
4263 using underlying_type = typename std::underlying_type<EnumType>::type;
4264 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4265 }
4266
4267 template<typename BasicJsonType>
4268 void to_json(BasicJsonType& j, const std::vector<bool>& e)
4269 {
4270 external_constructor<value_t::array>::construct(j, e);
4271 }
4272
4273 template < typename BasicJsonType, typename CompatibleArrayType,
4274 enable_if_t < is_compatible_array_type<BasicJsonType,
4275 CompatibleArrayType>::value&&
4276 !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
4277 !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
4278 !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
4279 !is_basic_json<CompatibleArrayType>::value,
4280 int > = 0 >
4281 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4282 {
4283 external_constructor<value_t::array>::construct(j, arr);
4284 }
4285
4286 template<typename BasicJsonType>
4287 void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4288 {
4289 external_constructor<value_t::binary>::construct(j, bin);
4290 }
4291
4292 template<typename BasicJsonType, typename T,
4293 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4294 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4295 {
4296 external_constructor<value_t::array>::construct(j, std::move(arr));
4297 }
4298
4299 template<typename BasicJsonType>
4300 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4301 {
4302 external_constructor<value_t::array>::construct(j, std::move(arr));
4303 }
4304
4305 template < typename BasicJsonType, typename CompatibleObjectType,
4306 enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
4307 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4308 {
4309 external_constructor<value_t::object>::construct(j, obj);
4310 }
4311
4312 template<typename BasicJsonType>
4313 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4314 {
4315 external_constructor<value_t::object>::construct(j, std::move(obj));
4316 }
4317
4318 template <
4319 typename BasicJsonType, typename T, std::size_t N,
4320 enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4321 const T(&)[N]>::value,
4322 int > = 0 >
4323 void to_json(BasicJsonType& j, const T(&arr)[N])
4324 {
4325 external_constructor<value_t::array>::construct(j, arr);
4326 }
4327
4328 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
4329 void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4330 {
4331 j = { p.first, p.second };
4332 }
4333
4334 // for https://github.com/nlohmann/json/pull/1134
4335 template<typename BasicJsonType, typename T,
4336 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
4337 void to_json(BasicJsonType& j, const T& b)
4338 {
4339 j = { {b.key(), b.value()} };
4340 }
4341
4342 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
4343 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4344 {
4345 j = { std::get<Idx>(t)... };
4346 }
4347
4348 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
4349 void to_json(BasicJsonType& j, const T& t)
4350 {
4351 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
4352 }
4353
4354 struct to_json_fn
4355 {
4356 template<typename BasicJsonType, typename T>
4357 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
4358 -> decltype(to_json(j, std::forward<T>(val)), void())
4359 {
4360 return to_json(j, std::forward<T>(val));
4361 }
4362 };
4363 } // namespace detail
4364
4366 namespace
4367 {
4368 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
4369 } // namespace
4370 } // namespace nlohmann
4371
4372
4373 namespace nlohmann
4374 {
4375
4376 template<typename, typename>
4377 struct adl_serializer
4378 {
4388 template<typename BasicJsonType, typename ValueType>
4389 static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
4390 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
4391 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
4392 {
4393 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
4394 }
4395
4405 template<typename BasicJsonType, typename ValueType>
4406 static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
4407 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
4408 -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void())
4409 {
4410 ::nlohmann::to_json(j, std::forward<ValueType>(val));
4411 }
4412 };
4413
4414 } // namespace nlohmann
4415
4416 // #include <nlohmann/byte_container_with_subtype.hpp>
4417
4418
4419 #include <cstdint> // uint8_t
4420 #include <tuple> // tie
4421 #include <utility> // move
4422
4423 namespace nlohmann
4424 {
4425
4439 template<typename BinaryType>
4440 class byte_container_with_subtype : public BinaryType
4441 {
4442 public:
4444 using container_type = BinaryType;
4445
4446 byte_container_with_subtype() noexcept(noexcept(container_type()))
4447 : container_type()
4448 {}
4449
4450 byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))
4451 : container_type(b)
4452 {}
4453
4454 byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
4455 : container_type(std::move(b))
4456 {}
4457
4458 byte_container_with_subtype(const container_type& b, std::uint8_t subtype) noexcept(noexcept(container_type(b)))
4459 : container_type(b)
4460 , m_subtype(subtype)
4461 , m_has_subtype(true)
4462 {}
4463
4464 byte_container_with_subtype(container_type&& b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b))))
4465 : container_type(std::move(b))
4466 , m_subtype(subtype)
4467 , m_has_subtype(true)
4468 {}
4469
4470 bool operator==(const byte_container_with_subtype& rhs) const
4471 {
4472 return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
4473 std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
4474 }
4475
4476 bool operator!=(const byte_container_with_subtype& rhs) const
4477 {
4478 return !(rhs == *this);
4479 }
4480
4499 void set_subtype(std::uint8_t subtype) noexcept
4500 {
4501 m_subtype = subtype;
4502 m_has_subtype = true;
4503 }
4504
4526 constexpr std::uint8_t subtype() const noexcept
4527 {
4528 return m_subtype;
4529 }
4530
4547 constexpr bool has_subtype() const noexcept
4548 {
4549 return m_has_subtype;
4550 }
4551
4571 void clear_subtype() noexcept
4572 {
4573 m_subtype = 0;
4574 m_has_subtype = false;
4575 }
4576
4577 private:
4578 std::uint8_t m_subtype = 0;
4579 bool m_has_subtype = false;
4580 };
4581
4582 } // namespace nlohmann
4583
4584 // #include <nlohmann/detail/conversions/from_json.hpp>
4585
4586 // #include <nlohmann/detail/conversions/to_json.hpp>
4587
4588 // #include <nlohmann/detail/exceptions.hpp>
4589
4590 // #include <nlohmann/detail/hash.hpp>
4591
4592
4593 #include <cstddef> // size_t, uint8_t
4594 #include <functional> // hash
4595
4596 namespace nlohmann
4597 {
4598 namespace detail
4599 {
4600
4601 // boost::hash_combine
4602 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
4603 {
4604 seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
4605 return seed;
4606 }
4607
4619 template<typename BasicJsonType>
4620 std::size_t hash(const BasicJsonType& j)
4621 {
4622 using string_t = typename BasicJsonType::string_t;
4623 using number_integer_t = typename BasicJsonType::number_integer_t;
4624 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4625 using number_float_t = typename BasicJsonType::number_float_t;
4626
4627 const auto type = static_cast<std::size_t>(j.type());
4628 switch (j.type())
4629 {
4630 case BasicJsonType::value_t::null:
4631 case BasicJsonType::value_t::discarded:
4632 {
4633 return combine(type, 0);
4634 }
4635
4636 case BasicJsonType::value_t::object:
4637 {
4638 auto seed = combine(type, j.size());
4639 for (const auto& element : j.items())
4640 {
4641 const auto h = std::hash<string_t> {}(element.key());
4642 seed = combine(seed, h);
4643 seed = combine(seed, hash(element.value()));
4644 }
4645 return seed;
4646 }
4647
4648 case BasicJsonType::value_t::array:
4649 {
4650 auto seed = combine(type, j.size());
4651 for (const auto& element : j)
4652 {
4653 seed = combine(seed, hash(element));
4654 }
4655 return seed;
4656 }
4657
4658 case BasicJsonType::value_t::string:
4659 {
4660 const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
4661 return combine(type, h);
4662 }
4663
4664 case BasicJsonType::value_t::boolean:
4665 {
4666 const auto h = std::hash<bool> {}(j.template get<bool>());
4667 return combine(type, h);
4668 }
4669
4670 case BasicJsonType::value_t::number_integer:
4671 {
4672 const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
4673 return combine(type, h);
4674 }
4675
4676 case BasicJsonType::value_t::number_unsigned:
4677 {
4678 const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
4679 return combine(type, h);
4680 }
4681
4682 case BasicJsonType::value_t::number_float:
4683 {
4684 const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
4685 return combine(type, h);
4686 }
4687
4688 case BasicJsonType::value_t::binary:
4689 {
4690 auto seed = combine(type, j.get_binary().size());
4691 const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
4692 seed = combine(seed, h);
4693 seed = combine(seed, j.get_binary().subtype());
4694 for (const auto byte : j.get_binary())
4695 {
4696 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
4697 }
4698 return seed;
4699 }
4700
4701 default: // LCOV_EXCL_LINE
4702 JSON_ASSERT(false); // LCOV_EXCL_LINE
4703 return 0; // LCOV_EXCL_LINE
4704 }
4705 }
4706
4707 } // namespace detail
4708 } // namespace nlohmann
4709
4710 // #include <nlohmann/detail/input/binary_reader.hpp>
4711
4712
4713 #include <algorithm> // generate_n
4714 #include <array> // array
4715 #include <cmath> // ldexp
4716 #include <cstddef> // size_t
4717 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
4718 #include <cstdio> // snprintf
4719 #include <cstring> // memcpy
4720 #include <iterator> // back_inserter
4721 #include <limits> // numeric_limits
4722 #include <string> // char_traits, string
4723 #include <utility> // make_pair, move
4724
4725 // #include <nlohmann/detail/exceptions.hpp>
4726
4727 // #include <nlohmann/detail/input/input_adapters.hpp>
4728
4729
4730 #include <array> // array
4731 #include <cstddef> // size_t
4732 #include <cstdio> //FILE *
4733 #include <cstring> // strlen
4734 #include <istream> // istream
4735 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
4736 #include <memory> // shared_ptr, make_shared, addressof
4737 #include <numeric> // accumulate
4738 #include <string> // string, char_traits
4739 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
4740 #include <utility> // pair, declval
4741
4742 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
4743
4744 // #include <nlohmann/detail/macro_scope.hpp>
4745
4746
4747 namespace nlohmann
4748 {
4749 namespace detail
4750 {
4752 enum class input_format_t { json, cbor, msgpack, ubjson, bson };
4753
4755 // input adapters //
4757
4762 class file_input_adapter
4763 {
4764 public:
4765 using char_type = char;
4766
4767 JSON_HEDLEY_NON_NULL(2)
4768 explicit file_input_adapter(std::FILE* f) noexcept
4769 : m_file(f)
4770 {}
4771
4772 // make class move-only
4773 file_input_adapter(const file_input_adapter&) = delete;
4774 file_input_adapter(file_input_adapter&&) = default;
4775 file_input_adapter& operator=(const file_input_adapter&) = delete;
4776 file_input_adapter& operator=(file_input_adapter&&) = delete;
4777
4778 std::char_traits<char>::int_type get_character() noexcept
4779 {
4780 return std::fgetc(m_file);
4781 }
4782
4783 private:
4785 std::FILE* m_file;
4786 };
4787
4788
4798 class input_stream_adapter
4799 {
4800 public:
4801 using char_type = char;
4802
4803 ~input_stream_adapter()
4804 {
4805 // clear stream flags; we use underlying streambuf I/O, do not
4806 // maintain ifstream flags, except eof
4807 if (is != nullptr)
4808 {
4809 is->clear(is->rdstate() & std::ios::eofbit);
4810 }
4811 }
4812
4813 explicit input_stream_adapter(std::istream& i)
4814 : is(&i), sb(i.rdbuf())
4815 {}
4816
4817 // delete because of pointer members
4818 input_stream_adapter(const input_stream_adapter&) = delete;
4819 input_stream_adapter& operator=(input_stream_adapter&) = delete;
4820 input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
4821
4822 input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs.is), sb(rhs.sb)
4823 {
4824 rhs.is = nullptr;
4825 rhs.sb = nullptr;
4826 }
4827
4828 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
4829 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
4830 // end up as the same value, eg. 0xFFFFFFFF.
4831 std::char_traits<char>::int_type get_character()
4832 {
4833 auto res = sb->sbumpc();
4834 // set eof manually, as we don't use the istream interface.
4835 if (JSON_HEDLEY_UNLIKELY(res == EOF))
4836 {
4837 is->clear(is->rdstate() | std::ios::eofbit);
4838 }
4839 return res;
4840 }
4841
4842 private:
4844 std::istream* is = nullptr;
4845 std::streambuf* sb = nullptr;
4846 };
4847
4848 // General-purpose iterator-based adapter. It might not be as fast as
4849 // theoretically possible for some containers, but it is extremely versatile.
4850 template<typename IteratorType>
4851 class iterator_input_adapter
4852 {
4853 public:
4854 using char_type = typename std::iterator_traits<IteratorType>::value_type;
4855
4856 iterator_input_adapter(IteratorType first, IteratorType last)
4857 : current(std::move(first)), end(std::move(last)) {}
4858
4859 typename std::char_traits<char_type>::int_type get_character()
4860 {
4861 if (JSON_HEDLEY_LIKELY(current != end))
4862 {
4863 auto result = std::char_traits<char_type>::to_int_type(*current);
4864 std::advance(current, 1);
4865 return result;
4866 }
4867 else
4868 {
4869 return std::char_traits<char_type>::eof();
4870 }
4871 }
4872
4873 private:
4874 IteratorType current;
4875 IteratorType end;
4876
4877 template<typename BaseInputAdapter, size_t T>
4878 friend struct wide_string_input_helper;
4879
4880 bool empty() const
4881 {
4882 return current == end;
4883 }
4884
4885 };
4886
4887
4888 template<typename BaseInputAdapter, size_t T>
4889 struct wide_string_input_helper;
4890
4891 template<typename BaseInputAdapter>
4892 struct wide_string_input_helper<BaseInputAdapter, 4>
4893 {
4894 // UTF-32
4895 static void fill_buffer(BaseInputAdapter& input,
4896 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4897 size_t& utf8_bytes_index,
4898 size_t& utf8_bytes_filled)
4899 {
4900 utf8_bytes_index = 0;
4901
4902 if (JSON_HEDLEY_UNLIKELY(input.empty()))
4903 {
4904 utf8_bytes[0] = std::char_traits<char>::eof();
4905 utf8_bytes_filled = 1;
4906 }
4907 else
4908 {
4909 // get the current character
4910 const auto wc = input.get_character();
4911
4912 // UTF-32 to UTF-8 encoding
4913 if (wc < 0x80)
4914 {
4915 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4916 utf8_bytes_filled = 1;
4917 }
4918 else if (wc <= 0x7FF)
4919 {
4920 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
4921 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4922 utf8_bytes_filled = 2;
4923 }
4924 else if (wc <= 0xFFFF)
4925 {
4926 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
4927 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4928 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4929 utf8_bytes_filled = 3;
4930 }
4931 else if (wc <= 0x10FFFF)
4932 {
4933 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
4934 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
4935 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4936 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4937 utf8_bytes_filled = 4;
4938 }
4939 else
4940 {
4941 // unknown character
4942 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4943 utf8_bytes_filled = 1;
4944 }
4945 }
4946 }
4947 };
4948
4949 template<typename BaseInputAdapter>
4950 struct wide_string_input_helper<BaseInputAdapter, 2>
4951 {
4952 // UTF-16
4953 static void fill_buffer(BaseInputAdapter& input,
4954 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4955 size_t& utf8_bytes_index,
4956 size_t& utf8_bytes_filled)
4957 {
4958 utf8_bytes_index = 0;
4959
4960 if (JSON_HEDLEY_UNLIKELY(input.empty()))
4961 {
4962 utf8_bytes[0] = std::char_traits<char>::eof();
4963 utf8_bytes_filled = 1;
4964 }
4965 else
4966 {
4967 // get the current character
4968 const auto wc = input.get_character();
4969
4970 // UTF-16 to UTF-8 encoding
4971 if (wc < 0x80)
4972 {
4973 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4974 utf8_bytes_filled = 1;
4975 }
4976 else if (wc <= 0x7FF)
4977 {
4978 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
4979 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4980 utf8_bytes_filled = 2;
4981 }
4982 else if (0xD800 > wc || wc >= 0xE000)
4983 {
4984 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
4985 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4986 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4987 utf8_bytes_filled = 3;
4988 }
4989 else
4990 {
4991 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
4992 {
4993 const auto wc2 = static_cast<unsigned int>(input.get_character());
4994 const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
4995 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
4996 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
4997 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
4998 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
4999 utf8_bytes_filled = 4;
5000 }
5001 else
5002 {
5003 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5004 utf8_bytes_filled = 1;
5005 }
5006 }
5007 }
5008 }
5009 };
5010
5011 // Wraps another input apdater to convert wide character types into individual bytes.
5012 template<typename BaseInputAdapter, typename WideCharType>
5013 class wide_string_input_adapter
5014 {
5015 public:
5016 using char_type = char;
5017
5018 wide_string_input_adapter(BaseInputAdapter base)
5019 : base_adapter(base) {}
5020
5021 typename std::char_traits<char>::int_type get_character() noexcept
5022 {
5023 // check if buffer needs to be filled
5024 if (utf8_bytes_index == utf8_bytes_filled)
5025 {
5026 fill_buffer<sizeof(WideCharType)>();
5027
5028 JSON_ASSERT(utf8_bytes_filled > 0);
5029 JSON_ASSERT(utf8_bytes_index == 0);
5030 }
5031
5032 // use buffer
5033 JSON_ASSERT(utf8_bytes_filled > 0);
5034 JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
5035 return utf8_bytes[utf8_bytes_index++];
5036 }
5037
5038 private:
5039 BaseInputAdapter base_adapter;
5040
5041 template<size_t T>
5042 void fill_buffer()
5043 {
5044 wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
5045 }
5046
5048 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5049
5051 std::size_t utf8_bytes_index = 0;
5053 std::size_t utf8_bytes_filled = 0;
5054 };
5055
5056
5057 template<typename IteratorType, typename Enable = void>
5058 struct iterator_input_adapter_factory
5059 {
5060 using iterator_type = IteratorType;
5061 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5062 using adapter_type = iterator_input_adapter<iterator_type>;
5063
5064 static adapter_type create(IteratorType first, IteratorType last)
5065 {
5066 return adapter_type(std::move(first), std::move(last));
5067 }
5068 };
5069
5070 template<typename T>
5071 struct is_iterator_of_multibyte
5072 {
5073 using value_type = typename std::iterator_traits<T>::value_type;
5074 enum
5075 {
5076 value = sizeof(value_type) > 1
5077 };
5078 };
5079
5080 template<typename IteratorType>
5081 struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
5082 {
5083 using iterator_type = IteratorType;
5084 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5085 using base_adapter_type = iterator_input_adapter<iterator_type>;
5086 using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
5087
5088 static adapter_type create(IteratorType first, IteratorType last)
5089 {
5090 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5091 }
5092 };
5093
5094 // General purpose iterator-based input
5095 template<typename IteratorType>
5096 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
5097 {
5098 using factory_type = iterator_input_adapter_factory<IteratorType>;
5099 return factory_type::create(first, last);
5100 }
5101
5102 // Convenience shorthand from container to iterator
5103 template<typename ContainerType>
5104 auto input_adapter(const ContainerType& container) -> decltype(input_adapter(begin(container), end(container)))
5105 {
5106 // Enable ADL
5107 using std::begin;
5108 using std::end;
5109
5110 return input_adapter(begin(container), end(container));
5111 }
5112
5113 // Special cases with fast paths
5114 inline file_input_adapter input_adapter(std::FILE* file)
5115 {
5116 return file_input_adapter(file);
5117 }
5118
5119 inline input_stream_adapter input_adapter(std::istream& stream)
5120 {
5121 return input_stream_adapter(stream);
5122 }
5123
5124 inline input_stream_adapter input_adapter(std::istream&& stream)
5125 {
5126 return input_stream_adapter(stream);
5127 }
5128
5129 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5130
5131 // Null-delimited strings, and the like.
5132 template < typename CharT,
5133 typename std::enable_if <
5134 std::is_pointer<CharT>::value&&
5135 !std::is_array<CharT>::value&&
5136 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5137 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5138 int >::type = 0 >
5139 contiguous_bytes_input_adapter input_adapter(CharT b)
5140 {
5141 auto length = std::strlen(reinterpret_cast<const char*>(b));
5142 const auto* ptr = reinterpret_cast<const char*>(b);
5143 return input_adapter(ptr, ptr + length);
5144 }
5145
5146 template<typename T, std::size_t N>
5147 auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N))
5148 {
5149 return input_adapter(array, array + N);
5150 }
5151
5152 // This class only handles inputs of input_buffer_adapter type.
5153 // It's required so that expressions like {ptr, len} can be implicitely casted
5154 // to the correct adapter.
5155 class span_input_adapter
5156 {
5157 public:
5158 template < typename CharT,
5159 typename std::enable_if <
5160 std::is_pointer<CharT>::value&&
5161 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5162 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5163 int >::type = 0 >
5164 span_input_adapter(CharT b, std::size_t l)
5165 : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5166
5167 template<class IteratorType,
5168 typename std::enable_if<
5169 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5170 int>::type = 0>
5171 span_input_adapter(IteratorType first, IteratorType last)
5172 : ia(input_adapter(first, last)) {}
5173
5174 contiguous_bytes_input_adapter&& get()
5175 {
5176 return std::move(ia);
5177 }
5178
5179 private:
5180 contiguous_bytes_input_adapter ia;
5181 };
5182 } // namespace detail
5183 } // namespace nlohmann
5184
5185 // #include <nlohmann/detail/input/json_sax.hpp>
5186
5187
5188 #include <cstddef>
5189 #include <string> // string
5190 #include <utility> // move
5191 #include <vector> // vector
5192
5193 // #include <nlohmann/detail/exceptions.hpp>
5194
5195 // #include <nlohmann/detail/macro_scope.hpp>
5196
5197
5198 namespace nlohmann
5199 {
5200
5209 template<typename BasicJsonType>
5210 struct json_sax
5211 {
5212 using number_integer_t = typename BasicJsonType::number_integer_t;
5213 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5214 using number_float_t = typename BasicJsonType::number_float_t;
5215 using string_t = typename BasicJsonType::string_t;
5216 using binary_t = typename BasicJsonType::binary_t;
5217
5222 virtual bool null() = 0;
5223
5229 virtual bool boolean(bool val) = 0;
5230
5236 virtual bool number_integer(number_integer_t val) = 0;
5237
5243 virtual bool number_unsigned(number_unsigned_t val) = 0;
5244
5251 virtual bool number_float(number_float_t val, const string_t& s) = 0;
5252
5259 virtual bool string(string_t& val) = 0;
5260
5267 virtual bool binary(binary_t& val) = 0;
5268
5275 virtual bool start_object(std::size_t elements) = 0;
5276
5283 virtual bool key(string_t& val) = 0;
5284
5289 virtual bool end_object() = 0;
5290
5297 virtual bool start_array(std::size_t elements) = 0;
5298
5303 virtual bool end_array() = 0;
5304
5312 virtual bool parse_error(std::size_t position,
5313 const std::string& last_token,
5314 const detail::exception& ex) = 0;
5315
5316 virtual ~json_sax() = default;
5317 };
5318
5319
5320 namespace detail
5321 {
5335 template<typename BasicJsonType>
5336 class json_sax_dom_parser
5337 {
5338 public:
5339 using number_integer_t = typename BasicJsonType::number_integer_t;
5340 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5341 using number_float_t = typename BasicJsonType::number_float_t;
5342 using string_t = typename BasicJsonType::string_t;
5343 using binary_t = typename BasicJsonType::binary_t;
5344
5350 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
5351 : root(r), allow_exceptions(allow_exceptions_)
5352 {}
5353
5354 // make class move-only
5355 json_sax_dom_parser(const json_sax_dom_parser&) = delete;
5356 json_sax_dom_parser(json_sax_dom_parser&&) = default;
5357 json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
5358 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
5359 ~json_sax_dom_parser() = default;
5360
5361 bool null()
5362 {
5363 handle_value(nullptr);
5364 return true;
5365 }
5366
5367 bool boolean(bool val)
5368 {
5369 handle_value(val);
5370 return true;
5371 }
5372
5373 bool number_integer(number_integer_t val)
5374 {
5375 handle_value(val);
5376 return true;
5377 }
5378
5379 bool number_unsigned(number_unsigned_t val)
5380 {
5381 handle_value(val);
5382 return true;
5383 }
5384
5385 bool number_float(number_float_t val, const string_t& /*unused*/)
5386 {
5387 handle_value(val);
5388 return true;
5389 }
5390
5391 bool string(string_t& val)
5392 {
5393 handle_value(val);
5394 return true;
5395 }
5396
5397 bool binary(binary_t& val)
5398 {
5399 handle_value(std::move(val));
5400 return true;
5401 }
5402
5403 bool start_object(std::size_t len)
5404 {
5405 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
5406
5407 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5408 {
5409 JSON_THROW(out_of_range::create(408,
5410 "excessive object size: " + std::to_string(len)));
5411 }
5412
5413 return true;
5414 }
5415
5416 bool key(string_t& val)
5417 {
5418 // add null at given key and store the reference for later
5419 object_element = &(ref_stack.back()->m_value.object->operator[](val));
5420 return true;
5421 }
5422
5423 bool end_object()
5424 {
5425 ref_stack.pop_back();
5426 return true;
5427 }
5428
5429 bool start_array(std::size_t len)
5430 {
5431 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
5432
5433 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5434 {
5435 JSON_THROW(out_of_range::create(408,
5436 "excessive array size: " + std::to_string(len)));
5437 }
5438
5439 return true;
5440 }
5441
5442 bool end_array()
5443 {
5444 ref_stack.pop_back();
5445 return true;
5446 }
5447
5448 template<class Exception>
5449 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5450 const Exception& ex)
5451 {
5452 errored = true;
5453 static_cast<void>(ex);
5454 if (allow_exceptions)
5455 {
5456 JSON_THROW(ex);
5457 }
5458 return false;
5459 }
5460
5461 constexpr bool is_errored() const
5462 {
5463 return errored;
5464 }
5465
5466 private:
5473 template<typename Value>
5474
5475 BasicJsonType* handle_value(Value&& v)
5476 {
5477 if (ref_stack.empty())
5478 {
5479 root = BasicJsonType(std::forward<Value>(v));
5480 return &root;
5481 }
5482
5483 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
5484
5485 if (ref_stack.back()->is_array())
5486 {
5487 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
5488 return &(ref_stack.back()->m_value.array->back());
5489 }
5490
5491 JSON_ASSERT(ref_stack.back()->is_object());
5492 JSON_ASSERT(object_element);
5493 *object_element = BasicJsonType(std::forward<Value>(v));
5494 return object_element;
5495 }
5496
5498 BasicJsonType& root;
5500 std::vector<BasicJsonType*> ref_stack {};
5502 BasicJsonType* object_element = nullptr;
5504 bool errored = false;
5506 const bool allow_exceptions = true;
5507 };
5508
5509 template<typename BasicJsonType>
5510 class json_sax_dom_callback_parser
5511 {
5512 public:
5513 using number_integer_t = typename BasicJsonType::number_integer_t;
5514 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5515 using number_float_t = typename BasicJsonType::number_float_t;
5516 using string_t = typename BasicJsonType::string_t;
5517 using binary_t = typename BasicJsonType::binary_t;
5518 using parser_callback_t = typename BasicJsonType::parser_callback_t;
5519 using parse_event_t = typename BasicJsonType::parse_event_t;
5520
5521 json_sax_dom_callback_parser(BasicJsonType& r,
5522 const parser_callback_t cb,
5523 const bool allow_exceptions_ = true)
5524 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
5525 {
5526 keep_stack.push_back(true);
5527 }
5528
5529 // make class move-only
5530 json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
5531 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default;
5532 json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
5533 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default;
5534 ~json_sax_dom_callback_parser() = default;
5535
5536 bool null()
5537 {
5538 handle_value(nullptr);
5539 return true;
5540 }
5541
5542 bool boolean(bool val)
5543 {
5544 handle_value(val);
5545 return true;
5546 }
5547
5548 bool number_integer(number_integer_t val)
5549 {
5550 handle_value(val);
5551 return true;
5552 }
5553
5554 bool number_unsigned(number_unsigned_t val)
5555 {
5556 handle_value(val);
5557 return true;
5558 }
5559
5560 bool number_float(number_float_t val, const string_t& /*unused*/)
5561 {
5562 handle_value(val);
5563 return true;
5564 }
5565
5566 bool string(string_t& val)
5567 {
5568 handle_value(val);
5569 return true;
5570 }
5571
5572 bool binary(binary_t& val)
5573 {
5574 handle_value(std::move(val));
5575 return true;
5576 }
5577
5578 bool start_object(std::size_t len)
5579 {
5580 // check callback for object start
5581 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
5582 keep_stack.push_back(keep);
5583
5584 auto val = handle_value(BasicJsonType::value_t::object, true);
5585 ref_stack.push_back(val.second);
5586
5587 // check object limit
5588 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5589 {
5590 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
5591 }
5592
5593 return true;
5594 }
5595
5596 bool key(string_t& val)
5597 {
5598 BasicJsonType k = BasicJsonType(val);
5599
5600 // check callback for key
5601 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
5602 key_keep_stack.push_back(keep);
5603
5604 // add discarded value at given key and store the reference for later
5605 if (keep && ref_stack.back())
5606 {
5607 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
5608 }
5609
5610 return true;
5611 }
5612
5613 bool end_object()
5614 {
5615 if (ref_stack.back() && !callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
5616 {
5617 // discard object
5618 *ref_stack.back() = discarded;
5619 }
5620
5621 JSON_ASSERT(!ref_stack.empty());
5622 JSON_ASSERT(!keep_stack.empty());
5623 ref_stack.pop_back();
5624 keep_stack.pop_back();
5625
5626 if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
5627 {
5628 // remove discarded value
5629 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
5630 {
5631 if (it->is_discarded())
5632 {
5633 ref_stack.back()->erase(it);
5634 break;
5635 }
5636 }
5637 }
5638
5639 return true;
5640 }
5641
5642 bool start_array(std::size_t len)
5643 {
5644 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
5645 keep_stack.push_back(keep);
5646
5647 auto val = handle_value(BasicJsonType::value_t::array, true);
5648 ref_stack.push_back(val.second);
5649
5650 // check array limit
5651 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5652 {
5653 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
5654 }
5655
5656 return true;
5657 }
5658
5659 bool end_array()
5660 {
5661 bool keep = true;
5662
5663 if (ref_stack.back())
5664 {
5665 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
5666 if (!keep)
5667 {
5668 // discard array
5669 *ref_stack.back() = discarded;
5670 }
5671 }
5672
5673 JSON_ASSERT(!ref_stack.empty());
5674 JSON_ASSERT(!keep_stack.empty());
5675 ref_stack.pop_back();
5676 keep_stack.pop_back();
5677
5678 // remove discarded value
5679 if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
5680 {
5681 ref_stack.back()->m_value.array->pop_back();
5682 }
5683
5684 return true;
5685 }
5686
5687 template<class Exception>
5688 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5689 const Exception& ex)
5690 {
5691 errored = true;
5692 static_cast<void>(ex);
5693 if (allow_exceptions)
5694 {
5695 JSON_THROW(ex);
5696 }
5697 return false;
5698 }
5699
5700 constexpr bool is_errored() const
5701 {
5702 return errored;
5703 }
5704
5705 private:
5721 template<typename Value>
5722 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
5723 {
5724 JSON_ASSERT(!keep_stack.empty());
5725
5726 // do not handle this value if we know it would be added to a discarded
5727 // container
5728 if (!keep_stack.back())
5729 {
5730 return {false, nullptr};
5731 }
5732
5733 // create value
5734 auto value = BasicJsonType(std::forward<Value>(v));
5735
5736 // check callback
5737 const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
5738
5739 // do not handle this value if we just learnt it shall be discarded
5740 if (!keep)
5741 {
5742 return {false, nullptr};
5743 }
5744
5745 if (ref_stack.empty())
5746 {
5747 root = std::move(value);
5748 return {true, &root};
5749 }
5750
5751 // skip this value if we already decided to skip the parent
5752 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
5753 if (!ref_stack.back())
5754 {
5755 return {false, nullptr};
5756 }
5757
5758 // we now only expect arrays and objects
5759 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
5760
5761 // array
5762 if (ref_stack.back()->is_array())
5763 {
5764 ref_stack.back()->m_value.array->push_back(std::move(value));
5765 return {true, &(ref_stack.back()->m_value.array->back())};
5766 }
5767
5768 // object
5769 JSON_ASSERT(ref_stack.back()->is_object());
5770 // check if we should store an element for the current key
5771 JSON_ASSERT(!key_keep_stack.empty());
5772 const bool store_element = key_keep_stack.back();
5773 key_keep_stack.pop_back();
5774
5775 if (!store_element)
5776 {
5777 return {false, nullptr};
5778 }
5779
5780 JSON_ASSERT(object_element);
5781 *object_element = std::move(value);
5782 return {true, object_element};
5783 }
5784
5786 BasicJsonType& root;
5788 std::vector<BasicJsonType*> ref_stack {};
5790 std::vector<bool> keep_stack {};
5792 std::vector<bool> key_keep_stack {};
5794 BasicJsonType* object_element = nullptr;
5796 bool errored = false;
5798 const parser_callback_t callback = nullptr;
5800 const bool allow_exceptions = true;
5802 BasicJsonType discarded = BasicJsonType::value_t::discarded;
5803 };
5804
5805 template<typename BasicJsonType>
5806 class json_sax_acceptor
5807 {
5808 public:
5809 using number_integer_t = typename BasicJsonType::number_integer_t;
5810 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5811 using number_float_t = typename BasicJsonType::number_float_t;
5812 using string_t = typename BasicJsonType::string_t;
5813 using binary_t = typename BasicJsonType::binary_t;
5814
5815 bool null()
5816 {
5817 return true;
5818 }
5819
5820 bool boolean(bool /*unused*/)
5821 {
5822 return true;
5823 }
5824
5825 bool number_integer(number_integer_t /*unused*/)
5826 {
5827 return true;
5828 }
5829
5830 bool number_unsigned(number_unsigned_t /*unused*/)
5831 {
5832 return true;
5833 }
5834
5835 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
5836 {
5837 return true;
5838 }
5839
5840 bool string(string_t& /*unused*/)
5841 {
5842 return true;
5843 }
5844
5845 bool binary(binary_t& /*unused*/)
5846 {
5847 return true;
5848 }
5849
5850 bool start_object(std::size_t /*unused*/ = std::size_t(-1))
5851 {
5852 return true;
5853 }
5854
5855 bool key(string_t& /*unused*/)
5856 {
5857 return true;
5858 }
5859
5860 bool end_object()
5861 {
5862 return true;
5863 }
5864
5865 bool start_array(std::size_t /*unused*/ = std::size_t(-1))
5866 {
5867 return true;
5868 }
5869
5870 bool end_array()
5871 {
5872 return true;
5873 }
5874
5875 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
5876 {
5877 return false;
5878 }
5879 };
5880 } // namespace detail
5881
5882 } // namespace nlohmann
5883
5884 // #include <nlohmann/detail/input/lexer.hpp>
5885
5886
5887 #include <array> // array
5888 #include <clocale> // localeconv
5889 #include <cstddef> // size_t
5890 #include <cstdio> // snprintf
5891 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
5892 #include <initializer_list> // initializer_list
5893 #include <string> // char_traits, string
5894 #include <utility> // move
5895 #include <vector> // vector
5896
5897 // #include <nlohmann/detail/input/input_adapters.hpp>
5898
5899 // #include <nlohmann/detail/input/position_t.hpp>
5900
5901 // #include <nlohmann/detail/macro_scope.hpp>
5902
5903
5904 namespace nlohmann
5905 {
5906 namespace detail
5907 {
5909 // lexer //
5911
5912 template<typename BasicJsonType>
5913 class lexer_base
5914 {
5915 public:
5917 enum class token_type
5918 {
5919 uninitialized,
5920 literal_true,
5921 literal_false,
5922 literal_null,
5923 value_string,
5924 value_unsigned,
5925 value_integer,
5926 value_float,
5927 begin_array,
5928 begin_object,
5929 end_array,
5930 end_object,
5931 name_separator,
5932 value_separator,
5933 parse_error,
5934 end_of_input,
5935 literal_or_value
5936 };
5937
5939
5940 JSON_HEDLEY_CONST
5941 static const char* token_type_name(const token_type t) noexcept
5942 {
5943 switch (t)
5944 {
5945 case token_type::uninitialized:
5946 return "<uninitialized>";
5947 case token_type::literal_true:
5948 return "true literal";
5949 case token_type::literal_false:
5950 return "false literal";
5951 case token_type::literal_null:
5952 return "null literal";
5953 case token_type::value_string:
5954 return "string literal";
5955 case token_type::value_unsigned:
5956 case token_type::value_integer:
5957 case token_type::value_float:
5958 return "number literal";
5959 case token_type::begin_array:
5960 return "'['";
5961 case token_type::begin_object:
5962 return "'{'";
5963 case token_type::end_array:
5964 return "']'";
5965 case token_type::end_object:
5966 return "'}'";
5967 case token_type::name_separator:
5968 return "':'";
5969 case token_type::value_separator:
5970 return "','";
5971 case token_type::parse_error:
5972 return "<parse error>";
5973 case token_type::end_of_input:
5974 return "end of input";
5975 case token_type::literal_or_value:
5976 return "'[', '{', or a literal";
5977 // LCOV_EXCL_START
5978 default: // catch non-enum values
5979 return "unknown token";
5980 // LCOV_EXCL_STOP
5981 }
5982 }
5983 };
5989 template<typename BasicJsonType, typename InputAdapterType>
5990 class lexer : public lexer_base<BasicJsonType>
5991 {
5992 using number_integer_t = typename BasicJsonType::number_integer_t;
5993 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5994 using number_float_t = typename BasicJsonType::number_float_t;
5995 using string_t = typename BasicJsonType::string_t;
5996 using char_type = typename InputAdapterType::char_type;
5997 using char_int_type = typename std::char_traits<char_type>::int_type;
5998
5999 public:
6000 using token_type = typename lexer_base<BasicJsonType>::token_type;
6001
6002 explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false)
6003 : ia(std::move(adapter))
6004 , ignore_comments(ignore_comments_)
6005 , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
6006 {}
6007
6008 // delete because of pointer members
6009 lexer(const lexer&) = delete;
6010 lexer(lexer&&) = default;
6011 lexer& operator=(lexer&) = delete;
6012 lexer& operator=(lexer&&) = default;
6013 ~lexer() = default;
6014
6015 private:
6017 // locales
6019
6021 JSON_HEDLEY_PURE
6022 static char get_decimal_point() noexcept
6023 {
6024 const auto* loc = localeconv();
6025 JSON_ASSERT(loc != nullptr);
6026 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6027 }
6028
6030 // scan functions
6032
6048 int get_codepoint()
6049 {
6050 // this function only makes sense after reading `\u`
6051 JSON_ASSERT(current == 'u');
6052 int codepoint = 0;
6053
6054 const auto factors = { 12u, 8u, 4u, 0u };
6055 for (const auto factor : factors)
6056 {
6057 get();
6058
6059 if (current >= '0' && current <= '9')
6060 {
6061 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6062 }
6063 else if (current >= 'A' && current <= 'F')
6064 {
6065 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6066 }
6067 else if (current >= 'a' && current <= 'f')
6068 {
6069 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6070 }
6071 else
6072 {
6073 return -1;
6074 }
6075 }
6076
6077 JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6078 return codepoint;
6079 }
6080
6096 bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6097 {
6098 JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6099 add(current);
6100
6101 for (auto range = ranges.begin(); range != ranges.end(); ++range)
6102 {
6103 get();
6104 if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6105 {
6106 add(current);
6107 }
6108 else
6109 {
6110 error_message = "invalid string: ill-formed UTF-8 byte";
6111 return false;
6112 }
6113 }
6114
6115 return true;
6116 }
6117
6133 token_type scan_string()
6134 {
6135 // reset token_buffer (ignore opening quote)
6136 reset();
6137
6138 // we entered the function by reading an open quote
6139 JSON_ASSERT(current == '\"');
6140
6141 while (true)
6142 {
6143 // get next character
6144 switch (get())
6145 {
6146 // end of file while parsing string
6147 case std::char_traits<char_type>::eof():
6148 {
6149 error_message = "invalid string: missing closing quote";
6150 return token_type::parse_error;
6151 }
6152
6153 // closing quote
6154 case '\"':
6155 {
6156 return token_type::value_string;
6157 }
6158
6159 // escapes
6160 case '\\':
6161 {
6162 switch (get())
6163 {
6164 // quotation mark
6165 case '\"':
6166 add('\"');
6167 break;
6168 // reverse solidus
6169 case '\\':
6170 add('\\');
6171 break;
6172 // solidus
6173 case '/':
6174 add('/');
6175 break;
6176 // backspace
6177 case 'b':
6178 add('\b');
6179 break;
6180 // form feed
6181 case 'f':
6182 add('\f');
6183 break;
6184 // line feed
6185 case 'n':
6186 add('\n');
6187 break;
6188 // carriage return
6189 case 'r':
6190 add('\r');
6191 break;
6192 // tab
6193 case 't':
6194 add('\t');
6195 break;
6196
6197 // unicode escapes
6198 case 'u':
6199 {
6200 const int codepoint1 = get_codepoint();
6201 int codepoint = codepoint1; // start with codepoint1
6202
6203 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
6204 {
6205 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6206 return token_type::parse_error;
6207 }
6208
6209 // check if code point is a high surrogate
6210 if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6211 {
6212 // expect next \uxxxx entry
6213 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6214 {
6215 const int codepoint2 = get_codepoint();
6216
6217 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
6218 {
6219 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6220 return token_type::parse_error;
6221 }
6222
6223 // check if codepoint2 is a low surrogate
6224 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6225 {
6226 // overwrite codepoint
6227 codepoint = static_cast<int>(
6228 // high surrogate occupies the most significant 22 bits
6229 (static_cast<unsigned int>(codepoint1) << 10u)
6230 // low surrogate occupies the least significant 15 bits
6231 + static_cast<unsigned int>(codepoint2)
6232 // there is still the 0xD800, 0xDC00 and 0x10000 noise
6233 // in the result so we have to subtract with:
6234 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6235 - 0x35FDC00u);
6236 }
6237 else
6238 {
6239 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6240 return token_type::parse_error;
6241 }
6242 }
6243 else
6244 {
6245 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6246 return token_type::parse_error;
6247 }
6248 }
6249 else
6250 {
6251 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6252 {
6253 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6254 return token_type::parse_error;
6255 }
6256 }
6257
6258 // result of the above calculation yields a proper codepoint
6259 JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
6260
6261 // translate codepoint into bytes
6262 if (codepoint < 0x80)
6263 {
6264 // 1-byte characters: 0xxxxxxx (ASCII)
6265 add(static_cast<char_int_type>(codepoint));
6266 }
6267 else if (codepoint <= 0x7FF)
6268 {
6269 // 2-byte characters: 110xxxxx 10xxxxxx
6270 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
6271 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6272 }
6273 else if (codepoint <= 0xFFFF)
6274 {
6275 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
6276 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
6277 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6278 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6279 }
6280 else
6281 {
6282 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
6283 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
6284 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
6285 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6286 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6287 }
6288
6289 break;
6290 }
6291
6292 // other characters after escape
6293 default:
6294 error_message = "invalid string: forbidden character after backslash";
6295 return token_type::parse_error;
6296 }
6297
6298 break;
6299 }
6300
6301 // invalid control characters
6302 case 0x00:
6303 {
6304 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
6305 return token_type::parse_error;
6306 }
6307
6308 case 0x01:
6309 {
6310 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
6311 return token_type::parse_error;
6312 }
6313
6314 case 0x02:
6315 {
6316 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
6317 return token_type::parse_error;
6318 }
6319
6320 case 0x03:
6321 {
6322 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
6323 return token_type::parse_error;
6324 }
6325
6326 case 0x04:
6327 {
6328 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
6329 return token_type::parse_error;
6330 }
6331
6332 case 0x05:
6333 {
6334 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
6335 return token_type::parse_error;
6336 }
6337
6338 case 0x06:
6339 {
6340 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
6341 return token_type::parse_error;
6342 }
6343
6344 case 0x07:
6345 {
6346 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
6347 return token_type::parse_error;
6348 }
6349
6350 case 0x08:
6351 {
6352 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
6353 return token_type::parse_error;
6354 }
6355
6356 case 0x09:
6357 {
6358 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
6359 return token_type::parse_error;
6360 }
6361
6362 case 0x0A:
6363 {
6364 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
6365 return token_type::parse_error;
6366 }
6367
6368 case 0x0B:
6369 {
6370 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
6371 return token_type::parse_error;
6372 }
6373
6374 case 0x0C:
6375 {
6376 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
6377 return token_type::parse_error;
6378 }
6379
6380 case 0x0D:
6381 {
6382 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
6383 return token_type::parse_error;
6384 }
6385
6386 case 0x0E:
6387 {
6388 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
6389 return token_type::parse_error;
6390 }
6391
6392 case 0x0F:
6393 {
6394 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
6395 return token_type::parse_error;
6396 }
6397
6398 case 0x10:
6399 {
6400 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
6401 return token_type::parse_error;
6402 }
6403
6404 case 0x11:
6405 {
6406 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
6407 return token_type::parse_error;
6408 }
6409
6410 case 0x12:
6411 {
6412 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
6413 return token_type::parse_error;
6414 }
6415
6416 case 0x13:
6417 {
6418 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
6419 return token_type::parse_error;
6420 }
6421
6422 case 0x14:
6423 {
6424 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
6425 return token_type::parse_error;
6426 }
6427
6428 case 0x15:
6429 {
6430 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
6431 return token_type::parse_error;
6432 }
6433
6434 case 0x16:
6435 {
6436 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
6437 return token_type::parse_error;
6438 }
6439
6440 case 0x17:
6441 {
6442 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
6443 return token_type::parse_error;
6444 }
6445
6446 case 0x18:
6447 {
6448 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
6449 return token_type::parse_error;
6450 }
6451
6452 case 0x19:
6453 {
6454 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
6455 return token_type::parse_error;
6456 }
6457
6458 case 0x1A:
6459 {
6460 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
6461 return token_type::parse_error;
6462 }
6463
6464 case 0x1B:
6465 {
6466 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
6467 return token_type::parse_error;
6468 }
6469
6470 case 0x1C:
6471 {
6472 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
6473 return token_type::parse_error;
6474 }
6475
6476 case 0x1D:
6477 {
6478 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
6479 return token_type::parse_error;
6480 }
6481
6482 case 0x1E:
6483 {
6484 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
6485 return token_type::parse_error;
6486 }
6487
6488 case 0x1F:
6489 {
6490 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
6491 return token_type::parse_error;
6492 }
6493
6494 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
6495 case 0x20:
6496 case 0x21:
6497 case 0x23:
6498 case 0x24:
6499 case 0x25:
6500 case 0x26:
6501 case 0x27:
6502 case 0x28:
6503 case 0x29:
6504 case 0x2A:
6505 case 0x2B:
6506 case 0x2C:
6507 case 0x2D:
6508 case 0x2E:
6509 case 0x2F:
6510 case 0x30:
6511 case 0x31:
6512 case 0x32:
6513 case 0x33:
6514 case 0x34:
6515 case 0x35:
6516 case 0x36:
6517 case 0x37:
6518 case 0x38:
6519 case 0x39:
6520 case 0x3A:
6521 case 0x3B:
6522 case 0x3C:
6523 case 0x3D:
6524 case 0x3E:
6525 case 0x3F:
6526 case 0x40:
6527 case 0x41:
6528 case 0x42:
6529 case 0x43:
6530 case 0x44:
6531 case 0x45:
6532 case 0x46:
6533 case 0x47:
6534 case 0x48:
6535 case 0x49:
6536 case 0x4A:
6537 case 0x4B:
6538 case 0x4C:
6539 case 0x4D:
6540 case 0x4E:
6541 case 0x4F:
6542 case 0x50:
6543 case 0x51:
6544 case 0x52:
6545 case 0x53:
6546 case 0x54:
6547 case 0x55:
6548 case 0x56:
6549 case 0x57:
6550 case 0x58:
6551 case 0x59:
6552 case 0x5A:
6553 case 0x5B:
6554 case 0x5D:
6555 case 0x5E:
6556 case 0x5F:
6557 case 0x60:
6558 case 0x61:
6559 case 0x62:
6560 case 0x63:
6561 case 0x64:
6562 case 0x65:
6563 case 0x66:
6564 case 0x67:
6565 case 0x68:
6566 case 0x69:
6567 case 0x6A:
6568 case 0x6B:
6569 case 0x6C:
6570 case 0x6D:
6571 case 0x6E:
6572 case 0x6F:
6573 case 0x70:
6574 case 0x71:
6575 case 0x72:
6576 case 0x73:
6577 case 0x74:
6578 case 0x75:
6579 case 0x76:
6580 case 0x77:
6581 case 0x78:
6582 case 0x79:
6583 case 0x7A:
6584 case 0x7B:
6585 case 0x7C:
6586 case 0x7D:
6587 case 0x7E:
6588 case 0x7F:
6589 {
6590 add(current);
6591 break;
6592 }
6593
6594 // U+0080..U+07FF: bytes C2..DF 80..BF
6595 case 0xC2:
6596 case 0xC3:
6597 case 0xC4:
6598 case 0xC5:
6599 case 0xC6:
6600 case 0xC7:
6601 case 0xC8:
6602 case 0xC9:
6603 case 0xCA:
6604 case 0xCB:
6605 case 0xCC:
6606 case 0xCD:
6607 case 0xCE:
6608 case 0xCF:
6609 case 0xD0:
6610 case 0xD1:
6611 case 0xD2:
6612 case 0xD3:
6613 case 0xD4:
6614 case 0xD5:
6615 case 0xD6:
6616 case 0xD7:
6617 case 0xD8:
6618 case 0xD9:
6619 case 0xDA:
6620 case 0xDB:
6621 case 0xDC:
6622 case 0xDD:
6623 case 0xDE:
6624 case 0xDF:
6625 {
6626 if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
6627 {
6628 return token_type::parse_error;
6629 }
6630 break;
6631 }
6632
6633 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
6634 case 0xE0:
6635 {
6636 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
6637 {
6638 return token_type::parse_error;
6639 }
6640 break;
6641 }
6642
6643 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
6644 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
6645 case 0xE1:
6646 case 0xE2:
6647 case 0xE3:
6648 case 0xE4:
6649 case 0xE5:
6650 case 0xE6:
6651 case 0xE7:
6652 case 0xE8:
6653 case 0xE9:
6654 case 0xEA:
6655 case 0xEB:
6656 case 0xEC:
6657 case 0xEE:
6658 case 0xEF:
6659 {
6660 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
6661 {
6662 return token_type::parse_error;
6663 }
6664 break;
6665 }
6666
6667 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
6668 case 0xED:
6669 {
6670 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
6671 {
6672 return token_type::parse_error;
6673 }
6674 break;
6675 }
6676
6677 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
6678 case 0xF0:
6679 {
6680 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6681 {
6682 return token_type::parse_error;
6683 }
6684 break;
6685 }
6686
6687 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
6688 case 0xF1:
6689 case 0xF2:
6690 case 0xF3:
6691 {
6692 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6693 {
6694 return token_type::parse_error;
6695 }
6696 break;
6697 }
6698
6699 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
6700 case 0xF4:
6701 {
6702 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
6703 {
6704 return token_type::parse_error;
6705 }
6706 break;
6707 }
6708
6709 // remaining bytes (80..C1 and F5..FF) are ill-formed
6710 default:
6711 {
6712 error_message = "invalid string: ill-formed UTF-8 byte";
6713 return token_type::parse_error;
6714 }
6715 }
6716 }
6717 }
6718
6723 bool scan_comment()
6724 {
6725 switch (get())
6726 {
6727 // single-line comments skip input until a newline or EOF is read
6728 case '/':
6729 {
6730 while (true)
6731 {
6732 switch (get())
6733 {
6734 case '\n':
6735 case '\r':
6736 case std::char_traits<char_type>::eof():
6737 case '\0':
6738 return true;
6739
6740 default:
6741 break;
6742 }
6743 }
6744 }
6745
6746 // multi-line comments skip input until */ is read
6747 case '*':
6748 {
6749 while (true)
6750 {
6751 switch (get())
6752 {
6753 case std::char_traits<char_type>::eof():
6754 case '\0':
6755 {
6756 error_message = "invalid comment; missing closing '*/'";
6757 return false;
6758 }
6759
6760 case '*':
6761 {
6762 switch (get())
6763 {
6764 case '/':
6765 return true;
6766
6767 default:
6768 {
6769 unget();
6770 continue;
6771 }
6772 }
6773 }
6774
6775 default:
6776 continue;
6777 }
6778 }
6779 }
6780
6781 // unexpected character after reading '/'
6782 default:
6783 {
6784 error_message = "invalid comment; expecting '/' or '*' after '/'";
6785 return false;
6786 }
6787 }
6788 }
6789
6790 JSON_HEDLEY_NON_NULL(2)
6791 static void strtof(float& f, const char* str, char** endptr) noexcept
6792 {
6793 f = std::strtof(str, endptr);
6794 }
6795
6796 JSON_HEDLEY_NON_NULL(2)
6797 static void strtof(double& f, const char* str, char** endptr) noexcept
6798 {
6799 f = std::strtod(str, endptr);
6800 }
6801
6802 JSON_HEDLEY_NON_NULL(2)
6803 static void strtof(long double& f, const char* str, char** endptr) noexcept
6804 {
6805 f = std::strtold(str, endptr);
6806 }
6807
6848 token_type scan_number() // lgtm [cpp/use-of-goto]
6849 {
6850 // reset token_buffer to store the number's bytes
6851 reset();
6852
6853 // the type of the parsed number; initially set to unsigned; will be
6854 // changed if minus sign, decimal point or exponent is read
6855 token_type number_type = token_type::value_unsigned;
6856
6857 // state (init): we just found out we need to scan a number
6858 switch (current)
6859 {
6860 case '-':
6861 {
6862 add(current);
6863 goto scan_number_minus;
6864 }
6865
6866 case '0':
6867 {
6868 add(current);
6869 goto scan_number_zero;
6870 }
6871
6872 case '1':
6873 case '2':
6874 case '3':
6875 case '4':
6876 case '5':
6877 case '6':
6878 case '7':
6879 case '8':
6880 case '9':
6881 {
6882 add(current);
6883 goto scan_number_any1;
6884 }
6885
6886 // all other characters are rejected outside scan_number()
6887 default: // LCOV_EXCL_LINE
6888 JSON_ASSERT(false); // LCOV_EXCL_LINE
6889 }
6890
6891 scan_number_minus:
6892 // state: we just parsed a leading minus sign
6893 number_type = token_type::value_integer;
6894 switch (get())
6895 {
6896 case '0':
6897 {
6898 add(current);
6899 goto scan_number_zero;
6900 }
6901
6902 case '1':
6903 case '2':
6904 case '3':
6905 case '4':
6906 case '5':
6907 case '6':
6908 case '7':
6909 case '8':
6910 case '9':
6911 {
6912 add(current);
6913 goto scan_number_any1;
6914 }
6915
6916 default:
6917 {
6918 error_message = "invalid number; expected digit after '-'";
6919 return token_type::parse_error;
6920 }
6921 }
6922
6923 scan_number_zero:
6924 // state: we just parse a zero (maybe with a leading minus sign)
6925 switch (get())
6926 {
6927 case '.':
6928 {
6929 add(decimal_point_char);
6930 goto scan_number_decimal1;
6931 }
6932
6933 case 'e':
6934 case 'E':
6935 {
6936 add(current);
6937 goto scan_number_exponent;
6938 }
6939
6940 default:
6941 goto scan_number_done;
6942 }
6943
6944 scan_number_any1:
6945 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
6946 switch (get())
6947 {
6948 case '0':
6949 case '1':
6950 case '2':
6951 case '3':
6952 case '4':
6953 case '5':
6954 case '6':
6955 case '7':
6956 case '8':
6957 case '9':
6958 {
6959 add(current);
6960 goto scan_number_any1;
6961 }
6962
6963 case '.':
6964 {
6965 add(decimal_point_char);
6966 goto scan_number_decimal1;
6967 }
6968
6969 case 'e':
6970 case 'E':
6971 {
6972 add(current);
6973 goto scan_number_exponent;
6974 }
6975
6976 default:
6977 goto scan_number_done;
6978 }
6979
6980 scan_number_decimal1:
6981 // state: we just parsed a decimal point
6982 number_type = token_type::value_float;
6983 switch (get())
6984 {
6985 case '0':
6986 case '1':
6987 case '2':
6988 case '3':
6989 case '4':
6990 case '5':
6991 case '6':
6992 case '7':
6993 case '8':
6994 case '9':
6995 {
6996 add(current);
6997 goto scan_number_decimal2;
6998 }
6999
7000 default:
7001 {
7002 error_message = "invalid number; expected digit after '.'";
7003 return token_type::parse_error;
7004 }
7005 }
7006
7007 scan_number_decimal2:
7008 // we just parsed at least one number after a decimal point
7009 switch (get())
7010 {
7011 case '0':
7012 case '1':
7013 case '2':
7014 case '3':
7015 case '4':
7016 case '5':
7017 case '6':
7018 case '7':
7019 case '8':
7020 case '9':
7021 {
7022 add(current);
7023 goto scan_number_decimal2;
7024 }
7025
7026 case 'e':
7027 case 'E':
7028 {
7029 add(current);
7030 goto scan_number_exponent;
7031 }
7032
7033 default:
7034 goto scan_number_done;
7035 }
7036
7037 scan_number_exponent:
7038 // we just parsed an exponent
7039 number_type = token_type::value_float;
7040 switch (get())
7041 {
7042 case '+':
7043 case '-':
7044 {
7045 add(current);
7046 goto scan_number_sign;
7047 }
7048
7049 case '0':
7050 case '1':
7051 case '2':
7052 case '3':
7053 case '4':
7054 case '5':
7055 case '6':
7056 case '7':
7057 case '8':
7058 case '9':
7059 {
7060 add(current);
7061 goto scan_number_any2;
7062 }
7063
7064 default:
7065 {
7066 error_message =
7067 "invalid number; expected '+', '-', or digit after exponent";
7068 return token_type::parse_error;
7069 }
7070 }
7071
7072 scan_number_sign:
7073 // we just parsed an exponent sign
7074 switch (get())
7075 {
7076 case '0':
7077 case '1':
7078 case '2':
7079 case '3':
7080 case '4':
7081 case '5':
7082 case '6':
7083 case '7':
7084 case '8':
7085 case '9':
7086 {
7087 add(current);
7088 goto scan_number_any2;
7089 }
7090
7091 default:
7092 {
7093 error_message = "invalid number; expected digit after exponent sign";
7094 return token_type::parse_error;
7095 }
7096 }
7097
7098 scan_number_any2:
7099 // we just parsed a number after the exponent or exponent sign
7100 switch (get())
7101 {
7102 case '0':
7103 case '1':
7104 case '2':
7105 case '3':
7106 case '4':
7107 case '5':
7108 case '6':
7109 case '7':
7110 case '8':
7111 case '9':
7112 {
7113 add(current);
7114 goto scan_number_any2;
7115 }
7116
7117 default:
7118 goto scan_number_done;
7119 }
7120
7121 scan_number_done:
7122 // unget the character after the number (we only read it to know that
7123 // we are done scanning a number)
7124 unget();
7125
7126 char* endptr = nullptr;
7127 errno = 0;
7128
7129 // try to parse integers first and fall back to floats
7130 if (number_type == token_type::value_unsigned)
7131 {
7132 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7133
7134 // we checked the number format before
7135 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7136
7137 if (errno == 0)
7138 {
7139 value_unsigned = static_cast<number_unsigned_t>(x);
7140 if (value_unsigned == x)
7141 {
7142 return token_type::value_unsigned;
7143 }
7144 }
7145 }
7146 else if (number_type == token_type::value_integer)
7147 {
7148 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7149
7150 // we checked the number format before
7151 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7152
7153 if (errno == 0)
7154 {
7155 value_integer = static_cast<number_integer_t>(x);
7156 if (value_integer == x)
7157 {
7158 return token_type::value_integer;
7159 }
7160 }
7161 }
7162
7163 // this code is reached if we parse a floating-point number or if an
7164 // integer conversion above failed
7165 strtof(value_float, token_buffer.data(), &endptr);
7166
7167 // we checked the number format before
7168 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7169
7170 return token_type::value_float;
7171 }
7172
7178 JSON_HEDLEY_NON_NULL(2)
7179 token_type scan_literal(const char_type* literal_text, const std::size_t length,
7180 token_type return_type)
7181 {
7182 JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
7183 for (std::size_t i = 1; i < length; ++i)
7184 {
7185 if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
7186 {
7187 error_message = "invalid literal";
7188 return token_type::parse_error;
7189 }
7190 }
7191 return return_type;
7192 }
7193
7195 // input management
7197
7199 void reset() noexcept
7200 {
7201 token_buffer.clear();
7202 token_string.clear();
7203 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7204 }
7205
7206 /*
7207 @brief get next character from the input
7208
7209 This function provides the interface to the used input adapter. It does
7210 not throw in case the input reached EOF, but returns a
7211 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
7212 for use in error messages.
7213
7214 @return character read from the input
7215 */
7216 char_int_type get()
7217 {
7218 ++position.chars_read_total;
7219 ++position.chars_read_current_line;
7220
7221 if (next_unget)
7222 {
7223 // just reset the next_unget variable and work with current
7224 next_unget = false;
7225 }
7226 else
7227 {
7228 current = ia.get_character();
7229 }
7230
7231 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7232 {
7233 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7234 }
7235
7236 if (current == '\n')
7237 {
7238 ++position.lines_read;
7239 position.chars_read_current_line = 0;
7240 }
7241
7242 return current;
7243 }
7244
7253 void unget()
7254 {
7255 next_unget = true;
7256
7257 --position.chars_read_total;
7258
7259 // in case we "unget" a newline, we have to also decrement the lines_read
7260 if (position.chars_read_current_line == 0)
7261 {
7262 if (position.lines_read > 0)
7263 {
7264 --position.lines_read;
7265 }
7266 }
7267 else
7268 {
7269 --position.chars_read_current_line;
7270 }
7271
7272 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7273 {
7274 JSON_ASSERT(!token_string.empty());
7275 token_string.pop_back();
7276 }
7277 }
7278
7280 void add(char_int_type c)
7281 {
7282 token_buffer.push_back(static_cast<typename string_t::value_type>(c));
7283 }
7284
7285 public:
7287 // value getters
7289
7291 constexpr number_integer_t get_number_integer() const noexcept
7292 {
7293 return value_integer;
7294 }
7295
7297 constexpr number_unsigned_t get_number_unsigned() const noexcept
7298 {
7299 return value_unsigned;
7300 }
7301
7303 constexpr number_float_t get_number_float() const noexcept
7304 {
7305 return value_float;
7306 }
7307
7309 string_t& get_string()
7310 {
7311 return token_buffer;
7312 }
7313
7315 // diagnostics
7317
7319 constexpr position_t get_position() const noexcept
7320 {
7321 return position;
7322 }
7323
7327 std::string get_token_string() const
7328 {
7329 // escape control characters
7330 std::string result;
7331 for (const auto c : token_string)
7332 {
7333 if (static_cast<unsigned char>(c) <= '\x1F')
7334 {
7335 // escape control characters
7336 std::array<char, 9> cs{{}};
7337 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c));
7338 result += cs.data();
7339 }
7340 else
7341 {
7342 // add character as is
7343 result.push_back(static_cast<std::string::value_type>(c));
7344 }
7345 }
7346
7347 return result;
7348 }
7349
7351
7352 constexpr const char* get_error_message() const noexcept
7353 {
7354 return error_message;
7355 }
7356
7358 // actual scanner
7360
7365 bool skip_bom()
7366 {
7367 if (get() == 0xEF)
7368 {
7369 // check if we completely parse the BOM
7370 return get() == 0xBB && get() == 0xBF;
7371 }
7372
7373 // the first character is not the beginning of the BOM; unget it to
7374 // process is later
7375 unget();
7376 return true;
7377 }
7378
7379 void skip_whitespace()
7380 {
7381 do
7382 {
7383 get();
7384 }
7385 while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
7386 }
7387
7388 token_type scan()
7389 {
7390 // initially, skip the BOM
7391 if (position.chars_read_total == 0 && !skip_bom())
7392 {
7393 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
7394 return token_type::parse_error;
7395 }
7396
7397 // read next character and ignore whitespace
7398 skip_whitespace();
7399
7400 // ignore comments
7401 while (ignore_comments && current == '/')
7402 {
7403 if (!scan_comment())
7404 {
7405 return token_type::parse_error;
7406 }
7407
7408 // skip following whitespace
7409 skip_whitespace();
7410 }
7411
7412 switch (current)
7413 {
7414 // structural characters
7415 case '[':
7416 return token_type::begin_array;
7417 case ']':
7418 return token_type::end_array;
7419 case '{':
7420 return token_type::begin_object;
7421 case '}':
7422 return token_type::end_object;
7423 case ':':
7424 return token_type::name_separator;
7425 case ',':
7426 return token_type::value_separator;
7427
7428 // literals
7429 case 't':
7430 {
7431 std::array<char_type, 4> true_literal = {{'t', 'r', 'u', 'e'}};
7432 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
7433 }
7434 case 'f':
7435 {
7436 std::array<char_type, 5> false_literal = {{'f', 'a', 'l', 's', 'e'}};
7437 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
7438 }
7439 case 'n':
7440 {
7441 std::array<char_type, 4> null_literal = {{'n', 'u', 'l', 'l'}};
7442 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
7443 }
7444
7445 // string
7446 case '\"':
7447 return scan_string();
7448
7449 // number
7450 case '-':
7451 case '0':
7452 case '1':
7453 case '2':
7454 case '3':
7455 case '4':
7456 case '5':
7457 case '6':
7458 case '7':
7459 case '8':
7460 case '9':
7461 return scan_number();
7462
7463 // end of input (the null byte is needed when parsing from
7464 // string literals)
7465 case '\0':
7466 case std::char_traits<char_type>::eof():
7467 return token_type::end_of_input;
7468
7469 // error
7470 default:
7471 error_message = "invalid literal";
7472 return token_type::parse_error;
7473 }
7474 }
7475
7476 private:
7478 InputAdapterType ia;
7479
7481 const bool ignore_comments = false;
7482
7484 char_int_type current = std::char_traits<char_type>::eof();
7485
7487 bool next_unget = false;
7488
7490 position_t position {};
7491
7493 std::vector<char_type> token_string {};
7494
7496 string_t token_buffer {};
7497
7499 const char* error_message = "";
7500
7501 // number values
7502 number_integer_t value_integer = 0;
7503 number_unsigned_t value_unsigned = 0;
7504 number_float_t value_float = 0;
7505
7507 const char_int_type decimal_point_char = '.';
7508 };
7509 } // namespace detail
7510 } // namespace nlohmann
7511
7512 // #include <nlohmann/detail/macro_scope.hpp>
7513
7514 // #include <nlohmann/detail/meta/is_sax.hpp>
7515
7516
7517 #include <cstdint> // size_t
7518 #include <utility> // declval
7519 #include <string> // string
7520
7521 // #include <nlohmann/detail/meta/detected.hpp>
7522
7523 // #include <nlohmann/detail/meta/type_traits.hpp>
7524
7525
7526 namespace nlohmann
7527 {
7528 namespace detail
7529 {
7530 template<typename T>
7531 using null_function_t = decltype(std::declval<T&>().null());
7532
7533 template<typename T>
7534 using boolean_function_t =
7535 decltype(std::declval<T&>().boolean(std::declval<bool>()));
7536
7537 template<typename T, typename Integer>
7538 using number_integer_function_t =
7539 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
7540
7541 template<typename T, typename Unsigned>
7542 using number_unsigned_function_t =
7543 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
7544
7545 template<typename T, typename Float, typename String>
7546 using number_float_function_t = decltype(std::declval<T&>().number_float(
7547 std::declval<Float>(), std::declval<const String&>()));
7548
7549 template<typename T, typename String>
7550 using string_function_t =
7551 decltype(std::declval<T&>().string(std::declval<String&>()));
7552
7553 template<typename T, typename Binary>
7554 using binary_function_t =
7555 decltype(std::declval<T&>().binary(std::declval<Binary&>()));
7556
7557 template<typename T>
7558 using start_object_function_t =
7559 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
7560
7561 template<typename T, typename String>
7562 using key_function_t =
7563 decltype(std::declval<T&>().key(std::declval<String&>()));
7564
7565 template<typename T>
7566 using end_object_function_t = decltype(std::declval<T&>().end_object());
7567
7568 template<typename T>
7569 using start_array_function_t =
7570 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
7571
7572 template<typename T>
7573 using end_array_function_t = decltype(std::declval<T&>().end_array());
7574
7575 template<typename T, typename Exception>
7576 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
7577 std::declval<std::size_t>(), std::declval<const std::string&>(),
7578 std::declval<const Exception&>()));
7579
7580 template<typename SAX, typename BasicJsonType>
7581 struct is_sax
7582 {
7583 private:
7584 static_assert(is_basic_json<BasicJsonType>::value,
7585 "BasicJsonType must be of type basic_json<...>");
7586
7587 using number_integer_t = typename BasicJsonType::number_integer_t;
7588 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7589 using number_float_t = typename BasicJsonType::number_float_t;
7590 using string_t = typename BasicJsonType::string_t;
7591 using binary_t = typename BasicJsonType::binary_t;
7592 using exception_t = typename BasicJsonType::exception;
7593
7594 public:
7595 static constexpr bool value =
7596 is_detected_exact<bool, null_function_t, SAX>::value &&
7597 is_detected_exact<bool, boolean_function_t, SAX>::value &&
7598 is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
7599 is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
7600 is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
7601 is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
7602 is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
7603 is_detected_exact<bool, start_object_function_t, SAX>::value &&
7604 is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
7605 is_detected_exact<bool, end_object_function_t, SAX>::value &&
7606 is_detected_exact<bool, start_array_function_t, SAX>::value &&
7607 is_detected_exact<bool, end_array_function_t, SAX>::value &&
7608 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
7609 };
7610
7611 template<typename SAX, typename BasicJsonType>
7612 struct is_sax_static_asserts
7613 {
7614 private:
7615 static_assert(is_basic_json<BasicJsonType>::value,
7616 "BasicJsonType must be of type basic_json<...>");
7617
7618 using number_integer_t = typename BasicJsonType::number_integer_t;
7619 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7620 using number_float_t = typename BasicJsonType::number_float_t;
7621 using string_t = typename BasicJsonType::string_t;
7622 using binary_t = typename BasicJsonType::binary_t;
7623 using exception_t = typename BasicJsonType::exception;
7624
7625 public:
7626 static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
7627 "Missing/invalid function: bool null()");
7628 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
7629 "Missing/invalid function: bool boolean(bool)");
7630 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
7631 "Missing/invalid function: bool boolean(bool)");
7632 static_assert(
7633 is_detected_exact<bool, number_integer_function_t, SAX,
7634 number_integer_t>::value,
7635 "Missing/invalid function: bool number_integer(number_integer_t)");
7636 static_assert(
7637 is_detected_exact<bool, number_unsigned_function_t, SAX,
7638 number_unsigned_t>::value,
7639 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
7640 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
7641 number_float_t, string_t>::value,
7642 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
7643 static_assert(
7644 is_detected_exact<bool, string_function_t, SAX, string_t>::value,
7645 "Missing/invalid function: bool string(string_t&)");
7646 static_assert(
7647 is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,
7648 "Missing/invalid function: bool binary(binary_t&)");
7649 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
7650 "Missing/invalid function: bool start_object(std::size_t)");
7651 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
7652 "Missing/invalid function: bool key(string_t&)");
7653 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
7654 "Missing/invalid function: bool end_object()");
7655 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
7656 "Missing/invalid function: bool start_array(std::size_t)");
7657 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
7658 "Missing/invalid function: bool end_array()");
7659 static_assert(
7660 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
7661 "Missing/invalid function: bool parse_error(std::size_t, const "
7662 "std::string&, const exception&)");
7663 };
7664 } // namespace detail
7665 } // namespace nlohmann
7666
7667 // #include <nlohmann/detail/value_t.hpp>
7668
7669
7670 namespace nlohmann
7671 {
7672 namespace detail
7673 {
7674
7676 enum class cbor_tag_handler_t
7677 {
7678 error,
7679 ignore
7680 };
7681
7689 static inline bool little_endianess(int num = 1) noexcept
7690 {
7691 return *reinterpret_cast<char*>(&num) == 1;
7692 }
7693
7694
7696 // binary reader //
7698
7702 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
7703 class binary_reader
7704 {
7705 using number_integer_t = typename BasicJsonType::number_integer_t;
7706 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7707 using number_float_t = typename BasicJsonType::number_float_t;
7708 using string_t = typename BasicJsonType::string_t;
7709 using binary_t = typename BasicJsonType::binary_t;
7710 using json_sax_t = SAX;
7711 using char_type = typename InputAdapterType::char_type;
7712 using char_int_type = typename std::char_traits<char_type>::int_type;
7713
7714 public:
7720 explicit binary_reader(InputAdapterType&& adapter) : ia(std::move(adapter))
7721 {
7722 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
7723 }
7724
7725 // make class move-only
7726 binary_reader(const binary_reader&) = delete;
7727 binary_reader(binary_reader&&) = default;
7728 binary_reader& operator=(const binary_reader&) = delete;
7729 binary_reader& operator=(binary_reader&&) = default;
7730 ~binary_reader() = default;
7731
7740 JSON_HEDLEY_NON_NULL(3)
7741 bool sax_parse(const input_format_t format,
7742 json_sax_t* sax_,
7743 const bool strict = true,
7744 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
7745 {
7746 sax = sax_;
7747 bool result = false;
7748
7749 switch (format)
7750 {
7751 case input_format_t::bson:
7752 result = parse_bson_internal();
7753 break;
7754
7755 case input_format_t::cbor:
7756 result = parse_cbor_internal(true, tag_handler);
7757 break;
7758
7759 case input_format_t::msgpack:
7760 result = parse_msgpack_internal();
7761 break;
7762
7763 case input_format_t::ubjson:
7764 result = parse_ubjson_internal();
7765 break;
7766
7767 default: // LCOV_EXCL_LINE
7768 JSON_ASSERT(false); // LCOV_EXCL_LINE
7769 }
7770
7771 // strict mode: next byte must be EOF
7772 if (result && strict)
7773 {
7774 if (format == input_format_t::ubjson)
7775 {
7776 get_ignore_noop();
7777 }
7778 else
7779 {
7780 get();
7781 }
7782
7783 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
7784 {
7785 return sax->parse_error(chars_read, get_token_string(),
7786 parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
7787 }
7788 }
7789
7790 return result;
7791 }
7792
7793 private:
7795 // BSON //
7797
7802 bool parse_bson_internal()
7803 {
7804 std::int32_t document_size{};
7805 get_number<std::int32_t, true>(input_format_t::bson, document_size);
7806
7807 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
7808 {
7809 return false;
7810 }
7811
7812 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
7813 {
7814 return false;
7815 }
7816
7817 return sax->end_object();
7818 }
7819
7827 bool get_bson_cstr(string_t& result)
7828 {
7829 auto out = std::back_inserter(result);
7830 while (true)
7831 {
7832 get();
7833 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
7834 {
7835 return false;
7836 }
7837 if (current == 0x00)
7838 {
7839 return true;
7840 }
7841 *out++ = static_cast<typename string_t::value_type>(current);
7842 }
7843 }
7844
7856 template<typename NumberType>
7857 bool get_bson_string(const NumberType len, string_t& result)
7858 {
7859 if (JSON_HEDLEY_UNLIKELY(len < 1))
7860 {
7861 auto last_token = get_token_string();
7862 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")));
7863 }
7864
7865 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
7866 }
7867
7877 template<typename NumberType>
7878 bool get_bson_binary(const NumberType len, binary_t& result)
7879 {
7880 if (JSON_HEDLEY_UNLIKELY(len < 0))
7881 {
7882 auto last_token = get_token_string();
7883 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")));
7884 }
7885
7886 // All BSON binary values have a subtype
7887 std::uint8_t subtype{};
7888 get_number<std::uint8_t>(input_format_t::bson, subtype);
7889 result.set_subtype(subtype);
7890
7891 return get_binary(input_format_t::bson, len, result);
7892 }
7893
7904 bool parse_bson_element_internal(const char_int_type element_type,
7905 const std::size_t element_type_parse_position)
7906 {
7907 switch (element_type)
7908 {
7909 case 0x01: // double
7910 {
7911 double number{};
7912 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
7913 }
7914
7915 case 0x02: // string
7916 {
7917 std::int32_t len{};
7918 string_t value;
7919 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
7920 }
7921
7922 case 0x03: // object
7923 {
7924 return parse_bson_internal();
7925 }
7926
7927 case 0x04: // array
7928 {
7929 return parse_bson_array();
7930 }
7931
7932 case 0x05: // binary
7933 {
7934 std::int32_t len{};
7935 binary_t value;
7936 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
7937 }
7938
7939 case 0x08: // boolean
7940 {
7941 return sax->boolean(get() != 0);
7942 }
7943
7944 case 0x0A: // null
7945 {
7946 return sax->null();
7947 }
7948
7949 case 0x10: // int32
7950 {
7951 std::int32_t value{};
7952 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
7953 }
7954
7955 case 0x12: // int64
7956 {
7957 std::int64_t value{};
7958 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
7959 }
7960
7961 default: // anything else not supported (yet)
7962 {
7963 std::array<char, 3> cr{{}};
7964 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type));
7965 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())));
7966 }
7967 }
7968 }
7969
7982 bool parse_bson_element_list(const bool is_array)
7983 {
7984 string_t key;
7985
7986 while (auto element_type = get())
7987 {
7988 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
7989 {
7990 return false;
7991 }
7992
7993 const std::size_t element_type_parse_position = chars_read;
7994 if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
7995 {
7996 return false;
7997 }
7998
7999 if (!is_array && !sax->key(key))
8000 {
8001 return false;
8002 }
8003
8004 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
8005 {
8006 return false;
8007 }
8008
8009 // get_bson_cstr only appends
8010 key.clear();
8011 }
8012
8013 return true;
8014 }
8015
8020 bool parse_bson_array()
8021 {
8022 std::int32_t document_size{};
8023 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8024
8025 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
8026 {
8027 return false;
8028 }
8029
8030 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8031 {
8032 return false;
8033 }
8034
8035 return sax->end_array();
8036 }
8037
8039 // CBOR //
8041
8050 bool parse_cbor_internal(const bool get_char,
8051 const cbor_tag_handler_t tag_handler)
8052 {
8053 switch (get_char ? get() : current)
8054 {
8055 // EOF
8056 case std::char_traits<char_type>::eof():
8057 return unexpect_eof(input_format_t::cbor, "value");
8058
8059 // Integer 0x00..0x17 (0..23)
8060 case 0x00:
8061 case 0x01:
8062 case 0x02:
8063 case 0x03:
8064 case 0x04:
8065 case 0x05:
8066 case 0x06:
8067 case 0x07:
8068 case 0x08:
8069 case 0x09:
8070 case 0x0A:
8071 case 0x0B:
8072 case 0x0C:
8073 case 0x0D:
8074 case 0x0E:
8075 case 0x0F:
8076 case 0x10:
8077 case 0x11:
8078 case 0x12:
8079 case 0x13:
8080 case 0x14:
8081 case 0x15:
8082 case 0x16:
8083 case 0x17:
8084 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8085
8086 case 0x18: // Unsigned integer (one-byte uint8_t follows)
8087 {
8088 std::uint8_t number{};
8089 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8090 }
8091
8092 case 0x19: // Unsigned integer (two-byte uint16_t follows)
8093 {
8094 std::uint16_t number{};
8095 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8096 }
8097
8098 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8099 {
8100 std::uint32_t number{};
8101 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8102 }
8103
8104 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8105 {
8106 std::uint64_t number{};
8107 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8108 }
8109
8110 // Negative integer -1-0x00..-1-0x17 (-1..-24)
8111 case 0x20:
8112 case 0x21:
8113 case 0x22:
8114 case 0x23:
8115 case 0x24:
8116 case 0x25:
8117 case 0x26:
8118 case 0x27:
8119 case 0x28:
8120 case 0x29:
8121 case 0x2A:
8122 case 0x2B:
8123 case 0x2C:
8124 case 0x2D:
8125 case 0x2E:
8126 case 0x2F:
8127 case 0x30:
8128 case 0x31:
8129 case 0x32:
8130 case 0x33:
8131 case 0x34:
8132 case 0x35:
8133 case 0x36:
8134 case 0x37:
8135 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8136
8137 case 0x38: // Negative integer (one-byte uint8_t follows)
8138 {
8139 std::uint8_t number{};
8140 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8141 }
8142
8143 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8144 {
8145 std::uint16_t number{};
8146 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8147 }
8148
8149 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8150 {
8151 std::uint32_t number{};
8152 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8153 }
8154
8155 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8156 {
8157 std::uint64_t number{};
8158 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8159 - static_cast<number_integer_t>(number));
8160 }
8161
8162 // Binary data (0x00..0x17 bytes follow)
8163 case 0x40:
8164 case 0x41:
8165 case 0x42:
8166 case 0x43:
8167 case 0x44:
8168 case 0x45:
8169 case 0x46:
8170 case 0x47:
8171 case 0x48:
8172 case 0x49:
8173 case 0x4A:
8174 case 0x4B:
8175 case 0x4C:
8176 case 0x4D:
8177 case 0x4E:
8178 case 0x4F:
8179 case 0x50:
8180 case 0x51:
8181 case 0x52:
8182 case 0x53:
8183 case 0x54:
8184 case 0x55:
8185 case 0x56:
8186 case 0x57:
8187 case 0x58: // Binary data (one-byte uint8_t for n follows)
8188 case 0x59: // Binary data (two-byte uint16_t for n follow)
8189 case 0x5A: // Binary data (four-byte uint32_t for n follow)
8190 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8191 case 0x5F: // Binary data (indefinite length)
8192 {
8193 binary_t b;
8194 return get_cbor_binary(b) && sax->binary(b);
8195 }
8196
8197 // UTF-8 string (0x00..0x17 bytes follow)
8198 case 0x60:
8199 case 0x61:
8200 case 0x62:
8201 case 0x63:
8202 case 0x64:
8203 case 0x65:
8204 case 0x66:
8205 case 0x67:
8206 case 0x68:
8207 case 0x69:
8208 case 0x6A:
8209 case 0x6B:
8210 case 0x6C:
8211 case 0x6D:
8212 case 0x6E:
8213 case 0x6F:
8214 case 0x70:
8215 case 0x71:
8216 case 0x72:
8217 case 0x73:
8218 case 0x74:
8219 case 0x75:
8220 case 0x76:
8221 case 0x77:
8222 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8223 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8224 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8225 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8226 case 0x7F: // UTF-8 string (indefinite length)
8227 {
8228 string_t s;
8229 return get_cbor_string(s) && sax->string(s);
8230 }
8231
8232 // array (0x00..0x17 data items follow)
8233 case 0x80:
8234 case 0x81:
8235 case 0x82:
8236 case 0x83:
8237 case 0x84:
8238 case 0x85:
8239 case 0x86:
8240 case 0x87:
8241 case 0x88:
8242 case 0x89:
8243 case 0x8A:
8244 case 0x8B:
8245 case 0x8C:
8246 case 0x8D:
8247 case 0x8E:
8248 case 0x8F:
8249 case 0x90:
8250 case 0x91:
8251 case 0x92:
8252 case 0x93:
8253 case 0x94:
8254 case 0x95:
8255 case 0x96:
8256 case 0x97:
8257 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8258
8259 case 0x98: // array (one-byte uint8_t for n follows)
8260 {
8261 std::uint8_t len{};
8262 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8263 }
8264
8265 case 0x99: // array (two-byte uint16_t for n follow)
8266 {
8267 std::uint16_t len{};
8268 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8269 }
8270
8271 case 0x9A: // array (four-byte uint32_t for n follow)
8272 {
8273 std::uint32_t len{};
8274 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8275 }
8276
8277 case 0x9B: // array (eight-byte uint64_t for n follow)
8278 {
8279 std::uint64_t len{};
8280 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8281 }
8282
8283 case 0x9F: // array (indefinite length)
8284 return get_cbor_array(std::size_t(-1), tag_handler);
8285
8286 // map (0x00..0x17 pairs of data items follow)
8287 case 0xA0:
8288 case 0xA1:
8289 case 0xA2:
8290 case 0xA3:
8291 case 0xA4:
8292 case 0xA5:
8293 case 0xA6:
8294 case 0xA7:
8295 case 0xA8:
8296 case 0xA9:
8297 case 0xAA:
8298 case 0xAB:
8299 case 0xAC:
8300 case 0xAD:
8301 case 0xAE:
8302 case 0xAF:
8303 case 0xB0:
8304 case 0xB1:
8305 case 0xB2:
8306 case 0xB3:
8307 case 0xB4:
8308 case 0xB5:
8309 case 0xB6:
8310 case 0xB7:
8311 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8312
8313 case 0xB8: // map (one-byte uint8_t for n follows)
8314 {
8315 std::uint8_t len{};
8316 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8317 }
8318
8319 case 0xB9: // map (two-byte uint16_t for n follow)
8320 {
8321 std::uint16_t len{};
8322 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8323 }
8324
8325 case 0xBA: // map (four-byte uint32_t for n follow)
8326 {
8327 std::uint32_t len{};
8328 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8329 }
8330
8331 case 0xBB: // map (eight-byte uint64_t for n follow)
8332 {
8333 std::uint64_t len{};
8334 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8335 }
8336
8337 case 0xBF: // map (indefinite length)
8338 return get_cbor_object(std::size_t(-1), tag_handler);
8339
8340 case 0xC6: // tagged item
8341 case 0xC7:
8342 case 0xC8:
8343 case 0xC9:
8344 case 0xCA:
8345 case 0xCB:
8346 case 0xCC:
8347 case 0xCD:
8348 case 0xCE:
8349 case 0xCF:
8350 case 0xD0:
8351 case 0xD1:
8352 case 0xD2:
8353 case 0xD3:
8354 case 0xD4:
8355 case 0xD8: // tagged item (1 bytes follow)
8356 case 0xD9: // tagged item (2 bytes follow)
8357 case 0xDA: // tagged item (4 bytes follow)
8358 case 0xDB: // tagged item (8 bytes follow)
8359 {
8360 switch (tag_handler)
8361 {
8362 case cbor_tag_handler_t::error:
8363 {
8364 auto last_token = get_token_string();
8365 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")));
8366 }
8367
8368 case cbor_tag_handler_t::ignore:
8369 {
8370 switch (current)
8371 {
8372 case 0xD8:
8373 {
8374 std::uint8_t len{};
8375 get_number(input_format_t::cbor, len);
8376 break;
8377 }
8378 case 0xD9:
8379 {
8380 std::uint16_t len{};
8381 get_number(input_format_t::cbor, len);
8382 break;
8383 }
8384 case 0xDA:
8385 {
8386 std::uint32_t len{};
8387 get_number(input_format_t::cbor, len);
8388 break;
8389 }
8390 case 0xDB:
8391 {
8392 std::uint64_t len{};
8393 get_number(input_format_t::cbor, len);
8394 break;
8395 }
8396 default:
8397 break;
8398 }
8399 return parse_cbor_internal(true, tag_handler);
8400 }
8401
8402 default: // LCOV_EXCL_LINE
8403 JSON_ASSERT(false); // LCOV_EXCL_LINE
8404 return false; // LCOV_EXCL_LINE
8405 }
8406 }
8407
8408 case 0xF4: // false
8409 return sax->boolean(false);
8410
8411 case 0xF5: // true
8412 return sax->boolean(true);
8413
8414 case 0xF6: // null
8415 return sax->null();
8416
8417 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
8418 {
8419 const auto byte1_raw = get();
8420 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
8421 {
8422 return false;
8423 }
8424 const auto byte2_raw = get();
8425 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
8426 {
8427 return false;
8428 }
8429
8430 const auto byte1 = static_cast<unsigned char>(byte1_raw);
8431 const auto byte2 = static_cast<unsigned char>(byte2_raw);
8432
8433 // code from RFC 7049, Appendix D, Figure 3:
8434 // As half-precision floating-point numbers were only added
8435 // to IEEE 754 in 2008, today's programming platforms often
8436 // still only have limited support for them. It is very
8437 // easy to include at least decoding support for them even
8438 // without such support. An example of a small decoder for
8439 // half-precision floating-point numbers in the C language
8440 // is shown in Fig. 3.
8441 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
8442 const double val = [&half]
8443 {
8444 const int exp = (half >> 10u) & 0x1Fu;
8445 const unsigned int mant = half & 0x3FFu;
8446 JSON_ASSERT(0 <= exp&& exp <= 32);
8447 JSON_ASSERT(mant <= 1024);
8448 switch (exp)
8449 {
8450 case 0:
8451 return std::ldexp(mant, -24);
8452 case 31:
8453 return (mant == 0)
8454 ? std::numeric_limits<double>::infinity()
8455 : std::numeric_limits<double>::quiet_NaN();
8456 default:
8457 return std::ldexp(mant + 1024, exp - 25);
8458 }
8459 }();
8460 return sax->number_float((half & 0x8000u) != 0
8461 ? static_cast<number_float_t>(-val)
8462 : static_cast<number_float_t>(val), "");
8463 }
8464
8465 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
8466 {
8467 float number{};
8468 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
8469 }
8470
8471 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
8472 {
8473 double number{};
8474 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
8475 }
8476
8477 default: // anything else (0xFF is handled inside the other types)
8478 {
8479 auto last_token = get_token_string();
8480 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")));
8481 }
8482 }
8483 }
8484
8496 bool get_cbor_string(string_t& result)
8497 {
8498 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
8499 {
8500 return false;
8501 }
8502
8503 switch (current)
8504 {
8505 // UTF-8 string (0x00..0x17 bytes follow)
8506 case 0x60:
8507 case 0x61:
8508 case 0x62:
8509 case 0x63:
8510 case 0x64:
8511 case 0x65:
8512 case 0x66:
8513 case 0x67:
8514 case 0x68:
8515 case 0x69:
8516 case 0x6A:
8517 case 0x6B:
8518 case 0x6C:
8519 case 0x6D:
8520 case 0x6E:
8521 case 0x6F:
8522 case 0x70:
8523 case 0x71:
8524 case 0x72:
8525 case 0x73:
8526 case 0x74:
8527 case 0x75:
8528 case 0x76:
8529 case 0x77:
8530 {
8531 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
8532 }
8533
8534 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8535 {
8536 std::uint8_t len{};
8537 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8538 }
8539
8540 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8541 {
8542 std::uint16_t len{};
8543 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8544 }
8545
8546 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8547 {
8548 std::uint32_t len{};
8549 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8550 }
8551
8552 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8553 {
8554 std::uint64_t len{};
8555 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8556 }
8557
8558 case 0x7F: // UTF-8 string (indefinite length)
8559 {
8560 while (get() != 0xFF)
8561 {
8562 string_t chunk;
8563 if (!get_cbor_string(chunk))
8564 {
8565 return false;
8566 }
8567 result.append(chunk);
8568 }
8569 return true;
8570 }
8571
8572 default:
8573 {
8574 auto last_token = get_token_string();
8575 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")));
8576 }
8577 }
8578 }
8579
8591 bool get_cbor_binary(binary_t& result)
8592 {
8593 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
8594 {
8595 return false;
8596 }
8597
8598 switch (current)
8599 {
8600 // Binary data (0x00..0x17 bytes follow)
8601 case 0x40:
8602 case 0x41:
8603 case 0x42:
8604 case 0x43:
8605 case 0x44:
8606 case 0x45:
8607 case 0x46:
8608 case 0x47:
8609 case 0x48:
8610 case 0x49:
8611 case 0x4A:
8612 case 0x4B:
8613 case 0x4C:
8614 case 0x4D:
8615 case 0x4E:
8616 case 0x4F:
8617 case 0x50:
8618 case 0x51:
8619 case 0x52:
8620 case 0x53:
8621 case 0x54:
8622 case 0x55:
8623 case 0x56:
8624 case 0x57:
8625 {
8626 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
8627 }
8628
8629 case 0x58: // Binary data (one-byte uint8_t for n follows)
8630 {
8631 std::uint8_t len{};
8632 return get_number(input_format_t::cbor, len) &&
8633 get_binary(input_format_t::cbor, len, result);
8634 }
8635
8636 case 0x59: // Binary data (two-byte uint16_t for n follow)
8637 {
8638 std::uint16_t len{};
8639 return get_number(input_format_t::cbor, len) &&
8640 get_binary(input_format_t::cbor, len, result);
8641 }
8642
8643 case 0x5A: // Binary data (four-byte uint32_t for n follow)
8644 {
8645 std::uint32_t len{};
8646 return get_number(input_format_t::cbor, len) &&
8647 get_binary(input_format_t::cbor, len, result);
8648 }
8649
8650 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8651 {
8652 std::uint64_t len{};
8653 return get_number(input_format_t::cbor, len) &&
8654 get_binary(input_format_t::cbor, len, result);
8655 }
8656
8657 case 0x5F: // Binary data (indefinite length)
8658 {
8659 while (get() != 0xFF)
8660 {
8661 binary_t chunk;
8662 if (!get_cbor_binary(chunk))
8663 {
8664 return false;
8665 }
8666 result.insert(result.end(), chunk.begin(), chunk.end());
8667 }
8668 return true;
8669 }
8670
8671 default:
8672 {
8673 auto last_token = get_token_string();
8674 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")));
8675 }
8676 }
8677 }
8678
8685 bool get_cbor_array(const std::size_t len,
8686 const cbor_tag_handler_t tag_handler)
8687 {
8688 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
8689 {
8690 return false;
8691 }
8692
8693 if (len != std::size_t(-1))
8694 {
8695 for (std::size_t i = 0; i < len; ++i)
8696 {
8697 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8698 {
8699 return false;
8700 }
8701 }
8702 }
8703 else
8704 {
8705 while (get() != 0xFF)
8706 {
8707 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
8708 {
8709 return false;
8710 }
8711 }
8712 }
8713
8714 return sax->end_array();
8715 }
8716
8723 bool get_cbor_object(const std::size_t len,
8724 const cbor_tag_handler_t tag_handler)
8725 {
8726 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
8727 {
8728 return false;
8729 }
8730
8731 string_t key;
8732 if (len != std::size_t(-1))
8733 {
8734 for (std::size_t i = 0; i < len; ++i)
8735 {
8736 get();
8737 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
8738 {
8739 return false;
8740 }
8741
8742 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8743 {
8744 return false;
8745 }
8746 key.clear();
8747 }
8748 }
8749 else
8750 {
8751 while (get() != 0xFF)
8752 {
8753 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
8754 {
8755 return false;
8756 }
8757
8758 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8759 {
8760 return false;
8761 }
8762 key.clear();
8763 }
8764 }
8765
8766 return sax->end_object();
8767 }
8768
8770 // MsgPack //
8772
8776 bool parse_msgpack_internal()
8777 {
8778 switch (get())
8779 {
8780 // EOF
8781 case std::char_traits<char_type>::eof():
8782 return unexpect_eof(input_format_t::msgpack, "value");
8783
8784 // positive fixint
8785 case 0x00:
8786 case 0x01:
8787 case 0x02:
8788 case 0x03:
8789 case 0x04:
8790 case 0x05:
8791 case 0x06:
8792 case 0x07:
8793 case 0x08:
8794 case 0x09:
8795 case 0x0A:
8796 case 0x0B:
8797 case 0x0C:
8798 case 0x0D:
8799 case 0x0E:
8800 case 0x0F:
8801 case 0x10:
8802 case 0x11:
8803 case 0x12:
8804 case 0x13:
8805 case 0x14:
8806 case 0x15:
8807 case 0x16:
8808 case 0x17:
8809 case 0x18:
8810 case 0x19:
8811 case 0x1A:
8812 case 0x1B:
8813 case 0x1C:
8814 case 0x1D:
8815 case 0x1E:
8816 case 0x1F:
8817 case 0x20:
8818 case 0x21:
8819 case 0x22:
8820 case 0x23:
8821 case 0x24:
8822 case 0x25:
8823 case 0x26:
8824 case 0x27:
8825 case 0x28:
8826 case 0x29:
8827 case 0x2A:
8828 case 0x2B:
8829 case 0x2C:
8830 case 0x2D:
8831 case 0x2E:
8832 case 0x2F:
8833 case 0x30:
8834 case 0x31:
8835 case 0x32:
8836 case 0x33:
8837 case 0x34:
8838 case 0x35:
8839 case 0x36:
8840 case 0x37:
8841 case 0x38:
8842 case 0x39:
8843 case 0x3A:
8844 case 0x3B:
8845 case 0x3C:
8846 case 0x3D:
8847 case 0x3E:
8848 case 0x3F:
8849 case 0x40:
8850 case 0x41:
8851 case 0x42:
8852 case 0x43:
8853 case 0x44:
8854 case 0x45:
8855 case 0x46:
8856 case 0x47:
8857 case 0x48:
8858 case 0x49:
8859 case 0x4A:
8860 case 0x4B:
8861 case 0x4C:
8862 case 0x4D:
8863 case 0x4E:
8864 case 0x4F:
8865 case 0x50:
8866 case 0x51:
8867 case 0x52:
8868 case 0x53:
8869 case 0x54:
8870 case 0x55:
8871 case 0x56:
8872 case 0x57:
8873 case 0x58:
8874 case 0x59:
8875 case 0x5A:
8876 case 0x5B:
8877 case 0x5C:
8878 case 0x5D:
8879 case 0x5E:
8880 case 0x5F:
8881 case 0x60:
8882 case 0x61:
8883 case 0x62:
8884 case 0x63:
8885 case 0x64:
8886 case 0x65:
8887 case 0x66:
8888 case 0x67:
8889 case 0x68:
8890 case 0x69:
8891 case 0x6A:
8892 case 0x6B:
8893 case 0x6C:
8894 case 0x6D:
8895 case 0x6E:
8896 case 0x6F:
8897 case 0x70:
8898 case 0x71:
8899 case 0x72:
8900 case 0x73:
8901 case 0x74:
8902 case 0x75:
8903 case 0x76:
8904 case 0x77:
8905 case 0x78:
8906 case 0x79:
8907 case 0x7A:
8908 case 0x7B:
8909 case 0x7C:
8910 case 0x7D:
8911 case 0x7E:
8912 case 0x7F:
8913 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8914
8915 // fixmap
8916 case 0x80:
8917 case 0x81:
8918 case 0x82:
8919 case 0x83:
8920 case 0x84:
8921 case 0x85:
8922 case 0x86:
8923 case 0x87:
8924 case 0x88:
8925 case 0x89:
8926 case 0x8A:
8927 case 0x8B:
8928 case 0x8C:
8929 case 0x8D:
8930 case 0x8E:
8931 case 0x8F:
8932 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
8933
8934 // fixarray
8935 case 0x90:
8936 case 0x91:
8937 case 0x92:
8938 case 0x93:
8939 case 0x94:
8940 case 0x95:
8941 case 0x96:
8942 case 0x97:
8943 case 0x98:
8944 case 0x99:
8945 case 0x9A:
8946 case 0x9B:
8947 case 0x9C:
8948 case 0x9D:
8949 case 0x9E:
8950 case 0x9F:
8951 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
8952
8953 // fixstr
8954 case 0xA0:
8955 case 0xA1:
8956 case 0xA2:
8957 case 0xA3:
8958 case 0xA4:
8959 case 0xA5:
8960 case 0xA6:
8961 case 0xA7:
8962 case 0xA8:
8963 case 0xA9:
8964 case 0xAA:
8965 case 0xAB:
8966 case 0xAC:
8967 case 0xAD:
8968 case 0xAE:
8969 case 0xAF:
8970 case 0xB0:
8971 case 0xB1:
8972 case 0xB2:
8973 case 0xB3:
8974 case 0xB4:
8975 case 0xB5:
8976 case 0xB6:
8977 case 0xB7:
8978 case 0xB8:
8979 case 0xB9:
8980 case 0xBA:
8981 case 0xBB:
8982 case 0xBC:
8983 case 0xBD:
8984 case 0xBE:
8985 case 0xBF:
8986 case 0xD9: // str 8
8987 case 0xDA: // str 16
8988 case 0xDB: // str 32
8989 {
8990 string_t s;
8991 return get_msgpack_string(s) && sax->string(s);
8992 }
8993
8994 case 0xC0: // nil
8995 return sax->null();
8996
8997 case 0xC2: // false
8998 return sax->boolean(false);
8999
9000 case 0xC3: // true
9001 return sax->boolean(true);
9002
9003 case 0xC4: // bin 8
9004 case 0xC5: // bin 16
9005 case 0xC6: // bin 32
9006 case 0xC7: // ext 8
9007 case 0xC8: // ext 16
9008 case 0xC9: // ext 32
9009 case 0xD4: // fixext 1
9010 case 0xD5: // fixext 2
9011 case 0xD6: // fixext 4
9012 case 0xD7: // fixext 8
9013 case 0xD8: // fixext 16
9014 {
9015 binary_t b;
9016 return get_msgpack_binary(b) && sax->binary(b);
9017 }
9018
9019 case 0xCA: // float 32
9020 {
9021 float number{};
9022 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9023 }
9024
9025 case 0xCB: // float 64
9026 {
9027 double number{};
9028 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9029 }
9030
9031 case 0xCC: // uint 8
9032 {
9033 std::uint8_t number{};
9034 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9035 }
9036
9037 case 0xCD: // uint 16
9038 {
9039 std::uint16_t number{};
9040 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9041 }
9042
9043 case 0xCE: // uint 32
9044 {
9045 std::uint32_t number{};
9046 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9047 }
9048
9049 case 0xCF: // uint 64
9050 {
9051 std::uint64_t number{};
9052 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9053 }
9054
9055 case 0xD0: // int 8
9056 {
9057 std::int8_t number{};
9058 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9059 }
9060
9061 case 0xD1: // int 16
9062 {
9063 std::int16_t number{};
9064 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9065 }
9066
9067 case 0xD2: // int 32
9068 {
9069 std::int32_t number{};
9070 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9071 }
9072
9073 case 0xD3: // int 64
9074 {
9075 std::int64_t number{};
9076 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9077 }
9078
9079 case 0xDC: // array 16
9080 {
9081 std::uint16_t len{};
9082 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9083 }
9084
9085 case 0xDD: // array 32
9086 {
9087 std::uint32_t len{};
9088 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9089 }
9090
9091 case 0xDE: // map 16
9092 {
9093 std::uint16_t len{};
9094 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9095 }
9096
9097 case 0xDF: // map 32
9098 {
9099 std::uint32_t len{};
9100 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9101 }
9102
9103 // negative fixint
9104 case 0xE0:
9105 case 0xE1:
9106 case 0xE2:
9107 case 0xE3:
9108 case 0xE4:
9109 case 0xE5:
9110 case 0xE6:
9111 case 0xE7:
9112 case 0xE8:
9113 case 0xE9:
9114 case 0xEA:
9115 case 0xEB:
9116 case 0xEC:
9117 case 0xED:
9118 case 0xEE:
9119 case 0xEF:
9120 case 0xF0:
9121 case 0xF1:
9122 case 0xF2:
9123 case 0xF3:
9124 case 0xF4:
9125 case 0xF5:
9126 case 0xF6:
9127 case 0xF7:
9128 case 0xF8:
9129 case 0xF9:
9130 case 0xFA:
9131 case 0xFB:
9132 case 0xFC:
9133 case 0xFD:
9134 case 0xFE:
9135 case 0xFF:
9136 return sax->number_integer(static_cast<std::int8_t>(current));
9137
9138 default: // anything else
9139 {
9140 auto last_token = get_token_string();
9141 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")));
9142 }
9143 }
9144 }
9145
9156 bool get_msgpack_string(string_t& result)
9157 {
9158 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
9159 {
9160 return false;
9161 }
9162
9163 switch (current)
9164 {
9165 // fixstr
9166 case 0xA0:
9167 case 0xA1:
9168 case 0xA2:
9169 case 0xA3:
9170 case 0xA4:
9171 case 0xA5:
9172 case 0xA6:
9173 case 0xA7:
9174 case 0xA8:
9175 case 0xA9:
9176 case 0xAA:
9177 case 0xAB:
9178 case 0xAC:
9179 case 0xAD:
9180 case 0xAE:
9181 case 0xAF:
9182 case 0xB0:
9183 case 0xB1:
9184 case 0xB2:
9185 case 0xB3:
9186 case 0xB4:
9187 case 0xB5:
9188 case 0xB6:
9189 case 0xB7:
9190 case 0xB8:
9191 case 0xB9:
9192 case 0xBA:
9193 case 0xBB:
9194 case 0xBC:
9195 case 0xBD:
9196 case 0xBE:
9197 case 0xBF:
9198 {
9199 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
9200 }
9201
9202 case 0xD9: // str 8
9203 {
9204 std::uint8_t len{};
9205 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9206 }
9207
9208 case 0xDA: // str 16
9209 {
9210 std::uint16_t len{};
9211 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9212 }
9213
9214 case 0xDB: // str 32
9215 {
9216 std::uint32_t len{};
9217 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9218 }
9219
9220 default:
9221 {
9222 auto last_token = get_token_string();
9223 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")));
9224 }
9225 }
9226 }
9227
9238 bool get_msgpack_binary(binary_t& result)
9239 {
9240 // helper function to set the subtype
9241 auto assign_and_return_true = [&result](std::int8_t subtype)
9242 {
9243 result.set_subtype(static_cast<std::uint8_t>(subtype));
9244 return true;
9245 };
9246
9247 switch (current)
9248 {
9249 case 0xC4: // bin 8
9250 {
9251 std::uint8_t len{};
9252 return get_number(input_format_t::msgpack, len) &&
9253 get_binary(input_format_t::msgpack, len, result);
9254 }
9255
9256 case 0xC5: // bin 16
9257 {
9258 std::uint16_t len{};
9259 return get_number(input_format_t::msgpack, len) &&
9260 get_binary(input_format_t::msgpack, len, result);
9261 }
9262
9263 case 0xC6: // bin 32
9264 {
9265 std::uint32_t len{};
9266 return get_number(input_format_t::msgpack, len) &&
9267 get_binary(input_format_t::msgpack, len, result);
9268 }
9269
9270 case 0xC7: // ext 8
9271 {
9272 std::uint8_t len{};
9273 std::int8_t subtype{};
9274 return get_number(input_format_t::msgpack, len) &&
9275 get_number(input_format_t::msgpack, subtype) &&
9276 get_binary(input_format_t::msgpack, len, result) &&
9277 assign_and_return_true(subtype);
9278 }
9279
9280 case 0xC8: // ext 16
9281 {
9282 std::uint16_t len{};
9283 std::int8_t subtype{};
9284 return get_number(input_format_t::msgpack, len) &&
9285 get_number(input_format_t::msgpack, subtype) &&
9286 get_binary(input_format_t::msgpack, len, result) &&
9287 assign_and_return_true(subtype);
9288 }
9289
9290 case 0xC9: // ext 32
9291 {
9292 std::uint32_t len{};
9293 std::int8_t subtype{};
9294 return get_number(input_format_t::msgpack, len) &&
9295 get_number(input_format_t::msgpack, subtype) &&
9296 get_binary(input_format_t::msgpack, len, result) &&
9297 assign_and_return_true(subtype);
9298 }
9299
9300 case 0xD4: // fixext 1
9301 {
9302 std::int8_t subtype{};
9303 return get_number(input_format_t::msgpack, subtype) &&
9304 get_binary(input_format_t::msgpack, 1, result) &&
9305 assign_and_return_true(subtype);
9306 }
9307
9308 case 0xD5: // fixext 2
9309 {
9310 std::int8_t subtype{};
9311 return get_number(input_format_t::msgpack, subtype) &&
9312 get_binary(input_format_t::msgpack, 2, result) &&
9313 assign_and_return_true(subtype);
9314 }
9315
9316 case 0xD6: // fixext 4
9317 {
9318 std::int8_t subtype{};
9319 return get_number(input_format_t::msgpack, subtype) &&
9320 get_binary(input_format_t::msgpack, 4, result) &&
9321 assign_and_return_true(subtype);
9322 }
9323
9324 case 0xD7: // fixext 8
9325 {
9326 std::int8_t subtype{};
9327 return get_number(input_format_t::msgpack, subtype) &&
9328 get_binary(input_format_t::msgpack, 8, result) &&
9329 assign_and_return_true(subtype);
9330 }
9331
9332 case 0xD8: // fixext 16
9333 {
9334 std::int8_t subtype{};
9335 return get_number(input_format_t::msgpack, subtype) &&
9336 get_binary(input_format_t::msgpack, 16, result) &&
9337 assign_and_return_true(subtype);
9338 }
9339
9340 default: // LCOV_EXCL_LINE
9341 return false; // LCOV_EXCL_LINE
9342 }
9343 }
9344
9349 bool get_msgpack_array(const std::size_t len)
9350 {
9351 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9352 {
9353 return false;
9354 }
9355
9356 for (std::size_t i = 0; i < len; ++i)
9357 {
9358 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
9359 {
9360 return false;
9361 }
9362 }
9363
9364 return sax->end_array();
9365 }
9366
9371 bool get_msgpack_object(const std::size_t len)
9372 {
9373 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9374 {
9375 return false;
9376 }
9377
9378 string_t key;
9379 for (std::size_t i = 0; i < len; ++i)
9380 {
9381 get();
9382 if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
9383 {
9384 return false;
9385 }
9386
9387 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
9388 {
9389 return false;
9390 }
9391 key.clear();
9392 }
9393
9394 return sax->end_object();
9395 }
9396
9398 // UBJSON //
9400
9408 bool parse_ubjson_internal(const bool get_char = true)
9409 {
9410 return get_ubjson_value(get_char ? get_ignore_noop() : current);
9411 }
9412
9427 bool get_ubjson_string(string_t& result, const bool get_char = true)
9428 {
9429 if (get_char)
9430 {
9431 get(); // TODO(niels): may we ignore N here?
9432 }
9433
9434 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
9435 {
9436 return false;
9437 }
9438
9439 switch (current)
9440 {
9441 case 'U':
9442 {
9443 std::uint8_t len{};
9444 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9445 }
9446
9447 case 'i':
9448 {
9449 std::int8_t len{};
9450 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9451 }
9452
9453 case 'I':
9454 {
9455 std::int16_t len{};
9456 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9457 }
9458
9459 case 'l':
9460 {
9461 std::int32_t len{};
9462 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9463 }
9464
9465 case 'L':
9466 {
9467 std::int64_t len{};
9468 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9469 }
9470
9471 default:
9472 auto last_token = get_token_string();
9473 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")));
9474 }
9475 }
9476
9481 bool get_ubjson_size_value(std::size_t& result)
9482 {
9483 switch (get_ignore_noop())
9484 {
9485 case 'U':
9486 {
9487 std::uint8_t number{};
9488 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9489 {
9490 return false;
9491 }
9492 result = static_cast<std::size_t>(number);
9493 return true;
9494 }
9495
9496 case 'i':
9497 {
9498 std::int8_t number{};
9499 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9500 {
9501 return false;
9502 }
9503 result = static_cast<std::size_t>(number);
9504 return true;
9505 }
9506
9507 case 'I':
9508 {
9509 std::int16_t number{};
9510 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9511 {
9512 return false;
9513 }
9514 result = static_cast<std::size_t>(number);
9515 return true;
9516 }
9517
9518 case 'l':
9519 {
9520 std::int32_t number{};
9521 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9522 {
9523 return false;
9524 }
9525 result = static_cast<std::size_t>(number);
9526 return true;
9527 }
9528
9529 case 'L':
9530 {
9531 std::int64_t number{};
9532 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9533 {
9534 return false;
9535 }
9536 result = static_cast<std::size_t>(number);
9537 return true;
9538 }
9539
9540 default:
9541 {
9542 auto last_token = get_token_string();
9543 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")));
9544 }
9545 }
9546 }
9547
9558 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
9559 {
9560 result.first = string_t::npos; // size
9561 result.second = 0; // type
9562
9563 get_ignore_noop();
9564
9565 if (current == '$')
9566 {
9567 result.second = get(); // must not ignore 'N', because 'N' maybe the type
9568 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type")))
9569 {
9570 return false;
9571 }
9572
9573 get_ignore_noop();
9574 if (JSON_HEDLEY_UNLIKELY(current != '#'))
9575 {
9576 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
9577 {
9578 return false;
9579 }
9580 auto last_token = get_token_string();
9581 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")));
9582 }
9583
9584 return get_ubjson_size_value(result.first);
9585 }
9586
9587 if (current == '#')
9588 {
9589 return get_ubjson_size_value(result.first);
9590 }
9591
9592 return true;
9593 }
9594
9599 bool get_ubjson_value(const char_int_type prefix)
9600 {
9601 switch (prefix)
9602 {
9603 case std::char_traits<char_type>::eof(): // EOF
9604 return unexpect_eof(input_format_t::ubjson, "value");
9605
9606 case 'T': // true
9607 return sax->boolean(true);
9608 case 'F': // false
9609 return sax->boolean(false);
9610
9611 case 'Z': // null
9612 return sax->null();
9613
9614 case 'U':
9615 {
9616 std::uint8_t number{};
9617 return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
9618 }
9619
9620 case 'i':
9621 {
9622 std::int8_t number{};
9623 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9624 }
9625
9626 case 'I':
9627 {
9628 std::int16_t number{};
9629 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9630 }
9631
9632 case 'l':
9633 {
9634 std::int32_t number{};
9635 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9636 }
9637
9638 case 'L':
9639 {
9640 std::int64_t number{};
9641 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9642 }
9643
9644 case 'd':
9645 {
9646 float number{};
9647 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9648 }
9649
9650 case 'D':
9651 {
9652 double number{};
9653 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9654 }
9655
9656 case 'H':
9657 {
9658 return get_ubjson_high_precision_number();
9659 }
9660
9661 case 'C': // char
9662 {
9663 get();
9664 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char")))
9665 {
9666 return false;
9667 }
9668 if (JSON_HEDLEY_UNLIKELY(current > 127))
9669 {
9670 auto last_token = get_token_string();
9671 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")));
9672 }
9673 string_t s(1, static_cast<typename string_t::value_type>(current));
9674 return sax->string(s);
9675 }
9676
9677 case 'S': // string
9678 {
9679 string_t s;
9680 return get_ubjson_string(s) && sax->string(s);
9681 }
9682
9683 case '[': // array
9684 return get_ubjson_array();
9685
9686 case '{': // object
9687 return get_ubjson_object();
9688
9689 default: // anything else
9690 {
9691 auto last_token = get_token_string();
9692 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")));
9693 }
9694 }
9695 }
9696
9700 bool get_ubjson_array()
9701 {
9702 std::pair<std::size_t, char_int_type> size_and_type;
9703 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
9704 {
9705 return false;
9706 }
9707
9708 if (size_and_type.first != string_t::npos)
9709 {
9710 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
9711 {
9712 return false;
9713 }
9714
9715 if (size_and_type.second != 0)
9716 {
9717 if (size_and_type.second != 'N')
9718 {
9719 for (std::size_t i = 0; i < size_and_type.first; ++i)
9720 {
9721 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
9722 {
9723 return false;
9724 }
9725 }
9726 }
9727 }
9728 else
9729 {
9730 for (std::size_t i = 0; i < size_and_type.first; ++i)
9731 {
9732 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
9733 {
9734 return false;
9735 }
9736 }
9737 }
9738 }
9739 else
9740 {
9741 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
9742 {
9743 return false;
9744 }
9745
9746 while (current != ']')
9747 {
9748 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
9749 {
9750 return false;
9751 }
9752 get_ignore_noop();
9753 }
9754 }
9755
9756 return sax->end_array();
9757 }
9758
9762 bool get_ubjson_object()
9763 {
9764 std::pair<std::size_t, char_int_type> size_and_type;
9765 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
9766 {
9767 return false;
9768 }
9769
9770 string_t key;
9771 if (size_and_type.first != string_t::npos)
9772 {
9773 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
9774 {
9775 return false;
9776 }
9777
9778 if (size_and_type.second != 0)
9779 {
9780 for (std::size_t i = 0; i < size_and_type.first; ++i)
9781 {
9782 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
9783 {
9784 return false;
9785 }
9786 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
9787 {
9788 return false;
9789 }
9790 key.clear();
9791 }
9792 }
9793 else
9794 {
9795 for (std::size_t i = 0; i < size_and_type.first; ++i)
9796 {
9797 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
9798 {
9799 return false;
9800 }
9801 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
9802 {
9803 return false;
9804 }
9805 key.clear();
9806 }
9807 }
9808 }
9809 else
9810 {
9811 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
9812 {
9813 return false;
9814 }
9815
9816 while (current != '}')
9817 {
9818 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
9819 {
9820 return false;
9821 }
9822 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
9823 {
9824 return false;
9825 }
9826 get_ignore_noop();
9827 key.clear();
9828 }
9829 }
9830
9831 return sax->end_object();
9832 }
9833
9834 // Note, no reader for UBJSON binary types is implemented because they do
9835 // not exist
9836
9837 bool get_ubjson_high_precision_number()
9838 {
9839 // get size of following number string
9840 std::size_t size{};
9841 auto res = get_ubjson_size_value(size);
9842 if (JSON_HEDLEY_UNLIKELY(!res))
9843 {
9844 return res;
9845 }
9846
9847 // get number string
9848 std::vector<char> number_vector;
9849 for (std::size_t i = 0; i < size; ++i)
9850 {
9851 get();
9852 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number")))
9853 {
9854 return false;
9855 }
9856 number_vector.push_back(static_cast<char>(current));
9857 }
9858
9859 // parse number string
9860 auto number_ia = detail::input_adapter(std::forward<decltype(number_vector)>(number_vector));
9861 auto number_lexer = detail::lexer<BasicJsonType, decltype(number_ia)>(std::move(number_ia), false);
9862 const auto result_number = number_lexer.scan();
9863 const auto number_string = number_lexer.get_token_string();
9864 const auto result_remainder = number_lexer.scan();
9865
9866 using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
9867
9868 if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
9869 {
9870 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number")));
9871 }
9872
9873 switch (result_number)
9874 {
9875 case token_type::value_integer:
9876 return sax->number_integer(number_lexer.get_number_integer());
9877 case token_type::value_unsigned:
9878 return sax->number_unsigned(number_lexer.get_number_unsigned());
9879 case token_type::value_float:
9880 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
9881 default:
9882 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number")));
9883 }
9884 }
9885
9887 // Utility functions //
9889
9899 char_int_type get()
9900 {
9901 ++chars_read;
9902 return current = ia.get_character();
9903 }
9904
9908 char_int_type get_ignore_noop()
9909 {
9910 do
9911 {
9912 get();
9913 }
9914 while (current == 'N');
9915
9916 return current;
9917 }
9918
9919 /*
9920 @brief read a number from the input
9921
9922 @tparam NumberType the type of the number
9923 @param[in] format the current format (for diagnostics)
9924 @param[out] result number of type @a NumberType
9925
9926 @return whether conversion completed
9927
9928 @note This function needs to respect the system's endianess, because
9929 bytes in CBOR, MessagePack, and UBJSON are stored in network order
9930 (big endian) and therefore need reordering on little endian systems.
9931 */
9932 template<typename NumberType, bool InputIsLittleEndian = false>
9933 bool get_number(const input_format_t format, NumberType& result)
9934 {
9935 // step 1: read input into array with system's byte order
9936 std::array<std::uint8_t, sizeof(NumberType)> vec;
9937 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
9938 {
9939 get();
9940 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
9941 {
9942 return false;
9943 }
9944
9945 // reverse byte order prior to conversion if necessary
9946 if (is_little_endian != InputIsLittleEndian)
9947 {
9948 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
9949 }
9950 else
9951 {
9952 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
9953 }
9954 }
9955
9956 // step 2: convert array into number of type T and return
9957 std::memcpy(&result, vec.data(), sizeof(NumberType));
9958 return true;
9959 }
9960
9975 template<typename NumberType>
9976 bool get_string(const input_format_t format,
9977 const NumberType len,
9978 string_t& result)
9979 {
9980 bool success = true;
9981 for (NumberType i = 0; i < len; i++)
9982 {
9983 get();
9984 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
9985 {
9986 success = false;
9987 break;
9988 }
9989 result.push_back(static_cast<typename string_t::value_type>(current));
9990 };
9991 return success;
9992 }
9993
10008 template<typename NumberType>
10009 bool get_binary(const input_format_t format,
10010 const NumberType len,
10011 binary_t& result)
10012 {
10013 bool success = true;
10014 for (NumberType i = 0; i < len; i++)
10015 {
10016 get();
10017 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10018 {
10019 success = false;
10020 break;
10021 }
10022 result.push_back(static_cast<std::uint8_t>(current));
10023 }
10024 return success;
10025 }
10026
10032 JSON_HEDLEY_NON_NULL(3)
10033 bool unexpect_eof(const input_format_t format, const char* context) const
10034 {
10035 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
10036 {
10037 return sax->parse_error(chars_read, "<end of file>",
10038 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
10039 }
10040 return true;
10041 }
10042
10046 std::string get_token_string() const
10047 {
10048 std::array<char, 3> cr{{}};
10049 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current));
10050 return std::string{cr.data()};
10051 }
10052
10059 std::string exception_message(const input_format_t format,
10060 const std::string& detail,
10061 const std::string& context) const
10062 {
10063 std::string error_msg = "syntax error while parsing ";
10064
10065 switch (format)
10066 {
10067 case input_format_t::cbor:
10068 error_msg += "CBOR";
10069 break;
10070
10071 case input_format_t::msgpack:
10072 error_msg += "MessagePack";
10073 break;
10074
10075 case input_format_t::ubjson:
10076 error_msg += "UBJSON";
10077 break;
10078
10079 case input_format_t::bson:
10080 error_msg += "BSON";
10081 break;
10082
10083 default: // LCOV_EXCL_LINE
10084 JSON_ASSERT(false); // LCOV_EXCL_LINE
10085 }
10086
10087 return error_msg + " " + context + ": " + detail;
10088 }
10089
10090 private:
10092 InputAdapterType ia;
10093
10095 char_int_type current = std::char_traits<char_type>::eof();
10096
10098 std::size_t chars_read = 0;
10099
10101 const bool is_little_endian = little_endianess();
10102
10104 json_sax_t* sax = nullptr;
10105 };
10106 } // namespace detail
10107 } // namespace nlohmann
10108
10109 // #include <nlohmann/detail/input/input_adapters.hpp>
10110
10111 // #include <nlohmann/detail/input/lexer.hpp>
10112
10113 // #include <nlohmann/detail/input/parser.hpp>
10114
10115
10116 #include <cmath> // isfinite
10117 #include <cstdint> // uint8_t
10118 #include <functional> // function
10119 #include <string> // string
10120 #include <utility> // move
10121 #include <vector> // vector
10122
10123 // #include <nlohmann/detail/exceptions.hpp>
10124
10125 // #include <nlohmann/detail/input/input_adapters.hpp>
10126
10127 // #include <nlohmann/detail/input/json_sax.hpp>
10128
10129 // #include <nlohmann/detail/input/lexer.hpp>
10130
10131 // #include <nlohmann/detail/macro_scope.hpp>
10132
10133 // #include <nlohmann/detail/meta/is_sax.hpp>
10134
10135 // #include <nlohmann/detail/value_t.hpp>
10136
10137
10138 namespace nlohmann
10139 {
10140 namespace detail
10141 {
10143 // parser //
10145
10146 enum class parse_event_t : uint8_t
10147 {
10149 object_start,
10151 object_end,
10153 array_start,
10155 array_end,
10157 key,
10159 value
10160 };
10161
10162 template<typename BasicJsonType>
10163 using parser_callback_t =
10164 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
10165
10171 template<typename BasicJsonType, typename InputAdapterType>
10172 class parser
10173 {
10174 using number_integer_t = typename BasicJsonType::number_integer_t;
10175 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10176 using number_float_t = typename BasicJsonType::number_float_t;
10177 using string_t = typename BasicJsonType::string_t;
10178 using lexer_t = lexer<BasicJsonType, InputAdapterType>;
10179 using token_type = typename lexer_t::token_type;
10180
10181 public:
10183 explicit parser(InputAdapterType&& adapter,
10184 const parser_callback_t<BasicJsonType> cb = nullptr,
10185 const bool allow_exceptions_ = true,
10186 const bool skip_comments = false)
10187 : callback(cb)
10188 , m_lexer(std::move(adapter), skip_comments)
10189 , allow_exceptions(allow_exceptions_)
10190 {
10191 // read first token
10192 get_token();
10193 }
10194
10205 void parse(const bool strict, BasicJsonType& result)
10206 {
10207 if (callback)
10208 {
10209 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
10210 sax_parse_internal(&sdp);
10211 result.assert_invariant();
10212
10213 // in strict mode, input must be completely read
10214 if (strict && (get_token() != token_type::end_of_input))
10215 {
10216 sdp.parse_error(m_lexer.get_position(),
10217 m_lexer.get_token_string(),
10218 parse_error::create(101, m_lexer.get_position(),
10219 exception_message(token_type::end_of_input, "value")));
10220 }
10221
10222 // in case of an error, return discarded value
10223 if (sdp.is_errored())
10224 {
10225 result = value_t::discarded;
10226 return;
10227 }
10228
10229 // set top-level value to null if it was discarded by the callback
10230 // function
10231 if (result.is_discarded())
10232 {
10233 result = nullptr;
10234 }
10235 }
10236 else
10237 {
10238 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
10239 sax_parse_internal(&sdp);
10240 result.assert_invariant();
10241
10242 // in strict mode, input must be completely read
10243 if (strict && (get_token() != token_type::end_of_input))
10244 {
10245 sdp.parse_error(m_lexer.get_position(),
10246 m_lexer.get_token_string(),
10247 parse_error::create(101, m_lexer.get_position(),
10248 exception_message(token_type::end_of_input, "value")));
10249 }
10250
10251 // in case of an error, return discarded value
10252 if (sdp.is_errored())
10253 {
10254 result = value_t::discarded;
10255 return;
10256 }
10257 }
10258 }
10259
10266 bool accept(const bool strict = true)
10267 {
10268 json_sax_acceptor<BasicJsonType> sax_acceptor;
10269 return sax_parse(&sax_acceptor, strict);
10270 }
10271
10272 template<typename SAX>
10273 JSON_HEDLEY_NON_NULL(2)
10274 bool sax_parse(SAX* sax, const bool strict = true)
10275 {
10276 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
10277 const bool result = sax_parse_internal(sax);
10278
10279 // strict mode: next byte must be EOF
10280 if (result && strict && (get_token() != token_type::end_of_input))
10281 {
10282 return sax->parse_error(m_lexer.get_position(),
10283 m_lexer.get_token_string(),
10284 parse_error::create(101, m_lexer.get_position(),
10285 exception_message(token_type::end_of_input, "value")));
10286 }
10287
10288 return result;
10289 }
10290
10291 private:
10292 template<typename SAX>
10293 JSON_HEDLEY_NON_NULL(2)
10294 bool sax_parse_internal(SAX* sax)
10295 {
10296 // stack to remember the hierarchy of structured values we are parsing
10297 // true = array; false = object
10298 std::vector<bool> states;
10299 // value to avoid a goto (see comment where set to true)
10300 bool skip_to_state_evaluation = false;
10301
10302 while (true)
10303 {
10304 if (!skip_to_state_evaluation)
10305 {
10306 // invariant: get_token() was called before each iteration
10307 switch (last_token)
10308 {
10309 case token_type::begin_object:
10310 {
10311 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10312 {
10313 return false;
10314 }
10315
10316 // closing } -> we are done
10317 if (get_token() == token_type::end_object)
10318 {
10319 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
10320 {
10321 return false;
10322 }
10323 break;
10324 }
10325
10326 // parse key
10327 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
10328 {
10329 return sax->parse_error(m_lexer.get_position(),
10330 m_lexer.get_token_string(),
10331 parse_error::create(101, m_lexer.get_position(),
10332 exception_message(token_type::value_string, "object key")));
10333 }
10334 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
10335 {
10336 return false;
10337 }
10338
10339 // parse separator (:)
10340 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10341 {
10342 return sax->parse_error(m_lexer.get_position(),
10343 m_lexer.get_token_string(),
10344 parse_error::create(101, m_lexer.get_position(),
10345 exception_message(token_type::name_separator, "object separator")));
10346 }
10347
10348 // remember we are now inside an object
10349 states.push_back(false);
10350
10351 // parse values
10352 get_token();
10353 continue;
10354 }
10355
10356 case token_type::begin_array:
10357 {
10358 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10359 {
10360 return false;
10361 }
10362
10363 // closing ] -> we are done
10364 if (get_token() == token_type::end_array)
10365 {
10366 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
10367 {
10368 return false;
10369 }
10370 break;
10371 }
10372
10373 // remember we are now inside an array
10374 states.push_back(true);
10375
10376 // parse values (no need to call get_token)
10377 continue;
10378 }
10379
10380 case token_type::value_float:
10381 {
10382 const auto res = m_lexer.get_number_float();
10383
10384 if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
10385 {
10386 return sax->parse_error(m_lexer.get_position(),
10387 m_lexer.get_token_string(),
10388 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
10389 }
10390
10391 if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
10392 {
10393 return false;
10394 }
10395
10396 break;
10397 }
10398
10399 case token_type::literal_false:
10400 {
10401 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
10402 {
10403 return false;
10404 }
10405 break;
10406 }
10407
10408 case token_type::literal_null:
10409 {
10410 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
10411 {
10412 return false;
10413 }
10414 break;
10415 }
10416
10417 case token_type::literal_true:
10418 {
10419 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
10420 {
10421 return false;
10422 }
10423 break;
10424 }
10425
10426 case token_type::value_integer:
10427 {
10428 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
10429 {
10430 return false;
10431 }
10432 break;
10433 }
10434
10435 case token_type::value_string:
10436 {
10437 if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
10438 {
10439 return false;
10440 }
10441 break;
10442 }
10443
10444 case token_type::value_unsigned:
10445 {
10446 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
10447 {
10448 return false;
10449 }
10450 break;
10451 }
10452
10453 case token_type::parse_error:
10454 {
10455 // using "uninitialized" to avoid "expected" message
10456 return sax->parse_error(m_lexer.get_position(),
10457 m_lexer.get_token_string(),
10458 parse_error::create(101, m_lexer.get_position(),
10459 exception_message(token_type::uninitialized, "value")));
10460 }
10461
10462 default: // the last token was unexpected
10463 {
10464 return sax->parse_error(m_lexer.get_position(),
10465 m_lexer.get_token_string(),
10466 parse_error::create(101, m_lexer.get_position(),
10467 exception_message(token_type::literal_or_value, "value")));
10468 }
10469 }
10470 }
10471 else
10472 {
10473 skip_to_state_evaluation = false;
10474 }
10475
10476 // we reached this line after we successfully parsed a value
10477 if (states.empty())
10478 {
10479 // empty stack: we reached the end of the hierarchy: done
10480 return true;
10481 }
10482
10483 if (states.back()) // array
10484 {
10485 // comma -> next value
10486 if (get_token() == token_type::value_separator)
10487 {
10488 // parse a new value
10489 get_token();
10490 continue;
10491 }
10492
10493 // closing ]
10494 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
10495 {
10496 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
10497 {
10498 return false;
10499 }
10500
10501 // We are done with this array. Before we can parse a
10502 // new value, we need to evaluate the new state first.
10503 // By setting skip_to_state_evaluation to false, we
10504 // are effectively jumping to the beginning of this if.
10505 JSON_ASSERT(!states.empty());
10506 states.pop_back();
10507 skip_to_state_evaluation = true;
10508 continue;
10509 }
10510
10511 return sax->parse_error(m_lexer.get_position(),
10512 m_lexer.get_token_string(),
10513 parse_error::create(101, m_lexer.get_position(),
10514 exception_message(token_type::end_array, "array")));
10515 }
10516 else // object
10517 {
10518 // comma -> next value
10519 if (get_token() == token_type::value_separator)
10520 {
10521 // parse key
10522 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
10523 {
10524 return sax->parse_error(m_lexer.get_position(),
10525 m_lexer.get_token_string(),
10526 parse_error::create(101, m_lexer.get_position(),
10527 exception_message(token_type::value_string, "object key")));
10528 }
10529
10530 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
10531 {
10532 return false;
10533 }
10534
10535 // parse separator (:)
10536 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10537 {
10538 return sax->parse_error(m_lexer.get_position(),
10539 m_lexer.get_token_string(),
10540 parse_error::create(101, m_lexer.get_position(),
10541 exception_message(token_type::name_separator, "object separator")));
10542 }
10543
10544 // parse values
10545 get_token();
10546 continue;
10547 }
10548
10549 // closing }
10550 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
10551 {
10552 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
10553 {
10554 return false;
10555 }
10556
10557 // We are done with this object. Before we can parse a
10558 // new value, we need to evaluate the new state first.
10559 // By setting skip_to_state_evaluation to false, we
10560 // are effectively jumping to the beginning of this if.
10561 JSON_ASSERT(!states.empty());
10562 states.pop_back();
10563 skip_to_state_evaluation = true;
10564 continue;
10565 }
10566
10567 return sax->parse_error(m_lexer.get_position(),
10568 m_lexer.get_token_string(),
10569 parse_error::create(101, m_lexer.get_position(),
10570 exception_message(token_type::end_object, "object")));
10571 }
10572 }
10573 }
10574
10576 token_type get_token()
10577 {
10578 return last_token = m_lexer.scan();
10579 }
10580
10581 std::string exception_message(const token_type expected, const std::string& context)
10582 {
10583 std::string error_msg = "syntax error ";
10584
10585 if (!context.empty())
10586 {
10587 error_msg += "while parsing " + context + " ";
10588 }
10589
10590 error_msg += "- ";
10591
10592 if (last_token == token_type::parse_error)
10593 {
10594 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
10595 m_lexer.get_token_string() + "'";
10596 }
10597 else
10598 {
10599 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
10600 }
10601
10602 if (expected != token_type::uninitialized)
10603 {
10604 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
10605 }
10606
10607 return error_msg;
10608 }
10609
10610 private:
10612 const parser_callback_t<BasicJsonType> callback = nullptr;
10614 token_type last_token = token_type::uninitialized;
10616 lexer_t m_lexer;
10618 const bool allow_exceptions = true;
10619 };
10620 } // namespace detail
10621 } // namespace nlohmann
10622
10623 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
10624
10625
10626 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10627
10628
10629 #include <cstddef> // ptrdiff_t
10630 #include <limits> // numeric_limits
10631
10632 namespace nlohmann
10633 {
10634 namespace detail
10635 {
10636 /*
10637 @brief an iterator for primitive JSON types
10638
10639 This class models an iterator for primitive JSON types (boolean, number,
10640 string). It's only purpose is to allow the iterator/const_iterator classes
10641 to "iterate" over primitive values. Internally, the iterator is modeled by
10642 a `difference_type` variable. Value begin_value (`0`) models the begin,
10643 end_value (`1`) models past the end.
10644 */
10645 class primitive_iterator_t
10646 {
10647 private:
10648 using difference_type = std::ptrdiff_t;
10649 static constexpr difference_type begin_value = 0;
10650 static constexpr difference_type end_value = begin_value + 1;
10651
10652 JSON_PRIVATE_UNLESS_TESTED:
10654 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
10655
10656 public:
10657 constexpr difference_type get_value() const noexcept
10658 {
10659 return m_it;
10660 }
10661
10663 void set_begin() noexcept
10664 {
10665 m_it = begin_value;
10666 }
10667
10669 void set_end() noexcept
10670 {
10671 m_it = end_value;
10672 }
10673
10675 constexpr bool is_begin() const noexcept
10676 {
10677 return m_it == begin_value;
10678 }
10679
10681 constexpr bool is_end() const noexcept
10682 {
10683 return m_it == end_value;
10684 }
10685
10686 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10687 {
10688 return lhs.m_it == rhs.m_it;
10689 }
10690
10691 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10692 {
10693 return lhs.m_it < rhs.m_it;
10694 }
10695
10696 primitive_iterator_t operator+(difference_type n) noexcept
10697 {
10698 auto result = *this;
10699 result += n;
10700 return result;
10701 }
10702
10703 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10704 {
10705 return lhs.m_it - rhs.m_it;
10706 }
10707
10708 primitive_iterator_t& operator++() noexcept
10709 {
10710 ++m_it;
10711 return *this;
10712 }
10713
10714 primitive_iterator_t const operator++(int) noexcept
10715 {
10716 auto result = *this;
10717 ++m_it;
10718 return result;
10719 }
10720
10721 primitive_iterator_t& operator--() noexcept
10722 {
10723 --m_it;
10724 return *this;
10725 }
10726
10727 primitive_iterator_t const operator--(int) noexcept
10728 {
10729 auto result = *this;
10730 --m_it;
10731 return result;
10732 }
10733
10734 primitive_iterator_t& operator+=(difference_type n) noexcept
10735 {
10736 m_it += n;
10737 return *this;
10738 }
10739
10740 primitive_iterator_t& operator-=(difference_type n) noexcept
10741 {
10742 m_it -= n;
10743 return *this;
10744 }
10745 };
10746 } // namespace detail
10747 } // namespace nlohmann
10748
10749
10750 namespace nlohmann
10751 {
10752 namespace detail
10753 {
10760 template<typename BasicJsonType> struct internal_iterator
10761 {
10763 typename BasicJsonType::object_t::iterator object_iterator {};
10765 typename BasicJsonType::array_t::iterator array_iterator {};
10767 primitive_iterator_t primitive_iterator {};
10768 };
10769 } // namespace detail
10770 } // namespace nlohmann
10771
10772 // #include <nlohmann/detail/iterators/iter_impl.hpp>
10773
10774
10775 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
10776 #include <type_traits> // conditional, is_const, remove_const
10777
10778 // #include <nlohmann/detail/exceptions.hpp>
10779
10780 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
10781
10782 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10783
10784 // #include <nlohmann/detail/macro_scope.hpp>
10785
10786 // #include <nlohmann/detail/meta/cpp_future.hpp>
10787
10788 // #include <nlohmann/detail/meta/type_traits.hpp>
10789
10790 // #include <nlohmann/detail/value_t.hpp>
10791
10792
10793 namespace nlohmann
10794 {
10795 namespace detail
10796 {
10797 // forward declare, to be able to friend it later on
10798 template<typename IteratorType> class iteration_proxy;
10799 template<typename IteratorType> class iteration_proxy_value;
10800
10817 template<typename BasicJsonType>
10818 class iter_impl
10819 {
10821 friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
10822 friend BasicJsonType;
10823 friend iteration_proxy<iter_impl>;
10824 friend iteration_proxy_value<iter_impl>;
10825
10826 using object_t = typename BasicJsonType::object_t;
10827 using array_t = typename BasicJsonType::array_t;
10828 // make sure BasicJsonType is basic_json or const basic_json
10829 static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
10830 "iter_impl only accepts (const) basic_json");
10831
10832 public:
10833
10839 using iterator_category = std::bidirectional_iterator_tag;
10840
10842 using value_type = typename BasicJsonType::value_type;
10844 using difference_type = typename BasicJsonType::difference_type;
10846 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
10847 typename BasicJsonType::const_pointer,
10848 typename BasicJsonType::pointer>::type;
10850 using reference =
10851 typename std::conditional<std::is_const<BasicJsonType>::value,
10852 typename BasicJsonType::const_reference,
10853 typename BasicJsonType::reference>::type;
10854
10856 iter_impl() = default;
10857
10864 explicit iter_impl(pointer object) noexcept : m_object(object)
10865 {
10866 JSON_ASSERT(m_object != nullptr);
10867
10868 switch (m_object->m_type)
10869 {
10870 case value_t::object:
10871 {
10872 m_it.object_iterator = typename object_t::iterator();
10873 break;
10874 }
10875
10876 case value_t::array:
10877 {
10878 m_it.array_iterator = typename array_t::iterator();
10879 break;
10880 }
10881
10882 default:
10883 {
10884 m_it.primitive_iterator = primitive_iterator_t();
10885 break;
10886 }
10887 }
10888 }
10889
10906 iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
10907 : m_object(other.m_object), m_it(other.m_it)
10908 {}
10909
10916 iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
10917 {
10918 m_object = other.m_object;
10919 m_it = other.m_it;
10920 return *this;
10921 }
10922
10928 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
10929 : m_object(other.m_object), m_it(other.m_it)
10930 {}
10931
10938 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
10939 {
10940 m_object = other.m_object;
10941 m_it = other.m_it;
10942 return *this;
10943 }
10944
10945 JSON_PRIVATE_UNLESS_TESTED:
10950 void set_begin() noexcept
10951 {
10952 JSON_ASSERT(m_object != nullptr);
10953
10954 switch (m_object->m_type)
10955 {
10956 case value_t::object:
10957 {
10958 m_it.object_iterator = m_object->m_value.object->begin();
10959 break;
10960 }
10961
10962 case value_t::array:
10963 {
10964 m_it.array_iterator = m_object->m_value.array->begin();
10965 break;
10966 }
10967
10968 case value_t::null:
10969 {
10970 // set to end so begin()==end() is true: null is empty
10971 m_it.primitive_iterator.set_end();
10972 break;
10973 }
10974
10975 default:
10976 {
10977 m_it.primitive_iterator.set_begin();
10978 break;
10979 }
10980 }
10981 }
10982
10987 void set_end() noexcept
10988 {
10989 JSON_ASSERT(m_object != nullptr);
10990
10991 switch (m_object->m_type)
10992 {
10993 case value_t::object:
10994 {
10995 m_it.object_iterator = m_object->m_value.object->end();
10996 break;
10997 }
10998
10999 case value_t::array:
11000 {
11001 m_it.array_iterator = m_object->m_value.array->end();
11002 break;
11003 }
11004
11005 default:
11006 {
11007 m_it.primitive_iterator.set_end();
11008 break;
11009 }
11010 }
11011 }
11012
11013 public:
11018 reference operator*() const
11019 {
11020 JSON_ASSERT(m_object != nullptr);
11021
11022 switch (m_object->m_type)
11023 {
11024 case value_t::object:
11025 {
11026 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11027 return m_it.object_iterator->second;
11028 }
11029
11030 case value_t::array:
11031 {
11032 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11033 return *m_it.array_iterator;
11034 }
11035
11036 case value_t::null:
11037 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11038
11039 default:
11040 {
11041 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11042 {
11043 return *m_object;
11044 }
11045
11046 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11047 }
11048 }
11049 }
11050
11055 pointer operator->() const
11056 {
11057 JSON_ASSERT(m_object != nullptr);
11058
11059 switch (m_object->m_type)
11060 {
11061 case value_t::object:
11062 {
11063 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11064 return &(m_it.object_iterator->second);
11065 }
11066
11067 case value_t::array:
11068 {
11069 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11070 return &*m_it.array_iterator;
11071 }
11072
11073 default:
11074 {
11075 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11076 {
11077 return m_object;
11078 }
11079
11080 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11081 }
11082 }
11083 }
11084
11089 iter_impl const operator++(int)
11090 {
11091 auto result = *this;
11092 ++(*this);
11093 return result;
11094 }
11095
11100 iter_impl& operator++()
11101 {
11102 JSON_ASSERT(m_object != nullptr);
11103
11104 switch (m_object->m_type)
11105 {
11106 case value_t::object:
11107 {
11108 std::advance(m_it.object_iterator, 1);
11109 break;
11110 }
11111
11112 case value_t::array:
11113 {
11114 std::advance(m_it.array_iterator, 1);
11115 break;
11116 }
11117
11118 default:
11119 {
11120 ++m_it.primitive_iterator;
11121 break;
11122 }
11123 }
11124
11125 return *this;
11126 }
11127
11132 iter_impl const operator--(int)
11133 {
11134 auto result = *this;
11135 --(*this);
11136 return result;
11137 }
11138
11143 iter_impl& operator--()
11144 {
11145 JSON_ASSERT(m_object != nullptr);
11146
11147 switch (m_object->m_type)
11148 {
11149 case value_t::object:
11150 {
11151 std::advance(m_it.object_iterator, -1);
11152 break;
11153 }
11154
11155 case value_t::array:
11156 {
11157 std::advance(m_it.array_iterator, -1);
11158 break;
11159 }
11160
11161 default:
11162 {
11163 --m_it.primitive_iterator;
11164 break;
11165 }
11166 }
11167
11168 return *this;
11169 }
11170
11175 bool operator==(const iter_impl& other) const
11176 {
11177 // if objects are not the same, the comparison is undefined
11178 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11179 {
11180 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
11181 }
11182
11183 JSON_ASSERT(m_object != nullptr);
11184
11185 switch (m_object->m_type)
11186 {
11187 case value_t::object:
11188 return (m_it.object_iterator == other.m_it.object_iterator);
11189
11190 case value_t::array:
11191 return (m_it.array_iterator == other.m_it.array_iterator);
11192
11193 default:
11194 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
11195 }
11196 }
11197
11202 bool operator!=(const iter_impl& other) const
11203 {
11204 return !operator==(other);
11205 }
11206
11211 bool operator<(const iter_impl& other) const
11212 {
11213 // if objects are not the same, the comparison is undefined
11214 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11215 {
11216 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
11217 }
11218
11219 JSON_ASSERT(m_object != nullptr);
11220
11221 switch (m_object->m_type)
11222 {
11223 case value_t::object:
11224 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
11225
11226 case value_t::array:
11227 return (m_it.array_iterator < other.m_it.array_iterator);
11228
11229 default:
11230 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
11231 }
11232 }
11233
11238 bool operator<=(const iter_impl& other) const
11239 {
11240 return !other.operator < (*this);
11241 }
11242
11247 bool operator>(const iter_impl& other) const
11248 {
11249 return !operator<=(other);
11250 }
11251
11256 bool operator>=(const iter_impl& other) const
11257 {
11258 return !operator<(other);
11259 }
11260
11265 iter_impl& operator+=(difference_type i)
11266 {
11267 JSON_ASSERT(m_object != nullptr);
11268
11269 switch (m_object->m_type)
11270 {
11271 case value_t::object:
11272 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
11273
11274 case value_t::array:
11275 {
11276 std::advance(m_it.array_iterator, i);
11277 break;
11278 }
11279
11280 default:
11281 {
11282 m_it.primitive_iterator += i;
11283 break;
11284 }
11285 }
11286
11287 return *this;
11288 }
11289
11294 iter_impl& operator-=(difference_type i)
11295 {
11296 return operator+=(-i);
11297 }
11298
11303 iter_impl operator+(difference_type i) const
11304 {
11305 auto result = *this;
11306 result += i;
11307 return result;
11308 }
11309
11314 friend iter_impl operator+(difference_type i, const iter_impl& it)
11315 {
11316 auto result = it;
11317 result += i;
11318 return result;
11319 }
11320
11325 iter_impl operator-(difference_type i) const
11326 {
11327 auto result = *this;
11328 result -= i;
11329 return result;
11330 }
11331
11336 difference_type operator-(const iter_impl& other) const
11337 {
11338 JSON_ASSERT(m_object != nullptr);
11339
11340 switch (m_object->m_type)
11341 {
11342 case value_t::object:
11343 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
11344
11345 case value_t::array:
11346 return m_it.array_iterator - other.m_it.array_iterator;
11347
11348 default:
11349 return m_it.primitive_iterator - other.m_it.primitive_iterator;
11350 }
11351 }
11352
11357 reference operator[](difference_type n) const
11358 {
11359 JSON_ASSERT(m_object != nullptr);
11360
11361 switch (m_object->m_type)
11362 {
11363 case value_t::object:
11364 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
11365
11366 case value_t::array:
11367 return *std::next(m_it.array_iterator, n);
11368
11369 case value_t::null:
11370 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11371
11372 default:
11373 {
11374 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
11375 {
11376 return *m_object;
11377 }
11378
11379 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11380 }
11381 }
11382 }
11383
11388 const typename object_t::key_type& key() const
11389 {
11390 JSON_ASSERT(m_object != nullptr);
11391
11392 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
11393 {
11394 return m_it.object_iterator->first;
11395 }
11396
11397 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
11398 }
11399
11404 reference value() const
11405 {
11406 return operator*();
11407 }
11408
11409 JSON_PRIVATE_UNLESS_TESTED:
11411 pointer m_object = nullptr;
11413 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
11414 };
11415 } // namespace detail
11416 } // namespace nlohmann
11417
11418 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
11419
11420 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
11421
11422
11423 #include <cstddef> // ptrdiff_t
11424 #include <iterator> // reverse_iterator
11425 #include <utility> // declval
11426
11427 namespace nlohmann
11428 {
11429 namespace detail
11430 {
11432 // reverse_iterator //
11434
11453 template<typename Base>
11454 class json_reverse_iterator : public std::reverse_iterator<Base>
11455 {
11456 public:
11457 using difference_type = std::ptrdiff_t;
11459 using base_iterator = std::reverse_iterator<Base>;
11461 using reference = typename Base::reference;
11462
11464 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
11465 : base_iterator(it) {}
11466
11468 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
11469
11471 json_reverse_iterator const operator++(int)
11472 {
11473 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
11474 }
11475
11477 json_reverse_iterator& operator++()
11478 {
11479 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
11480 }
11481
11483 json_reverse_iterator const operator--(int)
11484 {
11485 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
11486 }
11487
11489 json_reverse_iterator& operator--()
11490 {
11491 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
11492 }
11493
11495 json_reverse_iterator& operator+=(difference_type i)
11496 {
11497 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
11498 }
11499
11501 json_reverse_iterator operator+(difference_type i) const
11502 {
11503 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
11504 }
11505
11507 json_reverse_iterator operator-(difference_type i) const
11508 {
11509 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
11510 }
11511
11513 difference_type operator-(const json_reverse_iterator& other) const
11514 {
11515 return base_iterator(*this) - base_iterator(other);
11516 }
11517
11519 reference operator[](difference_type n) const
11520 {
11521 return *(this->operator+(n));
11522 }
11523
11525 auto key() const -> decltype(std::declval<Base>().key())
11526 {
11527 auto it = --this->base();
11528 return it.key();
11529 }
11530
11532 reference value() const
11533 {
11534 auto it = --this->base();
11535 return it.operator * ();
11536 }
11537 };
11538 } // namespace detail
11539 } // namespace nlohmann
11540
11541 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11542
11543 // #include <nlohmann/detail/json_pointer.hpp>
11544
11545
11546 #include <algorithm> // all_of
11547 #include <cctype> // isdigit
11548 #include <limits> // max
11549 #include <numeric> // accumulate
11550 #include <string> // string
11551 #include <utility> // move
11552 #include <vector> // vector
11553
11554 // #include <nlohmann/detail/exceptions.hpp>
11555
11556 // #include <nlohmann/detail/macro_scope.hpp>
11557
11558 // #include <nlohmann/detail/value_t.hpp>
11559
11560
11561 namespace nlohmann
11562 {
11563 template<typename BasicJsonType>
11564 class json_pointer
11565 {
11566 // allow basic_json to access private members
11567 NLOHMANN_BASIC_JSON_TPL_DECLARATION
11568 friend class basic_json;
11569
11570 public:
11592 explicit json_pointer(const std::string& s = "")
11593 : reference_tokens(split(s))
11594 {}
11595
11610 std::string to_string() const
11611 {
11612 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
11613 std::string{},
11614 [](const std::string & a, const std::string & b)
11615 {
11616 return a + "/" + escape(b);
11617 });
11618 }
11619
11621 operator std::string() const
11622 {
11623 return to_string();
11624 }
11625
11642 json_pointer& operator/=(const json_pointer& ptr)
11643 {
11644 reference_tokens.insert(reference_tokens.end(),
11645 ptr.reference_tokens.begin(),
11646 ptr.reference_tokens.end());
11647 return *this;
11648 }
11649
11666 json_pointer& operator/=(std::string token)
11667 {
11668 push_back(std::move(token));
11669 return *this;
11670 }
11671
11688 json_pointer& operator/=(std::size_t array_idx)
11689 {
11690 return *this /= std::to_string(array_idx);
11691 }
11692
11708 friend json_pointer operator/(const json_pointer& lhs,
11709 const json_pointer& rhs)
11710 {
11711 return json_pointer(lhs) /= rhs;
11712 }
11713
11729 friend json_pointer operator/(const json_pointer& ptr, std::string token)
11730 {
11731 return json_pointer(ptr) /= std::move(token);
11732 }
11733
11749 friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
11750 {
11751 return json_pointer(ptr) /= array_idx;
11752 }
11753
11767 json_pointer parent_pointer() const
11768 {
11769 if (empty())
11770 {
11771 return *this;
11772 }
11773
11774 json_pointer res = *this;
11775 res.pop_back();
11776 return res;
11777 }
11778
11792 void pop_back()
11793 {
11794 if (JSON_HEDLEY_UNLIKELY(empty()))
11795 {
11796 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11797 }
11798
11799 reference_tokens.pop_back();
11800 }
11801
11816 const std::string& back() const
11817 {
11818 if (JSON_HEDLEY_UNLIKELY(empty()))
11819 {
11820 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11821 }
11822
11823 return reference_tokens.back();
11824 }
11825
11838 void push_back(const std::string& token)
11839 {
11840 reference_tokens.push_back(token);
11841 }
11842
11844 void push_back(std::string&& token)
11845 {
11846 reference_tokens.push_back(std::move(token));
11847 }
11848
11863 bool empty() const noexcept
11864 {
11865 return reference_tokens.empty();
11866 }
11867
11868 private:
11879 static typename BasicJsonType::size_type array_index(const std::string& s)
11880 {
11881 using size_type = typename BasicJsonType::size_type;
11882
11883 // error condition (cf. RFC 6901, Sect. 4)
11884 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
11885 {
11886 JSON_THROW(detail::parse_error::create(106, 0,
11887 "array index '" + s +
11888 "' must not begin with '0'"));
11889 }
11890
11891 // error condition (cf. RFC 6901, Sect. 4)
11892 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
11893 {
11894 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number"));
11895 }
11896
11897 std::size_t processed_chars = 0;
11898 unsigned long long res = 0;
11899 JSON_TRY
11900 {
11901 res = std::stoull(s, &processed_chars);
11902 }
11903 JSON_CATCH(std::out_of_range&)
11904 {
11905 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11906 }
11907
11908 // check if the string was completely read
11909 if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
11910 {
11911 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11912 }
11913
11914 // only triggered on special platforms (like 32bit), see also
11915 // https://github.com/nlohmann/json/pull/2203
11916 if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)()))
11917 {
11918 JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type")); // LCOV_EXCL_LINE
11919 }
11920
11921 return static_cast<size_type>(res);
11922 }
11923
11924 JSON_PRIVATE_UNLESS_TESTED:
11925 json_pointer top() const
11926 {
11927 if (JSON_HEDLEY_UNLIKELY(empty()))
11928 {
11929 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11930 }
11931
11932 json_pointer result = *this;
11933 result.reference_tokens = {reference_tokens[0]};
11934 return result;
11935 }
11936
11937 private:
11946 BasicJsonType& get_and_create(BasicJsonType& j) const
11947 {
11948 auto result = &j;
11949
11950 // in case no reference tokens exist, return a reference to the JSON value
11951 // j which will be overwritten by a primitive value
11952 for (const auto& reference_token : reference_tokens)
11953 {
11954 switch (result->type())
11955 {
11956 case detail::value_t::null:
11957 {
11958 if (reference_token == "0")
11959 {
11960 // start a new array if reference token is 0
11961 result = &result->operator[](0);
11962 }
11963 else
11964 {
11965 // start a new object otherwise
11966 result = &result->operator[](reference_token);
11967 }
11968 break;
11969 }
11970
11971 case detail::value_t::object:
11972 {
11973 // create an entry in the object
11974 result = &result->operator[](reference_token);
11975 break;
11976 }
11977
11978 case detail::value_t::array:
11979 {
11980 // create an entry in the array
11981 result = &result->operator[](array_index(reference_token));
11982 break;
11983 }
11984
11985 /*
11986 The following code is only reached if there exists a reference
11987 token _and_ the current value is primitive. In this case, we have
11988 an error situation, because primitive values may only occur as
11989 single value; that is, with an empty list of reference tokens.
11990 */
11991 default:
11992 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
11993 }
11994 }
11995
11996 return *result;
11997 }
11998
12018 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
12019 {
12020 for (const auto& reference_token : reference_tokens)
12021 {
12022 // convert null values to arrays or objects before continuing
12023 if (ptr->is_null())
12024 {
12025 // check if reference token is a number
12026 const bool nums =
12027 std::all_of(reference_token.begin(), reference_token.end(),
12028 [](const unsigned char x)
12029 {
12030 return std::isdigit(x);
12031 });
12032
12033 // change value to array for numbers or "-" or to object otherwise
12034 *ptr = (nums || reference_token == "-")
12035 ? detail::value_t::array
12036 : detail::value_t::object;
12037 }
12038
12039 switch (ptr->type())
12040 {
12041 case detail::value_t::object:
12042 {
12043 // use unchecked object access
12044 ptr = &ptr->operator[](reference_token);
12045 break;
12046 }
12047
12048 case detail::value_t::array:
12049 {
12050 if (reference_token == "-")
12051 {
12052 // explicitly treat "-" as index beyond the end
12053 ptr = &ptr->operator[](ptr->m_value.array->size());
12054 }
12055 else
12056 {
12057 // convert array index to number; unchecked access
12058 ptr = &ptr->operator[](array_index(reference_token));
12059 }
12060 break;
12061 }
12062
12063 default:
12064 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12065 }
12066 }
12067
12068 return *ptr;
12069 }
12070
12077 BasicJsonType& get_checked(BasicJsonType* ptr) const
12078 {
12079 for (const auto& reference_token : reference_tokens)
12080 {
12081 switch (ptr->type())
12082 {
12083 case detail::value_t::object:
12084 {
12085 // note: at performs range check
12086 ptr = &ptr->at(reference_token);
12087 break;
12088 }
12089
12090 case detail::value_t::array:
12091 {
12092 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12093 {
12094 // "-" always fails the range check
12095 JSON_THROW(detail::out_of_range::create(402,
12096 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12097 ") is out of range"));
12098 }
12099
12100 // note: at performs range check
12101 ptr = &ptr->at(array_index(reference_token));
12102 break;
12103 }
12104
12105 default:
12106 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12107 }
12108 }
12109
12110 return *ptr;
12111 }
12112
12126 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
12127 {
12128 for (const auto& reference_token : reference_tokens)
12129 {
12130 switch (ptr->type())
12131 {
12132 case detail::value_t::object:
12133 {
12134 // use unchecked object access
12135 ptr = &ptr->operator[](reference_token);
12136 break;
12137 }
12138
12139 case detail::value_t::array:
12140 {
12141 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12142 {
12143 // "-" cannot be used for const access
12144 JSON_THROW(detail::out_of_range::create(402,
12145 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12146 ") is out of range"));
12147 }
12148
12149 // use unchecked array access
12150 ptr = &ptr->operator[](array_index(reference_token));
12151 break;
12152 }
12153
12154 default:
12155 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12156 }
12157 }
12158
12159 return *ptr;
12160 }
12161
12168 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
12169 {
12170 for (const auto& reference_token : reference_tokens)
12171 {
12172 switch (ptr->type())
12173 {
12174 case detail::value_t::object:
12175 {
12176 // note: at performs range check
12177 ptr = &ptr->at(reference_token);
12178 break;
12179 }
12180
12181 case detail::value_t::array:
12182 {
12183 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12184 {
12185 // "-" always fails the range check
12186 JSON_THROW(detail::out_of_range::create(402,
12187 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12188 ") is out of range"));
12189 }
12190
12191 // note: at performs range check
12192 ptr = &ptr->at(array_index(reference_token));
12193 break;
12194 }
12195
12196 default:
12197 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12198 }
12199 }
12200
12201 return *ptr;
12202 }
12203
12208 bool contains(const BasicJsonType* ptr) const
12209 {
12210 for (const auto& reference_token : reference_tokens)
12211 {
12212 switch (ptr->type())
12213 {
12214 case detail::value_t::object:
12215 {
12216 if (!ptr->contains(reference_token))
12217 {
12218 // we did not find the key in the object
12219 return false;
12220 }
12221
12222 ptr = &ptr->operator[](reference_token);
12223 break;
12224 }
12225
12226 case detail::value_t::array:
12227 {
12228 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12229 {
12230 // "-" always fails the range check
12231 return false;
12232 }
12233 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
12234 {
12235 // invalid char
12236 return false;
12237 }
12238 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
12239 {
12240 if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
12241 {
12242 // first char should be between '1' and '9'
12243 return false;
12244 }
12245 for (std::size_t i = 1; i < reference_token.size(); i++)
12246 {
12247 if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
12248 {
12249 // other char should be between '0' and '9'
12250 return false;
12251 }
12252 }
12253 }
12254
12255 const auto idx = array_index(reference_token);
12256 if (idx >= ptr->size())
12257 {
12258 // index out of range
12259 return false;
12260 }
12261
12262 ptr = &ptr->operator[](idx);
12263 break;
12264 }
12265
12266 default:
12267 {
12268 // we do not expect primitive values if there is still a
12269 // reference token to process
12270 return false;
12271 }
12272 }
12273 }
12274
12275 // no reference token left means we found a primitive value
12276 return true;
12277 }
12278
12288 static std::vector<std::string> split(const std::string& reference_string)
12289 {
12290 std::vector<std::string> result;
12291
12292 // special case: empty reference string -> no reference tokens
12293 if (reference_string.empty())
12294 {
12295 return result;
12296 }
12297
12298 // check if nonempty reference string begins with slash
12299 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
12300 {
12301 JSON_THROW(detail::parse_error::create(107, 1,
12302 "JSON pointer must be empty or begin with '/' - was: '" +
12303 reference_string + "'"));
12304 }
12305
12306 // extract the reference tokens:
12307 // - slash: position of the last read slash (or end of string)
12308 // - start: position after the previous slash
12309 for (
12310 // search for the first slash after the first character
12311 std::size_t slash = reference_string.find_first_of('/', 1),
12312 // set the beginning of the first reference token
12313 start = 1;
12314 // we can stop if start == 0 (if slash == std::string::npos)
12315 start != 0;
12316 // set the beginning of the next reference token
12317 // (will eventually be 0 if slash == std::string::npos)
12318 start = (slash == std::string::npos) ? 0 : slash + 1,
12319 // find next slash
12320 slash = reference_string.find_first_of('/', start))
12321 {
12322 // use the text between the beginning of the reference token
12323 // (start) and the last slash (slash).
12324 auto reference_token = reference_string.substr(start, slash - start);
12325
12326 // check reference tokens are properly escaped
12327 for (std::size_t pos = reference_token.find_first_of('~');
12328 pos != std::string::npos;
12329 pos = reference_token.find_first_of('~', pos + 1))
12330 {
12331 JSON_ASSERT(reference_token[pos] == '~');
12332
12333 // ~ must be followed by 0 or 1
12334 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
12335 (reference_token[pos + 1] != '0' &&
12336 reference_token[pos + 1] != '1')))
12337 {
12338 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
12339 }
12340 }
12341
12342 // finally, store the reference token
12343 unescape(reference_token);
12344 result.push_back(reference_token);
12345 }
12346
12347 return result;
12348 }
12349
12363 static void replace_substring(std::string& s, const std::string& f,
12364 const std::string& t)
12365 {
12366 JSON_ASSERT(!f.empty());
12367 for (auto pos = s.find(f); // find first occurrence of f
12368 pos != std::string::npos; // make sure f was found
12369 s.replace(pos, f.size(), t), // replace with t, and
12370 pos = s.find(f, pos + t.size())) // find next occurrence of f
12371 {}
12372 }
12373
12374 JSON_PRIVATE_UNLESS_TESTED:
12376 static std::string escape(std::string s)
12377 {
12378 replace_substring(s, "~", "~0");
12379 replace_substring(s, "/", "~1");
12380 return s;
12381 }
12382
12384 static void unescape(std::string& s)
12385 {
12386 replace_substring(s, "~1", "/");
12387 replace_substring(s, "~0", "~");
12388 }
12389
12390 private:
12398 static void flatten(const std::string& reference_string,
12399 const BasicJsonType& value,
12400 BasicJsonType& result)
12401 {
12402 switch (value.type())
12403 {
12404 case detail::value_t::array:
12405 {
12406 if (value.m_value.array->empty())
12407 {
12408 // flatten empty array as null
12409 result[reference_string] = nullptr;
12410 }
12411 else
12412 {
12413 // iterate array and use index as reference string
12414 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
12415 {
12416 flatten(reference_string + "/" + std::to_string(i),
12417 value.m_value.array->operator[](i), result);
12418 }
12419 }
12420 break;
12421 }
12422
12423 case detail::value_t::object:
12424 {
12425 if (value.m_value.object->empty())
12426 {
12427 // flatten empty object as null
12428 result[reference_string] = nullptr;
12429 }
12430 else
12431 {
12432 // iterate object and use keys as reference string
12433 for (const auto& element : *value.m_value.object)
12434 {
12435 flatten(reference_string + "/" + escape(element.first), element.second, result);
12436 }
12437 }
12438 break;
12439 }
12440
12441 default:
12442 {
12443 // add primitive value with its reference string
12444 result[reference_string] = value;
12445 break;
12446 }
12447 }
12448 }
12449
12460 static BasicJsonType
12461 unflatten(const BasicJsonType& value)
12462 {
12463 if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
12464 {
12465 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
12466 }
12467
12468 BasicJsonType result;
12469
12470 // iterate the JSON object values
12471 for (const auto& element : *value.m_value.object)
12472 {
12473 if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
12474 {
12475 JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
12476 }
12477
12478 // assign value to reference pointed to by JSON pointer; Note that if
12479 // the JSON pointer is "" (i.e., points to the whole value), function
12480 // get_and_create returns a reference to result itself. An assignment
12481 // will then create a primitive value.
12482 json_pointer(element.first).get_and_create(result) = element.second;
12483 }
12484
12485 return result;
12486 }
12487
12499 friend bool operator==(json_pointer const& lhs,
12500 json_pointer const& rhs) noexcept
12501 {
12502 return lhs.reference_tokens == rhs.reference_tokens;
12503 }
12504
12516 friend bool operator!=(json_pointer const& lhs,
12517 json_pointer const& rhs) noexcept
12518 {
12519 return !(lhs == rhs);
12520 }
12521
12523 std::vector<std::string> reference_tokens;
12524 };
12525 } // namespace nlohmann
12526
12527 // #include <nlohmann/detail/json_ref.hpp>
12528
12529
12530 #include <initializer_list>
12531 #include <utility>
12532
12533 // #include <nlohmann/detail/meta/type_traits.hpp>
12534
12535
12536 namespace nlohmann
12537 {
12538 namespace detail
12539 {
12540 template<typename BasicJsonType>
12541 class json_ref
12542 {
12543 public:
12544 using value_type = BasicJsonType;
12545
12546 json_ref(value_type&& value)
12547 : owned_value(std::move(value))
12548 , value_ref(&owned_value)
12549 , is_rvalue(true)
12550 {}
12551
12552 json_ref(const value_type& value)
12553 : value_ref(const_cast<value_type*>(&value))
12554 , is_rvalue(false)
12555 {}
12556
12557 json_ref(std::initializer_list<json_ref> init)
12558 : owned_value(init)
12559 , value_ref(&owned_value)
12560 , is_rvalue(true)
12561 {}
12562
12563 template <
12564 class... Args,
12565 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
12566 json_ref(Args && ... args)
12567 : owned_value(std::forward<Args>(args)...)
12568 , value_ref(&owned_value)
12569 , is_rvalue(true)
12570 {}
12571
12572 // class should be movable only
12573 json_ref(json_ref&&) = default;
12574 json_ref(const json_ref&) = delete;
12575 json_ref& operator=(const json_ref&) = delete;
12576 json_ref& operator=(json_ref&&) = delete;
12577 ~json_ref() = default;
12578
12579 value_type moved_or_copied() const
12580 {
12581 if (is_rvalue)
12582 {
12583 return std::move(*value_ref);
12584 }
12585 return *value_ref;
12586 }
12587
12588 value_type const& operator*() const
12589 {
12590 return *static_cast<value_type const*>(value_ref);
12591 }
12592
12593 value_type const* operator->() const
12594 {
12595 return static_cast<value_type const*>(value_ref);
12596 }
12597
12598 private:
12599 mutable value_type owned_value = nullptr;
12600 value_type* value_ref = nullptr;
12601 const bool is_rvalue = true;
12602 };
12603 } // namespace detail
12604 } // namespace nlohmann
12605
12606 // #include <nlohmann/detail/macro_scope.hpp>
12607
12608 // #include <nlohmann/detail/meta/cpp_future.hpp>
12609
12610 // #include <nlohmann/detail/meta/type_traits.hpp>
12611
12612 // #include <nlohmann/detail/output/binary_writer.hpp>
12613
12614
12615 #include <algorithm> // reverse
12616 #include <array> // array
12617 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
12618 #include <cstring> // memcpy
12619 #include <limits> // numeric_limits
12620 #include <string> // string
12621 #include <cmath> // isnan, isinf
12622
12623 // #include <nlohmann/detail/input/binary_reader.hpp>
12624
12625 // #include <nlohmann/detail/macro_scope.hpp>
12626
12627 // #include <nlohmann/detail/output/output_adapters.hpp>
12628
12629
12630 #include <algorithm> // copy
12631 #include <cstddef> // size_t
12632 #include <ios> // streamsize
12633 #include <iterator> // back_inserter
12634 #include <memory> // shared_ptr, make_shared
12635 #include <ostream> // basic_ostream
12636 #include <string> // basic_string
12637 #include <vector> // vector
12638 // #include <nlohmann/detail/macro_scope.hpp>
12639
12640
12641 namespace nlohmann
12642 {
12643 namespace detail
12644 {
12646 template<typename CharType> struct output_adapter_protocol
12647 {
12648 virtual void write_character(CharType c) = 0;
12649 virtual void write_characters(const CharType* s, std::size_t length) = 0;
12650 virtual ~output_adapter_protocol() = default;
12651 };
12652
12654 template<typename CharType>
12655 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
12656
12658 template<typename CharType>
12659 class output_vector_adapter : public output_adapter_protocol<CharType>
12660 {
12661 public:
12662 explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
12663 : v(vec)
12664 {}
12665
12666 void write_character(CharType c) override
12667 {
12668 v.push_back(c);
12669 }
12670
12671 JSON_HEDLEY_NON_NULL(2)
12672 void write_characters(const CharType* s, std::size_t length) override
12673 {
12674 std::copy(s, s + length, std::back_inserter(v));
12675 }
12676
12677 private:
12678 std::vector<CharType>& v;
12679 };
12680
12682 template<typename CharType>
12683 class output_stream_adapter : public output_adapter_protocol<CharType>
12684 {
12685 public:
12686 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
12687 : stream(s)
12688 {}
12689
12690 void write_character(CharType c) override
12691 {
12692 stream.put(c);
12693 }
12694
12695 JSON_HEDLEY_NON_NULL(2)
12696 void write_characters(const CharType* s, std::size_t length) override
12697 {
12698 stream.write(s, static_cast<std::streamsize>(length));
12699 }
12700
12701 private:
12702 std::basic_ostream<CharType>& stream;
12703 };
12704
12706 template<typename CharType, typename StringType = std::basic_string<CharType>>
12707 class output_string_adapter : public output_adapter_protocol<CharType>
12708 {
12709 public:
12710 explicit output_string_adapter(StringType& s) noexcept
12711 : str(s)
12712 {}
12713
12714 void write_character(CharType c) override
12715 {
12716 str.push_back(c);
12717 }
12718
12719 JSON_HEDLEY_NON_NULL(2)
12720 void write_characters(const CharType* s, std::size_t length) override
12721 {
12722 str.append(s, length);
12723 }
12724
12725 private:
12726 StringType& str;
12727 };
12728
12729 template<typename CharType, typename StringType = std::basic_string<CharType>>
12730 class output_adapter
12731 {
12732 public:
12733 output_adapter(std::vector<CharType>& vec)
12734 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
12735
12736 output_adapter(std::basic_ostream<CharType>& s)
12737 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
12738
12739 output_adapter(StringType& s)
12740 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
12741
12742 operator output_adapter_t<CharType>()
12743 {
12744 return oa;
12745 }
12746
12747 private:
12748 output_adapter_t<CharType> oa = nullptr;
12749 };
12750 } // namespace detail
12751 } // namespace nlohmann
12752
12753
12754 namespace nlohmann
12755 {
12756 namespace detail
12757 {
12759 // binary writer //
12761
12765 template<typename BasicJsonType, typename CharType>
12766 class binary_writer
12767 {
12768 using string_t = typename BasicJsonType::string_t;
12769 using binary_t = typename BasicJsonType::binary_t;
12770 using number_float_t = typename BasicJsonType::number_float_t;
12771
12772 public:
12778 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
12779 {
12780 JSON_ASSERT(oa);
12781 }
12782
12787 void write_bson(const BasicJsonType& j)
12788 {
12789 switch (j.type())
12790 {
12791 case value_t::object:
12792 {
12793 write_bson_object(*j.m_value.object);
12794 break;
12795 }
12796
12797 default:
12798 {
12799 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
12800 }
12801 }
12802 }
12803
12807 void write_cbor(const BasicJsonType& j)
12808 {
12809 switch (j.type())
12810 {
12811 case value_t::null:
12812 {
12813 oa->write_character(to_char_type(0xF6));
12814 break;
12815 }
12816
12817 case value_t::boolean:
12818 {
12819 oa->write_character(j.m_value.boolean
12820 ? to_char_type(0xF5)
12821 : to_char_type(0xF4));
12822 break;
12823 }
12824
12825 case value_t::number_integer:
12826 {
12827 if (j.m_value.number_integer >= 0)
12828 {
12829 // CBOR does not differentiate between positive signed
12830 // integers and unsigned integers. Therefore, we used the
12831 // code from the value_t::number_unsigned case here.
12832 if (j.m_value.number_integer <= 0x17)
12833 {
12834 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12835 }
12836 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
12837 {
12838 oa->write_character(to_char_type(0x18));
12839 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12840 }
12841 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
12842 {
12843 oa->write_character(to_char_type(0x19));
12844 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
12845 }
12846 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
12847 {
12848 oa->write_character(to_char_type(0x1A));
12849 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
12850 }
12851 else
12852 {
12853 oa->write_character(to_char_type(0x1B));
12854 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
12855 }
12856 }
12857 else
12858 {
12859 // The conversions below encode the sign in the first
12860 // byte, and the value is converted to a positive number.
12861 const auto positive_number = -1 - j.m_value.number_integer;
12862 if (j.m_value.number_integer >= -24)
12863 {
12864 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
12865 }
12866 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
12867 {
12868 oa->write_character(to_char_type(0x38));
12869 write_number(static_cast<std::uint8_t>(positive_number));
12870 }
12871 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
12872 {
12873 oa->write_character(to_char_type(0x39));
12874 write_number(static_cast<std::uint16_t>(positive_number));
12875 }
12876 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
12877 {
12878 oa->write_character(to_char_type(0x3A));
12879 write_number(static_cast<std::uint32_t>(positive_number));
12880 }
12881 else
12882 {
12883 oa->write_character(to_char_type(0x3B));
12884 write_number(static_cast<std::uint64_t>(positive_number));
12885 }
12886 }
12887 break;
12888 }
12889
12890 case value_t::number_unsigned:
12891 {
12892 if (j.m_value.number_unsigned <= 0x17)
12893 {
12894 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
12895 }
12896 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12897 {
12898 oa->write_character(to_char_type(0x18));
12899 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
12900 }
12901 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12902 {
12903 oa->write_character(to_char_type(0x19));
12904 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
12905 }
12906 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12907 {
12908 oa->write_character(to_char_type(0x1A));
12909 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
12910 }
12911 else
12912 {
12913 oa->write_character(to_char_type(0x1B));
12914 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
12915 }
12916 break;
12917 }
12918
12919 case value_t::number_float:
12920 {
12921 if (std::isnan(j.m_value.number_float))
12922 {
12923 // NaN is 0xf97e00 in CBOR
12924 oa->write_character(to_char_type(0xF9));
12925 oa->write_character(to_char_type(0x7E));
12926 oa->write_character(to_char_type(0x00));
12927 }
12928 else if (std::isinf(j.m_value.number_float))
12929 {
12930 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
12931 oa->write_character(to_char_type(0xf9));
12932 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
12933 oa->write_character(to_char_type(0x00));
12934 }
12935 else
12936 {
12937 write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
12938 }
12939 break;
12940 }
12941
12942 case value_t::string:
12943 {
12944 // step 1: write control byte and the string length
12945 const auto N = j.m_value.string->size();
12946 if (N <= 0x17)
12947 {
12948 write_number(static_cast<std::uint8_t>(0x60 + N));
12949 }
12950 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12951 {
12952 oa->write_character(to_char_type(0x78));
12953 write_number(static_cast<std::uint8_t>(N));
12954 }
12955 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12956 {
12957 oa->write_character(to_char_type(0x79));
12958 write_number(static_cast<std::uint16_t>(N));
12959 }
12960 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12961 {
12962 oa->write_character(to_char_type(0x7A));
12963 write_number(static_cast<std::uint32_t>(N));
12964 }
12965 // LCOV_EXCL_START
12966 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12967 {
12968 oa->write_character(to_char_type(0x7B));
12969 write_number(static_cast<std::uint64_t>(N));
12970 }
12971 // LCOV_EXCL_STOP
12972
12973 // step 2: write the string
12974 oa->write_characters(
12975 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
12976 j.m_value.string->size());
12977 break;
12978 }
12979
12980 case value_t::array:
12981 {
12982 // step 1: write control byte and the array size
12983 const auto N = j.m_value.array->size();
12984 if (N <= 0x17)
12985 {
12986 write_number(static_cast<std::uint8_t>(0x80 + N));
12987 }
12988 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12989 {
12990 oa->write_character(to_char_type(0x98));
12991 write_number(static_cast<std::uint8_t>(N));
12992 }
12993 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12994 {
12995 oa->write_character(to_char_type(0x99));
12996 write_number(static_cast<std::uint16_t>(N));
12997 }
12998 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12999 {
13000 oa->write_character(to_char_type(0x9A));
13001 write_number(static_cast<std::uint32_t>(N));
13002 }
13003 // LCOV_EXCL_START
13004 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13005 {
13006 oa->write_character(to_char_type(0x9B));
13007 write_number(static_cast<std::uint64_t>(N));
13008 }
13009 // LCOV_EXCL_STOP
13010
13011 // step 2: write each element
13012 for (const auto& el : *j.m_value.array)
13013 {
13014 write_cbor(el);
13015 }
13016 break;
13017 }
13018
13019 case value_t::binary:
13020 {
13021 if (j.m_value.binary->has_subtype())
13022 {
13023 write_number(static_cast<std::uint8_t>(0xd8));
13024 write_number(j.m_value.binary->subtype());
13025 }
13026
13027 // step 1: write control byte and the binary array size
13028 const auto N = j.m_value.binary->size();
13029 if (N <= 0x17)
13030 {
13031 write_number(static_cast<std::uint8_t>(0x40 + N));
13032 }
13033 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13034 {
13035 oa->write_character(to_char_type(0x58));
13036 write_number(static_cast<std::uint8_t>(N));
13037 }
13038 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13039 {
13040 oa->write_character(to_char_type(0x59));
13041 write_number(static_cast<std::uint16_t>(N));
13042 }
13043 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13044 {
13045 oa->write_character(to_char_type(0x5A));
13046 write_number(static_cast<std::uint32_t>(N));
13047 }
13048 // LCOV_EXCL_START
13049 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13050 {
13051 oa->write_character(to_char_type(0x5B));
13052 write_number(static_cast<std::uint64_t>(N));
13053 }
13054 // LCOV_EXCL_STOP
13055
13056 // step 2: write each element
13057 oa->write_characters(
13058 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13059 N);
13060
13061 break;
13062 }
13063
13064 case value_t::object:
13065 {
13066 // step 1: write control byte and the object size
13067 const auto N = j.m_value.object->size();
13068 if (N <= 0x17)
13069 {
13070 write_number(static_cast<std::uint8_t>(0xA0 + N));
13071 }
13072 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13073 {
13074 oa->write_character(to_char_type(0xB8));
13075 write_number(static_cast<std::uint8_t>(N));
13076 }
13077 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13078 {
13079 oa->write_character(to_char_type(0xB9));
13080 write_number(static_cast<std::uint16_t>(N));
13081 }
13082 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13083 {
13084 oa->write_character(to_char_type(0xBA));
13085 write_number(static_cast<std::uint32_t>(N));
13086 }
13087 // LCOV_EXCL_START
13088 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13089 {
13090 oa->write_character(to_char_type(0xBB));
13091 write_number(static_cast<std::uint64_t>(N));
13092 }
13093 // LCOV_EXCL_STOP
13094
13095 // step 2: write each element
13096 for (const auto& el : *j.m_value.object)
13097 {
13098 write_cbor(el.first);
13099 write_cbor(el.second);
13100 }
13101 break;
13102 }
13103
13104 default:
13105 break;
13106 }
13107 }
13108
13112 void write_msgpack(const BasicJsonType& j)
13113 {
13114 switch (j.type())
13115 {
13116 case value_t::null: // nil
13117 {
13118 oa->write_character(to_char_type(0xC0));
13119 break;
13120 }
13121
13122 case value_t::boolean: // true and false
13123 {
13124 oa->write_character(j.m_value.boolean
13125 ? to_char_type(0xC3)
13126 : to_char_type(0xC2));
13127 break;
13128 }
13129
13130 case value_t::number_integer:
13131 {
13132 if (j.m_value.number_integer >= 0)
13133 {
13134 // MessagePack does not differentiate between positive
13135 // signed integers and unsigned integers. Therefore, we used
13136 // the code from the value_t::number_unsigned case here.
13137 if (j.m_value.number_unsigned < 128)
13138 {
13139 // positive fixnum
13140 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13141 }
13142 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13143 {
13144 // uint 8
13145 oa->write_character(to_char_type(0xCC));
13146 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13147 }
13148 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13149 {
13150 // uint 16
13151 oa->write_character(to_char_type(0xCD));
13152 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13153 }
13154 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13155 {
13156 // uint 32
13157 oa->write_character(to_char_type(0xCE));
13158 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13159 }
13160 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
13161 {
13162 // uint 64
13163 oa->write_character(to_char_type(0xCF));
13164 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13165 }
13166 }
13167 else
13168 {
13169 if (j.m_value.number_integer >= -32)
13170 {
13171 // negative fixnum
13172 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
13173 }
13174 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
13175 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
13176 {
13177 // int 8
13178 oa->write_character(to_char_type(0xD0));
13179 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
13180 }
13181 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
13182 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
13183 {
13184 // int 16
13185 oa->write_character(to_char_type(0xD1));
13186 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
13187 }
13188 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
13189 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
13190 {
13191 // int 32
13192 oa->write_character(to_char_type(0xD2));
13193 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
13194 }
13195 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
13196 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
13197 {
13198 // int 64
13199 oa->write_character(to_char_type(0xD3));
13200 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
13201 }
13202 }
13203 break;
13204 }
13205
13206 case value_t::number_unsigned:
13207 {
13208 if (j.m_value.number_unsigned < 128)
13209 {
13210 // positive fixnum
13211 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13212 }
13213 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13214 {
13215 // uint 8
13216 oa->write_character(to_char_type(0xCC));
13217 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13218 }
13219 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13220 {
13221 // uint 16
13222 oa->write_character(to_char_type(0xCD));
13223 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13224 }
13225 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13226 {
13227 // uint 32
13228 oa->write_character(to_char_type(0xCE));
13229 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13230 }
13231 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
13232 {
13233 // uint 64
13234 oa->write_character(to_char_type(0xCF));
13235 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13236 }
13237 break;
13238 }
13239
13240 case value_t::number_float:
13241 {
13242 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
13243 break;
13244 }
13245
13246 case value_t::string:
13247 {
13248 // step 1: write control byte and the string length
13249 const auto N = j.m_value.string->size();
13250 if (N <= 31)
13251 {
13252 // fixstr
13253 write_number(static_cast<std::uint8_t>(0xA0 | N));
13254 }
13255 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13256 {
13257 // str 8
13258 oa->write_character(to_char_type(0xD9));
13259 write_number(static_cast<std::uint8_t>(N));
13260 }
13261 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13262 {
13263 // str 16
13264 oa->write_character(to_char_type(0xDA));
13265 write_number(static_cast<std::uint16_t>(N));
13266 }
13267 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13268 {
13269 // str 32
13270 oa->write_character(to_char_type(0xDB));
13271 write_number(static_cast<std::uint32_t>(N));
13272 }
13273
13274 // step 2: write the string
13275 oa->write_characters(
13276 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13277 j.m_value.string->size());
13278 break;
13279 }
13280
13281 case value_t::array:
13282 {
13283 // step 1: write control byte and the array size
13284 const auto N = j.m_value.array->size();
13285 if (N <= 15)
13286 {
13287 // fixarray
13288 write_number(static_cast<std::uint8_t>(0x90 | N));
13289 }
13290 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13291 {
13292 // array 16
13293 oa->write_character(to_char_type(0xDC));
13294 write_number(static_cast<std::uint16_t>(N));
13295 }
13296 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13297 {
13298 // array 32
13299 oa->write_character(to_char_type(0xDD));
13300 write_number(static_cast<std::uint32_t>(N));
13301 }
13302
13303 // step 2: write each element
13304 for (const auto& el : *j.m_value.array)
13305 {
13306 write_msgpack(el);
13307 }
13308 break;
13309 }
13310
13311 case value_t::binary:
13312 {
13313 // step 0: determine if the binary type has a set subtype to
13314 // determine whether or not to use the ext or fixext types
13315 const bool use_ext = j.m_value.binary->has_subtype();
13316
13317 // step 1: write control byte and the byte string length
13318 const auto N = j.m_value.binary->size();
13319 if (N <= (std::numeric_limits<std::uint8_t>::max)())
13320 {
13321 std::uint8_t output_type{};
13322 bool fixed = true;
13323 if (use_ext)
13324 {
13325 switch (N)
13326 {
13327 case 1:
13328 output_type = 0xD4; // fixext 1
13329 break;
13330 case 2:
13331 output_type = 0xD5; // fixext 2
13332 break;
13333 case 4:
13334 output_type = 0xD6; // fixext 4
13335 break;
13336 case 8:
13337 output_type = 0xD7; // fixext 8
13338 break;
13339 case 16:
13340 output_type = 0xD8; // fixext 16
13341 break;
13342 default:
13343 output_type = 0xC7; // ext 8
13344 fixed = false;
13345 break;
13346 }
13347
13348 }
13349 else
13350 {
13351 output_type = 0xC4; // bin 8
13352 fixed = false;
13353 }
13354
13355 oa->write_character(to_char_type(output_type));
13356 if (!fixed)
13357 {
13358 write_number(static_cast<std::uint8_t>(N));
13359 }
13360 }
13361 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13362 {
13363 std::uint8_t output_type = use_ext
13364 ? 0xC8 // ext 16
13365 : 0xC5; // bin 16
13366
13367 oa->write_character(to_char_type(output_type));
13368 write_number(static_cast<std::uint16_t>(N));
13369 }
13370 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13371 {
13372 std::uint8_t output_type = use_ext
13373 ? 0xC9 // ext 32
13374 : 0xC6; // bin 32
13375
13376 oa->write_character(to_char_type(output_type));
13377 write_number(static_cast<std::uint32_t>(N));
13378 }
13379
13380 // step 1.5: if this is an ext type, write the subtype
13381 if (use_ext)
13382 {
13383 write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
13384 }
13385
13386 // step 2: write the byte string
13387 oa->write_characters(
13388 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13389 N);
13390
13391 break;
13392 }
13393
13394 case value_t::object:
13395 {
13396 // step 1: write control byte and the object size
13397 const auto N = j.m_value.object->size();
13398 if (N <= 15)
13399 {
13400 // fixmap
13401 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
13402 }
13403 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13404 {
13405 // map 16
13406 oa->write_character(to_char_type(0xDE));
13407 write_number(static_cast<std::uint16_t>(N));
13408 }
13409 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13410 {
13411 // map 32
13412 oa->write_character(to_char_type(0xDF));
13413 write_number(static_cast<std::uint32_t>(N));
13414 }
13415
13416 // step 2: write each element
13417 for (const auto& el : *j.m_value.object)
13418 {
13419 write_msgpack(el.first);
13420 write_msgpack(el.second);
13421 }
13422 break;
13423 }
13424
13425 default:
13426 break;
13427 }
13428 }
13429
13436 void write_ubjson(const BasicJsonType& j, const bool use_count,
13437 const bool use_type, const bool add_prefix = true)
13438 {
13439 switch (j.type())
13440 {
13441 case value_t::null:
13442 {
13443 if (add_prefix)
13444 {
13445 oa->write_character(to_char_type('Z'));
13446 }
13447 break;
13448 }
13449
13450 case value_t::boolean:
13451 {
13452 if (add_prefix)
13453 {
13454 oa->write_character(j.m_value.boolean
13455 ? to_char_type('T')
13456 : to_char_type('F'));
13457 }
13458 break;
13459 }
13460
13461 case value_t::number_integer:
13462 {
13463 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
13464 break;
13465 }
13466
13467 case value_t::number_unsigned:
13468 {
13469 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
13470 break;
13471 }
13472
13473 case value_t::number_float:
13474 {
13475 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
13476 break;
13477 }
13478
13479 case value_t::string:
13480 {
13481 if (add_prefix)
13482 {
13483 oa->write_character(to_char_type('S'));
13484 }
13485 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
13486 oa->write_characters(
13487 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13488 j.m_value.string->size());
13489 break;
13490 }
13491
13492 case value_t::array:
13493 {
13494 if (add_prefix)
13495 {
13496 oa->write_character(to_char_type('['));
13497 }
13498
13499 bool prefix_required = true;
13500 if (use_type && !j.m_value.array->empty())
13501 {
13502 JSON_ASSERT(use_count);
13503 const CharType first_prefix = ubjson_prefix(j.front());
13504 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
13505 [this, first_prefix](const BasicJsonType & v)
13506 {
13507 return ubjson_prefix(v) == first_prefix;
13508 });
13509
13510 if (same_prefix)
13511 {
13512 prefix_required = false;
13513 oa->write_character(to_char_type('$'));
13514 oa->write_character(first_prefix);
13515 }
13516 }
13517
13518 if (use_count)
13519 {
13520 oa->write_character(to_char_type('#'));
13521 write_number_with_ubjson_prefix(j.m_value.array->size(), true);
13522 }
13523
13524 for (const auto& el : *j.m_value.array)
13525 {
13526 write_ubjson(el, use_count, use_type, prefix_required);
13527 }
13528
13529 if (!use_count)
13530 {
13531 oa->write_character(to_char_type(']'));
13532 }
13533
13534 break;
13535 }
13536
13537 case value_t::binary:
13538 {
13539 if (add_prefix)
13540 {
13541 oa->write_character(to_char_type('['));
13542 }
13543
13544 if (use_type && !j.m_value.binary->empty())
13545 {
13546 JSON_ASSERT(use_count);
13547 oa->write_character(to_char_type('$'));
13548 oa->write_character('U');
13549 }
13550
13551 if (use_count)
13552 {
13553 oa->write_character(to_char_type('#'));
13554 write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
13555 }
13556
13557 if (use_type)
13558 {
13559 oa->write_characters(
13560 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13561 j.m_value.binary->size());
13562 }
13563 else
13564 {
13565 for (size_t i = 0; i < j.m_value.binary->size(); ++i)
13566 {
13567 oa->write_character(to_char_type('U'));
13568 oa->write_character(j.m_value.binary->data()[i]);
13569 }
13570 }
13571
13572 if (!use_count)
13573 {
13574 oa->write_character(to_char_type(']'));
13575 }
13576
13577 break;
13578 }
13579
13580 case value_t::object:
13581 {
13582 if (add_prefix)
13583 {
13584 oa->write_character(to_char_type('{'));
13585 }
13586
13587 bool prefix_required = true;
13588 if (use_type && !j.m_value.object->empty())
13589 {
13590 JSON_ASSERT(use_count);
13591 const CharType first_prefix = ubjson_prefix(j.front());
13592 const bool same_prefix = std::all_of(j.begin(), j.end(),
13593 [this, first_prefix](const BasicJsonType & v)
13594 {
13595 return ubjson_prefix(v) == first_prefix;
13596 });
13597
13598 if (same_prefix)
13599 {
13600 prefix_required = false;
13601 oa->write_character(to_char_type('$'));
13602 oa->write_character(first_prefix);
13603 }
13604 }
13605
13606 if (use_count)
13607 {
13608 oa->write_character(to_char_type('#'));
13609 write_number_with_ubjson_prefix(j.m_value.object->size(), true);
13610 }
13611
13612 for (const auto& el : *j.m_value.object)
13613 {
13614 write_number_with_ubjson_prefix(el.first.size(), true);
13615 oa->write_characters(
13616 reinterpret_cast<const CharType*>(el.first.c_str()),
13617 el.first.size());
13618 write_ubjson(el.second, use_count, use_type, prefix_required);
13619 }
13620
13621 if (!use_count)
13622 {
13623 oa->write_character(to_char_type('}'));
13624 }
13625
13626 break;
13627 }
13628
13629 default:
13630 break;
13631 }
13632 }
13633
13634 private:
13636 // BSON //
13638
13643 static std::size_t calc_bson_entry_header_size(const string_t& name)
13644 {
13645 const auto it = name.find(static_cast<typename string_t::value_type>(0));
13646 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
13647 {
13648 JSON_THROW(out_of_range::create(409,
13649 "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
13650 }
13651
13652 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
13653 }
13654
13658 void write_bson_entry_header(const string_t& name,
13659 const std::uint8_t element_type)
13660 {
13661 oa->write_character(to_char_type(element_type)); // boolean
13662 oa->write_characters(
13663 reinterpret_cast<const CharType*>(name.c_str()),
13664 name.size() + 1u);
13665 }
13666
13670 void write_bson_boolean(const string_t& name,
13671 const bool value)
13672 {
13673 write_bson_entry_header(name, 0x08);
13674 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
13675 }
13676
13680 void write_bson_double(const string_t& name,
13681 const double value)
13682 {
13683 write_bson_entry_header(name, 0x01);
13684 write_number<double, true>(value);
13685 }
13686
13690 static std::size_t calc_bson_string_size(const string_t& value)
13691 {
13692 return sizeof(std::int32_t) + value.size() + 1ul;
13693 }
13694
13698 void write_bson_string(const string_t& name,
13699 const string_t& value)
13700 {
13701 write_bson_entry_header(name, 0x02);
13702
13703 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
13704 oa->write_characters(
13705 reinterpret_cast<const CharType*>(value.c_str()),
13706 value.size() + 1);
13707 }
13708
13712 void write_bson_null(const string_t& name)
13713 {
13714 write_bson_entry_header(name, 0x0A);
13715 }
13716
13720 static std::size_t calc_bson_integer_size(const std::int64_t value)
13721 {
13722 return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
13723 ? sizeof(std::int32_t)
13724 : sizeof(std::int64_t);
13725 }
13726
13730 void write_bson_integer(const string_t& name,
13731 const std::int64_t value)
13732 {
13733 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
13734 {
13735 write_bson_entry_header(name, 0x10); // int32
13736 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
13737 }
13738 else
13739 {
13740 write_bson_entry_header(name, 0x12); // int64
13741 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
13742 }
13743 }
13744
13748 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
13749 {
13750 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13751 ? sizeof(std::int32_t)
13752 : sizeof(std::int64_t);
13753 }
13754
13758 void write_bson_unsigned(const string_t& name,
13759 const std::uint64_t value)
13760 {
13761 if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13762 {
13763 write_bson_entry_header(name, 0x10 /* int32 */);
13764 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
13765 }
13766 else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
13767 {
13768 write_bson_entry_header(name, 0x12 /* int64 */);
13769 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
13770 }
13771 else
13772 {
13773 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
13774 }
13775 }
13776
13780 void write_bson_object_entry(const string_t& name,
13781 const typename BasicJsonType::object_t& value)
13782 {
13783 write_bson_entry_header(name, 0x03); // object
13784 write_bson_object(value);
13785 }
13786
13790 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
13791 {
13792 std::size_t array_index = 0ul;
13793
13794 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)
13795 {
13796 return result + calc_bson_element_size(std::to_string(array_index++), el);
13797 });
13798
13799 return sizeof(std::int32_t) + embedded_document_size + 1ul;
13800 }
13801
13805 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
13806 {
13807 return sizeof(std::int32_t) + value.size() + 1ul;
13808 }
13809
13813 void write_bson_array(const string_t& name,
13814 const typename BasicJsonType::array_t& value)
13815 {
13816 write_bson_entry_header(name, 0x04); // array
13817 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
13818
13819 std::size_t array_index = 0ul;
13820
13821 for (const auto& el : value)
13822 {
13823 write_bson_element(std::to_string(array_index++), el);
13824 }
13825
13826 oa->write_character(to_char_type(0x00));
13827 }
13828
13832 void write_bson_binary(const string_t& name,
13833 const binary_t& value)
13834 {
13835 write_bson_entry_header(name, 0x05);
13836
13837 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
13838 write_number(value.has_subtype() ? value.subtype() : std::uint8_t(0x00));
13839
13840 oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
13841 }
13842
13847 static std::size_t calc_bson_element_size(const string_t& name,
13848 const BasicJsonType& j)
13849 {
13850 const auto header_size = calc_bson_entry_header_size(name);
13851 switch (j.type())
13852 {
13853 case value_t::object:
13854 return header_size + calc_bson_object_size(*j.m_value.object);
13855
13856 case value_t::array:
13857 return header_size + calc_bson_array_size(*j.m_value.array);
13858
13859 case value_t::binary:
13860 return header_size + calc_bson_binary_size(*j.m_value.binary);
13861
13862 case value_t::boolean:
13863 return header_size + 1ul;
13864
13865 case value_t::number_float:
13866 return header_size + 8ul;
13867
13868 case value_t::number_integer:
13869 return header_size + calc_bson_integer_size(j.m_value.number_integer);
13870
13871 case value_t::number_unsigned:
13872 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
13873
13874 case value_t::string:
13875 return header_size + calc_bson_string_size(*j.m_value.string);
13876
13877 case value_t::null:
13878 return header_size + 0ul;
13879
13880 // LCOV_EXCL_START
13881 default:
13882 JSON_ASSERT(false);
13883 return 0ul;
13884 // LCOV_EXCL_STOP
13885 }
13886 }
13887
13895 void write_bson_element(const string_t& name,
13896 const BasicJsonType& j)
13897 {
13898 switch (j.type())
13899 {
13900 case value_t::object:
13901 return write_bson_object_entry(name, *j.m_value.object);
13902
13903 case value_t::array:
13904 return write_bson_array(name, *j.m_value.array);
13905
13906 case value_t::binary:
13907 return write_bson_binary(name, *j.m_value.binary);
13908
13909 case value_t::boolean:
13910 return write_bson_boolean(name, j.m_value.boolean);
13911
13912 case value_t::number_float:
13913 return write_bson_double(name, j.m_value.number_float);
13914
13915 case value_t::number_integer:
13916 return write_bson_integer(name, j.m_value.number_integer);
13917
13918 case value_t::number_unsigned:
13919 return write_bson_unsigned(name, j.m_value.number_unsigned);
13920
13921 case value_t::string:
13922 return write_bson_string(name, *j.m_value.string);
13923
13924 case value_t::null:
13925 return write_bson_null(name);
13926
13927 // LCOV_EXCL_START
13928 default:
13929 JSON_ASSERT(false);
13930 return;
13931 // LCOV_EXCL_STOP
13932 }
13933 }
13934
13941 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
13942 {
13943 std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
13944 [](size_t result, const typename BasicJsonType::object_t::value_type & el)
13945 {
13946 return result += calc_bson_element_size(el.first, el.second);
13947 });
13948
13949 return sizeof(std::int32_t) + document_size + 1ul;
13950 }
13951
13956 void write_bson_object(const typename BasicJsonType::object_t& value)
13957 {
13958 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
13959
13960 for (const auto& el : value)
13961 {
13962 write_bson_element(el.first, el.second);
13963 }
13964
13965 oa->write_character(to_char_type(0x00));
13966 }
13967
13969 // CBOR //
13971
13972 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
13973 {
13974 return to_char_type(0xFA); // Single-Precision Float
13975 }
13976
13977 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
13978 {
13979 return to_char_type(0xFB); // Double-Precision Float
13980 }
13981
13983 // MsgPack //
13985
13986 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
13987 {
13988 return to_char_type(0xCA); // float 32
13989 }
13990
13991 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
13992 {
13993 return to_char_type(0xCB); // float 64
13994 }
13995
13997 // UBJSON //
13999
14000 // UBJSON: write number (floating point)
14001 template<typename NumberType, typename std::enable_if<
14002 std::is_floating_point<NumberType>::value, int>::type = 0>
14003 void write_number_with_ubjson_prefix(const NumberType n,
14004 const bool add_prefix)
14005 {
14006 if (add_prefix)
14007 {
14008 oa->write_character(get_ubjson_float_prefix(n));
14009 }
14010 write_number(n);
14011 }
14012
14013 // UBJSON: write number (unsigned integer)
14014 template<typename NumberType, typename std::enable_if<
14015 std::is_unsigned<NumberType>::value, int>::type = 0>
14016 void write_number_with_ubjson_prefix(const NumberType n,
14017 const bool add_prefix)
14018 {
14019 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14020 {
14021 if (add_prefix)
14022 {
14023 oa->write_character(to_char_type('i')); // int8
14024 }
14025 write_number(static_cast<std::uint8_t>(n));
14026 }
14027 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
14028 {
14029 if (add_prefix)
14030 {
14031 oa->write_character(to_char_type('U')); // uint8
14032 }
14033 write_number(static_cast<std::uint8_t>(n));
14034 }
14035 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14036 {
14037 if (add_prefix)
14038 {
14039 oa->write_character(to_char_type('I')); // int16
14040 }
14041 write_number(static_cast<std::int16_t>(n));
14042 }
14043 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14044 {
14045 if (add_prefix)
14046 {
14047 oa->write_character(to_char_type('l')); // int32
14048 }
14049 write_number(static_cast<std::int32_t>(n));
14050 }
14051 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14052 {
14053 if (add_prefix)
14054 {
14055 oa->write_character(to_char_type('L')); // int64
14056 }
14057 write_number(static_cast<std::int64_t>(n));
14058 }
14059 else
14060 {
14061 if (add_prefix)
14062 {
14063 oa->write_character(to_char_type('H')); // high-precision number
14064 }
14065
14066 const auto number = BasicJsonType(n).dump();
14067 write_number_with_ubjson_prefix(number.size(), true);
14068 for (std::size_t i = 0; i < number.size(); ++i)
14069 {
14070 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14071 }
14072 }
14073 }
14074
14075 // UBJSON: write number (signed integer)
14076 template < typename NumberType, typename std::enable_if <
14077 std::is_signed<NumberType>::value&&
14078 !std::is_floating_point<NumberType>::value, int >::type = 0 >
14079 void write_number_with_ubjson_prefix(const NumberType n,
14080 const bool add_prefix)
14081 {
14082 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
14083 {
14084 if (add_prefix)
14085 {
14086 oa->write_character(to_char_type('i')); // int8
14087 }
14088 write_number(static_cast<std::int8_t>(n));
14089 }
14090 else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
14091 {
14092 if (add_prefix)
14093 {
14094 oa->write_character(to_char_type('U')); // uint8
14095 }
14096 write_number(static_cast<std::uint8_t>(n));
14097 }
14098 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
14099 {
14100 if (add_prefix)
14101 {
14102 oa->write_character(to_char_type('I')); // int16
14103 }
14104 write_number(static_cast<std::int16_t>(n));
14105 }
14106 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
14107 {
14108 if (add_prefix)
14109 {
14110 oa->write_character(to_char_type('l')); // int32
14111 }
14112 write_number(static_cast<std::int32_t>(n));
14113 }
14114 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
14115 {
14116 if (add_prefix)
14117 {
14118 oa->write_character(to_char_type('L')); // int64
14119 }
14120 write_number(static_cast<std::int64_t>(n));
14121 }
14122 // LCOV_EXCL_START
14123 else
14124 {
14125 if (add_prefix)
14126 {
14127 oa->write_character(to_char_type('H')); // high-precision number
14128 }
14129
14130 const auto number = BasicJsonType(n).dump();
14131 write_number_with_ubjson_prefix(number.size(), true);
14132 for (std::size_t i = 0; i < number.size(); ++i)
14133 {
14134 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14135 }
14136 }
14137 // LCOV_EXCL_STOP
14138 }
14139
14143 CharType ubjson_prefix(const BasicJsonType& j) const noexcept
14144 {
14145 switch (j.type())
14146 {
14147 case value_t::null:
14148 return 'Z';
14149
14150 case value_t::boolean:
14151 return j.m_value.boolean ? 'T' : 'F';
14152
14153 case value_t::number_integer:
14154 {
14155 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
14156 {
14157 return 'i';
14158 }
14159 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
14160 {
14161 return 'U';
14162 }
14163 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
14164 {
14165 return 'I';
14166 }
14167 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
14168 {
14169 return 'l';
14170 }
14171 if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
14172 {
14173 return 'L';
14174 }
14175 // anything else is treated as high-precision number
14176 return 'H'; // LCOV_EXCL_LINE
14177 }
14178
14179 case value_t::number_unsigned:
14180 {
14181 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14182 {
14183 return 'i';
14184 }
14185 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
14186 {
14187 return 'U';
14188 }
14189 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14190 {
14191 return 'I';
14192 }
14193 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14194 {
14195 return 'l';
14196 }
14197 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14198 {
14199 return 'L';
14200 }
14201 // anything else is treated as high-precision number
14202 return 'H'; // LCOV_EXCL_LINE
14203 }
14204
14205 case value_t::number_float:
14206 return get_ubjson_float_prefix(j.m_value.number_float);
14207
14208 case value_t::string:
14209 return 'S';
14210
14211 case value_t::array: // fallthrough
14212 case value_t::binary:
14213 return '[';
14214
14215 case value_t::object:
14216 return '{';
14217
14218 default: // discarded values
14219 return 'N';
14220 }
14221 }
14222
14223 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
14224 {
14225 return 'd'; // float 32
14226 }
14227
14228 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
14229 {
14230 return 'D'; // float 64
14231 }
14232
14234 // Utility functions //
14236
14237 /*
14238 @brief write a number to output input
14239 @param[in] n number of type @a NumberType
14240 @tparam NumberType the type of the number
14241 @tparam OutputIsLittleEndian Set to true if output data is
14242 required to be little endian
14243
14244 @note This function needs to respect the system's endianess, because bytes
14245 in CBOR, MessagePack, and UBJSON are stored in network order (big
14246 endian) and therefore need reordering on little endian systems.
14247 */
14248 template<typename NumberType, bool OutputIsLittleEndian = false>
14249 void write_number(const NumberType n)
14250 {
14251 // step 1: write number to array of length NumberType
14252 std::array<CharType, sizeof(NumberType)> vec;
14253 std::memcpy(vec.data(), &n, sizeof(NumberType));
14254
14255 // step 2: write array to output (with possible reordering)
14256 if (is_little_endian != OutputIsLittleEndian)
14257 {
14258 // reverse byte order prior to conversion if necessary
14259 std::reverse(vec.begin(), vec.end());
14260 }
14261
14262 oa->write_characters(vec.data(), sizeof(NumberType));
14263 }
14264
14265 void write_compact_float(const number_float_t n, detail::input_format_t format)
14266 {
14267 if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
14268 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
14269 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
14270 {
14271 oa->write_character(format == detail::input_format_t::cbor
14272 ? get_cbor_float_prefix(static_cast<float>(n))
14273 : get_msgpack_float_prefix(static_cast<float>(n)));
14274 write_number(static_cast<float>(n));
14275 }
14276 else
14277 {
14278 oa->write_character(format == detail::input_format_t::cbor
14279 ? get_cbor_float_prefix(n)
14280 : get_msgpack_float_prefix(n));
14281 write_number(n);
14282 }
14283 }
14284
14285 public:
14286 // The following to_char_type functions are implement the conversion
14287 // between uint8_t and CharType. In case CharType is not unsigned,
14288 // such a conversion is required to allow values greater than 128.
14289 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
14290 template < typename C = CharType,
14291 enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
14292 static constexpr CharType to_char_type(std::uint8_t x) noexcept
14293 {
14294 return *reinterpret_cast<char*>(&x);
14295 }
14296
14297 template < typename C = CharType,
14298 enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
14299 static CharType to_char_type(std::uint8_t x) noexcept
14300 {
14301 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
14302 static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
14303 CharType result;
14304 std::memcpy(&result, &x, sizeof(x));
14305 return result;
14306 }
14307
14308 template<typename C = CharType,
14309 enable_if_t<std::is_unsigned<C>::value>* = nullptr>
14310 static constexpr CharType to_char_type(std::uint8_t x) noexcept
14311 {
14312 return x;
14313 }
14314
14315 template < typename InputCharType, typename C = CharType,
14316 enable_if_t <
14317 std::is_signed<C>::value &&
14318 std::is_signed<char>::value &&
14319 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
14320 > * = nullptr >
14321 static constexpr CharType to_char_type(InputCharType x) noexcept
14322 {
14323 return x;
14324 }
14325
14326 private:
14328 const bool is_little_endian = little_endianess();
14329
14331 output_adapter_t<CharType> oa = nullptr;
14332 };
14333 } // namespace detail
14334 } // namespace nlohmann
14335
14336 // #include <nlohmann/detail/output/output_adapters.hpp>
14337
14338 // #include <nlohmann/detail/output/serializer.hpp>
14339
14340
14341 #include <algorithm> // reverse, remove, fill, find, none_of
14342 #include <array> // array
14343 #include <clocale> // localeconv, lconv
14344 #include <cmath> // labs, isfinite, isnan, signbit
14345 #include <cstddef> // size_t, ptrdiff_t
14346 #include <cstdint> // uint8_t
14347 #include <cstdio> // snprintf
14348 #include <limits> // numeric_limits
14349 #include <string> // string, char_traits
14350 #include <type_traits> // is_same
14351 #include <utility> // move
14352
14353 // #include <nlohmann/detail/conversions/to_chars.hpp>
14354
14355
14356 #include <array> // array
14357 #include <cmath> // signbit, isfinite
14358 #include <cstdint> // intN_t, uintN_t
14359 #include <cstring> // memcpy, memmove
14360 #include <limits> // numeric_limits
14361 #include <type_traits> // conditional
14362
14363 // #include <nlohmann/detail/macro_scope.hpp>
14364
14365
14366 namespace nlohmann
14367 {
14368 namespace detail
14369 {
14370
14390 namespace dtoa_impl
14391 {
14392
14393 template<typename Target, typename Source>
14394 Target reinterpret_bits(const Source source)
14395 {
14396 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
14397
14398 Target target;
14399 std::memcpy(&target, &source, sizeof(Source));
14400 return target;
14401 }
14402
14403 struct diyfp // f * 2^e
14404 {
14405 static constexpr int kPrecision = 64; // = q
14406
14407 std::uint64_t f = 0;
14408 int e = 0;
14409
14410 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
14411
14416 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
14417 {
14418 JSON_ASSERT(x.e == y.e);
14419 JSON_ASSERT(x.f >= y.f);
14420
14421 return {x.f - y.f, x.e};
14422 }
14423
14428 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
14429 {
14430 static_assert(kPrecision == 64, "internal error");
14431
14432 // Computes:
14433 // f = round((x.f * y.f) / 2^q)
14434 // e = x.e + y.e + q
14435
14436 // Emulate the 64-bit * 64-bit multiplication:
14437 //
14438 // p = u * v
14439 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
14440 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
14441 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
14442 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
14443 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
14444 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
14445 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
14446 //
14447 // (Since Q might be larger than 2^32 - 1)
14448 //
14449 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
14450 //
14451 // (Q_hi + H does not overflow a 64-bit int)
14452 //
14453 // = p_lo + 2^64 p_hi
14454
14455 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
14456 const std::uint64_t u_hi = x.f >> 32u;
14457 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
14458 const std::uint64_t v_hi = y.f >> 32u;
14459
14460 const std::uint64_t p0 = u_lo * v_lo;
14461 const std::uint64_t p1 = u_lo * v_hi;
14462 const std::uint64_t p2 = u_hi * v_lo;
14463 const std::uint64_t p3 = u_hi * v_hi;
14464
14465 const std::uint64_t p0_hi = p0 >> 32u;
14466 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
14467 const std::uint64_t p1_hi = p1 >> 32u;
14468 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
14469 const std::uint64_t p2_hi = p2 >> 32u;
14470
14471 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
14472
14473 // The full product might now be computed as
14474 //
14475 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
14476 // p_lo = p0_lo + (Q << 32)
14477 //
14478 // But in this particular case here, the full p_lo is not required.
14479 // Effectively we only need to add the highest bit in p_lo to p_hi (and
14480 // Q_hi + 1 does not overflow).
14481
14482 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
14483
14484 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
14485
14486 return {h, x.e + y.e + 64};
14487 }
14488
14493 static diyfp normalize(diyfp x) noexcept
14494 {
14495 JSON_ASSERT(x.f != 0);
14496
14497 while ((x.f >> 63u) == 0)
14498 {
14499 x.f <<= 1u;
14500 x.e--;
14501 }
14502
14503 return x;
14504 }
14505
14510 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
14511 {
14512 const int delta = x.e - target_exponent;
14513
14514 JSON_ASSERT(delta >= 0);
14515 JSON_ASSERT(((x.f << delta) >> delta) == x.f);
14516
14517 return {x.f << delta, target_exponent};
14518 }
14519 };
14520
14521 struct boundaries
14522 {
14523 diyfp w;
14524 diyfp minus;
14525 diyfp plus;
14526 };
14527
14534 template<typename FloatType>
14535 boundaries compute_boundaries(FloatType value)
14536 {
14537 JSON_ASSERT(std::isfinite(value));
14538 JSON_ASSERT(value > 0);
14539
14540 // Convert the IEEE representation into a diyfp.
14541 //
14542 // If v is denormal:
14543 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
14544 // If v is normalized:
14545 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
14546
14547 static_assert(std::numeric_limits<FloatType>::is_iec559,
14548 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
14549
14550 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
14551 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
14552 constexpr int kMinExp = 1 - kBias;
14553 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
14554
14555 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
14556
14557 const std::uint64_t bits = reinterpret_bits<bits_type>(value);
14558 const std::uint64_t E = bits >> (kPrecision - 1);
14559 const std::uint64_t F = bits & (kHiddenBit - 1);
14560
14561 const bool is_denormal = E == 0;
14562 const diyfp v = is_denormal
14563 ? diyfp(F, kMinExp)
14564 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
14565
14566 // Compute the boundaries m- and m+ of the floating-point value
14567 // v = f * 2^e.
14568 //
14569 // Determine v- and v+, the floating-point predecessor and successor if v,
14570 // respectively.
14571 //
14572 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
14573 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
14574 //
14575 // v+ = v + 2^e
14576 //
14577 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
14578 // between m- and m+ round to v, regardless of how the input rounding
14579 // algorithm breaks ties.
14580 //
14581 // ---+-------------+-------------+-------------+-------------+--- (A)
14582 // v- m- v m+ v+
14583 //
14584 // -----------------+------+------+-------------+-------------+--- (B)
14585 // v- m- v m+ v+
14586
14587 const bool lower_boundary_is_closer = F == 0 && E > 1;
14588 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
14589 const diyfp m_minus = lower_boundary_is_closer
14590 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
14591 : diyfp(2 * v.f - 1, v.e - 1); // (A)
14592
14593 // Determine the normalized w+ = m+.
14594 const diyfp w_plus = diyfp::normalize(m_plus);
14595
14596 // Determine w- = m- such that e_(w-) = e_(w+).
14597 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
14598
14599 return {diyfp::normalize(v), w_minus, w_plus};
14600 }
14601
14602 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
14603 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
14604 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
14605 //
14606 // alpha <= e = e_c + e_w + q <= gamma
14607 //
14608 // or
14609 //
14610 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
14611 // <= f_c * f_w * 2^gamma
14612 //
14613 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
14614 //
14615 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
14616 //
14617 // or
14618 //
14619 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
14620 //
14621 // The choice of (alpha,gamma) determines the size of the table and the form of
14622 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
14623 // in practice:
14624 //
14625 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
14626 // processed independently: An integral part p1, and a fractional part p2:
14627 //
14628 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
14629 // = (f div 2^-e) + (f mod 2^-e) * 2^e
14630 // = p1 + p2 * 2^e
14631 //
14632 // The conversion of p1 into decimal form requires a series of divisions and
14633 // modulos by (a power of) 10. These operations are faster for 32-bit than for
14634 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
14635 // achieved by choosing
14636 //
14637 // -e >= 32 or e <= -32 := gamma
14638 //
14639 // In order to convert the fractional part
14640 //
14641 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
14642 //
14643 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
14644 // d[-i] are extracted in order:
14645 //
14646 // (10 * p2) div 2^-e = d[-1]
14647 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
14648 //
14649 // The multiplication by 10 must not overflow. It is sufficient to choose
14650 //
14651 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
14652 //
14653 // Since p2 = f mod 2^-e < 2^-e,
14654 //
14655 // -e <= 60 or e >= -60 := alpha
14656
14657 constexpr int kAlpha = -60;
14658 constexpr int kGamma = -32;
14659
14660 struct cached_power // c = f * 2^e ~= 10^k
14661 {
14662 std::uint64_t f;
14663 int e;
14664 int k;
14665 };
14666
14674 inline cached_power get_cached_power_for_binary_exponent(int e)
14675 {
14676 // Now
14677 //
14678 // alpha <= e_c + e + q <= gamma (1)
14679 // ==> f_c * 2^alpha <= c * 2^e * 2^q
14680 //
14681 // and since the c's are normalized, 2^(q-1) <= f_c,
14682 //
14683 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
14684 // ==> 2^(alpha - e - 1) <= c
14685 //
14686 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
14687 //
14688 // k = ceil( log_10( 2^(alpha - e - 1) ) )
14689 // = ceil( (alpha - e - 1) * log_10(2) )
14690 //
14691 // From the paper:
14692 // "In theory the result of the procedure could be wrong since c is rounded,
14693 // and the computation itself is approximated [...]. In practice, however,
14694 // this simple function is sufficient."
14695 //
14696 // For IEEE double precision floating-point numbers converted into
14697 // normalized diyfp's w = f * 2^e, with q = 64,
14698 //
14699 // e >= -1022 (min IEEE exponent)
14700 // -52 (p - 1)
14701 // -52 (p - 1, possibly normalize denormal IEEE numbers)
14702 // -11 (normalize the diyfp)
14703 // = -1137
14704 //
14705 // and
14706 //
14707 // e <= +1023 (max IEEE exponent)
14708 // -52 (p - 1)
14709 // -11 (normalize the diyfp)
14710 // = 960
14711 //
14712 // This binary exponent range [-1137,960] results in a decimal exponent
14713 // range [-307,324]. One does not need to store a cached power for each
14714 // k in this range. For each such k it suffices to find a cached power
14715 // such that the exponent of the product lies in [alpha,gamma].
14716 // This implies that the difference of the decimal exponents of adjacent
14717 // table entries must be less than or equal to
14718 //
14719 // floor( (gamma - alpha) * log_10(2) ) = 8.
14720 //
14721 // (A smaller distance gamma-alpha would require a larger table.)
14722
14723 // NB:
14724 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
14725
14726 constexpr int kCachedPowersMinDecExp = -300;
14727 constexpr int kCachedPowersDecStep = 8;
14728
14729 static constexpr std::array<cached_power, 79> kCachedPowers =
14730 {
14731 {
14732 { 0xAB70FE17C79AC6CA, -1060, -300 },
14733 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
14734 { 0xBE5691EF416BD60C, -1007, -284 },
14735 { 0x8DD01FAD907FFC3C, -980, -276 },
14736 { 0xD3515C2831559A83, -954, -268 },
14737 { 0x9D71AC8FADA6C9B5, -927, -260 },
14738 { 0xEA9C227723EE8BCB, -901, -252 },
14739 { 0xAECC49914078536D, -874, -244 },
14740 { 0x823C12795DB6CE57, -847, -236 },
14741 { 0xC21094364DFB5637, -821, -228 },
14742 { 0x9096EA6F3848984F, -794, -220 },
14743 { 0xD77485CB25823AC7, -768, -212 },
14744 { 0xA086CFCD97BF97F4, -741, -204 },
14745 { 0xEF340A98172AACE5, -715, -196 },
14746 { 0xB23867FB2A35B28E, -688, -188 },
14747 { 0x84C8D4DFD2C63F3B, -661, -180 },
14748 { 0xC5DD44271AD3CDBA, -635, -172 },
14749 { 0x936B9FCEBB25C996, -608, -164 },
14750 { 0xDBAC6C247D62A584, -582, -156 },
14751 { 0xA3AB66580D5FDAF6, -555, -148 },
14752 { 0xF3E2F893DEC3F126, -529, -140 },
14753 { 0xB5B5ADA8AAFF80B8, -502, -132 },
14754 { 0x87625F056C7C4A8B, -475, -124 },
14755 { 0xC9BCFF6034C13053, -449, -116 },
14756 { 0x964E858C91BA2655, -422, -108 },
14757 { 0xDFF9772470297EBD, -396, -100 },
14758 { 0xA6DFBD9FB8E5B88F, -369, -92 },
14759 { 0xF8A95FCF88747D94, -343, -84 },
14760 { 0xB94470938FA89BCF, -316, -76 },
14761 { 0x8A08F0F8BF0F156B, -289, -68 },
14762 { 0xCDB02555653131B6, -263, -60 },
14763 { 0x993FE2C6D07B7FAC, -236, -52 },
14764 { 0xE45C10C42A2B3B06, -210, -44 },
14765 { 0xAA242499697392D3, -183, -36 },
14766 { 0xFD87B5F28300CA0E, -157, -28 },
14767 { 0xBCE5086492111AEB, -130, -20 },
14768 { 0x8CBCCC096F5088CC, -103, -12 },
14769 { 0xD1B71758E219652C, -77, -4 },
14770 { 0x9C40000000000000, -50, 4 },
14771 { 0xE8D4A51000000000, -24, 12 },
14772 { 0xAD78EBC5AC620000, 3, 20 },
14773 { 0x813F3978F8940984, 30, 28 },
14774 { 0xC097CE7BC90715B3, 56, 36 },
14775 { 0x8F7E32CE7BEA5C70, 83, 44 },
14776 { 0xD5D238A4ABE98068, 109, 52 },
14777 { 0x9F4F2726179A2245, 136, 60 },
14778 { 0xED63A231D4C4FB27, 162, 68 },
14779 { 0xB0DE65388CC8ADA8, 189, 76 },
14780 { 0x83C7088E1AAB65DB, 216, 84 },
14781 { 0xC45D1DF942711D9A, 242, 92 },
14782 { 0x924D692CA61BE758, 269, 100 },
14783 { 0xDA01EE641A708DEA, 295, 108 },
14784 { 0xA26DA3999AEF774A, 322, 116 },
14785 { 0xF209787BB47D6B85, 348, 124 },
14786 { 0xB454E4A179DD1877, 375, 132 },
14787 { 0x865B86925B9BC5C2, 402, 140 },
14788 { 0xC83553C5C8965D3D, 428, 148 },
14789 { 0x952AB45CFA97A0B3, 455, 156 },
14790 { 0xDE469FBD99A05FE3, 481, 164 },
14791 { 0xA59BC234DB398C25, 508, 172 },
14792 { 0xF6C69A72A3989F5C, 534, 180 },
14793 { 0xB7DCBF5354E9BECE, 561, 188 },
14794 { 0x88FCF317F22241E2, 588, 196 },
14795 { 0xCC20CE9BD35C78A5, 614, 204 },
14796 { 0x98165AF37B2153DF, 641, 212 },
14797 { 0xE2A0B5DC971F303A, 667, 220 },
14798 { 0xA8D9D1535CE3B396, 694, 228 },
14799 { 0xFB9B7CD9A4A7443C, 720, 236 },
14800 { 0xBB764C4CA7A44410, 747, 244 },
14801 { 0x8BAB8EEFB6409C1A, 774, 252 },
14802 { 0xD01FEF10A657842C, 800, 260 },
14803 { 0x9B10A4E5E9913129, 827, 268 },
14804 { 0xE7109BFBA19C0C9D, 853, 276 },
14805 { 0xAC2820D9623BF429, 880, 284 },
14806 { 0x80444B5E7AA7CF85, 907, 292 },
14807 { 0xBF21E44003ACDD2D, 933, 300 },
14808 { 0x8E679C2F5E44FF8F, 960, 308 },
14809 { 0xD433179D9C8CB841, 986, 316 },
14810 { 0x9E19DB92B4E31BA9, 1013, 324 },
14811 }
14812 };
14813
14814 // This computation gives exactly the same results for k as
14815 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
14816 // for |e| <= 1500, but doesn't require floating-point operations.
14817 // NB: log_10(2) ~= 78913 / 2^18
14818 JSON_ASSERT(e >= -1500);
14819 JSON_ASSERT(e <= 1500);
14820 const int f = kAlpha - e - 1;
14821 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
14822
14823 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
14824 JSON_ASSERT(index >= 0);
14825 JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
14826
14827 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
14828 JSON_ASSERT(kAlpha <= cached.e + e + 64);
14829 JSON_ASSERT(kGamma >= cached.e + e + 64);
14830
14831 return cached;
14832 }
14833
14838 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
14839 {
14840 // LCOV_EXCL_START
14841 if (n >= 1000000000)
14842 {
14843 pow10 = 1000000000;
14844 return 10;
14845 }
14846 // LCOV_EXCL_STOP
14847 else if (n >= 100000000)
14848 {
14849 pow10 = 100000000;
14850 return 9;
14851 }
14852 else if (n >= 10000000)
14853 {
14854 pow10 = 10000000;
14855 return 8;
14856 }
14857 else if (n >= 1000000)
14858 {
14859 pow10 = 1000000;
14860 return 7;
14861 }
14862 else if (n >= 100000)
14863 {
14864 pow10 = 100000;
14865 return 6;
14866 }
14867 else if (n >= 10000)
14868 {
14869 pow10 = 10000;
14870 return 5;
14871 }
14872 else if (n >= 1000)
14873 {
14874 pow10 = 1000;
14875 return 4;
14876 }
14877 else if (n >= 100)
14878 {
14879 pow10 = 100;
14880 return 3;
14881 }
14882 else if (n >= 10)
14883 {
14884 pow10 = 10;
14885 return 2;
14886 }
14887 else
14888 {
14889 pow10 = 1;
14890 return 1;
14891 }
14892 }
14893
14894 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
14895 std::uint64_t rest, std::uint64_t ten_k)
14896 {
14897 JSON_ASSERT(len >= 1);
14898 JSON_ASSERT(dist <= delta);
14899 JSON_ASSERT(rest <= delta);
14900 JSON_ASSERT(ten_k > 0);
14901
14902 // <--------------------------- delta ---->
14903 // <---- dist --------->
14904 // --------------[------------------+-------------------]--------------
14905 // M- w M+
14906 //
14907 // ten_k
14908 // <------>
14909 // <---- rest ---->
14910 // --------------[------------------+----+--------------]--------------
14911 // w V
14912 // = buf * 10^k
14913 //
14914 // ten_k represents a unit-in-the-last-place in the decimal representation
14915 // stored in buf.
14916 // Decrement buf by ten_k while this takes buf closer to w.
14917
14918 // The tests are written in this order to avoid overflow in unsigned
14919 // integer arithmetic.
14920
14921 while (rest < dist
14922 && delta - rest >= ten_k
14923 && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
14924 {
14925 JSON_ASSERT(buf[len - 1] != '0');
14926 buf[len - 1]--;
14927 rest += ten_k;
14928 }
14929 }
14930
14935 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
14936 diyfp M_minus, diyfp w, diyfp M_plus)
14937 {
14938 static_assert(kAlpha >= -60, "internal error");
14939 static_assert(kGamma <= -32, "internal error");
14940
14941 // Generates the digits (and the exponent) of a decimal floating-point
14942 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
14943 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
14944 //
14945 // <--------------------------- delta ---->
14946 // <---- dist --------->
14947 // --------------[------------------+-------------------]--------------
14948 // M- w M+
14949 //
14950 // Grisu2 generates the digits of M+ from left to right and stops as soon as
14951 // V is in [M-,M+].
14952
14953 JSON_ASSERT(M_plus.e >= kAlpha);
14954 JSON_ASSERT(M_plus.e <= kGamma);
14955
14956 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
14957 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
14958
14959 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
14960 //
14961 // M+ = f * 2^e
14962 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
14963 // = ((p1 ) * 2^-e + (p2 )) * 2^e
14964 // = p1 + p2 * 2^e
14965
14966 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
14967
14968 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.)
14969 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
14970
14971 // 1)
14972 //
14973 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
14974
14975 JSON_ASSERT(p1 > 0);
14976
14977 std::uint32_t pow10;
14978 const int k = find_largest_pow10(p1, pow10);
14979
14980 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
14981 //
14982 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
14983 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
14984 //
14985 // M+ = p1 + p2 * 2^e
14986 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
14987 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
14988 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
14989 //
14990 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
14991 //
14992 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
14993 //
14994 // but stop as soon as
14995 //
14996 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
14997
14998 int n = k;
14999 while (n > 0)
15000 {
15001 // Invariants:
15002 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
15003 // pow10 = 10^(n-1) <= p1 < 10^n
15004 //
15005 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
15006 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
15007 //
15008 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
15009 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
15010 //
15011 JSON_ASSERT(d <= 9);
15012 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15013 //
15014 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
15015 //
15016 p1 = r;
15017 n--;
15018 //
15019 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
15020 // pow10 = 10^n
15021 //
15022
15023 // Now check if enough digits have been generated.
15024 // Compute
15025 //
15026 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
15027 //
15028 // Note:
15029 // Since rest and delta share the same exponent e, it suffices to
15030 // compare the significands.
15031 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
15032 if (rest <= delta)
15033 {
15034 // V = buffer * 10^n, with M- <= V <= M+.
15035
15036 decimal_exponent += n;
15037
15038 // We may now just stop. But instead look if the buffer could be
15039 // decremented to bring V closer to w.
15040 //
15041 // pow10 = 10^n is now 1 ulp in the decimal representation V.
15042 // The rounding procedure works with diyfp's with an implicit
15043 // exponent of e.
15044 //
15045 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
15046 //
15047 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
15048 grisu2_round(buffer, length, dist, delta, rest, ten_n);
15049
15050 return;
15051 }
15052
15053 pow10 /= 10;
15054 //
15055 // pow10 = 10^(n-1) <= p1 < 10^n
15056 // Invariants restored.
15057 }
15058
15059 // 2)
15060 //
15061 // The digits of the integral part have been generated:
15062 //
15063 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
15064 // = buffer + p2 * 2^e
15065 //
15066 // Now generate the digits of the fractional part p2 * 2^e.
15067 //
15068 // Note:
15069 // No decimal point is generated: the exponent is adjusted instead.
15070 //
15071 // p2 actually represents the fraction
15072 //
15073 // p2 * 2^e
15074 // = p2 / 2^-e
15075 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
15076 //
15077 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
15078 //
15079 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
15080 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
15081 //
15082 // using
15083 //
15084 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
15085 // = ( d) * 2^-e + ( r)
15086 //
15087 // or
15088 // 10^m * p2 * 2^e = d + r * 2^e
15089 //
15090 // i.e.
15091 //
15092 // M+ = buffer + p2 * 2^e
15093 // = buffer + 10^-m * (d + r * 2^e)
15094 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
15095 //
15096 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
15097
15098 JSON_ASSERT(p2 > delta);
15099
15100 int m = 0;
15101 for (;;)
15102 {
15103 // Invariant:
15104 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
15105 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
15106 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
15107 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
15108 //
15109 JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
15110 p2 *= 10;
15111 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
15112 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
15113 //
15114 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
15115 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
15116 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
15117 //
15118 JSON_ASSERT(d <= 9);
15119 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15120 //
15121 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
15122 //
15123 p2 = r;
15124 m++;
15125 //
15126 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
15127 // Invariant restored.
15128
15129 // Check if enough digits have been generated.
15130 //
15131 // 10^-m * p2 * 2^e <= delta * 2^e
15132 // p2 * 2^e <= 10^m * delta * 2^e
15133 // p2 <= 10^m * delta
15134 delta *= 10;
15135 dist *= 10;
15136 if (p2 <= delta)
15137 {
15138 break;
15139 }
15140 }
15141
15142 // V = buffer * 10^-m, with M- <= V <= M+.
15143
15144 decimal_exponent -= m;
15145
15146 // 1 ulp in the decimal representation is now 10^-m.
15147 // Since delta and dist are now scaled by 10^m, we need to do the
15148 // same with ulp in order to keep the units in sync.
15149 //
15150 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
15151 //
15152 const std::uint64_t ten_m = one.f;
15153 grisu2_round(buffer, length, dist, delta, p2, ten_m);
15154
15155 // By construction this algorithm generates the shortest possible decimal
15156 // number (Loitsch, Theorem 6.2) which rounds back to w.
15157 // For an input number of precision p, at least
15158 //
15159 // N = 1 + ceil(p * log_10(2))
15160 //
15161 // decimal digits are sufficient to identify all binary floating-point
15162 // numbers (Matula, "In-and-Out conversions").
15163 // This implies that the algorithm does not produce more than N decimal
15164 // digits.
15165 //
15166 // N = 17 for p = 53 (IEEE double precision)
15167 // N = 9 for p = 24 (IEEE single precision)
15168 }
15169
15175 JSON_HEDLEY_NON_NULL(1)
15176 inline void grisu2(char* buf, int& len, int& decimal_exponent,
15177 diyfp m_minus, diyfp v, diyfp m_plus)
15178 {
15179 JSON_ASSERT(m_plus.e == m_minus.e);
15180 JSON_ASSERT(m_plus.e == v.e);
15181
15182 // --------(-----------------------+-----------------------)-------- (A)
15183 // m- v m+
15184 //
15185 // --------------------(-----------+-----------------------)-------- (B)
15186 // m- v m+
15187 //
15188 // First scale v (and m- and m+) such that the exponent is in the range
15189 // [alpha, gamma].
15190
15191 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
15192
15193 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
15194
15195 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
15196 const diyfp w = diyfp::mul(v, c_minus_k);
15197 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
15198 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
15199
15200 // ----(---+---)---------------(---+---)---------------(---+---)----
15201 // w- w w+
15202 // = c*m- = c*v = c*m+
15203 //
15204 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
15205 // w+ are now off by a small amount.
15206 // In fact:
15207 //
15208 // w - v * 10^k < 1 ulp
15209 //
15210 // To account for this inaccuracy, add resp. subtract 1 ulp.
15211 //
15212 // --------+---[---------------(---+---)---------------]---+--------
15213 // w- M- w M+ w+
15214 //
15215 // Now any number in [M-, M+] (bounds included) will round to w when input,
15216 // regardless of how the input rounding algorithm breaks ties.
15217 //
15218 // And digit_gen generates the shortest possible such number in [M-, M+].
15219 // Note that this does not mean that Grisu2 always generates the shortest
15220 // possible number in the interval (m-, m+).
15221 const diyfp M_minus(w_minus.f + 1, w_minus.e);
15222 const diyfp M_plus (w_plus.f - 1, w_plus.e );
15223
15224 decimal_exponent = -cached.k; // = -(-k) = k
15225
15226 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
15227 }
15228
15234 template<typename FloatType>
15235 JSON_HEDLEY_NON_NULL(1)
15236 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
15237 {
15238 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
15239 "internal error: not enough precision");
15240
15241 JSON_ASSERT(std::isfinite(value));
15242 JSON_ASSERT(value > 0);
15243
15244 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
15245 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
15246 // decimal representations are not exactly "short".
15247 //
15248 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
15249 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
15250 // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
15251 // does.
15252 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
15253 // representation using the corresponding std::from_chars function recovers value exactly". That
15254 // indicates that single precision floating-point numbers should be recovered using
15255 // 'std::strtof'.
15256 //
15257 // NB: If the neighbors are computed for single-precision numbers, there is a single float
15258 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
15259 // value is off by 1 ulp.
15260 #if 0
15261 const boundaries w = compute_boundaries(static_cast<double>(value));
15262 #else
15263 const boundaries w = compute_boundaries(value);
15264 #endif
15265
15266 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
15267 }
15268
15274 JSON_HEDLEY_NON_NULL(1)
15275
15276 inline char* append_exponent(char* buf, int e)
15277 {
15278 JSON_ASSERT(e > -1000);
15279 JSON_ASSERT(e < 1000);
15280
15281 if (e < 0)
15282 {
15283 e = -e;
15284 *buf++ = '-';
15285 }
15286 else
15287 {
15288 *buf++ = '+';
15289 }
15290
15291 auto k = static_cast<std::uint32_t>(e);
15292 if (k < 10)
15293 {
15294 // Always print at least two digits in the exponent.
15295 // This is for compatibility with printf("%g").
15296 *buf++ = '0';
15297 *buf++ = static_cast<char>('0' + k);
15298 }
15299 else if (k < 100)
15300 {
15301 *buf++ = static_cast<char>('0' + k / 10);
15302 k %= 10;
15303 *buf++ = static_cast<char>('0' + k);
15304 }
15305 else
15306 {
15307 *buf++ = static_cast<char>('0' + k / 100);
15308 k %= 100;
15309 *buf++ = static_cast<char>('0' + k / 10);
15310 k %= 10;
15311 *buf++ = static_cast<char>('0' + k);
15312 }
15313
15314 return buf;
15315 }
15316
15326 JSON_HEDLEY_NON_NULL(1)
15327
15328 inline char* format_buffer(char* buf, int len, int decimal_exponent,
15329 int min_exp, int max_exp)
15330 {
15331 JSON_ASSERT(min_exp < 0);
15332 JSON_ASSERT(max_exp > 0);
15333
15334 const int k = len;
15335 const int n = len + decimal_exponent;
15336
15337 // v = buf * 10^(n-k)
15338 // k is the length of the buffer (number of decimal digits)
15339 // n is the position of the decimal point relative to the start of the buffer.
15340
15341 if (k <= n && n <= max_exp)
15342 {
15343 // digits[000]
15344 // len <= max_exp + 2
15345
15346 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
15347 // Make it look like a floating-point number (#362, #378)
15348 buf[n + 0] = '.';
15349 buf[n + 1] = '0';
15350 return buf + (static_cast<size_t>(n) + 2);
15351 }
15352
15353 if (0 < n && n <= max_exp)
15354 {
15355 // dig.its
15356 // len <= max_digits10 + 1
15357
15358 JSON_ASSERT(k > n);
15359
15360 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
15361 buf[n] = '.';
15362 return buf + (static_cast<size_t>(k) + 1U);
15363 }
15364
15365 if (min_exp < n && n <= 0)
15366 {
15367 // 0.[000]digits
15368 // len <= 2 + (-min_exp - 1) + max_digits10
15369
15370 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
15371 buf[0] = '0';
15372 buf[1] = '.';
15373 std::memset(buf + 2, '0', static_cast<size_t>(-n));
15374 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
15375 }
15376
15377 if (k == 1)
15378 {
15379 // dE+123
15380 // len <= 1 + 5
15381
15382 buf += 1;
15383 }
15384 else
15385 {
15386 // d.igitsE+123
15387 // len <= max_digits10 + 1 + 5
15388
15389 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
15390 buf[1] = '.';
15391 buf += 1 + static_cast<size_t>(k);
15392 }
15393
15394 *buf++ = 'e';
15395 return append_exponent(buf, n - 1);
15396 }
15397
15398 } // namespace dtoa_impl
15399
15410 template<typename FloatType>
15411 JSON_HEDLEY_NON_NULL(1, 2)
15412
15413 char* to_chars(char* first, const char* last, FloatType value)
15414 {
15415 static_cast<void>(last); // maybe unused - fix warning
15416 JSON_ASSERT(std::isfinite(value));
15417
15418 // Use signbit(value) instead of (value < 0) since signbit works for -0.
15419 if (std::signbit(value))
15420 {
15421 value = -value;
15422 *first++ = '-';
15423 }
15424
15425 if (value == 0) // +-0
15426 {
15427 *first++ = '0';
15428 // Make it look like a floating-point number (#362, #378)
15429 *first++ = '.';
15430 *first++ = '0';
15431 return first;
15432 }
15433
15434 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
15435
15436 // Compute v = buffer * 10^decimal_exponent.
15437 // The decimal digits are stored in the buffer, which needs to be interpreted
15438 // as an unsigned decimal integer.
15439 // len is the length of the buffer, i.e. the number of decimal digits.
15440 int len = 0;
15441 int decimal_exponent = 0;
15442 dtoa_impl::grisu2(first, len, decimal_exponent, value);
15443
15444 JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
15445
15446 // Format the buffer like printf("%.*g", prec, value)
15447 constexpr int kMinExp = -4;
15448 // Use digits10 here to increase compatibility with version 2.
15449 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
15450
15451 JSON_ASSERT(last - first >= kMaxExp + 2);
15452 JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
15453 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
15454
15455 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
15456 }
15457
15458 } // namespace detail
15459 } // namespace nlohmann
15460
15461 // #include <nlohmann/detail/exceptions.hpp>
15462
15463 // #include <nlohmann/detail/macro_scope.hpp>
15464
15465 // #include <nlohmann/detail/meta/cpp_future.hpp>
15466
15467 // #include <nlohmann/detail/output/binary_writer.hpp>
15468
15469 // #include <nlohmann/detail/output/output_adapters.hpp>
15470
15471 // #include <nlohmann/detail/value_t.hpp>
15472
15473
15474 namespace nlohmann
15475 {
15476 namespace detail
15477 {
15479 // serialization //
15481
15483 enum class error_handler_t
15484 {
15485 strict,
15486 replace,
15487 ignore
15488 };
15489
15490 template<typename BasicJsonType>
15491 class serializer
15492 {
15493 using string_t = typename BasicJsonType::string_t;
15494 using number_float_t = typename BasicJsonType::number_float_t;
15495 using number_integer_t = typename BasicJsonType::number_integer_t;
15496 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
15497 using binary_char_t = typename BasicJsonType::binary_t::value_type;
15498 static constexpr std::uint8_t UTF8_ACCEPT = 0;
15499 static constexpr std::uint8_t UTF8_REJECT = 1;
15500
15501 public:
15507 serializer(output_adapter_t<char> s, const char ichar,
15508 error_handler_t error_handler_ = error_handler_t::strict)
15509 : o(std::move(s))
15510 , loc(std::localeconv())
15511 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
15512 , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
15513 , indent_char(ichar)
15514 , indent_string(512, indent_char)
15515 , error_handler(error_handler_)
15516 {}
15517
15518 // delete because of pointer members
15519 serializer(const serializer&) = delete;
15520 serializer& operator=(const serializer&) = delete;
15521 serializer(serializer&&) = delete;
15522 serializer& operator=(serializer&&) = delete;
15523 ~serializer() = default;
15524
15547 void dump(const BasicJsonType& val,
15548 const bool pretty_print,
15549 const bool ensure_ascii,
15550 const unsigned int indent_step,
15551 const unsigned int current_indent = 0)
15552 {
15553 switch (val.m_type)
15554 {
15555 case value_t::object:
15556 {
15557 if (val.m_value.object->empty())
15558 {
15559 o->write_characters("{}", 2);
15560 return;
15561 }
15562
15563 if (pretty_print)
15564 {
15565 o->write_characters("{\n", 2);
15566
15567 // variable to hold indentation for recursive calls
15568 const auto new_indent = current_indent + indent_step;
15569 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15570 {
15571 indent_string.resize(indent_string.size() * 2, ' ');
15572 }
15573
15574 // first n-1 elements
15575 auto i = val.m_value.object->cbegin();
15576 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15577 {
15578 o->write_characters(indent_string.c_str(), new_indent);
15579 o->write_character('\"');
15580 dump_escaped(i->first, ensure_ascii);
15581 o->write_characters("\": ", 3);
15582 dump(i->second, true, ensure_ascii, indent_step, new_indent);
15583 o->write_characters(",\n", 2);
15584 }
15585
15586 // last element
15587 JSON_ASSERT(i != val.m_value.object->cend());
15588 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
15589 o->write_characters(indent_string.c_str(), new_indent);
15590 o->write_character('\"');
15591 dump_escaped(i->first, ensure_ascii);
15592 o->write_characters("\": ", 3);
15593 dump(i->second, true, ensure_ascii, indent_step, new_indent);
15594
15595 o->write_character('\n');
15596 o->write_characters(indent_string.c_str(), current_indent);
15597 o->write_character('}');
15598 }
15599 else
15600 {
15601 o->write_character('{');
15602
15603 // first n-1 elements
15604 auto i = val.m_value.object->cbegin();
15605 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15606 {
15607 o->write_character('\"');
15608 dump_escaped(i->first, ensure_ascii);
15609 o->write_characters("\":", 2);
15610 dump(i->second, false, ensure_ascii, indent_step, current_indent);
15611 o->write_character(',');
15612 }
15613
15614 // last element
15615 JSON_ASSERT(i != val.m_value.object->cend());
15616 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
15617 o->write_character('\"');
15618 dump_escaped(i->first, ensure_ascii);
15619 o->write_characters("\":", 2);
15620 dump(i->second, false, ensure_ascii, indent_step, current_indent);
15621
15622 o->write_character('}');
15623 }
15624
15625 return;
15626 }
15627
15628 case value_t::array:
15629 {
15630 if (val.m_value.array->empty())
15631 {
15632 o->write_characters("[]", 2);
15633 return;
15634 }
15635
15636 if (pretty_print)
15637 {
15638 o->write_characters("[\n", 2);
15639
15640 // variable to hold indentation for recursive calls
15641 const auto new_indent = current_indent + indent_step;
15642 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15643 {
15644 indent_string.resize(indent_string.size() * 2, ' ');
15645 }
15646
15647 // first n-1 elements
15648 for (auto i = val.m_value.array->cbegin();
15649 i != val.m_value.array->cend() - 1; ++i)
15650 {
15651 o->write_characters(indent_string.c_str(), new_indent);
15652 dump(*i, true, ensure_ascii, indent_step, new_indent);
15653 o->write_characters(",\n", 2);
15654 }
15655
15656 // last element
15657 JSON_ASSERT(!val.m_value.array->empty());
15658 o->write_characters(indent_string.c_str(), new_indent);
15659 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
15660
15661 o->write_character('\n');
15662 o->write_characters(indent_string.c_str(), current_indent);
15663 o->write_character(']');
15664 }
15665 else
15666 {
15667 o->write_character('[');
15668
15669 // first n-1 elements
15670 for (auto i = val.m_value.array->cbegin();
15671 i != val.m_value.array->cend() - 1; ++i)
15672 {
15673 dump(*i, false, ensure_ascii, indent_step, current_indent);
15674 o->write_character(',');
15675 }
15676
15677 // last element
15678 JSON_ASSERT(!val.m_value.array->empty());
15679 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
15680
15681 o->write_character(']');
15682 }
15683
15684 return;
15685 }
15686
15687 case value_t::string:
15688 {
15689 o->write_character('\"');
15690 dump_escaped(*val.m_value.string, ensure_ascii);
15691 o->write_character('\"');
15692 return;
15693 }
15694
15695 case value_t::binary:
15696 {
15697 if (pretty_print)
15698 {
15699 o->write_characters("{\n", 2);
15700
15701 // variable to hold indentation for recursive calls
15702 const auto new_indent = current_indent + indent_step;
15703 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15704 {
15705 indent_string.resize(indent_string.size() * 2, ' ');
15706 }
15707
15708 o->write_characters(indent_string.c_str(), new_indent);
15709
15710 o->write_characters("\"bytes\": [", 10);
15711
15712 if (!val.m_value.binary->empty())
15713 {
15714 for (auto i = val.m_value.binary->cbegin();
15715 i != val.m_value.binary->cend() - 1; ++i)
15716 {
15717 dump_integer(*i);
15718 o->write_characters(", ", 2);
15719 }
15720 dump_integer(val.m_value.binary->back());
15721 }
15722
15723 o->write_characters("],\n", 3);
15724 o->write_characters(indent_string.c_str(), new_indent);
15725
15726 o->write_characters("\"subtype\": ", 11);
15727 if (val.m_value.binary->has_subtype())
15728 {
15729 dump_integer(val.m_value.binary->subtype());
15730 }
15731 else
15732 {
15733 o->write_characters("null", 4);
15734 }
15735 o->write_character('\n');
15736 o->write_characters(indent_string.c_str(), current_indent);
15737 o->write_character('}');
15738 }
15739 else
15740 {
15741 o->write_characters("{\"bytes\":[", 10);
15742
15743 if (!val.m_value.binary->empty())
15744 {
15745 for (auto i = val.m_value.binary->cbegin();
15746 i != val.m_value.binary->cend() - 1; ++i)
15747 {
15748 dump_integer(*i);
15749 o->write_character(',');
15750 }
15751 dump_integer(val.m_value.binary->back());
15752 }
15753
15754 o->write_characters("],\"subtype\":", 12);
15755 if (val.m_value.binary->has_subtype())
15756 {
15757 dump_integer(val.m_value.binary->subtype());
15758 o->write_character('}');
15759 }
15760 else
15761 {
15762 o->write_characters("null}", 5);
15763 }
15764 }
15765 return;
15766 }
15767
15768 case value_t::boolean:
15769 {
15770 if (val.m_value.boolean)
15771 {
15772 o->write_characters("true", 4);
15773 }
15774 else
15775 {
15776 o->write_characters("false", 5);
15777 }
15778 return;
15779 }
15780
15781 case value_t::number_integer:
15782 {
15783 dump_integer(val.m_value.number_integer);
15784 return;
15785 }
15786
15787 case value_t::number_unsigned:
15788 {
15789 dump_integer(val.m_value.number_unsigned);
15790 return;
15791 }
15792
15793 case value_t::number_float:
15794 {
15795 dump_float(val.m_value.number_float);
15796 return;
15797 }
15798
15799 case value_t::discarded:
15800 {
15801 o->write_characters("<discarded>", 11);
15802 return;
15803 }
15804
15805 case value_t::null:
15806 {
15807 o->write_characters("null", 4);
15808 return;
15809 }
15810
15811 default: // LCOV_EXCL_LINE
15812 JSON_ASSERT(false); // LCOV_EXCL_LINE
15813 }
15814 }
15815
15816 JSON_PRIVATE_UNLESS_TESTED:
15831 void dump_escaped(const string_t& s, const bool ensure_ascii)
15832 {
15833 std::uint32_t codepoint;
15834 std::uint8_t state = UTF8_ACCEPT;
15835 std::size_t bytes = 0; // number of bytes written to string_buffer
15836
15837 // number of bytes written at the point of the last valid byte
15838 std::size_t bytes_after_last_accept = 0;
15839 std::size_t undumped_chars = 0;
15840
15841 for (std::size_t i = 0; i < s.size(); ++i)
15842 {
15843 const auto byte = static_cast<uint8_t>(s[i]);
15844
15845 switch (decode(state, codepoint, byte))
15846 {
15847 case UTF8_ACCEPT: // decode found a new code point
15848 {
15849 switch (codepoint)
15850 {
15851 case 0x08: // backspace
15852 {
15853 string_buffer[bytes++] = '\\';
15854 string_buffer[bytes++] = 'b';
15855 break;
15856 }
15857
15858 case 0x09: // horizontal tab
15859 {
15860 string_buffer[bytes++] = '\\';
15861 string_buffer[bytes++] = 't';
15862 break;
15863 }
15864
15865 case 0x0A: // newline
15866 {
15867 string_buffer[bytes++] = '\\';
15868 string_buffer[bytes++] = 'n';
15869 break;
15870 }
15871
15872 case 0x0C: // formfeed
15873 {
15874 string_buffer[bytes++] = '\\';
15875 string_buffer[bytes++] = 'f';
15876 break;
15877 }
15878
15879 case 0x0D: // carriage return
15880 {
15881 string_buffer[bytes++] = '\\';
15882 string_buffer[bytes++] = 'r';
15883 break;
15884 }
15885
15886 case 0x22: // quotation mark
15887 {
15888 string_buffer[bytes++] = '\\';
15889 string_buffer[bytes++] = '\"';
15890 break;
15891 }
15892
15893 case 0x5C: // reverse solidus
15894 {
15895 string_buffer[bytes++] = '\\';
15896 string_buffer[bytes++] = '\\';
15897 break;
15898 }
15899
15900 default:
15901 {
15902 // escape control characters (0x00..0x1F) or, if
15903 // ensure_ascii parameter is used, non-ASCII characters
15904 if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
15905 {
15906 if (codepoint <= 0xFFFF)
15907 {
15908 (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
15909 static_cast<std::uint16_t>(codepoint));
15910 bytes += 6;
15911 }
15912 else
15913 {
15914 (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
15915 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
15916 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
15917 bytes += 12;
15918 }
15919 }
15920 else
15921 {
15922 // copy byte to buffer (all previous bytes
15923 // been copied have in default case above)
15924 string_buffer[bytes++] = s[i];
15925 }
15926 break;
15927 }
15928 }
15929
15930 // write buffer and reset index; there must be 13 bytes
15931 // left, as this is the maximal number of bytes to be
15932 // written ("\uxxxx\uxxxx\0") for one code point
15933 if (string_buffer.size() - bytes < 13)
15934 {
15935 o->write_characters(string_buffer.data(), bytes);
15936 bytes = 0;
15937 }
15938
15939 // remember the byte position of this accept
15940 bytes_after_last_accept = bytes;
15941 undumped_chars = 0;
15942 break;
15943 }
15944
15945 case UTF8_REJECT: // decode found invalid UTF-8 byte
15946 {
15947 switch (error_handler)
15948 {
15949 case error_handler_t::strict:
15950 {
15951 std::string sn(3, '\0');
15952 (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
15953 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
15954 }
15955
15956 case error_handler_t::ignore:
15957 case error_handler_t::replace:
15958 {
15959 // in case we saw this character the first time, we
15960 // would like to read it again, because the byte
15961 // may be OK for itself, but just not OK for the
15962 // previous sequence
15963 if (undumped_chars > 0)
15964 {
15965 --i;
15966 }
15967
15968 // reset length buffer to the last accepted index;
15969 // thus removing/ignoring the invalid characters
15970 bytes = bytes_after_last_accept;
15971
15972 if (error_handler == error_handler_t::replace)
15973 {
15974 // add a replacement character
15975 if (ensure_ascii)
15976 {
15977 string_buffer[bytes++] = '\\';
15978 string_buffer[bytes++] = 'u';
15979 string_buffer[bytes++] = 'f';
15980 string_buffer[bytes++] = 'f';
15981 string_buffer[bytes++] = 'f';
15982 string_buffer[bytes++] = 'd';
15983 }
15984 else
15985 {
15986 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
15987 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
15988 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
15989 }
15990
15991 // write buffer and reset index; there must be 13 bytes
15992 // left, as this is the maximal number of bytes to be
15993 // written ("\uxxxx\uxxxx\0") for one code point
15994 if (string_buffer.size() - bytes < 13)
15995 {
15996 o->write_characters(string_buffer.data(), bytes);
15997 bytes = 0;
15998 }
15999
16000 bytes_after_last_accept = bytes;
16001 }
16002
16003 undumped_chars = 0;
16004
16005 // continue processing the string
16006 state = UTF8_ACCEPT;
16007 break;
16008 }
16009
16010 default: // LCOV_EXCL_LINE
16011 JSON_ASSERT(false); // LCOV_EXCL_LINE
16012 }
16013 break;
16014 }
16015
16016 default: // decode found yet incomplete multi-byte code point
16017 {
16018 if (!ensure_ascii)
16019 {
16020 // code point will not be escaped - copy byte to buffer
16021 string_buffer[bytes++] = s[i];
16022 }
16023 ++undumped_chars;
16024 break;
16025 }
16026 }
16027 }
16028
16029 // we finished processing the string
16030 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
16031 {
16032 // write buffer
16033 if (bytes > 0)
16034 {
16035 o->write_characters(string_buffer.data(), bytes);
16036 }
16037 }
16038 else
16039 {
16040 // we finish reading, but do not accept: string was incomplete
16041 switch (error_handler)
16042 {
16043 case error_handler_t::strict:
16044 {
16045 std::string sn(3, '\0');
16046 (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
16047 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
16048 }
16049
16050 case error_handler_t::ignore:
16051 {
16052 // write all accepted bytes
16053 o->write_characters(string_buffer.data(), bytes_after_last_accept);
16054 break;
16055 }
16056
16057 case error_handler_t::replace:
16058 {
16059 // write all accepted bytes
16060 o->write_characters(string_buffer.data(), bytes_after_last_accept);
16061 // add a replacement character
16062 if (ensure_ascii)
16063 {
16064 o->write_characters("\\ufffd", 6);
16065 }
16066 else
16067 {
16068 o->write_characters("\xEF\xBF\xBD", 3);
16069 }
16070 break;
16071 }
16072
16073 default: // LCOV_EXCL_LINE
16074 JSON_ASSERT(false); // LCOV_EXCL_LINE
16075 }
16076 }
16077 }
16078
16079 private:
16088 inline unsigned int count_digits(number_unsigned_t x) noexcept
16089 {
16090 unsigned int n_digits = 1;
16091 for (;;)
16092 {
16093 if (x < 10)
16094 {
16095 return n_digits;
16096 }
16097 if (x < 100)
16098 {
16099 return n_digits + 1;
16100 }
16101 if (x < 1000)
16102 {
16103 return n_digits + 2;
16104 }
16105 if (x < 10000)
16106 {
16107 return n_digits + 3;
16108 }
16109 x = x / 10000u;
16110 n_digits += 4;
16111 }
16112 }
16113
16123 template < typename NumberType, detail::enable_if_t <
16124 std::is_same<NumberType, number_unsigned_t>::value ||
16125 std::is_same<NumberType, number_integer_t>::value ||
16126 std::is_same<NumberType, binary_char_t>::value,
16127 int > = 0 >
16128 void dump_integer(NumberType x)
16129 {
16130 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
16131 {
16132 {
16133 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
16134 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
16135 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
16136 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
16137 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
16138 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
16139 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
16140 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
16141 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
16142 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
16143 }
16144 };
16145
16146 // special case for "0"
16147 if (x == 0)
16148 {
16149 o->write_character('0');
16150 return;
16151 }
16152
16153 // use a pointer to fill the buffer
16154 auto buffer_ptr = number_buffer.begin();
16155
16156 const bool is_negative = std::is_same<NumberType, number_integer_t>::value && !(x >= 0); // see issue #755
16157 number_unsigned_t abs_value;
16158
16159 unsigned int n_chars;
16160
16161 if (is_negative)
16162 {
16163 *buffer_ptr = '-';
16164 abs_value = remove_sign(static_cast<number_integer_t>(x));
16165
16166 // account one more byte for the minus sign
16167 n_chars = 1 + count_digits(abs_value);
16168 }
16169 else
16170 {
16171 abs_value = static_cast<number_unsigned_t>(x);
16172 n_chars = count_digits(abs_value);
16173 }
16174
16175 // spare 1 byte for '\0'
16176 JSON_ASSERT(n_chars < number_buffer.size() - 1);
16177
16178 // jump to the end to generate the string from backward
16179 // so we later avoid reversing the result
16180 buffer_ptr += n_chars;
16181
16182 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
16183 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
16184 while (abs_value >= 100)
16185 {
16186 const auto digits_index = static_cast<unsigned>((abs_value % 100));
16187 abs_value /= 100;
16188 *(--buffer_ptr) = digits_to_99[digits_index][1];
16189 *(--buffer_ptr) = digits_to_99[digits_index][0];
16190 }
16191
16192 if (abs_value >= 10)
16193 {
16194 const auto digits_index = static_cast<unsigned>(abs_value);
16195 *(--buffer_ptr) = digits_to_99[digits_index][1];
16196 *(--buffer_ptr) = digits_to_99[digits_index][0];
16197 }
16198 else
16199 {
16200 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
16201 }
16202
16203 o->write_characters(number_buffer.data(), n_chars);
16204 }
16205
16214 void dump_float(number_float_t x)
16215 {
16216 // NaN / inf
16217 if (!std::isfinite(x))
16218 {
16219 o->write_characters("null", 4);
16220 return;
16221 }
16222
16223 // If number_float_t is an IEEE-754 single or double precision number,
16224 // use the Grisu2 algorithm to produce short numbers which are
16225 // guaranteed to round-trip, using strtof and strtod, resp.
16226 //
16227 // NB: The test below works if <long double> == <double>.
16228 static constexpr bool is_ieee_single_or_double
16229 = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
16230 (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
16231
16232 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
16233 }
16234
16235 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
16236 {
16237 char* begin = number_buffer.data();
16238 char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
16239
16240 o->write_characters(begin, static_cast<size_t>(end - begin));
16241 }
16242
16243 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
16244 {
16245 // get number of digits for a float -> text -> float round-trip
16246 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
16247
16248 // the actual conversion
16249 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
16250
16251 // negative value indicates an error
16252 JSON_ASSERT(len > 0);
16253 // check if buffer was large enough
16254 JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
16255
16256 // erase thousands separator
16257 if (thousands_sep != '\0')
16258 {
16259 const auto end = std::remove(number_buffer.begin(),
16260 number_buffer.begin() + len, thousands_sep);
16261 std::fill(end, number_buffer.end(), '\0');
16262 JSON_ASSERT((end - number_buffer.begin()) <= len);
16263 len = (end - number_buffer.begin());
16264 }
16265
16266 // convert decimal point to '.'
16267 if (decimal_point != '\0' && decimal_point != '.')
16268 {
16269 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
16270 if (dec_pos != number_buffer.end())
16271 {
16272 *dec_pos = '.';
16273 }
16274 }
16275
16276 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
16277
16278 // determine if need to append ".0"
16279 const bool value_is_int_like =
16280 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
16281 [](char c)
16282 {
16283 return c == '.' || c == 'e';
16284 });
16285
16286 if (value_is_int_like)
16287 {
16288 o->write_characters(".0", 2);
16289 }
16290 }
16291
16313 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
16314 {
16315 static const std::array<std::uint8_t, 400> utf8d =
16316 {
16317 {
16318 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
16319 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
16320 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
16321 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
16322 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
16323 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
16324 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
16325 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
16326 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
16327 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
16328 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
16329 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
16330 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
16331 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
16332 }
16333 };
16334
16335 const std::uint8_t type = utf8d[byte];
16336
16337 codep = (state != UTF8_ACCEPT)
16338 ? (byte & 0x3fu) | (codep << 6u)
16339 : (0xFFu >> type) & (byte);
16340
16341 std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
16342 JSON_ASSERT(index < 400);
16343 state = utf8d[index];
16344 return state;
16345 }
16346
16347 /*
16348 * Overload to make the compiler happy while it is instantiating
16349 * dump_integer for number_unsigned_t.
16350 * Must never be called.
16351 */
16352 number_unsigned_t remove_sign(number_unsigned_t x)
16353 {
16354 JSON_ASSERT(false); // LCOV_EXCL_LINE
16355 return x; // LCOV_EXCL_LINE
16356 }
16357
16358 /*
16359 * Helper function for dump_integer
16360 *
16361 * This function takes a negative signed integer and returns its absolute
16362 * value as unsigned integer. The plus/minus shuffling is necessary as we can
16363 * not directly remove the sign of an arbitrary signed integer as the
16364 * absolute values of INT_MIN and INT_MAX are usually not the same. See
16365 * #1708 for details.
16366 */
16367 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
16368 {
16369 JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)());
16370 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
16371 }
16372
16373 private:
16375 output_adapter_t<char> o = nullptr;
16376
16378 std::array<char, 64> number_buffer{{}};
16379
16381 const std::lconv* loc = nullptr;
16383 const char thousands_sep = '\0';
16385 const char decimal_point = '\0';
16386
16388 std::array<char, 512> string_buffer{{}};
16389
16391 const char indent_char;
16393 string_t indent_string;
16394
16396 const error_handler_t error_handler;
16397 };
16398 } // namespace detail
16399 } // namespace nlohmann
16400
16401 // #include <nlohmann/detail/value_t.hpp>
16402
16403 // #include <nlohmann/json_fwd.hpp>
16404
16405 // #include <nlohmann/ordered_map.hpp>
16406
16407
16408 #include <functional> // less
16409 #include <memory> // allocator
16410 #include <utility> // pair
16411 #include <vector> // vector
16412
16413 // #include <nlohmann/detail/macro_scope.hpp>
16414
16415
16416 namespace nlohmann
16417 {
16418
16421 template <class Key, class T, class IgnoredLess = std::less<Key>,
16422 class Allocator = std::allocator<std::pair<const Key, T>>>
16423 struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
16424 {
16425 using key_type = Key;
16426 using mapped_type = T;
16427 using Container = std::vector<std::pair<const Key, T>, Allocator>;
16428 using typename Container::iterator;
16429 using typename Container::const_iterator;
16430 using typename Container::size_type;
16431 using typename Container::value_type;
16432
16433 // Explicit constructors instead of `using Container::Container`
16434 // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
16435 ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
16436 template <class It>
16437 ordered_map(It first, It last, const Allocator& alloc = Allocator())
16438 : Container{first, last, alloc} {}
16439 ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
16440 : Container{init, alloc} {}
16441
16442 std::pair<iterator, bool> emplace(const key_type& key, T&& t)
16443 {
16444 for (auto it = this->begin(); it != this->end(); ++it)
16445 {
16446 if (it->first == key)
16447 {
16448 return {it, false};
16449 }
16450 }
16451 Container::emplace_back(key, t);
16452 return {--this->end(), true};
16453 }
16454
16455 T& operator[](const Key& key)
16456 {
16457 return emplace(key, T{}).first->second;
16458 }
16459
16460 const T& operator[](const Key& key) const
16461 {
16462 return at(key);
16463 }
16464
16465 T& at(const Key& key)
16466 {
16467 for (auto it = this->begin(); it != this->end(); ++it)
16468 {
16469 if (it->first == key)
16470 {
16471 return it->second;
16472 }
16473 }
16474
16475 JSON_THROW(std::out_of_range("key not found"));
16476 }
16477
16478 const T& at(const Key& key) const
16479 {
16480 for (auto it = this->begin(); it != this->end(); ++it)
16481 {
16482 if (it->first == key)
16483 {
16484 return it->second;
16485 }
16486 }
16487
16488 JSON_THROW(std::out_of_range("key not found"));
16489 }
16490
16491 size_type erase(const Key& key)
16492 {
16493 for (auto it = this->begin(); it != this->end(); ++it)
16494 {
16495 if (it->first == key)
16496 {
16497 // Since we cannot move const Keys, re-construct them in place
16498 for (auto next = it; ++next != this->end(); ++it)
16499 {
16500 it->~value_type(); // Destroy but keep allocation
16501 new (&*it) value_type{std::move(*next)};
16502 }
16503 Container::pop_back();
16504 return 1;
16505 }
16506 }
16507 return 0;
16508 }
16509
16510 iterator erase(iterator pos)
16511 {
16512 auto it = pos;
16513
16514 // Since we cannot move const Keys, re-construct them in place
16515 for (auto next = it; ++next != this->end(); ++it)
16516 {
16517 it->~value_type(); // Destroy but keep allocation
16518 new (&*it) value_type{std::move(*next)};
16519 }
16520 Container::pop_back();
16521 return pos;
16522 }
16523
16524 size_type count(const Key& key) const
16525 {
16526 for (auto it = this->begin(); it != this->end(); ++it)
16527 {
16528 if (it->first == key)
16529 {
16530 return 1;
16531 }
16532 }
16533 return 0;
16534 }
16535
16536 iterator find(const Key& key)
16537 {
16538 for (auto it = this->begin(); it != this->end(); ++it)
16539 {
16540 if (it->first == key)
16541 {
16542 return it;
16543 }
16544 }
16545 return Container::end();
16546 }
16547
16548 const_iterator find(const Key& key) const
16549 {
16550 for (auto it = this->begin(); it != this->end(); ++it)
16551 {
16552 if (it->first == key)
16553 {
16554 return it;
16555 }
16556 }
16557 return Container::end();
16558 }
16559
16560 std::pair<iterator, bool> insert( value_type&& value )
16561 {
16562 return emplace(value.first, std::move(value.second));
16563 }
16564
16565 std::pair<iterator, bool> insert( const value_type& value )
16566 {
16567 for (auto it = this->begin(); it != this->end(); ++it)
16568 {
16569 if (it->first == value.first)
16570 {
16571 return {it, false};
16572 }
16573 }
16574 Container::push_back(value);
16575 return {--this->end(), true};
16576 }
16577 };
16578
16579 } // namespace nlohmann
16580
16581
16587 namespace nlohmann
16588 {
16589
16674 NLOHMANN_BASIC_JSON_TPL_DECLARATION
16675 class basic_json
16676 {
16677 private:
16678 template<detail::value_t> friend struct detail::external_constructor;
16679 friend ::nlohmann::json_pointer<basic_json>;
16680
16681 template<typename BasicJsonType, typename InputType>
16682 friend class ::nlohmann::detail::parser;
16683 friend ::nlohmann::detail::serializer<basic_json>;
16684 template<typename BasicJsonType>
16685 friend class ::nlohmann::detail::iter_impl;
16686 template<typename BasicJsonType, typename CharType>
16687 friend class ::nlohmann::detail::binary_writer;
16688 template<typename BasicJsonType, typename InputType, typename SAX>
16689 friend class ::nlohmann::detail::binary_reader;
16690 template<typename BasicJsonType>
16691 friend class ::nlohmann::detail::json_sax_dom_parser;
16692 template<typename BasicJsonType>
16693 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
16694
16696 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
16697
16698 JSON_PRIVATE_UNLESS_TESTED:
16699 // convenience aliases for types residing in namespace detail;
16700 using lexer = ::nlohmann::detail::lexer_base<basic_json>;
16701
16702 template<typename InputAdapterType>
16703 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
16704 InputAdapterType adapter,
16705 detail::parser_callback_t<basic_json>cb = nullptr,
16706 const bool allow_exceptions = true,
16707 const bool ignore_comments = false
16708 )
16709 {
16710 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
16711 std::move(cb), allow_exceptions, ignore_comments);
16712 }
16713
16714 private:
16715 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
16716 template<typename BasicJsonType>
16717 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
16718 template<typename BasicJsonType>
16719 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
16720 template<typename Iterator>
16721 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
16722 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
16723
16724 template<typename CharType>
16725 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
16726
16727 template<typename InputType>
16728 using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
16729 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
16730
16731 JSON_PRIVATE_UNLESS_TESTED:
16732 using serializer = ::nlohmann::detail::serializer<basic_json>;
16733
16734 public:
16735 using value_t = detail::value_t;
16737 using json_pointer = ::nlohmann::json_pointer<basic_json>;
16738 template<typename T, typename SFINAE>
16739 using json_serializer = JSONSerializer<T, SFINAE>;
16741 using error_handler_t = detail::error_handler_t;
16743 using cbor_tag_handler_t = detail::cbor_tag_handler_t;
16745 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
16746
16747 using input_format_t = detail::input_format_t;
16749 using json_sax_t = json_sax<basic_json>;
16750
16752 // exceptions //
16754
16758
16760 using exception = detail::exception;
16762 using parse_error = detail::parse_error;
16764 using invalid_iterator = detail::invalid_iterator;
16766 using type_error = detail::type_error;
16768 using out_of_range = detail::out_of_range;
16770 using other_error = detail::other_error;
16771
16773
16774
16776 // container types //
16778
16783
16785 using value_type = basic_json;
16786
16788 using reference = value_type&;
16790 using const_reference = const value_type&;
16791
16793 using difference_type = std::ptrdiff_t;
16795 using size_type = std::size_t;
16796
16798 using allocator_type = AllocatorType<basic_json>;
16799
16801 using pointer = typename std::allocator_traits<allocator_type>::pointer;
16803 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
16804
16806 using iterator = iter_impl<basic_json>;
16808 using const_iterator = iter_impl<const basic_json>;
16810 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
16812 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
16813
16815
16816
16820 static allocator_type get_allocator()
16821 {
16822 return allocator_type();
16823 }
16824
16851
16852 static basic_json meta()
16853 {
16854 basic_json result;
16855
16856 result["copyright"] = "(C) 2013-2020 Niels Lohmann";
16857 result["name"] = "JSON for Modern C++";
16858 result["url"] = "https://github.com/nlohmann/json";
16859 result["version"]["string"] =
16860 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
16861 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
16862 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
16863 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
16864 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
16865 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
16866
16867 #ifdef _WIN32
16868 result["platform"] = "win32";
16869 #elif defined __linux__
16870 result["platform"] = "linux";
16871 #elif defined __APPLE__
16872 result["platform"] = "apple";
16873 #elif defined __unix__
16874 result["platform"] = "unix";
16875 #else
16876 result["platform"] = "unknown";
16877 #endif
16878
16879 #if defined(__ICC) || defined(__INTEL_COMPILER)
16880 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
16881 #elif defined(__clang__)
16882 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
16883 #elif defined(__GNUC__) || defined(__GNUG__)
16884 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
16885 #elif defined(__HP_cc) || defined(__HP_aCC)
16886 result["compiler"] = "hp"
16887 #elif defined(__IBMCPP__)
16888 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
16889 #elif defined(_MSC_VER)
16890 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
16891 #elif defined(__PGI)
16892 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
16893 #elif defined(__SUNPRO_CC)
16894 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
16895 #else
16896 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
16897 #endif
16898
16899 #ifdef __cplusplus
16900 result["compiler"]["c++"] = std::to_string(__cplusplus);
16901 #else
16902 result["compiler"]["c++"] = "unknown";
16903 #endif
16904 return result;
16905 }
16906
16907
16909 // JSON value data types //
16911
16916
16917 #if defined(JSON_HAS_CPP_14)
16918 // Use transparent comparator if possible, combined with perfect forwarding
16919 // on find() and count() calls prevents unnecessary string construction.
16920 using object_comparator_t = std::less<>;
16921 #else
16922 using object_comparator_t = std::less<StringType>;
16923 #endif
16924
17008 using object_t = ObjectType<StringType,
17009 basic_json,
17010 object_comparator_t,
17011 AllocatorType<std::pair<const StringType,
17012 basic_json>>>;
17013
17058 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
17059
17111 using string_t = StringType;
17112
17137 using boolean_t = BooleanType;
17138
17209 using number_integer_t = NumberIntegerType;
17210
17280 using number_unsigned_t = NumberUnsignedType;
17281
17348 using number_float_t = NumberFloatType;
17349
17419 using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
17421
17422 private:
17423
17425 template<typename T, typename... Args>
17426
17427 static T* create(Args&& ... args)
17428 {
17429 AllocatorType<T> alloc;
17430 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
17431
17432 auto deleter = [&](T * object)
17433 {
17434 AllocatorTraits::deallocate(alloc, object, 1);
17435 };
17436 std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
17437 AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
17438 JSON_ASSERT(object != nullptr);
17439 return object.release();
17440 }
17441
17443 // JSON value storage //
17445
17446 JSON_PRIVATE_UNLESS_TESTED:
17472 union json_value
17473 {
17475 object_t* object;
17477 array_t* array;
17479 string_t* string;
17481 binary_t* binary;
17483 boolean_t boolean;
17485 number_integer_t number_integer;
17487 number_unsigned_t number_unsigned;
17489 number_float_t number_float;
17490
17492 json_value() = default;
17494 json_value(boolean_t v) noexcept : boolean(v) {}
17496 json_value(number_integer_t v) noexcept : number_integer(v) {}
17498 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
17500 json_value(number_float_t v) noexcept : number_float(v) {}
17502 json_value(value_t t)
17503 {
17504 switch (t)
17505 {
17506 case value_t::object:
17507 {
17508 object = create<object_t>();
17509 break;
17510 }
17511
17512 case value_t::array:
17513 {
17514 array = create<array_t>();
17515 break;
17516 }
17517
17518 case value_t::string:
17519 {
17520 string = create<string_t>("");
17521 break;
17522 }
17523
17524 case value_t::binary:
17525 {
17526 binary = create<binary_t>();
17527 break;
17528 }
17529
17530 case value_t::boolean:
17531 {
17532 boolean = boolean_t(false);
17533 break;
17534 }
17535
17536 case value_t::number_integer:
17537 {
17538 number_integer = number_integer_t(0);
17539 break;
17540 }
17541
17542 case value_t::number_unsigned:
17543 {
17544 number_unsigned = number_unsigned_t(0);
17545 break;
17546 }
17547
17548 case value_t::number_float:
17549 {
17550 number_float = number_float_t(0.0);
17551 break;
17552 }
17553
17554 case value_t::null:
17555 {
17556 object = nullptr; // silence warning, see #821
17557 break;
17558 }
17559
17560 default:
17561 {
17562 object = nullptr; // silence warning, see #821
17563 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
17564 {
17565 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.9.1")); // LCOV_EXCL_LINE
17566 }
17567 break;
17568 }
17569 }
17570 }
17571
17573 json_value(const string_t& value)
17574 {
17575 string = create<string_t>(value);
17576 }
17577
17579 json_value(string_t&& value)
17580 {
17581 string = create<string_t>(std::move(value));
17582 }
17583
17585 json_value(const object_t& value)
17586 {
17587 object = create<object_t>(value);
17588 }
17589
17591 json_value(object_t&& value)
17592 {
17593 object = create<object_t>(std::move(value));
17594 }
17595
17597 json_value(const array_t& value)
17598 {
17599 array = create<array_t>(value);
17600 }
17601
17603 json_value(array_t&& value)
17604 {
17605 array = create<array_t>(std::move(value));
17606 }
17607
17609 json_value(const typename binary_t::container_type& value)
17610 {
17611 binary = create<binary_t>(value);
17612 }
17613
17615 json_value(typename binary_t::container_type&& value)
17616 {
17617 binary = create<binary_t>(std::move(value));
17618 }
17619
17621 json_value(const binary_t& value)
17622 {
17623 binary = create<binary_t>(value);
17624 }
17625
17627 json_value(binary_t&& value)
17628 {
17629 binary = create<binary_t>(std::move(value));
17630 }
17631
17632 void destroy(value_t t) noexcept
17633 {
17634 // flatten the current json_value to a heap-allocated stack
17635 std::vector<basic_json> stack;
17636
17637 // move the top-level items to stack
17638 if (t == value_t::array)
17639 {
17640 stack.reserve(array->size());
17641 std::move(array->begin(), array->end(), std::back_inserter(stack));
17642 }
17643 else if (t == value_t::object)
17644 {
17645 stack.reserve(object->size());
17646 for (auto&& it : *object)
17647 {
17648 stack.push_back(std::move(it.second));
17649 }
17650 }
17651
17652 while (!stack.empty())
17653 {
17654 // move the last item to local variable to be processed
17655 basic_json current_item(std::move(stack.back()));
17656 stack.pop_back();
17657
17658 // if current_item is array/object, move
17659 // its children to the stack to be processed later
17660 if (current_item.is_array())
17661 {
17662 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
17663 std::back_inserter(stack));
17664
17665 current_item.m_value.array->clear();
17666 }
17667 else if (current_item.is_object())
17668 {
17669 for (auto&& it : *current_item.m_value.object)
17670 {
17671 stack.push_back(std::move(it.second));
17672 }
17673
17674 current_item.m_value.object->clear();
17675 }
17676
17677 // it's now safe that current_item get destructed
17678 // since it doesn't have any children
17679 }
17680
17681 switch (t)
17682 {
17683 case value_t::object:
17684 {
17685 AllocatorType<object_t> alloc;
17686 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
17687 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
17688 break;
17689 }
17690
17691 case value_t::array:
17692 {
17693 AllocatorType<array_t> alloc;
17694 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
17695 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
17696 break;
17697 }
17698
17699 case value_t::string:
17700 {
17701 AllocatorType<string_t> alloc;
17702 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
17703 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
17704 break;
17705 }
17706
17707 case value_t::binary:
17708 {
17709 AllocatorType<binary_t> alloc;
17710 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
17711 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
17712 break;
17713 }
17714
17715 default:
17716 {
17717 break;
17718 }
17719 }
17720 }
17721 };
17722
17723 private:
17733 void assert_invariant() const noexcept
17734 {
17735 JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
17736 JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
17737 JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
17738 JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
17739 }
17740
17741 public:
17743 // JSON parser callback //
17745
17761 using parse_event_t = detail::parse_event_t;
17762
17812 using parser_callback_t = detail::parser_callback_t<basic_json>;
17813
17815 // constructors //
17817
17822
17853 basic_json(const value_t v)
17854 : m_type(v), m_value(v)
17855 {
17856 assert_invariant();
17857 }
17858
17877 basic_json(std::nullptr_t = nullptr) noexcept
17878 : basic_json(value_t::null)
17879 {
17880 assert_invariant();
17881 }
17882
17946 template < typename CompatibleType,
17947 typename U = detail::uncvref_t<CompatibleType>,
17948 detail::enable_if_t <
17949 !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
17950 basic_json(CompatibleType && val) noexcept(noexcept(
17951 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
17952 std::forward<CompatibleType>(val))))
17953 {
17954 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
17955 assert_invariant();
17956 }
17957
17984 template < typename BasicJsonType,
17985 detail::enable_if_t <
17986 detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
17987 basic_json(const BasicJsonType& val)
17988 {
17989 using other_boolean_t = typename BasicJsonType::boolean_t;
17990 using other_number_float_t = typename BasicJsonType::number_float_t;
17991 using other_number_integer_t = typename BasicJsonType::number_integer_t;
17992 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
17993 using other_string_t = typename BasicJsonType::string_t;
17994 using other_object_t = typename BasicJsonType::object_t;
17995 using other_array_t = typename BasicJsonType::array_t;
17996 using other_binary_t = typename BasicJsonType::binary_t;
17997
17998 switch (val.type())
17999 {
18000 case value_t::boolean:
18001 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
18002 break;
18003 case value_t::number_float:
18004 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
18005 break;
18006 case value_t::number_integer:
18007 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
18008 break;
18009 case value_t::number_unsigned:
18010 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
18011 break;
18012 case value_t::string:
18013 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
18014 break;
18015 case value_t::object:
18016 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
18017 break;
18018 case value_t::array:
18019 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
18020 break;
18021 case value_t::binary:
18022 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
18023 break;
18024 case value_t::null:
18025 *this = nullptr;
18026 break;
18027 case value_t::discarded:
18028 m_type = value_t::discarded;
18029 break;
18030 default: // LCOV_EXCL_LINE
18031 JSON_ASSERT(false); // LCOV_EXCL_LINE
18032 }
18033 assert_invariant();
18034 }
18035
18110 basic_json(initializer_list_t init,
18111 bool type_deduction = true,
18112 value_t manual_type = value_t::array)
18113 {
18114 // check if each element is an array with two elements whose first
18115 // element is a string
18116 bool is_an_object = std::all_of(init.begin(), init.end(),
18117 [](const detail::json_ref<basic_json>& element_ref)
18118 {
18119 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
18120 });
18121
18122 // adjust type if type deduction is not wanted
18123 if (!type_deduction)
18124 {
18125 // if array is wanted, do not create an object though possible
18126 if (manual_type == value_t::array)
18127 {
18128 is_an_object = false;
18129 }
18130
18131 // if object is wanted but impossible, throw an exception
18132 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
18133 {
18134 JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
18135 }
18136 }
18137
18138 if (is_an_object)
18139 {
18140 // the initializer list is a list of pairs -> create object
18141 m_type = value_t::object;
18142 m_value = value_t::object;
18143
18144 std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
18145 {
18146 auto element = element_ref.moved_or_copied();
18147 m_value.object->emplace(
18148 std::move(*((*element.m_value.array)[0].m_value.string)),
18149 std::move((*element.m_value.array)[1]));
18150 });
18151 }
18152 else
18153 {
18154 // the initializer list describes an array -> create array
18155 m_type = value_t::array;
18156 m_value.array = create<array_t>(init.begin(), init.end());
18157 }
18158
18159 assert_invariant();
18160 }
18161
18189
18190 static basic_json binary(const typename binary_t::container_type& init)
18191 {
18192 auto res = basic_json();
18193 res.m_type = value_t::binary;
18194 res.m_value = init;
18195 return res;
18196 }
18197
18226
18227 static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype)
18228 {
18229 auto res = basic_json();
18230 res.m_type = value_t::binary;
18231 res.m_value = binary_t(init, subtype);
18232 return res;
18233 }
18234
18236
18237 static basic_json binary(typename binary_t::container_type&& init)
18238 {
18239 auto res = basic_json();
18240 res.m_type = value_t::binary;
18241 res.m_value = std::move(init);
18242 return res;
18243 }
18244
18246
18247 static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype)
18248 {
18249 auto res = basic_json();
18250 res.m_type = value_t::binary;
18251 res.m_value = binary_t(std::move(init), subtype);
18252 return res;
18253 }
18254
18292
18293 static basic_json array(initializer_list_t init = {})
18294 {
18295 return basic_json(init, false, value_t::array);
18296 }
18297
18336
18337 static basic_json object(initializer_list_t init = {})
18338 {
18339 return basic_json(init, false, value_t::object);
18340 }
18341
18364 basic_json(size_type cnt, const basic_json& val)
18365 : m_type(value_t::array)
18366 {
18367 m_value.array = create<array_t>(cnt, val);
18368 assert_invariant();
18369 }
18370
18426 template < class InputIT, typename std::enable_if <
18427 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
18428 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
18429 basic_json(InputIT first, InputIT last)
18430 {
18431 JSON_ASSERT(first.m_object != nullptr);
18432 JSON_ASSERT(last.m_object != nullptr);
18433
18434 // make sure iterator fits the current value
18435 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
18436 {
18437 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
18438 }
18439
18440 // copy type from first iterator
18441 m_type = first.m_object->m_type;
18442
18443 // check if iterator range is complete for primitive values
18444 switch (m_type)
18445 {
18446 case value_t::boolean:
18447 case value_t::number_float:
18448 case value_t::number_integer:
18449 case value_t::number_unsigned:
18450 case value_t::string:
18451 {
18452 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
18453 || !last.m_it.primitive_iterator.is_end()))
18454 {
18455 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
18456 }
18457 break;
18458 }
18459
18460 default:
18461 break;
18462 }
18463
18464 switch (m_type)
18465 {
18466 case value_t::number_integer:
18467 {
18468 m_value.number_integer = first.m_object->m_value.number_integer;
18469 break;
18470 }
18471
18472 case value_t::number_unsigned:
18473 {
18474 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
18475 break;
18476 }
18477
18478 case value_t::number_float:
18479 {
18480 m_value.number_float = first.m_object->m_value.number_float;
18481 break;
18482 }
18483
18484 case value_t::boolean:
18485 {
18486 m_value.boolean = first.m_object->m_value.boolean;
18487 break;
18488 }
18489
18490 case value_t::string:
18491 {
18492 m_value = *first.m_object->m_value.string;
18493 break;
18494 }
18495
18496 case value_t::object:
18497 {
18498 m_value.object = create<object_t>(first.m_it.object_iterator,
18499 last.m_it.object_iterator);
18500 break;
18501 }
18502
18503 case value_t::array:
18504 {
18505 m_value.array = create<array_t>(first.m_it.array_iterator,
18506 last.m_it.array_iterator);
18507 break;
18508 }
18509
18510 case value_t::binary:
18511 {
18512 m_value = *first.m_object->m_value.binary;
18513 break;
18514 }
18515
18516 default:
18517 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
18518 std::string(first.m_object->type_name())));
18519 }
18520
18521 assert_invariant();
18522 }
18523
18524
18526 // other constructors and destructor //
18528
18529 template<typename JsonRef,
18530 detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
18531 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
18532 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
18533
18559 basic_json(const basic_json& other)
18560 : m_type(other.m_type)
18561 {
18562 // check of passed value is valid
18563 other.assert_invariant();
18564
18565 switch (m_type)
18566 {
18567 case value_t::object:
18568 {
18569 m_value = *other.m_value.object;
18570 break;
18571 }
18572
18573 case value_t::array:
18574 {
18575 m_value = *other.m_value.array;
18576 break;
18577 }
18578
18579 case value_t::string:
18580 {
18581 m_value = *other.m_value.string;
18582 break;
18583 }
18584
18585 case value_t::boolean:
18586 {
18587 m_value = other.m_value.boolean;
18588 break;
18589 }
18590
18591 case value_t::number_integer:
18592 {
18593 m_value = other.m_value.number_integer;
18594 break;
18595 }
18596
18597 case value_t::number_unsigned:
18598 {
18599 m_value = other.m_value.number_unsigned;
18600 break;
18601 }
18602
18603 case value_t::number_float:
18604 {
18605 m_value = other.m_value.number_float;
18606 break;
18607 }
18608
18609 case value_t::binary:
18610 {
18611 m_value = *other.m_value.binary;
18612 break;
18613 }
18614
18615 default:
18616 break;
18617 }
18618
18619 assert_invariant();
18620 }
18621
18648 basic_json(basic_json&& other) noexcept
18649 : m_type(std::move(other.m_type)),
18650 m_value(std::move(other.m_value))
18651 {
18652 // check that passed value is valid
18653 other.assert_invariant();
18654
18655 // invalidate payload
18656 other.m_type = value_t::null;
18657 other.m_value = {};
18658
18659 assert_invariant();
18660 }
18661
18685 basic_json& operator=(basic_json other) noexcept (
18686 std::is_nothrow_move_constructible<value_t>::value&&
18687 std::is_nothrow_move_assignable<value_t>::value&&
18688 std::is_nothrow_move_constructible<json_value>::value&&
18689 std::is_nothrow_move_assignable<json_value>::value
18690 )
18691 {
18692 // check that passed value is valid
18693 other.assert_invariant();
18694
18695 using std::swap;
18696 swap(m_type, other.m_type);
18697 swap(m_value, other.m_value);
18698
18699 assert_invariant();
18700 return *this;
18701 }
18702
18718 ~basic_json() noexcept
18719 {
18720 assert_invariant();
18721 m_value.destroy(m_type);
18722 }
18723
18725
18726 public:
18728 // object inspection //
18730
18734
18782 string_t dump(const int indent = -1,
18783 const char indent_char = ' ',
18784 const bool ensure_ascii = false,
18785 const error_handler_t error_handler = error_handler_t::strict) const
18786 {
18787 string_t result;
18788 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
18789
18790 if (indent >= 0)
18791 {
18792 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
18793 }
18794 else
18795 {
18796 s.dump(*this, false, ensure_ascii, 0);
18797 }
18798
18799 return result;
18800 }
18801
18835 constexpr value_t type() const noexcept
18836 {
18837 return m_type;
18838 }
18839
18866 constexpr bool is_primitive() const noexcept
18867 {
18868 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
18869 }
18870
18893 constexpr bool is_structured() const noexcept
18894 {
18895 return is_array() || is_object();
18896 }
18897
18915 constexpr bool is_null() const noexcept
18916 {
18917 return m_type == value_t::null;
18918 }
18919
18937 constexpr bool is_boolean() const noexcept
18938 {
18939 return m_type == value_t::boolean;
18940 }
18941
18967 constexpr bool is_number() const noexcept
18968 {
18969 return is_number_integer() || is_number_float();
18970 }
18971
18996 constexpr bool is_number_integer() const noexcept
18997 {
18998 return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
18999 }
19000
19024 constexpr bool is_number_unsigned() const noexcept
19025 {
19026 return m_type == value_t::number_unsigned;
19027 }
19028
19052 constexpr bool is_number_float() const noexcept
19053 {
19054 return m_type == value_t::number_float;
19055 }
19056
19074 constexpr bool is_object() const noexcept
19075 {
19076 return m_type == value_t::object;
19077 }
19078
19096 constexpr bool is_array() const noexcept
19097 {
19098 return m_type == value_t::array;
19099 }
19100
19118 constexpr bool is_string() const noexcept
19119 {
19120 return m_type == value_t::string;
19121 }
19122
19140 constexpr bool is_binary() const noexcept
19141 {
19142 return m_type == value_t::binary;
19143 }
19144
19167 constexpr bool is_discarded() const noexcept
19168 {
19169 return m_type == value_t::discarded;
19170 }
19171
19193 constexpr operator value_t() const noexcept
19194 {
19195 return m_type;
19196 }
19197
19199
19200 private:
19202 // value access //
19204
19206 boolean_t get_impl(boolean_t* /*unused*/) const
19207 {
19208 if (JSON_HEDLEY_LIKELY(is_boolean()))
19209 {
19210 return m_value.boolean;
19211 }
19212
19213 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
19214 }
19215
19217 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
19218 {
19219 return is_object() ? m_value.object : nullptr;
19220 }
19221
19223 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
19224 {
19225 return is_object() ? m_value.object : nullptr;
19226 }
19227
19229 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
19230 {
19231 return is_array() ? m_value.array : nullptr;
19232 }
19233
19235 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
19236 {
19237 return is_array() ? m_value.array : nullptr;
19238 }
19239
19241 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
19242 {
19243 return is_string() ? m_value.string : nullptr;
19244 }
19245
19247 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
19248 {
19249 return is_string() ? m_value.string : nullptr;
19250 }
19251
19253 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
19254 {
19255 return is_boolean() ? &m_value.boolean : nullptr;
19256 }
19257
19259 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
19260 {
19261 return is_boolean() ? &m_value.boolean : nullptr;
19262 }
19263
19265 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
19266 {
19267 return is_number_integer() ? &m_value.number_integer : nullptr;
19268 }
19269
19271 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
19272 {
19273 return is_number_integer() ? &m_value.number_integer : nullptr;
19274 }
19275
19277 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
19278 {
19279 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19280 }
19281
19283 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
19284 {
19285 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19286 }
19287
19289 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
19290 {
19291 return is_number_float() ? &m_value.number_float : nullptr;
19292 }
19293
19295 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
19296 {
19297 return is_number_float() ? &m_value.number_float : nullptr;
19298 }
19299
19301 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
19302 {
19303 return is_binary() ? m_value.binary : nullptr;
19304 }
19305
19307 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
19308 {
19309 return is_binary() ? m_value.binary : nullptr;
19310 }
19311
19323 template<typename ReferenceType, typename ThisType>
19324 static ReferenceType get_ref_impl(ThisType& obj)
19325 {
19326 // delegate the call to get_ptr<>()
19327 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
19328
19329 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
19330 {
19331 return *ptr;
19332 }
19333
19334 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
19335 }
19336
19337 public:
19341
19356 template<typename BasicJsonType, detail::enable_if_t<
19357 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
19358 int> = 0>
19359 basic_json get() const
19360 {
19361 return *this;
19362 }
19363
19379 template < typename BasicJsonType, detail::enable_if_t <
19380 !std::is_same<BasicJsonType, basic_json>::value&&
19381 detail::is_basic_json<BasicJsonType>::value, int > = 0 >
19382 BasicJsonType get() const
19383 {
19384 return *this;
19385 }
19386
19426 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
19427 detail::enable_if_t <
19428 !detail::is_basic_json<ValueType>::value &&
19429 detail::has_from_json<basic_json_t, ValueType>::value &&
19430 !detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19431 int > = 0 >
19432 ValueType get() const noexcept(noexcept(
19433 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
19434 {
19435 // we cannot static_assert on ValueTypeCV being non-const, because
19436 // there is support for get<const basic_json_t>(), which is why we
19437 // still need the uncvref
19438 static_assert(!std::is_reference<ValueTypeCV>::value,
19439 "get() cannot be used with reference types, you might want to use get_ref()");
19440 static_assert(std::is_default_constructible<ValueType>::value,
19441 "types must be DefaultConstructible when used with get()");
19442
19443 ValueType ret;
19444 JSONSerializer<ValueType>::from_json(*this, ret);
19445 return ret;
19446 }
19447
19479 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
19480 detail::enable_if_t < !std::is_same<basic_json_t, ValueType>::value &&
19481 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19482 int > = 0 >
19483 ValueType get() const noexcept(noexcept(
19484 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
19485 {
19486 static_assert(!std::is_reference<ValueTypeCV>::value,
19487 "get() cannot be used with reference types, you might want to use get_ref()");
19488 return JSONSerializer<ValueType>::from_json(*this);
19489 }
19490
19524 template < typename ValueType,
19525 detail::enable_if_t <
19526 !detail::is_basic_json<ValueType>::value&&
19527 detail::has_from_json<basic_json_t, ValueType>::value,
19528 int > = 0 >
19529 ValueType & get_to(ValueType& v) const noexcept(noexcept(
19530 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
19531 {
19532 JSONSerializer<ValueType>::from_json(*this, v);
19533 return v;
19534 }
19535
19536 // specialization to allow to call get_to with a basic_json value
19537 // see https://github.com/nlohmann/json/issues/2175
19538 template<typename ValueType,
19539 detail::enable_if_t <
19540 detail::is_basic_json<ValueType>::value,
19541 int> = 0>
19542 ValueType & get_to(ValueType& v) const
19543 {
19544 v = *this;
19545 return v;
19546 }
19547
19548 template <
19549 typename T, std::size_t N,
19550 typename Array = T (&)[N],
19551 detail::enable_if_t <
19552 detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
19553 Array get_to(T (&v)[N]) const
19554 noexcept(noexcept(JSONSerializer<Array>::from_json(
19555 std::declval<const basic_json_t&>(), v)))
19556 {
19557 JSONSerializer<Array>::from_json(*this, v);
19558 return v;
19559 }
19560
19561
19588 template<typename PointerType, typename std::enable_if<
19589 std::is_pointer<PointerType>::value, int>::type = 0>
19590 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19591 {
19592 // delegate the call to get_impl_ptr<>()
19593 return get_impl_ptr(static_cast<PointerType>(nullptr));
19594 }
19595
19600 template < typename PointerType, typename std::enable_if <
19601 std::is_pointer<PointerType>::value&&
19602 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
19603 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19604 {
19605 // delegate the call to get_impl_ptr<>() const
19606 return get_impl_ptr(static_cast<PointerType>(nullptr));
19607 }
19608
19636 template<typename PointerType, typename std::enable_if<
19637 std::is_pointer<PointerType>::value, int>::type = 0>
19638 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
19639 {
19640 // delegate the call to get_ptr
19641 return get_ptr<PointerType>();
19642 }
19643
19648 template<typename PointerType, typename std::enable_if<
19649 std::is_pointer<PointerType>::value, int>::type = 0>
19650 constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
19651 {
19652 // delegate the call to get_ptr
19653 return get_ptr<PointerType>();
19654 }
19655
19682 template<typename ReferenceType, typename std::enable_if<
19683 std::is_reference<ReferenceType>::value, int>::type = 0>
19684 ReferenceType get_ref()
19685 {
19686 // delegate call to get_ref_impl
19687 return get_ref_impl<ReferenceType>(*this);
19688 }
19689
19694 template < typename ReferenceType, typename std::enable_if <
19695 std::is_reference<ReferenceType>::value&&
19696 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
19697 ReferenceType get_ref() const
19698 {
19699 // delegate call to get_ref_impl
19700 return get_ref_impl<ReferenceType>(*this);
19701 }
19702
19732 template < typename ValueType, typename std::enable_if <
19733 !std::is_pointer<ValueType>::value&&
19734 !std::is_same<ValueType, detail::json_ref<basic_json>>::value&&
19735 !std::is_same<ValueType, typename string_t::value_type>::value&&
19736 !detail::is_basic_json<ValueType>::value
19737 && !std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
19738 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
19739 && !std::is_same<ValueType, typename std::string_view>::value
19740 #endif
19741 && detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
19742 , int >::type = 0 >
19743 JSON_EXPLICIT operator ValueType() const
19744 {
19745 // delegate the call to get<>() const
19746 return get<ValueType>();
19747 }
19748
19758 binary_t& get_binary()
19759 {
19760 if (!is_binary())
19761 {
19762 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19763 }
19764
19765 return *get_ptr<binary_t*>();
19766 }
19767
19769 const binary_t& get_binary() const
19770 {
19771 if (!is_binary())
19772 {
19773 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19774 }
19775
19776 return *get_ptr<const binary_t*>();
19777 }
19778
19780
19781
19783 // element access //
19785
19789
19816 reference at(size_type idx)
19817 {
19818 // at only works for arrays
19819 if (JSON_HEDLEY_LIKELY(is_array()))
19820 {
19821 JSON_TRY
19822 {
19823 return m_value.array->at(idx);
19824 }
19825 JSON_CATCH (std::out_of_range&)
19826 {
19827 // create better exception explanation
19828 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19829 }
19830 }
19831 else
19832 {
19833 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19834 }
19835 }
19836
19863 const_reference at(size_type idx) const
19864 {
19865 // at only works for arrays
19866 if (JSON_HEDLEY_LIKELY(is_array()))
19867 {
19868 JSON_TRY
19869 {
19870 return m_value.array->at(idx);
19871 }
19872 JSON_CATCH (std::out_of_range&)
19873 {
19874 // create better exception explanation
19875 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19876 }
19877 }
19878 else
19879 {
19880 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19881 }
19882 }
19883
19914 reference at(const typename object_t::key_type& key)
19915 {
19916 // at only works for objects
19917 if (JSON_HEDLEY_LIKELY(is_object()))
19918 {
19919 JSON_TRY
19920 {
19921 return m_value.object->at(key);
19922 }
19923 JSON_CATCH (std::out_of_range&)
19924 {
19925 // create better exception explanation
19926 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19927 }
19928 }
19929 else
19930 {
19931 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19932 }
19933 }
19934
19965 const_reference at(const typename object_t::key_type& key) const
19966 {
19967 // at only works for objects
19968 if (JSON_HEDLEY_LIKELY(is_object()))
19969 {
19970 JSON_TRY
19971 {
19972 return m_value.object->at(key);
19973 }
19974 JSON_CATCH (std::out_of_range&)
19975 {
19976 // create better exception explanation
19977 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19978 }
19979 }
19980 else
19981 {
19982 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19983 }
19984 }
19985
20011 reference operator[](size_type idx)
20012 {
20013 // implicitly convert null value to an empty array
20014 if (is_null())
20015 {
20016 m_type = value_t::array;
20017 m_value.array = create<array_t>();
20018 assert_invariant();
20019 }
20020
20021 // operator[] only works for arrays
20022 if (JSON_HEDLEY_LIKELY(is_array()))
20023 {
20024 // fill up array with null values if given idx is outside range
20025 if (idx >= m_value.array->size())
20026 {
20027 m_value.array->insert(m_value.array->end(),
20028 idx - m_value.array->size() + 1,
20029 basic_json());
20030 }
20031
20032 return m_value.array->operator[](idx);
20033 }
20034
20035 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
20036 }
20037
20057 const_reference operator[](size_type idx) const
20058 {
20059 // const operator[] only works for arrays
20060 if (JSON_HEDLEY_LIKELY(is_array()))
20061 {
20062 return m_value.array->operator[](idx);
20063 }
20064
20065 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
20066 }
20067
20095 reference operator[](const typename object_t::key_type& key)
20096 {
20097 // implicitly convert null value to an empty object
20098 if (is_null())
20099 {
20100 m_type = value_t::object;
20101 m_value.object = create<object_t>();
20102 assert_invariant();
20103 }
20104
20105 // operator[] only works for objects
20106 if (JSON_HEDLEY_LIKELY(is_object()))
20107 {
20108 return m_value.object->operator[](key);
20109 }
20110
20111 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20112 }
20113
20144 const_reference operator[](const typename object_t::key_type& key) const
20145 {
20146 // const operator[] only works for objects
20147 if (JSON_HEDLEY_LIKELY(is_object()))
20148 {
20149 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20150 return m_value.object->find(key)->second;
20151 }
20152
20153 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20154 }
20155
20183 template<typename T>
20184 JSON_HEDLEY_NON_NULL(2)
20185 reference operator[](T* key)
20186 {
20187 // implicitly convert null to object
20188 if (is_null())
20189 {
20190 m_type = value_t::object;
20191 m_value = value_t::object;
20192 assert_invariant();
20193 }
20194
20195 // at only works for objects
20196 if (JSON_HEDLEY_LIKELY(is_object()))
20197 {
20198 return m_value.object->operator[](key);
20199 }
20200
20201 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20202 }
20203
20234 template<typename T>
20235 JSON_HEDLEY_NON_NULL(2)
20236 const_reference operator[](T* key) const
20237 {
20238 // at only works for objects
20239 if (JSON_HEDLEY_LIKELY(is_object()))
20240 {
20241 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20242 return m_value.object->find(key)->second;
20243 }
20244
20245 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20246 }
20247
20298 // using std::is_convertible in a std::enable_if will fail when using explicit conversions
20299 template < class ValueType, typename std::enable_if <
20300 detail::is_getable<basic_json_t, ValueType>::value
20301 && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
20302 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
20303 {
20304 // at only works for objects
20305 if (JSON_HEDLEY_LIKELY(is_object()))
20306 {
20307 // if key is found, return value and given default value otherwise
20308 const auto it = find(key);
20309 if (it != end())
20310 {
20311 return it->template get<ValueType>();
20312 }
20313
20314 return default_value;
20315 }
20316
20317 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
20318 }
20319
20324 string_t value(const typename object_t::key_type& key, const char* default_value) const
20325 {
20326 return value(key, string_t(default_value));
20327 }
20328
20372 template<class ValueType, typename std::enable_if<
20373 detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
20374 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
20375 {
20376 // at only works for objects
20377 if (JSON_HEDLEY_LIKELY(is_object()))
20378 {
20379 // if pointer resolves a value, return it or use default value
20380 JSON_TRY
20381 {
20382 return ptr.get_checked(this).template get<ValueType>();
20383 }
20384 JSON_INTERNAL_CATCH (out_of_range&)
20385 {
20386 return default_value;
20387 }
20388 }
20389
20390 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
20391 }
20392
20397 JSON_HEDLEY_NON_NULL(3)
20398 string_t value(const json_pointer& ptr, const char* default_value) const
20399 {
20400 return value(ptr, string_t(default_value));
20401 }
20402
20428 reference front()
20429 {
20430 return *begin();
20431 }
20432
20436 const_reference front() const
20437 {
20438 return *cbegin();
20439 }
20440
20472 reference back()
20473 {
20474 auto tmp = end();
20475 --tmp;
20476 return *tmp;
20477 }
20478
20482 const_reference back() const
20483 {
20484 auto tmp = cend();
20485 --tmp;
20486 return *tmp;
20487 }
20488
20535 template < class IteratorType, typename std::enable_if <
20536 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20537 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
20538 = 0 >
20539 IteratorType erase(IteratorType pos)
20540 {
20541 // make sure iterator fits the current value
20542 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
20543 {
20544 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
20545 }
20546
20547 IteratorType result = end();
20548
20549 switch (m_type)
20550 {
20551 case value_t::boolean:
20552 case value_t::number_float:
20553 case value_t::number_integer:
20554 case value_t::number_unsigned:
20555 case value_t::string:
20556 case value_t::binary:
20557 {
20558 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
20559 {
20560 JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
20561 }
20562
20563 if (is_string())
20564 {
20565 AllocatorType<string_t> alloc;
20566 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20567 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20568 m_value.string = nullptr;
20569 }
20570 else if (is_binary())
20571 {
20572 AllocatorType<binary_t> alloc;
20573 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20574 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20575 m_value.binary = nullptr;
20576 }
20577
20578 m_type = value_t::null;
20579 assert_invariant();
20580 break;
20581 }
20582
20583 case value_t::object:
20584 {
20585 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
20586 break;
20587 }
20588
20589 case value_t::array:
20590 {
20591 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
20592 break;
20593 }
20594
20595 default:
20596 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20597 }
20598
20599 return result;
20600 }
20601
20648 template < class IteratorType, typename std::enable_if <
20649 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20650 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
20651 = 0 >
20652 IteratorType erase(IteratorType first, IteratorType last)
20653 {
20654 // make sure iterator fits the current value
20655 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
20656 {
20657 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
20658 }
20659
20660 IteratorType result = end();
20661
20662 switch (m_type)
20663 {
20664 case value_t::boolean:
20665 case value_t::number_float:
20666 case value_t::number_integer:
20667 case value_t::number_unsigned:
20668 case value_t::string:
20669 case value_t::binary:
20670 {
20671 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
20672 || !last.m_it.primitive_iterator.is_end()))
20673 {
20674 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
20675 }
20676
20677 if (is_string())
20678 {
20679 AllocatorType<string_t> alloc;
20680 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20681 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20682 m_value.string = nullptr;
20683 }
20684 else if (is_binary())
20685 {
20686 AllocatorType<binary_t> alloc;
20687 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20688 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20689 m_value.binary = nullptr;
20690 }
20691
20692 m_type = value_t::null;
20693 assert_invariant();
20694 break;
20695 }
20696
20697 case value_t::object:
20698 {
20699 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
20700 last.m_it.object_iterator);
20701 break;
20702 }
20703
20704 case value_t::array:
20705 {
20706 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
20707 last.m_it.array_iterator);
20708 break;
20709 }
20710
20711 default:
20712 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20713 }
20714
20715 return result;
20716 }
20717
20747 size_type erase(const typename object_t::key_type& key)
20748 {
20749 // this erase only works for objects
20750 if (JSON_HEDLEY_LIKELY(is_object()))
20751 {
20752 return m_value.object->erase(key);
20753 }
20754
20755 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20756 }
20757
20782 void erase(const size_type idx)
20783 {
20784 // this erase only works for arrays
20785 if (JSON_HEDLEY_LIKELY(is_array()))
20786 {
20787 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
20788 {
20789 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
20790 }
20791
20792 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
20793 }
20794 else
20795 {
20796 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20797 }
20798 }
20799
20801
20802
20804 // lookup //
20806
20809
20834 template<typename KeyT>
20835 iterator find(KeyT&& key)
20836 {
20837 auto result = end();
20838
20839 if (is_object())
20840 {
20841 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20842 }
20843
20844 return result;
20845 }
20846
20851 template<typename KeyT>
20852 const_iterator find(KeyT&& key) const
20853 {
20854 auto result = cend();
20855
20856 if (is_object())
20857 {
20858 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20859 }
20860
20861 return result;
20862 }
20863
20885 template<typename KeyT>
20886 size_type count(KeyT&& key) const
20887 {
20888 // return 0 for all nonobject types
20889 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
20890 }
20891
20917 template < typename KeyT, typename std::enable_if <
20918 !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
20919 bool contains(KeyT && key) const
20920 {
20921 return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
20922 }
20923
20950 bool contains(const json_pointer& ptr) const
20951 {
20952 return ptr.contains(this);
20953 }
20954
20956
20957
20959 // iterators //
20961
20964
20989 iterator begin() noexcept
20990 {
20991 iterator result(this);
20992 result.set_begin();
20993 return result;
20994 }
20995
20999 const_iterator begin() const noexcept
21000 {
21001 return cbegin();
21002 }
21003
21029 const_iterator cbegin() const noexcept
21030 {
21031 const_iterator result(this);
21032 result.set_begin();
21033 return result;
21034 }
21035
21060 iterator end() noexcept
21061 {
21062 iterator result(this);
21063 result.set_end();
21064 return result;
21065 }
21066
21070 const_iterator end() const noexcept
21071 {
21072 return cend();
21073 }
21074
21100 const_iterator cend() const noexcept
21101 {
21102 const_iterator result(this);
21103 result.set_end();
21104 return result;
21105 }
21106
21130 reverse_iterator rbegin() noexcept
21131 {
21132 return reverse_iterator(end());
21133 }
21134
21138 const_reverse_iterator rbegin() const noexcept
21139 {
21140 return crbegin();
21141 }
21142
21167 reverse_iterator rend() noexcept
21168 {
21169 return reverse_iterator(begin());
21170 }
21171
21175 const_reverse_iterator rend() const noexcept
21176 {
21177 return crend();
21178 }
21179
21204 const_reverse_iterator crbegin() const noexcept
21205 {
21206 return const_reverse_iterator(cend());
21207 }
21208
21233 const_reverse_iterator crend() const noexcept
21234 {
21235 return const_reverse_iterator(cbegin());
21236 }
21237
21238 public:
21296 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21297 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
21298 {
21299 return ref.items();
21300 }
21301
21305 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21306 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
21307 {
21308 return ref.items();
21309 }
21310
21379 iteration_proxy<iterator> items() noexcept
21380 {
21381 return iteration_proxy<iterator>(*this);
21382 }
21383
21387 iteration_proxy<const_iterator> items() const noexcept
21388 {
21389 return iteration_proxy<const_iterator>(*this);
21390 }
21391
21393
21394
21396 // capacity //
21398
21401
21444 bool empty() const noexcept
21445 {
21446 switch (m_type)
21447 {
21448 case value_t::null:
21449 {
21450 // null values are empty
21451 return true;
21452 }
21453
21454 case value_t::array:
21455 {
21456 // delegate call to array_t::empty()
21457 return m_value.array->empty();
21458 }
21459
21460 case value_t::object:
21461 {
21462 // delegate call to object_t::empty()
21463 return m_value.object->empty();
21464 }
21465
21466 default:
21467 {
21468 // all other types are nonempty
21469 return false;
21470 }
21471 }
21472 }
21473
21517 size_type size() const noexcept
21518 {
21519 switch (m_type)
21520 {
21521 case value_t::null:
21522 {
21523 // null values are empty
21524 return 0;
21525 }
21526
21527 case value_t::array:
21528 {
21529 // delegate call to array_t::size()
21530 return m_value.array->size();
21531 }
21532
21533 case value_t::object:
21534 {
21535 // delegate call to object_t::size()
21536 return m_value.object->size();
21537 }
21538
21539 default:
21540 {
21541 // all other types have size 1
21542 return 1;
21543 }
21544 }
21545 }
21546
21588 size_type max_size() const noexcept
21589 {
21590 switch (m_type)
21591 {
21592 case value_t::array:
21593 {
21594 // delegate call to array_t::max_size()
21595 return m_value.array->max_size();
21596 }
21597
21598 case value_t::object:
21599 {
21600 // delegate call to object_t::max_size()
21601 return m_value.object->max_size();
21602 }
21603
21604 default:
21605 {
21606 // all other types have max_size() == size()
21607 return size();
21608 }
21609 }
21610 }
21611
21613
21614
21616 // modifiers //
21618
21621
21659 void clear() noexcept
21660 {
21661 switch (m_type)
21662 {
21663 case value_t::number_integer:
21664 {
21665 m_value.number_integer = 0;
21666 break;
21667 }
21668
21669 case value_t::number_unsigned:
21670 {
21671 m_value.number_unsigned = 0;
21672 break;
21673 }
21674
21675 case value_t::number_float:
21676 {
21677 m_value.number_float = 0.0;
21678 break;
21679 }
21680
21681 case value_t::boolean:
21682 {
21683 m_value.boolean = false;
21684 break;
21685 }
21686
21687 case value_t::string:
21688 {
21689 m_value.string->clear();
21690 break;
21691 }
21692
21693 case value_t::binary:
21694 {
21695 m_value.binary->clear();
21696 break;
21697 }
21698
21699 case value_t::array:
21700 {
21701 m_value.array->clear();
21702 break;
21703 }
21704
21705 case value_t::object:
21706 {
21707 m_value.object->clear();
21708 break;
21709 }
21710
21711 default:
21712 break;
21713 }
21714 }
21715
21736 void push_back(basic_json&& val)
21737 {
21738 // push_back only works for null objects or arrays
21739 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21740 {
21741 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21742 }
21743
21744 // transform null object into an array
21745 if (is_null())
21746 {
21747 m_type = value_t::array;
21748 m_value = value_t::array;
21749 assert_invariant();
21750 }
21751
21752 // add element to array (move semantics)
21753 m_value.array->push_back(std::move(val));
21754 // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
21755 }
21756
21761 reference operator+=(basic_json&& val)
21762 {
21763 push_back(std::move(val));
21764 return *this;
21765 }
21766
21771 void push_back(const basic_json& val)
21772 {
21773 // push_back only works for null objects or arrays
21774 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21775 {
21776 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21777 }
21778
21779 // transform null object into an array
21780 if (is_null())
21781 {
21782 m_type = value_t::array;
21783 m_value = value_t::array;
21784 assert_invariant();
21785 }
21786
21787 // add element to array
21788 m_value.array->push_back(val);
21789 }
21790
21795 reference operator+=(const basic_json& val)
21796 {
21797 push_back(val);
21798 return *this;
21799 }
21800
21821 void push_back(const typename object_t::value_type& val)
21822 {
21823 // push_back only works for null objects or objects
21824 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21825 {
21826 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21827 }
21828
21829 // transform null object into an object
21830 if (is_null())
21831 {
21832 m_type = value_t::object;
21833 m_value = value_t::object;
21834 assert_invariant();
21835 }
21836
21837 // add element to array
21838 m_value.object->insert(val);
21839 }
21840
21845 reference operator+=(const typename object_t::value_type& val)
21846 {
21847 push_back(val);
21848 return *this;
21849 }
21850
21876 void push_back(initializer_list_t init)
21877 {
21878 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
21879 {
21880 basic_json&& key = init.begin()->moved_or_copied();
21881 push_back(typename object_t::value_type(
21882 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
21883 }
21884 else
21885 {
21886 push_back(basic_json(init));
21887 }
21888 }
21889
21894 reference operator+=(initializer_list_t init)
21895 {
21896 push_back(init);
21897 return *this;
21898 }
21899
21923 template<class... Args>
21924 reference emplace_back(Args&& ... args)
21925 {
21926 // emplace_back only works for null objects or arrays
21927 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21928 {
21929 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
21930 }
21931
21932 // transform null object into an array
21933 if (is_null())
21934 {
21935 m_type = value_t::array;
21936 m_value = value_t::array;
21937 assert_invariant();
21938 }
21939
21940 // add element to array (perfect forwarding)
21941 #ifdef JSON_HAS_CPP_17
21942 return m_value.array->emplace_back(std::forward<Args>(args)...);
21943 #else
21944 m_value.array->emplace_back(std::forward<Args>(args)...);
21945 return m_value.array->back();
21946 #endif
21947 }
21948
21976 template<class... Args>
21977 std::pair<iterator, bool> emplace(Args&& ... args)
21978 {
21979 // emplace only works for null objects or arrays
21980 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21981 {
21982 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
21983 }
21984
21985 // transform null object into an object
21986 if (is_null())
21987 {
21988 m_type = value_t::object;
21989 m_value = value_t::object;
21990 assert_invariant();
21991 }
21992
21993 // add element to array (perfect forwarding)
21994 auto res = m_value.object->emplace(std::forward<Args>(args)...);
21995 // create result iterator and set iterator to the result of emplace
21996 auto it = begin();
21997 it.m_it.object_iterator = res.first;
21998
21999 // return pair of iterator and boolean
22000 return {it, res.second};
22001 }
22002
22006 template<typename... Args>
22007 iterator insert_iterator(const_iterator pos, Args&& ... args)
22008 {
22009 iterator result(this);
22010 JSON_ASSERT(m_value.array != nullptr);
22011
22012 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
22013 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
22014 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
22015
22016 // This could have been written as:
22017 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
22018 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
22019
22020 return result;
22021 }
22022
22045 iterator insert(const_iterator pos, const basic_json& val)
22046 {
22047 // insert only works for arrays
22048 if (JSON_HEDLEY_LIKELY(is_array()))
22049 {
22050 // check if iterator pos fits to this JSON value
22051 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22052 {
22053 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22054 }
22055
22056 // insert to array and return iterator
22057 return insert_iterator(pos, val);
22058 }
22059
22060 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22061 }
22062
22067 iterator insert(const_iterator pos, basic_json&& val)
22068 {
22069 return insert(pos, val);
22070 }
22071
22096 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
22097 {
22098 // insert only works for arrays
22099 if (JSON_HEDLEY_LIKELY(is_array()))
22100 {
22101 // check if iterator pos fits to this JSON value
22102 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22103 {
22104 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22105 }
22106
22107 // insert to array and return iterator
22108 return insert_iterator(pos, cnt, val);
22109 }
22110
22111 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22112 }
22113
22144 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
22145 {
22146 // insert only works for arrays
22147 if (JSON_HEDLEY_UNLIKELY(!is_array()))
22148 {
22149 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22150 }
22151
22152 // check if iterator pos fits to this JSON value
22153 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22154 {
22155 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22156 }
22157
22158 // check if range iterators belong to the same JSON object
22159 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22160 {
22161 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22162 }
22163
22164 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
22165 {
22166 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
22167 }
22168
22169 // insert to array and return iterator
22170 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
22171 }
22172
22197 iterator insert(const_iterator pos, initializer_list_t ilist)
22198 {
22199 // insert only works for arrays
22200 if (JSON_HEDLEY_UNLIKELY(!is_array()))
22201 {
22202 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22203 }
22204
22205 // check if iterator pos fits to this JSON value
22206 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22207 {
22208 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22209 }
22210
22211 // insert to array and return iterator
22212 return insert_iterator(pos, ilist.begin(), ilist.end());
22213 }
22214
22238 void insert(const_iterator first, const_iterator last)
22239 {
22240 // insert only works for objects
22241 if (JSON_HEDLEY_UNLIKELY(!is_object()))
22242 {
22243 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22244 }
22245
22246 // check if range iterators belong to the same JSON object
22247 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22248 {
22249 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22250 }
22251
22252 // passed iterators must belong to objects
22253 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22254 {
22255 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
22256 }
22257
22258 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
22259 }
22260
22280 void update(const_reference j)
22281 {
22282 // implicitly convert null value to an empty object
22283 if (is_null())
22284 {
22285 m_type = value_t::object;
22286 m_value.object = create<object_t>();
22287 assert_invariant();
22288 }
22289
22290 if (JSON_HEDLEY_UNLIKELY(!is_object()))
22291 {
22292 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
22293 }
22294 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
22295 {
22296 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
22297 }
22298
22299 for (auto it = j.cbegin(); it != j.cend(); ++it)
22300 {
22301 m_value.object->operator[](it.key()) = it.value();
22302 }
22303 }
22304
22331 void update(const_iterator first, const_iterator last)
22332 {
22333 // implicitly convert null value to an empty object
22334 if (is_null())
22335 {
22336 m_type = value_t::object;
22337 m_value.object = create<object_t>();
22338 assert_invariant();
22339 }
22340
22341 if (JSON_HEDLEY_UNLIKELY(!is_object()))
22342 {
22343 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
22344 }
22345
22346 // check if range iterators belong to the same JSON object
22347 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22348 {
22349 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22350 }
22351
22352 // passed iterators must belong to objects
22353 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
22354 || !last.m_object->is_object()))
22355 {
22356 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
22357 }
22358
22359 for (auto it = first; it != last; ++it)
22360 {
22361 m_value.object->operator[](it.key()) = it.value();
22362 }
22363 }
22364
22382 void swap(reference other) noexcept (
22383 std::is_nothrow_move_constructible<value_t>::value&&
22384 std::is_nothrow_move_assignable<value_t>::value&&
22385 std::is_nothrow_move_constructible<json_value>::value&&
22386 std::is_nothrow_move_assignable<json_value>::value
22387 )
22388 {
22389 std::swap(m_type, other.m_type);
22390 std::swap(m_value, other.m_value);
22391 assert_invariant();
22392 }
22393
22412 friend void swap(reference left, reference right) noexcept (
22413 std::is_nothrow_move_constructible<value_t>::value&&
22414 std::is_nothrow_move_assignable<value_t>::value&&
22415 std::is_nothrow_move_constructible<json_value>::value&&
22416 std::is_nothrow_move_assignable<json_value>::value
22417 )
22418 {
22419 left.swap(right);
22420 }
22421
22442 void swap(array_t& other)
22443 {
22444 // swap only works for arrays
22445 if (JSON_HEDLEY_LIKELY(is_array()))
22446 {
22447 std::swap(*(m_value.array), other);
22448 }
22449 else
22450 {
22451 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22452 }
22453 }
22454
22475 void swap(object_t& other)
22476 {
22477 // swap only works for objects
22478 if (JSON_HEDLEY_LIKELY(is_object()))
22479 {
22480 std::swap(*(m_value.object), other);
22481 }
22482 else
22483 {
22484 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22485 }
22486 }
22487
22508 void swap(string_t& other)
22509 {
22510 // swap only works for strings
22511 if (JSON_HEDLEY_LIKELY(is_string()))
22512 {
22513 std::swap(*(m_value.string), other);
22514 }
22515 else
22516 {
22517 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22518 }
22519 }
22520
22541 void swap(binary_t& other)
22542 {
22543 // swap only works for strings
22544 if (JSON_HEDLEY_LIKELY(is_binary()))
22545 {
22546 std::swap(*(m_value.binary), other);
22547 }
22548 else
22549 {
22550 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22551 }
22552 }
22553
22555 void swap(typename binary_t::container_type& other)
22556 {
22557 // swap only works for strings
22558 if (JSON_HEDLEY_LIKELY(is_binary()))
22559 {
22560 std::swap(*(m_value.binary), other);
22561 }
22562 else
22563 {
22564 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22565 }
22566 }
22567
22569
22570 public:
22572 // lexicographical comparison operators //
22574
22577
22633 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
22634 {
22635 const auto lhs_type = lhs.type();
22636 const auto rhs_type = rhs.type();
22637
22638 if (lhs_type == rhs_type)
22639 {
22640 switch (lhs_type)
22641 {
22642 case value_t::array:
22643 return *lhs.m_value.array == *rhs.m_value.array;
22644
22645 case value_t::object:
22646 return *lhs.m_value.object == *rhs.m_value.object;
22647
22648 case value_t::null:
22649 return true;
22650
22651 case value_t::string:
22652 return *lhs.m_value.string == *rhs.m_value.string;
22653
22654 case value_t::boolean:
22655 return lhs.m_value.boolean == rhs.m_value.boolean;
22656
22657 case value_t::number_integer:
22658 return lhs.m_value.number_integer == rhs.m_value.number_integer;
22659
22660 case value_t::number_unsigned:
22661 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
22662
22663 case value_t::number_float:
22664 return lhs.m_value.number_float == rhs.m_value.number_float;
22665
22666 case value_t::binary:
22667 return *lhs.m_value.binary == *rhs.m_value.binary;
22668
22669 default:
22670 return false;
22671 }
22672 }
22673 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
22674 {
22675 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
22676 }
22677 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
22678 {
22679 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
22680 }
22681 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
22682 {
22683 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
22684 }
22685 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
22686 {
22687 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
22688 }
22689 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
22690 {
22691 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
22692 }
22693 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
22694 {
22695 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22696 }
22697
22698 return false;
22699 }
22700
22705 template<typename ScalarType, typename std::enable_if<
22706 std::is_scalar<ScalarType>::value, int>::type = 0>
22707 friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
22708 {
22709 return lhs == basic_json(rhs);
22710 }
22711
22716 template<typename ScalarType, typename std::enable_if<
22717 std::is_scalar<ScalarType>::value, int>::type = 0>
22718 friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
22719 {
22720 return basic_json(lhs) == rhs;
22721 }
22722
22741 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
22742 {
22743 return !(lhs == rhs);
22744 }
22745
22750 template<typename ScalarType, typename std::enable_if<
22751 std::is_scalar<ScalarType>::value, int>::type = 0>
22752 friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
22753 {
22754 return lhs != basic_json(rhs);
22755 }
22756
22761 template<typename ScalarType, typename std::enable_if<
22762 std::is_scalar<ScalarType>::value, int>::type = 0>
22763 friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
22764 {
22765 return basic_json(lhs) != rhs;
22766 }
22767
22794 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
22795 {
22796 const auto lhs_type = lhs.type();
22797 const auto rhs_type = rhs.type();
22798
22799 if (lhs_type == rhs_type)
22800 {
22801 switch (lhs_type)
22802 {
22803 case value_t::array:
22804 // note parentheses are necessary, see
22805 // https://github.com/nlohmann/json/issues/1530
22806 return (*lhs.m_value.array) < (*rhs.m_value.array);
22807
22808 case value_t::object:
22809 return (*lhs.m_value.object) < (*rhs.m_value.object);
22810
22811 case value_t::null:
22812 return false;
22813
22814 case value_t::string:
22815 return (*lhs.m_value.string) < (*rhs.m_value.string);
22816
22817 case value_t::boolean:
22818 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
22819
22820 case value_t::number_integer:
22821 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
22822
22823 case value_t::number_unsigned:
22824 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
22825
22826 case value_t::number_float:
22827 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
22828
22829 case value_t::binary:
22830 return (*lhs.m_value.binary) < (*rhs.m_value.binary);
22831
22832 default:
22833 return false;
22834 }
22835 }
22836 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
22837 {
22838 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
22839 }
22840 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
22841 {
22842 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
22843 }
22844 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
22845 {
22846 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
22847 }
22848 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
22849 {
22850 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
22851 }
22852 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
22853 {
22854 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22855 }
22856 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
22857 {
22858 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
22859 }
22860
22861 // We only reach this line if we cannot compare values. In that case,
22862 // we compare types. Note we have to call the operator explicitly,
22863 // because MSVC has problems otherwise.
22864 return operator<(lhs_type, rhs_type);
22865 }
22866
22871 template<typename ScalarType, typename std::enable_if<
22872 std::is_scalar<ScalarType>::value, int>::type = 0>
22873 friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
22874 {
22875 return lhs < basic_json(rhs);
22876 }
22877
22882 template<typename ScalarType, typename std::enable_if<
22883 std::is_scalar<ScalarType>::value, int>::type = 0>
22884 friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
22885 {
22886 return basic_json(lhs) < rhs;
22887 }
22888
22908 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
22909 {
22910 return !(rhs < lhs);
22911 }
22912
22917 template<typename ScalarType, typename std::enable_if<
22918 std::is_scalar<ScalarType>::value, int>::type = 0>
22919 friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
22920 {
22921 return lhs <= basic_json(rhs);
22922 }
22923
22928 template<typename ScalarType, typename std::enable_if<
22929 std::is_scalar<ScalarType>::value, int>::type = 0>
22930 friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
22931 {
22932 return basic_json(lhs) <= rhs;
22933 }
22934
22954 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
22955 {
22956 return !(lhs <= rhs);
22957 }
22958
22963 template<typename ScalarType, typename std::enable_if<
22964 std::is_scalar<ScalarType>::value, int>::type = 0>
22965 friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
22966 {
22967 return lhs > basic_json(rhs);
22968 }
22969
22974 template<typename ScalarType, typename std::enable_if<
22975 std::is_scalar<ScalarType>::value, int>::type = 0>
22976 friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
22977 {
22978 return basic_json(lhs) > rhs;
22979 }
22980
23000 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
23001 {
23002 return !(lhs < rhs);
23003 }
23004
23009 template<typename ScalarType, typename std::enable_if<
23010 std::is_scalar<ScalarType>::value, int>::type = 0>
23011 friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
23012 {
23013 return lhs >= basic_json(rhs);
23014 }
23015
23020 template<typename ScalarType, typename std::enable_if<
23021 std::is_scalar<ScalarType>::value, int>::type = 0>
23022 friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
23023 {
23024 return basic_json(lhs) >= rhs;
23025 }
23026
23028
23030 // serialization //
23032
23035
23067 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
23068 {
23069 // read width member and use it as indentation parameter if nonzero
23070 const bool pretty_print = o.width() > 0;
23071 const auto indentation = pretty_print ? o.width() : 0;
23072
23073 // reset width to 0 for subsequent calls to this stream
23074 o.width(0);
23075
23076 // do the actual serialization
23077 serializer s(detail::output_adapter<char>(o), o.fill());
23078 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
23079 return o;
23080 }
23081
23090 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
23091 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
23092 {
23093 return o << j;
23094 }
23095
23097
23098
23100 // deserialization //
23102
23105
23157 template<typename InputType>
23158
23159 static basic_json parse(InputType&& i,
23160 const parser_callback_t cb = nullptr,
23161 const bool allow_exceptions = true,
23162 const bool ignore_comments = false)
23163 {
23164 basic_json result;
23165 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
23166 return result;
23167 }
23168
23195 template<typename IteratorType>
23196
23197 static basic_json parse(IteratorType first,
23198 IteratorType last,
23199 const parser_callback_t cb = nullptr,
23200 const bool allow_exceptions = true,
23201 const bool ignore_comments = false)
23202 {
23203 basic_json result;
23204 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
23205 return result;
23206 }
23207
23208
23209 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
23210 static basic_json parse(detail::span_input_adapter&& i,
23211 const parser_callback_t cb = nullptr,
23212 const bool allow_exceptions = true,
23213 const bool ignore_comments = false)
23214 {
23215 basic_json result;
23216 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
23217 return result;
23218 }
23219
23250 template<typename InputType>
23251 static bool accept(InputType&& i,
23252 const bool ignore_comments = false)
23253 {
23254 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
23255 }
23256
23257 template<typename IteratorType>
23258 static bool accept(IteratorType first, IteratorType last,
23259 const bool ignore_comments = false)
23260 {
23261 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
23262 }
23263
23264
23265 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
23266 static bool accept(detail::span_input_adapter&& i,
23267 const bool ignore_comments = false)
23268 {
23269 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
23270 }
23271
23312 template <typename InputType, typename SAX>
23313 JSON_HEDLEY_NON_NULL(2)
23314 static bool sax_parse(InputType&& i, SAX* sax,
23315 input_format_t format = input_format_t::json,
23316 const bool strict = true,
23317 const bool ignore_comments = false)
23318 {
23319 auto ia = detail::input_adapter(std::forward<InputType>(i));
23320 return format == input_format_t::json
23321 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23322 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23323 }
23324
23325 template<class IteratorType, class SAX>
23326 JSON_HEDLEY_NON_NULL(3)
23327 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
23328 input_format_t format = input_format_t::json,
23329 const bool strict = true,
23330 const bool ignore_comments = false)
23331 {
23332 auto ia = detail::input_adapter(std::move(first), std::move(last));
23333 return format == input_format_t::json
23334 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23335 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23336 }
23337
23338 template <typename SAX>
23339 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
23340 JSON_HEDLEY_NON_NULL(2)
23341 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
23342 input_format_t format = input_format_t::json,
23343 const bool strict = true,
23344 const bool ignore_comments = false)
23345 {
23346 auto ia = i.get();
23347 return format == input_format_t::json
23348 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23349 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23350 }
23351
23360 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
23361 friend std::istream& operator<<(basic_json& j, std::istream& i)
23362 {
23363 return operator>>(i, j);
23364 }
23365
23391 friend std::istream& operator>>(std::istream& i, basic_json& j)
23392 {
23393 parser(detail::input_adapter(i)).parse(false, j);
23394 return i;
23395 }
23396
23398
23400 // convenience functions //
23402
23434
23435 const char* type_name() const noexcept
23436 {
23437 {
23438 switch (m_type)
23439 {
23440 case value_t::null:
23441 return "null";
23442 case value_t::object:
23443 return "object";
23444 case value_t::array:
23445 return "array";
23446 case value_t::string:
23447 return "string";
23448 case value_t::boolean:
23449 return "boolean";
23450 case value_t::binary:
23451 return "binary";
23452 case value_t::discarded:
23453 return "discarded";
23454 default:
23455 return "number";
23456 }
23457 }
23458 }
23459
23460
23461 JSON_PRIVATE_UNLESS_TESTED:
23463 // member variables //
23465
23467 value_t m_type = value_t::null;
23468
23470 json_value m_value = {};
23471
23473 // binary serialization/deserialization //
23475
23478
23479 public:
23574 static std::vector<uint8_t> to_cbor(const basic_json& j)
23575 {
23576 std::vector<uint8_t> result;
23577 to_cbor(j, result);
23578 return result;
23579 }
23580
23581 static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
23582 {
23583 binary_writer<uint8_t>(o).write_cbor(j);
23584 }
23585
23586 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
23587 {
23588 binary_writer<char>(o).write_cbor(j);
23589 }
23590
23669 static std::vector<uint8_t> to_msgpack(const basic_json& j)
23670 {
23671 std::vector<uint8_t> result;
23672 to_msgpack(j, result);
23673 return result;
23674 }
23675
23676 static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
23677 {
23678 binary_writer<uint8_t>(o).write_msgpack(j);
23679 }
23680
23681 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
23682 {
23683 binary_writer<char>(o).write_msgpack(j);
23684 }
23685
23772 static std::vector<uint8_t> to_ubjson(const basic_json& j,
23773 const bool use_size = false,
23774 const bool use_type = false)
23775 {
23776 std::vector<uint8_t> result;
23777 to_ubjson(j, result, use_size, use_type);
23778 return result;
23779 }
23780
23781 static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
23782 const bool use_size = false, const bool use_type = false)
23783 {
23784 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
23785 }
23786
23787 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
23788 const bool use_size = false, const bool use_type = false)
23789 {
23790 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23791 }
23792
23793
23850 static std::vector<uint8_t> to_bson(const basic_json& j)
23851 {
23852 std::vector<uint8_t> result;
23853 to_bson(j, result);
23854 return result;
23855 }
23856
23865 static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
23866 {
23867 binary_writer<uint8_t>(o).write_bson(j);
23868 }
23869
23873 static void to_bson(const basic_json& j, detail::output_adapter<char> o)
23874 {
23875 binary_writer<char>(o).write_bson(j);
23876 }
23877
23878
23981 template<typename InputType>
23982
23983 static basic_json from_cbor(InputType&& i,
23984 const bool strict = true,
23985 const bool allow_exceptions = true,
23986 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23987 {
23988 basic_json result;
23989 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23990 auto ia = detail::input_adapter(std::forward<InputType>(i));
23991 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23992 return res ? result : basic_json(value_t::discarded);
23993 }
23994
23998 template<typename IteratorType>
23999
24000 static basic_json from_cbor(IteratorType first, IteratorType last,
24001 const bool strict = true,
24002 const bool allow_exceptions = true,
24003 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24004 {
24005 basic_json result;
24006 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24007 auto ia = detail::input_adapter(std::move(first), std::move(last));
24008 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24009 return res ? result : basic_json(value_t::discarded);
24010 }
24011
24012 template<typename T>
24013
24014 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
24015 static basic_json from_cbor(const T* ptr, std::size_t len,
24016 const bool strict = true,
24017 const bool allow_exceptions = true,
24018 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24019 {
24020 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
24021 }
24022
24023
24024
24025 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
24026 static basic_json from_cbor(detail::span_input_adapter&& i,
24027 const bool strict = true,
24028 const bool allow_exceptions = true,
24029 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24030 {
24031 basic_json result;
24032 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24033 auto ia = i.get();
24034 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24035 return res ? result : basic_json(value_t::discarded);
24036 }
24037
24124 template<typename InputType>
24125
24126 static basic_json from_msgpack(InputType&& i,
24127 const bool strict = true,
24128 const bool allow_exceptions = true)
24129 {
24130 basic_json result;
24131 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24132 auto ia = detail::input_adapter(std::forward<InputType>(i));
24133 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24134 return res ? result : basic_json(value_t::discarded);
24135 }
24136
24140 template<typename IteratorType>
24141
24142 static basic_json from_msgpack(IteratorType first, IteratorType last,
24143 const bool strict = true,
24144 const bool allow_exceptions = true)
24145 {
24146 basic_json result;
24147 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24148 auto ia = detail::input_adapter(std::move(first), std::move(last));
24149 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24150 return res ? result : basic_json(value_t::discarded);
24151 }
24152
24153
24154 template<typename T>
24155
24156 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
24157 static basic_json from_msgpack(const T* ptr, std::size_t len,
24158 const bool strict = true,
24159 const bool allow_exceptions = true)
24160 {
24161 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
24162 }
24163
24164
24165 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
24166 static basic_json from_msgpack(detail::span_input_adapter&& i,
24167 const bool strict = true,
24168 const bool allow_exceptions = true)
24169 {
24170 basic_json result;
24171 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24172 auto ia = i.get();
24173 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24174 return res ? result : basic_json(value_t::discarded);
24175 }
24176
24177
24240 template<typename InputType>
24241
24242 static basic_json from_ubjson(InputType&& i,
24243 const bool strict = true,
24244 const bool allow_exceptions = true)
24245 {
24246 basic_json result;
24247 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24248 auto ia = detail::input_adapter(std::forward<InputType>(i));
24249 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24250 return res ? result : basic_json(value_t::discarded);
24251 }
24252
24256 template<typename IteratorType>
24257
24258 static basic_json from_ubjson(IteratorType first, IteratorType last,
24259 const bool strict = true,
24260 const bool allow_exceptions = true)
24261 {
24262 basic_json result;
24263 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24264 auto ia = detail::input_adapter(std::move(first), std::move(last));
24265 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24266 return res ? result : basic_json(value_t::discarded);
24267 }
24268
24269 template<typename T>
24270
24271 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
24272 static basic_json from_ubjson(const T* ptr, std::size_t len,
24273 const bool strict = true,
24274 const bool allow_exceptions = true)
24275 {
24276 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
24277 }
24278
24279
24280 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
24281 static basic_json from_ubjson(detail::span_input_adapter&& i,
24282 const bool strict = true,
24283 const bool allow_exceptions = true)
24284 {
24285 basic_json result;
24286 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24287 auto ia = i.get();
24288 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24289 return res ? result : basic_json(value_t::discarded);
24290 }
24291
24292
24353 template<typename InputType>
24354
24355 static basic_json from_bson(InputType&& i,
24356 const bool strict = true,
24357 const bool allow_exceptions = true)
24358 {
24359 basic_json result;
24360 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24361 auto ia = detail::input_adapter(std::forward<InputType>(i));
24362 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24363 return res ? result : basic_json(value_t::discarded);
24364 }
24365
24369 template<typename IteratorType>
24370
24371 static basic_json from_bson(IteratorType first, IteratorType last,
24372 const bool strict = true,
24373 const bool allow_exceptions = true)
24374 {
24375 basic_json result;
24376 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24377 auto ia = detail::input_adapter(std::move(first), std::move(last));
24378 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24379 return res ? result : basic_json(value_t::discarded);
24380 }
24381
24382 template<typename T>
24383
24384 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
24385 static basic_json from_bson(const T* ptr, std::size_t len,
24386 const bool strict = true,
24387 const bool allow_exceptions = true)
24388 {
24389 return from_bson(ptr, ptr + len, strict, allow_exceptions);
24390 }
24391
24392
24393 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
24394 static basic_json from_bson(detail::span_input_adapter&& i,
24395 const bool strict = true,
24396 const bool allow_exceptions = true)
24397 {
24398 basic_json result;
24399 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24400 auto ia = i.get();
24401 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24402 return res ? result : basic_json(value_t::discarded);
24403 }
24405
24407 // JSON Pointer support //
24409
24412
24446 reference operator[](const json_pointer& ptr)
24447 {
24448 return ptr.get_unchecked(this);
24449 }
24450
24474 const_reference operator[](const json_pointer& ptr) const
24475 {
24476 return ptr.get_unchecked(this);
24477 }
24478
24517 reference at(const json_pointer& ptr)
24518 {
24519 return ptr.get_checked(this);
24520 }
24521
24560 const_reference at(const json_pointer& ptr) const
24561 {
24562 return ptr.get_checked(this);
24563 }
24564
24587 basic_json flatten() const
24588 {
24589 basic_json result(value_t::object);
24590 json_pointer::flatten("", *this, result);
24591 return result;
24592 }
24593
24624 basic_json unflatten() const
24625 {
24626 return json_pointer::unflatten(*this);
24627 }
24628
24630
24632 // JSON Patch functions //
24634
24637
24685 basic_json patch(const basic_json& json_patch) const
24686 {
24687 // make a working copy to apply the patch to
24688 basic_json result = *this;
24689
24690 // the valid JSON Patch operations
24691 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
24692
24693 const auto get_op = [](const std::string & op)
24694 {
24695 if (op == "add")
24696 {
24697 return patch_operations::add;
24698 }
24699 if (op == "remove")
24700 {
24701 return patch_operations::remove;
24702 }
24703 if (op == "replace")
24704 {
24705 return patch_operations::replace;
24706 }
24707 if (op == "move")
24708 {
24709 return patch_operations::move;
24710 }
24711 if (op == "copy")
24712 {
24713 return patch_operations::copy;
24714 }
24715 if (op == "test")
24716 {
24717 return patch_operations::test;
24718 }
24719
24720 return patch_operations::invalid;
24721 };
24722
24723 // wrapper for "add" operation; add value at ptr
24724 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
24725 {
24726 // adding to the root of the target document means replacing it
24727 if (ptr.empty())
24728 {
24729 result = val;
24730 return;
24731 }
24732
24733 // make sure the top element of the pointer exists
24734 json_pointer top_pointer = ptr.top();
24735 if (top_pointer != ptr)
24736 {
24737 result.at(top_pointer);
24738 }
24739
24740 // get reference to parent of JSON pointer ptr
24741 const auto last_path = ptr.back();
24742 ptr.pop_back();
24743 basic_json& parent = result[ptr];
24744
24745 switch (parent.m_type)
24746 {
24747 case value_t::null:
24748 case value_t::object:
24749 {
24750 // use operator[] to add value
24751 parent[last_path] = val;
24752 break;
24753 }
24754
24755 case value_t::array:
24756 {
24757 if (last_path == "-")
24758 {
24759 // special case: append to back
24760 parent.push_back(val);
24761 }
24762 else
24763 {
24764 const auto idx = json_pointer::array_index(last_path);
24765 if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
24766 {
24767 // avoid undefined behavior
24768 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
24769 }
24770
24771 // default case: insert add offset
24772 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
24773 }
24774 break;
24775 }
24776
24777 // if there exists a parent it cannot be primitive
24778 default: // LCOV_EXCL_LINE
24779 JSON_ASSERT(false); // LCOV_EXCL_LINE
24780 }
24781 };
24782
24783 // wrapper for "remove" operation; remove value at ptr
24784 const auto operation_remove = [&result](json_pointer & ptr)
24785 {
24786 // get reference to parent of JSON pointer ptr
24787 const auto last_path = ptr.back();
24788 ptr.pop_back();
24789 basic_json& parent = result.at(ptr);
24790
24791 // remove child
24792 if (parent.is_object())
24793 {
24794 // perform range check
24795 auto it = parent.find(last_path);
24796 if (JSON_HEDLEY_LIKELY(it != parent.end()))
24797 {
24798 parent.erase(it);
24799 }
24800 else
24801 {
24802 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
24803 }
24804 }
24805 else if (parent.is_array())
24806 {
24807 // note erase performs range check
24808 parent.erase(json_pointer::array_index(last_path));
24809 }
24810 };
24811
24812 // type check: top level value must be an array
24813 if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
24814 {
24815 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24816 }
24817
24818 // iterate and apply the operations
24819 for (const auto& val : json_patch)
24820 {
24821 // wrapper to get a value for an operation
24822 const auto get_value = [&val](const std::string & op,
24823 const std::string & member,
24824 bool string_type) -> basic_json &
24825 {
24826 // find value
24827 auto it = val.m_value.object->find(member);
24828
24829 // context-sensitive error message
24830 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
24831
24832 // check if desired value is present
24833 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
24834 {
24835 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
24836 }
24837
24838 // check if result is of type string
24839 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
24840 {
24841 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
24842 }
24843
24844 // no error: return value
24845 return it->second;
24846 };
24847
24848 // type check: every element of the array must be an object
24849 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
24850 {
24851 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24852 }
24853
24854 // collect mandatory members
24855 const auto op = get_value("op", "op", true).template get<std::string>();
24856 const auto path = get_value(op, "path", true).template get<std::string>();
24857 json_pointer ptr(path);
24858
24859 switch (get_op(op))
24860 {
24861 case patch_operations::add:
24862 {
24863 operation_add(ptr, get_value("add", "value", false));
24864 break;
24865 }
24866
24867 case patch_operations::remove:
24868 {
24869 operation_remove(ptr);
24870 break;
24871 }
24872
24873 case patch_operations::replace:
24874 {
24875 // the "path" location must exist - use at()
24876 result.at(ptr) = get_value("replace", "value", false);
24877 break;
24878 }
24879
24880 case patch_operations::move:
24881 {
24882 const auto from_path = get_value("move", "from", true).template get<std::string>();
24883 json_pointer from_ptr(from_path);
24884
24885 // the "from" location must exist - use at()
24886 basic_json v = result.at(from_ptr);
24887
24888 // The move operation is functionally identical to a
24889 // "remove" operation on the "from" location, followed
24890 // immediately by an "add" operation at the target
24891 // location with the value that was just removed.
24892 operation_remove(from_ptr);
24893 operation_add(ptr, v);
24894 break;
24895 }
24896
24897 case patch_operations::copy:
24898 {
24899 const auto from_path = get_value("copy", "from", true).template get<std::string>();
24900 const json_pointer from_ptr(from_path);
24901
24902 // the "from" location must exist - use at()
24903 basic_json v = result.at(from_ptr);
24904
24905 // The copy is functionally identical to an "add"
24906 // operation at the target location using the value
24907 // specified in the "from" member.
24908 operation_add(ptr, v);
24909 break;
24910 }
24911
24912 case patch_operations::test:
24913 {
24914 bool success = false;
24915 JSON_TRY
24916 {
24917 // check if "value" matches the one at "path"
24918 // the "path" location must exist - use at()
24919 success = (result.at(ptr) == get_value("test", "value", false));
24920 }
24921 JSON_INTERNAL_CATCH (out_of_range&)
24922 {
24923 // ignore out of range errors: success remains false
24924 }
24925
24926 // throw an exception if test fails
24927 if (JSON_HEDLEY_UNLIKELY(!success))
24928 {
24929 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
24930 }
24931
24932 break;
24933 }
24934
24935 default:
24936 {
24937 // op must be "add", "remove", "replace", "move", "copy", or
24938 // "test"
24939 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
24940 }
24941 }
24942 }
24943
24944 return result;
24945 }
24946
24980
24981 static basic_json diff(const basic_json& source, const basic_json& target,
24982 const std::string& path = "")
24983 {
24984 // the patch
24985 basic_json result(value_t::array);
24986
24987 // if the values are the same, return empty patch
24988 if (source == target)
24989 {
24990 return result;
24991 }
24992
24993 if (source.type() != target.type())
24994 {
24995 // different types: replace value
24996 result.push_back(
24997 {
24998 {"op", "replace"}, {"path", path}, {"value", target}
24999 });
25000 return result;
25001 }
25002
25003 switch (source.type())
25004 {
25005 case value_t::array:
25006 {
25007 // first pass: traverse common elements
25008 std::size_t i = 0;
25009 while (i < source.size() && i < target.size())
25010 {
25011 // recursive call to compare array values at index i
25012 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
25013 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
25014 ++i;
25015 }
25016
25017 // i now reached the end of at least one array
25018 // in a second pass, traverse the remaining elements
25019
25020 // remove my remaining elements
25021 const auto end_index = static_cast<difference_type>(result.size());
25022 while (i < source.size())
25023 {
25024 // add operations in reverse order to avoid invalid
25025 // indices
25026 result.insert(result.begin() + end_index, object(
25027 {
25028 {"op", "remove"},
25029 {"path", path + "/" + std::to_string(i)}
25030 }));
25031 ++i;
25032 }
25033
25034 // add other remaining elements
25035 while (i < target.size())
25036 {
25037 result.push_back(
25038 {
25039 {"op", "add"},
25040 {"path", path + "/-"},
25041 {"value", target[i]}
25042 });
25043 ++i;
25044 }
25045
25046 break;
25047 }
25048
25049 case value_t::object:
25050 {
25051 // first pass: traverse this object's elements
25052 for (auto it = source.cbegin(); it != source.cend(); ++it)
25053 {
25054 // escape the key name to be used in a JSON patch
25055 const auto key = json_pointer::escape(it.key());
25056
25057 if (target.find(it.key()) != target.end())
25058 {
25059 // recursive call to compare object values at key it
25060 auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
25061 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
25062 }
25063 else
25064 {
25065 // found a key that is not in o -> remove it
25066 result.push_back(object(
25067 {
25068 {"op", "remove"}, {"path", path + "/" + key}
25069 }));
25070 }
25071 }
25072
25073 // second pass: traverse other object's elements
25074 for (auto it = target.cbegin(); it != target.cend(); ++it)
25075 {
25076 if (source.find(it.key()) == source.end())
25077 {
25078 // found a key that is not in this -> add it
25079 const auto key = json_pointer::escape(it.key());
25080 result.push_back(
25081 {
25082 {"op", "add"}, {"path", path + "/" + key},
25083 {"value", it.value()}
25084 });
25085 }
25086 }
25087
25088 break;
25089 }
25090
25091 default:
25092 {
25093 // both primitive type: replace value
25094 result.push_back(
25095 {
25096 {"op", "replace"}, {"path", path}, {"value", target}
25097 });
25098 break;
25099 }
25100 }
25101
25102 return result;
25103 }
25104
25106
25108 // JSON Merge Patch functions //
25110
25113
25156 void merge_patch(const basic_json& apply_patch)
25157 {
25158 if (apply_patch.is_object())
25159 {
25160 if (!is_object())
25161 {
25162 *this = object();
25163 }
25164 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
25165 {
25166 if (it.value().is_null())
25167 {
25168 erase(it.key());
25169 }
25170 else
25171 {
25172 operator[](it.key()).merge_patch(it.value());
25173 }
25174 }
25175 }
25176 else
25177 {
25178 *this = apply_patch;
25179 }
25180 }
25181
25183 };
25184
25194 NLOHMANN_BASIC_JSON_TPL_DECLARATION
25195 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
25196 {
25197 return j.dump();
25198 }
25199 } // namespace nlohmann
25200
25202 // nonmember support //
25204
25205 // specialization of std::swap, and std::hash
25206 namespace std
25207 {
25208
25210 template<>
25211 struct hash<nlohmann::json>
25212 {
25218 std::size_t operator()(const nlohmann::json& j) const
25219 {
25220 return nlohmann::detail::hash(j);
25221 }
25222 };
25223
25227 template<>
25228 struct less<::nlohmann::detail::value_t>
25229 {
25234 bool operator()(nlohmann::detail::value_t lhs,
25235 nlohmann::detail::value_t rhs) const noexcept
25236 {
25237 return nlohmann::detail::operator<(lhs, rhs);
25238 }
25239 };
25240
25241 // C++20 prohibit function specialization in the std namespace.
25242 #ifndef JSON_HAS_CPP_20
25243
25249 template<>
25250 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
25251 is_nothrow_move_constructible<nlohmann::json>::value&&
25252 is_nothrow_move_assignable<nlohmann::json>::value
25253 )
25254 {
25255 j1.swap(j2);
25256 }
25257
25258 #endif
25259
25260 } // namespace std
25261
25275 JSON_HEDLEY_NON_NULL(1)
25276 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
25277 {
25278 return nlohmann::json::parse(s, s + n);
25279 }
25280
25294 JSON_HEDLEY_NON_NULL(1)
25295 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
25296 {
25297 return nlohmann::json::json_pointer(std::string(s, n));
25298 }
25299
25300 // #include <nlohmann/detail/macro_unscope.hpp>
25301
25302
25303 // restore GCC/clang diagnostic settings
25304 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
25305 #pragma GCC diagnostic pop
25306 #endif
25307 #if defined(__clang__)
25308 #pragma GCC diagnostic pop
25309 #endif
25310
25311 // clean up
25312 #undef JSON_ASSERT
25313 #undef JSON_INTERNAL_CATCH
25314 #undef JSON_CATCH
25315 #undef JSON_THROW
25316 #undef JSON_TRY
25317 #undef JSON_PRIVATE_UNLESS_TESTED
25318 #undef JSON_HAS_CPP_14
25319 #undef JSON_HAS_CPP_17
25320 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
25321 #undef NLOHMANN_BASIC_JSON_TPL
25322 #undef JSON_EXPLICIT
25323
25324 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
25325 #undef JSON_HEDLEY_ALWAYS_INLINE
25326 #undef JSON_HEDLEY_ARM_VERSION
25327 #undef JSON_HEDLEY_ARM_VERSION_CHECK
25328 #undef JSON_HEDLEY_ARRAY_PARAM
25329 #undef JSON_HEDLEY_ASSUME
25330 #undef JSON_HEDLEY_BEGIN_C_DECLS
25331 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
25332 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
25333 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
25334 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
25335 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
25336 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
25337 #undef JSON_HEDLEY_CLANG_HAS_WARNING
25338 #undef JSON_HEDLEY_COMPCERT_VERSION
25339 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
25340 #undef JSON_HEDLEY_CONCAT
25341 #undef JSON_HEDLEY_CONCAT3
25342 #undef JSON_HEDLEY_CONCAT3_EX
25343 #undef JSON_HEDLEY_CONCAT_EX
25344 #undef JSON_HEDLEY_CONST
25345 #undef JSON_HEDLEY_CONSTEXPR
25346 #undef JSON_HEDLEY_CONST_CAST
25347 #undef JSON_HEDLEY_CPP_CAST
25348 #undef JSON_HEDLEY_CRAY_VERSION
25349 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
25350 #undef JSON_HEDLEY_C_DECL
25351 #undef JSON_HEDLEY_DEPRECATED
25352 #undef JSON_HEDLEY_DEPRECATED_FOR
25353 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
25354 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
25355 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
25356 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
25357 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
25358 #undef JSON_HEDLEY_DIAGNOSTIC_POP
25359 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
25360 #undef JSON_HEDLEY_DMC_VERSION
25361 #undef JSON_HEDLEY_DMC_VERSION_CHECK
25362 #undef JSON_HEDLEY_EMPTY_BASES
25363 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
25364 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
25365 #undef JSON_HEDLEY_END_C_DECLS
25366 #undef JSON_HEDLEY_FLAGS
25367 #undef JSON_HEDLEY_FLAGS_CAST
25368 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
25369 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
25370 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
25371 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
25372 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
25373 #undef JSON_HEDLEY_GCC_HAS_FEATURE
25374 #undef JSON_HEDLEY_GCC_HAS_WARNING
25375 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
25376 #undef JSON_HEDLEY_GCC_VERSION
25377 #undef JSON_HEDLEY_GCC_VERSION_CHECK
25378 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
25379 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
25380 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
25381 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
25382 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
25383 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
25384 #undef JSON_HEDLEY_GNUC_HAS_WARNING
25385 #undef JSON_HEDLEY_GNUC_VERSION
25386 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
25387 #undef JSON_HEDLEY_HAS_ATTRIBUTE
25388 #undef JSON_HEDLEY_HAS_BUILTIN
25389 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
25390 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
25391 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
25392 #undef JSON_HEDLEY_HAS_EXTENSION
25393 #undef JSON_HEDLEY_HAS_FEATURE
25394 #undef JSON_HEDLEY_HAS_WARNING
25395 #undef JSON_HEDLEY_IAR_VERSION
25396 #undef JSON_HEDLEY_IAR_VERSION_CHECK
25397 #undef JSON_HEDLEY_IBM_VERSION
25398 #undef JSON_HEDLEY_IBM_VERSION_CHECK
25399 #undef JSON_HEDLEY_IMPORT
25400 #undef JSON_HEDLEY_INLINE
25401 #undef JSON_HEDLEY_INTEL_VERSION
25402 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
25403 #undef JSON_HEDLEY_IS_CONSTANT
25404 #undef JSON_HEDLEY_IS_CONSTEXPR_
25405 #undef JSON_HEDLEY_LIKELY
25406 #undef JSON_HEDLEY_MALLOC
25407 #undef JSON_HEDLEY_MESSAGE
25408 #undef JSON_HEDLEY_MSVC_VERSION
25409 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
25410 #undef JSON_HEDLEY_NEVER_INLINE
25411 #undef JSON_HEDLEY_NON_NULL
25412 #undef JSON_HEDLEY_NO_ESCAPE
25413 #undef JSON_HEDLEY_NO_RETURN
25414 #undef JSON_HEDLEY_NO_THROW
25415 #undef JSON_HEDLEY_NULL
25416 #undef JSON_HEDLEY_PELLES_VERSION
25417 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
25418 #undef JSON_HEDLEY_PGI_VERSION
25419 #undef JSON_HEDLEY_PGI_VERSION_CHECK
25420 #undef JSON_HEDLEY_PREDICT
25421 #undef JSON_HEDLEY_PRINTF_FORMAT
25422 #undef JSON_HEDLEY_PRIVATE
25423 #undef JSON_HEDLEY_PUBLIC
25424 #undef JSON_HEDLEY_PURE
25425 #undef JSON_HEDLEY_REINTERPRET_CAST
25426 #undef JSON_HEDLEY_REQUIRE
25427 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
25428 #undef JSON_HEDLEY_REQUIRE_MSG
25429 #undef JSON_HEDLEY_RESTRICT
25430 #undef
25431 #undef JSON_HEDLEY_SENTINEL
25432 #undef JSON_HEDLEY_STATIC_ASSERT
25433 #undef JSON_HEDLEY_STATIC_CAST
25434 #undef JSON_HEDLEY_STRINGIFY
25435 #undef JSON_HEDLEY_STRINGIFY_EX
25436 #undef JSON_HEDLEY_SUNPRO_VERSION
25437 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
25438 #undef JSON_HEDLEY_TINYC_VERSION
25439 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
25440 #undef JSON_HEDLEY_TI_ARMCL_VERSION
25441 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
25442 #undef JSON_HEDLEY_TI_CL2000_VERSION
25443 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
25444 #undef JSON_HEDLEY_TI_CL430_VERSION
25445 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
25446 #undef JSON_HEDLEY_TI_CL6X_VERSION
25447 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
25448 #undef JSON_HEDLEY_TI_CL7X_VERSION
25449 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
25450 #undef JSON_HEDLEY_TI_CLPRU_VERSION
25451 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
25452 #undef JSON_HEDLEY_TI_VERSION
25453 #undef JSON_HEDLEY_TI_VERSION_CHECK
25454 #undef JSON_HEDLEY_UNAVAILABLE
25455 #undef JSON_HEDLEY_UNLIKELY
25456 #undef JSON_HEDLEY_UNPREDICTABLE
25457 #undef JSON_HEDLEY_UNREACHABLE
25458 #undef JSON_HEDLEY_UNREACHABLE_RETURN
25459 #undef JSON_HEDLEY_VERSION
25460 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
25461 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
25462 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
25463 #undef JSON_HEDLEY_VERSION_ENCODE
25464 #undef JSON_HEDLEY_WARNING
25465 #undef
25466 #undef _MSG
25467 #undef JSON_HEDLEY_FALL_THROUGH
25468
25469
25470
25471 #endif // INCLUDE_NLOHMANN_JSON_HPP_
nlohmann::basic_json::get_to
ValueType & get_to(ValueType &v) const
Definition: json.hpp:19542
nlohmann::ordered_map::insert
std::pair< iterator, bool > insert(value_type &&value)
Definition: json.hpp:16560
nlohmann::basic_json::insert_iterator
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.hpp:22017
nlohmann::json_sax::boolean
virtual bool boolean(bool val)=0
a boolean value was read
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:4470
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:16745
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:19553
nlohmann::basic_json::basic_json
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:17877
nlohmann::basic_json::patch
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:24695
nlohmann::basic_json::number_integer_t
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:17209
nlohmann::basic_json::value_t
detail::value_t value_t
Definition: json.hpp:16735
nlohmann::basic_json::pointer
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:16801
nlohmann::basic_json::array
static basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:18293
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:23584
nlohmann::basic_json::emplace_back
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:21934
nlohmann::basic_json::basic_json
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:18648
nlohmann::basic_json::operator>>
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:23101
nlohmann::byte_container_with_subtype::set_subtype
void set_subtype(std::uint8_t subtype) noexcept
sets the binary subtype
Definition: json.hpp:4499
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:18247
nlohmann::basic_json::clear
void clear() noexcept
clears the contents
Definition: json.hpp:21669
nlohmann::basic_json::get
BasicJsonType get() const
get special-case overload
Definition: json.hpp:19382
nlohmann::basic_json::number_float_t
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:17348
nlohmann::basic_json::m_value
json_value m_value
the value of the current element
Definition: json.hpp:23480
nlohmann::basic_json::rend
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:21177
nlohmann::basic_json::operator>
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:22964
nlohmann::basic_json::unflatten
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:24634
nlohmann::ordered_map::at
T & at(const Key &key)
Definition: json.hpp:16465
nlohmann::ordered_map::Container
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.hpp:16427
nlohmann::basic_json::is_number_float
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:19052
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:24136
nlohmann::basic_json::cbor_tag_handler_t
detail::cbor_tag_handler_t cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:16743
nlohmann::basic_json::invalid_iterator
detail::invalid_iterator invalid_iterator
exception indicating errors with iterators
Definition: json.hpp:16764
nlohmann::basic_json::is_string
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:19118
nlohmann::json_sax::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:5216
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:19638
nlohmann::basic_json::accept
static bool accept(InputType &&i, const bool ignore_comments=false)
check if the input is valid JSON
Definition: json.hpp:23261
nlohmann::basic_json::const_reference
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:16790
nlohmann::json_pointer::back
const std::string & back() const
return last reference token
Definition: json.hpp:11816
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:11610
nlohmann::basic_json::operator==
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:22643
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:18782
nlohmann::ordered_map
Definition: json.hpp:16424
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:23860
nlohmann::basic_json::front
reference front()
access the first element
Definition: json.hpp:20438
nlohmann::basic_json::operator=
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:18685
nlohmann::ordered_map::mapped_type
T mapped_type
Definition: json.hpp:16426
nlohmann::basic_json::is_null
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:18915
nlohmann
namespace for Niels Lohmann
Definition: json.hpp:82
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:19529
nlohmann::basic_json::is_primitive
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:18866
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:23782
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:19590
nlohmann::byte_container_with_subtype::has_subtype
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:4547
nlohmann::basic_json::basic_json
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:18429
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::parse
static basic_json parse(InputType &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a compatible input
Definition: json.hpp:23169
nlohmann::json_pointer
JSON Pointer.
Definition: json.hpp:11565
nlohmann::basic_json::push_back
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:21746
nlohmann::ordered_map::operator[]
T & operator[](const Key &key)
Definition: json.hpp:16455
nlohmann::basic_json::difference_type
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:16793
nlohmann::basic_json::get_allocator
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:16820
nlohmann::basic_json::begin
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:20999
nlohmann::byte_container_with_subtype::operator!=
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:4476
nlohmann::basic_json::operator!=
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:22751
nlohmann::json_pointer::empty
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:11863
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:20312
nlohmann::basic_json::max_size
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:21598
nlohmann::basic_json::basic_json
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:17987
nlohmann::anonymous_namespace{json.hpp}::from_json
constexpr const auto & from_json
Definition: json.hpp:3808
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:20896
nlohmann::basic_json::operator+=
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:21771
nlohmann::ordered_map::operator[]
const T & operator[](const Key &key) const
Definition: json.hpp:16460
nlohmann::basic_json::is_boolean
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:18937
nlohmann::basic_json::is_number_unsigned
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:19024
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:16803
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:12499
nlohmann::basic_json::parse_error
detail::parse_error parse_error
exception indicating a parse error
Definition: json.hpp:16762
nlohmann::ordered_map::ordered_map
ordered_map(std::initializer_list< T > init, const Allocator &alloc=Allocator())
Definition: json.hpp:16439
nlohmann::basic_json::external_constructor
friend struct detail::external_constructor
Definition: json.hpp:16678
nlohmann::basic_json::crend
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:21243
nlohmann::basic_json::~basic_json
~basic_json() noexcept
destructor
Definition: json.hpp:18718
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:4464
nlohmann::adl_serializer
default JSONSerializer template argument
Definition: json.hpp:4378
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:25205
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:4389
nlohmann::basic_json::size_type
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:16795
nlohmann::basic_json::basic_json
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:18559
nlohmann::basic_json::operator>=
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:23010
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:5212
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:24252
nlohmann::basic_json::insert
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:22055
nlohmann::ordered_map::count
size_type count(const Key &key) const
Definition: json.hpp:16524
nlohmann::basic_json::operator<=
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:22918
nlohmann::basic_json::exception
detail::exception exception
general exception of the basic_json class
Definition: json.hpp:16760
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:17012
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:11708
nlohmann::ordered_map::erase
size_type erase(const Key &key)
Definition: json.hpp:16491
nlohmann::json_sax::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:5214
nlohmann::basic_json::crbegin
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:21214
nlohmann::basic_json::json_serializer
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:16739
nlohmann::ordered_map::key_type
Key key_type
Definition: json.hpp:16425
nlohmann::basic_json::from_cbor
static basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:23993
nlohmann::basic_json::flatten
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:24597
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:23679
nlohmann::basic_json::type_name
const char * type_name() const noexcept
return the type as string
Definition: json.hpp:23445
nlohmann::basic_json::string_t
StringType string_t
a type for a string
Definition: json.hpp:17111
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:18190
nlohmann::basic_json::operator<<
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:23077
nlohmann::json_sax::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:5213
nlohmann::json_sax::start_array
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
nlohmann::basic_json::cbegin
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:21039
nlohmann::basic_json::input_format_t
detail::input_format_t input_format_t
Definition: json.hpp:16747
nlohmann::basic_json::object_comparator_t
std::less< StringType > object_comparator_t
Definition: json.hpp:16922
nlohmann::basic_json::find
iterator find(KeyT &&key)
find an element in a JSON object
Definition: json.hpp:20845
nlohmann::json_sax::~json_sax
virtual ~json_sax()=default
nlohmann::basic_json::back
reference back()
access the last element
Definition: json.hpp:20482
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:4454
nlohmann::basic_json::reference
value_type & reference
the type of an element reference
Definition: json.hpp:16788
nlohmann::ordered_map::find
const_iterator find(const Key &key) const
Definition: json.hpp:16548
nlohmann::basic_json::meta
static basic_json meta()
returns version information on the library
Definition: json.hpp:16852
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:18364
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:19650
nlohmann::basic_json::parser_callback_t
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:17812
nlohmann::basic_json::const_iterator
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.hpp:16808
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:11838
nlohmann::ordered_map::erase
iterator erase(iterator pos)
Definition: json.hpp:16510
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:11688
nlohmann::ordered_map::ordered_map
ordered_map(const Allocator &alloc=Allocator())
Definition: json.hpp:16435
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:18110
nlohmann::basic_json::boolean_t
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:17137
nlohmann::basic_json::basic_json
basic_json(const JsonRef &ref)
Definition: json.hpp:18532
nlohmann::basic_json::binary_t
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:17419
nlohmann::basic_json::is_discarded
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:19167
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:19432
nlohmann::basic_json::binary
static basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array (without subtype)
Definition: json.hpp:18237
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:17950
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:11642
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:11844
nlohmann::ordered_map::insert
std::pair< iterator, bool > insert(const value_type &value)
Definition: json.hpp:16565
nlohmann::basic_json::end
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:21070
nlohmann::basic_json::operator[]
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:20021
nlohmann::basic_json::out_of_range
detail::out_of_range out_of_range
exception indicating access out of the defined range
Definition: json.hpp:16768
nlohmann::json_sax::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:5215
nlohmann::basic_json
a class to store JSON values
Definition: json.hpp:16676
nlohmann::basic_json::is_number_integer
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:18996
nlohmann::json_sax::end_object
virtual bool end_object()=0
the end of an object was read
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:18227
nlohmann::basic_json::get_binary
const binary_t & get_binary() const
Definition: json.hpp:19769
nlohmann::basic_json::is_object
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:19074
nlohmann::basic_json::merge_patch
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:25166
nlohmann::byte_container_with_subtype::clear_subtype
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:4571
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:21307
nlohmann::ordered_map::find
iterator find(const Key &key)
Definition: json.hpp:16536
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:11749
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:12516
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::ordered_map::ordered_map
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition: json.hpp:16437
nlohmann::basic_json::erase
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:20549
nlohmann::byte_container_with_subtype::subtype
constexpr std::uint8_t subtype() const noexcept
return the binary subtype
Definition: json.hpp:4526
nlohmann::basic_json::rbegin
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:21140
nlohmann::basic_json::object
static basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:18337
nlohmann::anonymous_namespace{json.hpp}::to_json
constexpr const auto & to_json
Definition: json.hpp:4368
nlohmann::byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:4446
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:4450
nlohmann::basic_json::json_pointer
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:16737
nlohmann::basic_json::array_t
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:17058
nlohmann::basic_json::type
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:18835
nlohmann::json_pointer::json_pointer
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.hpp:11592
nlohmann::basic_json::get_ref
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:19684
nlohmann::basic_json::iterator
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.hpp:16806
nlohmann::basic_json::basic_json
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:17853
nlohmann::json_pointer::pop_back
void pop_back()
remove last reference token
Definition: json.hpp:11792
nlohmann::basic_json::cend
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:21110
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:19603
nlohmann::basic_json::get_ref
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:19697
nlohmann::basic_json::number_unsigned_t
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:17280
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:19483
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:11666
nlohmann::basic_json::is_structured
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:18893
nlohmann::json_pointer::parent_pointer
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:11767
nlohmann::basic_json::update
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:22290
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, const bool ignore_comments=false)
generate SAX events
Definition: json.hpp:23324
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:11729
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:24991
nlohmann::basic_json::swap
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:22392
nlohmann::basic_json::push_back
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:21886
nlohmann::ordered_map::emplace
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition: json.hpp:16442
nlohmann::basic_json::is_number
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:18967
nlohmann::json
basic_json<> json
default JSON class
Definition: json.hpp:2940
nlohmann::basic_json::items
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:21389
nlohmann::json_sax
SAX interface.
Definition: json.hpp:5211
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:4458
nlohmann::basic_json::get_binary
binary_t & get_binary()
Definition: json.hpp:19758
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:4406
nlohmann::basic_json::at
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:19816
nlohmann::byte_container_with_subtype
an internal type for a backed binary type
Definition: json.hpp:4441
nlohmann::basic_json::operator<
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:22804
nlohmann::basic_json::is_binary
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:19140
nlohmann::ordered_map::at
const T & at(const Key &key) const
Definition: json.hpp:16478
nlohmann::basic_json::from_cbor
static basic_json from_cbor(const T *ptr, std::size_t len, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition: json.hpp:24025
nlohmann::basic_json::empty
bool empty() const noexcept
checks whether the container is empty.
Definition: json.hpp:21454
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:16810
nlohmann::basic_json::is_array
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:19096
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:21987
nlohmann::basic_json::type_error
detail::type_error type_error
exception indicating executing a member function with a wrong type
Definition: json.hpp:16766
nlohmann::basic_json::size
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:21527
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:24365
nlohmann::basic_json::contains
bool contains(KeyT &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:20929
nlohmann::basic_json::get
basic_json get() const
get special-case overload
Definition: json.hpp:19359
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:16812
nlohmann::basic_json::other_error
detail::other_error other_error
exception indicating other library errors
Definition: json.hpp:16770
nlohmann::basic_json::allocator_type
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:16798
nlohmann::byte_container_with_subtype::container_type
BinaryType container_type
the type of the underlying container
Definition: json.hpp:4444