JSON for Modern C++ 3.8.0

json.hpp
1 /*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.8.0
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
6
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
17
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29
30 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
31 #define INCLUDE_NLOHMANN_JSON_HPP_
32
33 #define NLOHMANN_JSON_VERSION_MAJOR 3
34 #define NLOHMANN_JSON_VERSION_MINOR 8
35 #define NLOHMANN_JSON_VERSION_PATCH 0
36
37 #include <algorithm> // all_of, find, for_each
38 #include <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
2108 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2109 template<typename BasicJsonType> \
2110 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2111 { \
2112 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2113 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2114 auto it = std::find_if(std::begin(m), std::end(m), \
2115 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2116 { \
2117 return ej_pair.first == e; \
2118 }); \
2119 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2120 } \
2121 template<typename BasicJsonType> \
2122 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2123 { \
2124 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2125 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2126 auto it = std::find_if(std::begin(m), std::end(m), \
2127 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2128 { \
2129 return ej_pair.second == j; \
2130 }); \
2131 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2132 }
2133
2134 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2135 // may be removed in the future once the class is split.
2136
2137 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2138 template<template<typename, typename, typename...> class ObjectType, \
2139 template<typename, typename...> class ArrayType, \
2140 class StringType, class BooleanType, class NumberIntegerType, \
2141 class NumberUnsignedType, class NumberFloatType, \
2142 template<typename> class AllocatorType, \
2143 template<typename, typename = void> class JSONSerializer, \
2144 class BinaryType>
2145
2146 #define NLOHMANN_BASIC_JSON_TPL \
2147 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2148 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2149 AllocatorType, JSONSerializer, BinaryType>
2150
2151 // Macros to simplify conversion from/to types
2152
2153 #define NLOHMANN_JSON_EXPAND( x ) x
2154 #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
2155 #define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2156 NLOHMANN_JSON_PASTE64, \
2157 NLOHMANN_JSON_PASTE63, \
2158 NLOHMANN_JSON_PASTE62, \
2159 NLOHMANN_JSON_PASTE61, \
2160 NLOHMANN_JSON_PASTE60, \
2161 NLOHMANN_JSON_PASTE59, \
2162 NLOHMANN_JSON_PASTE58, \
2163 NLOHMANN_JSON_PASTE57, \
2164 NLOHMANN_JSON_PASTE56, \
2165 NLOHMANN_JSON_PASTE55, \
2166 NLOHMANN_JSON_PASTE54, \
2167 NLOHMANN_JSON_PASTE53, \
2168 NLOHMANN_JSON_PASTE52, \
2169 NLOHMANN_JSON_PASTE51, \
2170 NLOHMANN_JSON_PASTE50, \
2171 NLOHMANN_JSON_PASTE49, \
2172 NLOHMANN_JSON_PASTE48, \
2173 NLOHMANN_JSON_PASTE47, \
2174 NLOHMANN_JSON_PASTE46, \
2175 NLOHMANN_JSON_PASTE45, \
2176 NLOHMANN_JSON_PASTE44, \
2177 NLOHMANN_JSON_PASTE43, \
2178 NLOHMANN_JSON_PASTE42, \
2179 NLOHMANN_JSON_PASTE41, \
2180 NLOHMANN_JSON_PASTE40, \
2181 NLOHMANN_JSON_PASTE39, \
2182 NLOHMANN_JSON_PASTE38, \
2183 NLOHMANN_JSON_PASTE37, \
2184 NLOHMANN_JSON_PASTE36, \
2185 NLOHMANN_JSON_PASTE35, \
2186 NLOHMANN_JSON_PASTE34, \
2187 NLOHMANN_JSON_PASTE33, \
2188 NLOHMANN_JSON_PASTE32, \
2189 NLOHMANN_JSON_PASTE31, \
2190 NLOHMANN_JSON_PASTE30, \
2191 NLOHMANN_JSON_PASTE29, \
2192 NLOHMANN_JSON_PASTE28, \
2193 NLOHMANN_JSON_PASTE27, \
2194 NLOHMANN_JSON_PASTE26, \
2195 NLOHMANN_JSON_PASTE25, \
2196 NLOHMANN_JSON_PASTE24, \
2197 NLOHMANN_JSON_PASTE23, \
2198 NLOHMANN_JSON_PASTE22, \
2199 NLOHMANN_JSON_PASTE21, \
2200 NLOHMANN_JSON_PASTE20, \
2201 NLOHMANN_JSON_PASTE19, \
2202 NLOHMANN_JSON_PASTE18, \
2203 NLOHMANN_JSON_PASTE17, \
2204 NLOHMANN_JSON_PASTE16, \
2205 NLOHMANN_JSON_PASTE15, \
2206 NLOHMANN_JSON_PASTE14, \
2207 NLOHMANN_JSON_PASTE13, \
2208 NLOHMANN_JSON_PASTE12, \
2209 NLOHMANN_JSON_PASTE11, \
2210 NLOHMANN_JSON_PASTE10, \
2211 NLOHMANN_JSON_PASTE9, \
2212 NLOHMANN_JSON_PASTE8, \
2213 NLOHMANN_JSON_PASTE7, \
2214 NLOHMANN_JSON_PASTE6, \
2215 NLOHMANN_JSON_PASTE5, \
2216 NLOHMANN_JSON_PASTE4, \
2217 NLOHMANN_JSON_PASTE3, \
2218 NLOHMANN_JSON_PASTE2, \
2219 NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2220 #define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2221 #define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2222 #define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2223 #define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2224 #define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2225 #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)
2226 #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)
2227 #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)
2228 #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)
2229 #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)
2230 #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)
2231 #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)
2232 #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)
2233 #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)
2234 #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)
2235 #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)
2236 #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)
2237 #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)
2238 #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)
2239 #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)
2240 #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)
2241 #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)
2242 #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)
2243 #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)
2244 #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)
2245 #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)
2246 #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)
2247 #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)
2248 #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)
2249 #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)
2250 #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)
2251 #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)
2252 #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)
2253 #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)
2254 #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)
2255 #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)
2256 #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)
2257 #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)
2258 #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)
2259 #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)
2260 #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)
2261 #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)
2262 #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)
2263 #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)
2264 #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)
2265 #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)
2266 #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)
2267 #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)
2268 #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)
2269 #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)
2270 #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)
2271 #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)
2272 #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)
2273 #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)
2274 #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)
2275 #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)
2276 #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)
2277 #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)
2278 #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)
2279 #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)
2280 #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)
2281 #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)
2282 #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)
2283
2284 #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2285 #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2286
2292 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2293 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__)) } \
2294 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__)) }
2295
2301 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2302 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__)) } \
2303 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__)) }
2304
2305 #ifndef JSON_USE_IMPLICIT_CONVERSIONS
2306 #define JSON_USE_IMPLICIT_CONVERSIONS 1
2307 #endif
2308
2309 #if JSON_USE_IMPLICIT_CONVERSIONS
2310 #define JSON_EXPLICIT
2311 #else
2312 #define JSON_EXPLICIT explicit
2313 #endif
2314
2315
2316 namespace nlohmann
2317 {
2318 namespace detail
2319 {
2321 // exceptions //
2323
2352 class exception : public std::exception
2353 {
2354 public:
2356
2357 const char* what() const noexcept override
2358 {
2359 return m.what();
2360 }
2361
2363 const int id;
2364
2365 protected:
2366 JSON_HEDLEY_NON_NULL(3)
2367 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
2368
2369 static std::string name(const std::string& ename, int id_)
2370 {
2371 return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2372 }
2373
2374 private:
2376 std::runtime_error m;
2377 };
2378
2424 class parse_error : public exception
2425 {
2426 public:
2436 static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
2437 {
2438 std::string w = exception::name("parse_error", id_) + "parse error" +
2439 position_string(pos) + ": " + what_arg;
2440 return parse_error(id_, pos.chars_read_total, w.c_str());
2441 }
2442
2443 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
2444 {
2445 std::string w = exception::name("parse_error", id_) + "parse error" +
2446 (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2447 ": " + what_arg;
2448 return parse_error(id_, byte_, w.c_str());
2449 }
2450
2460 const std::size_t byte;
2461
2462 private:
2463 parse_error(int id_, std::size_t byte_, const char* what_arg)
2464 : exception(id_, what_arg), byte(byte_) {}
2465
2466 static std::string position_string(const position_t& pos)
2467 {
2468 return " at line " + std::to_string(pos.lines_read + 1) +
2469 ", column " + std::to_string(pos.chars_read_current_line);
2470 }
2471 };
2472
2510 class invalid_iterator : public exception
2511 {
2512 public:
2513 static invalid_iterator create(int id_, const std::string& what_arg)
2514 {
2515 std::string w = exception::name("invalid_iterator", id_) + what_arg;
2516 return invalid_iterator(id_, w.c_str());
2517 }
2518
2519 private:
2520 JSON_HEDLEY_NON_NULL(3)
2521 invalid_iterator(int id_, const char* what_arg)
2522 : exception(id_, what_arg) {}
2523 };
2524
2564 class type_error : public exception
2565 {
2566 public:
2567 static type_error create(int id_, const std::string& what_arg)
2568 {
2569 std::string w = exception::name("type_error", id_) + what_arg;
2570 return type_error(id_, w.c_str());
2571 }
2572
2573 private:
2574 JSON_HEDLEY_NON_NULL(3)
2575 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2576 };
2577
2611 class out_of_range : public exception
2612 {
2613 public:
2614 static out_of_range create(int id_, const std::string& what_arg)
2615 {
2616 std::string w = exception::name("out_of_range", id_) + what_arg;
2617 return out_of_range(id_, w.c_str());
2618 }
2619
2620 private:
2621 JSON_HEDLEY_NON_NULL(3)
2622 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
2623 };
2624
2649 class other_error : public exception
2650 {
2651 public:
2652 static other_error create(int id_, const std::string& what_arg)
2653 {
2654 std::string w = exception::name("other_error", id_) + what_arg;
2655 return other_error(id_, w.c_str());
2656 }
2657
2658 private:
2659 JSON_HEDLEY_NON_NULL(3)
2660 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2661 };
2662 } // namespace detail
2663 } // namespace nlohmann
2664
2665 // #include <nlohmann/detail/macro_scope.hpp>
2666
2667 // #include <nlohmann/detail/meta/cpp_future.hpp>
2668
2669
2670 #include <cstddef> // size_t
2671 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
2672
2673 namespace nlohmann
2674 {
2675 namespace detail
2676 {
2677 // alias templates to reduce boilerplate
2678 template<bool B, typename T = void>
2679 using enable_if_t = typename std::enable_if<B, T>::type;
2680
2681 template<typename T>
2682 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
2683
2684 // implementation of C++14 index_sequence and affiliates
2685 // source: https://stackoverflow.com/a/32223343
2686 template<std::size_t... Ints>
2687 struct index_sequence
2688 {
2689 using type = index_sequence;
2690 using value_type = std::size_t;
2691 static constexpr std::size_t size() noexcept
2692 {
2693 return sizeof...(Ints);
2694 }
2695 };
2696
2697 template<class Sequence1, class Sequence2>
2698 struct merge_and_renumber;
2699
2700 template<std::size_t... I1, std::size_t... I2>
2701 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
2702 : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
2703
2704 template<std::size_t N>
2705 struct make_index_sequence
2706 : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
2707 typename make_index_sequence < N - N / 2 >::type > {};
2708
2709 template<> struct make_index_sequence<0> : index_sequence<> {};
2710 template<> struct make_index_sequence<1> : index_sequence<0> {};
2711
2712 template<typename... Ts>
2713 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
2714
2715 // dispatch utility (taken from ranges-v3)
2716 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
2717 template<> struct priority_tag<0> {};
2718
2719 // taken from ranges-v3
2720 template<typename T>
2721 struct static_const
2722 {
2723 static constexpr T value{};
2724 };
2725
2726 template<typename T>
2727 constexpr T static_const<T>::value;
2728 } // namespace detail
2729 } // namespace nlohmann
2730
2731 // #include <nlohmann/detail/meta/type_traits.hpp>
2732
2733
2734 #include <limits> // numeric_limits
2735 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
2736 #include <utility> // declval
2737
2738 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
2739
2740
2741 #include <iterator> // random_access_iterator_tag
2742
2743 // #include <nlohmann/detail/meta/void_t.hpp>
2744
2745
2746 namespace nlohmann
2747 {
2748 namespace detail
2749 {
2750 template<typename ...Ts> struct make_void
2751 {
2752 using type = void;
2753 };
2754 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
2755 } // namespace detail
2756 } // namespace nlohmann
2757
2758 // #include <nlohmann/detail/meta/cpp_future.hpp>
2759
2760
2761 namespace nlohmann
2762 {
2763 namespace detail
2764 {
2765 template<typename It, typename = void>
2766 struct iterator_types {};
2767
2768 template<typename It>
2769 struct iterator_types <
2770 It,
2771 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
2772 typename It::reference, typename It::iterator_category >>
2773 {
2774 using difference_type = typename It::difference_type;
2775 using value_type = typename It::value_type;
2776 using pointer = typename It::pointer;
2777 using reference = typename It::reference;
2778 using iterator_category = typename It::iterator_category;
2779 };
2780
2781 // This is required as some compilers implement std::iterator_traits in a way that
2782 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
2783 template<typename T, typename = void>
2784 struct iterator_traits
2785 {
2786 };
2787
2788 template<typename T>
2789 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
2790 : iterator_types<T>
2791 {
2792 };
2793
2794 template<typename T>
2795 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
2796 {
2797 using iterator_category = std::random_access_iterator_tag;
2798 using value_type = T;
2799 using difference_type = ptrdiff_t;
2800 using pointer = T*;
2801 using reference = T&;
2802 };
2803 } // namespace detail
2804 } // namespace nlohmann
2805
2806 // #include <nlohmann/detail/macro_scope.hpp>
2807
2808 // #include <nlohmann/detail/meta/cpp_future.hpp>
2809
2810 // #include <nlohmann/detail/meta/detected.hpp>
2811
2812
2813 #include <type_traits>
2814
2815 // #include <nlohmann/detail/meta/void_t.hpp>
2816
2817
2818 // https://en.cppreference.com/w/cpp/experimental/is_detected
2819 namespace nlohmann
2820 {
2821 namespace detail
2822 {
2823 struct nonesuch
2824 {
2825 nonesuch() = delete;
2826 ~nonesuch() = delete;
2827 nonesuch(nonesuch const&) = delete;
2828 nonesuch(nonesuch const&&) = delete;
2829 void operator=(nonesuch const&) = delete;
2830 void operator=(nonesuch&&) = delete;
2831 };
2832
2833 template<class Default,
2834 class AlwaysVoid,
2835 template<class...> class Op,
2836 class... Args>
2837 struct detector
2838 {
2839 using value_t = std::false_type;
2840 using type = Default;
2841 };
2842
2843 template<class Default, template<class...> class Op, class... Args>
2844 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2845 {
2846 using value_t = std::true_type;
2847 using type = Op<Args...>;
2848 };
2849
2850 template<template<class...> class Op, class... Args>
2851 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2852
2853 template<template<class...> class Op, class... Args>
2854 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2855
2856 template<class Default, template<class...> class Op, class... Args>
2857 using detected_or = detector<Default, void, Op, Args...>;
2858
2859 template<class Default, template<class...> class Op, class... Args>
2860 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2861
2862 template<class Expected, template<class...> class Op, class... Args>
2863 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2864
2865 template<class To, template<class...> class Op, class... Args>
2866 using is_detected_convertible =
2867 std::is_convertible<detected_t<Op, Args...>, To>;
2868 } // namespace detail
2869 } // namespace nlohmann
2870
2871 // #include <nlohmann/json_fwd.hpp>
2872 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
2873 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
2874
2875 #include <cstdint> // int64_t, uint64_t
2876 #include <map> // map
2877 #include <memory> // allocator
2878 #include <string> // string
2879 #include <vector> // vector
2880
2886 namespace nlohmann
2887 {
2895 template<typename T = void, typename SFINAE = void>
2896 struct adl_serializer;
2897
2898 template<template<typename U, typename V, typename... Args> class ObjectType =
2899 std::map,
2900 template<typename U, typename... Args> class ArrayType = std::vector,
2901 class StringType = std::string, class BooleanType = bool,
2902 class NumberIntegerType = std::int64_t,
2903 class NumberUnsignedType = std::uint64_t,
2904 class NumberFloatType = double,
2905 template<typename U> class AllocatorType = std::allocator,
2906 template<typename T, typename SFINAE = void> class JSONSerializer =
2907 adl_serializer,
2908 class BinaryType = std::vector<std::uint8_t>>
2909 class basic_json;
2910
2922 template<typename BasicJsonType>
2923 class json_pointer;
2924
2933 using json = basic_json<>;
2934
2935 template<class Key, class T, class IgnoredLess, class Allocator>
2936 struct ordered_map;
2937
2945 using ordered_json = basic_json<nlohmann::ordered_map>;
2946
2947 } // namespace nlohmann
2948
2949 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
2950
2951
2952 namespace nlohmann
2953 {
2962 namespace detail
2963 {
2965 // helpers //
2967
2968 // Note to maintainers:
2969 //
2970 // Every trait in this file expects a non CV-qualified type.
2971 // The only exceptions are in the 'aliases for detected' section
2972 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
2973 //
2974 // In this case, T has to be properly CV-qualified to constraint the function arguments
2975 // (e.g. to_json(BasicJsonType&, const T&))
2976
2977 template<typename> struct is_basic_json : std::false_type {};
2978
2979 NLOHMANN_BASIC_JSON_TPL_DECLARATION
2980 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
2981
2983 // json_ref helpers //
2985
2986 template<typename>
2987 class json_ref;
2988
2989 template<typename>
2990 struct is_json_ref : std::false_type {};
2991
2992 template<typename T>
2993 struct is_json_ref<json_ref<T>> : std::true_type {};
2994
2996 // aliases for detected //
2998
2999 template<typename T>
3000 using mapped_type_t = typename T::mapped_type;
3001
3002 template<typename T>
3003 using key_type_t = typename T::key_type;
3004
3005 template<typename T>
3006 using value_type_t = typename T::value_type;
3007
3008 template<typename T>
3009 using difference_type_t = typename T::difference_type;
3010
3011 template<typename T>
3012 using pointer_t = typename T::pointer;
3013
3014 template<typename T>
3015 using reference_t = typename T::reference;
3016
3017 template<typename T>
3018 using iterator_category_t = typename T::iterator_category;
3019
3020 template<typename T>
3021 using iterator_t = typename T::iterator;
3022
3023 template<typename T, typename... Args>
3024 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3025
3026 template<typename T, typename... Args>
3027 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3028
3029 template<typename T, typename U>
3030 using get_template_function = decltype(std::declval<T>().template get<U>());
3031
3032 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3033 template<typename BasicJsonType, typename T, typename = void>
3034 struct has_from_json : std::false_type {};
3035
3036 // trait checking if j.get<T> is valid
3037 // use this trait instead of std::is_constructible or std::is_convertible,
3038 // both rely on, or make use of implicit conversions, and thus fail when T
3039 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3040 template <typename BasicJsonType, typename T>
3041 struct is_getable
3042 {
3043 static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
3044 };
3045
3046 template<typename BasicJsonType, typename T>
3047 struct has_from_json < BasicJsonType, T,
3048 enable_if_t < !is_basic_json<T>::value >>
3049 {
3050 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3051
3052 static constexpr bool value =
3053 is_detected_exact<void, from_json_function, serializer,
3054 const BasicJsonType&, T&>::value;
3055 };
3056
3057 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3058 // this overload is used for non-default-constructible user-defined-types
3059 template<typename BasicJsonType, typename T, typename = void>
3060 struct has_non_default_from_json : std::false_type {};
3061
3062 template<typename BasicJsonType, typename T>
3063 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3064 {
3065 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3066
3067 static constexpr bool value =
3068 is_detected_exact<T, from_json_function, serializer,
3069 const BasicJsonType&>::value;
3070 };
3071
3072 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3073 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3074 template<typename BasicJsonType, typename T, typename = void>
3075 struct has_to_json : std::false_type {};
3076
3077 template<typename BasicJsonType, typename T>
3078 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3079 {
3080 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3081
3082 static constexpr bool value =
3083 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3084 T>::value;
3085 };
3086
3087
3089 // is_ functions //
3091
3092 template<typename T, typename = void>
3093 struct is_iterator_traits : std::false_type {};
3094
3095 template<typename T>
3096 struct is_iterator_traits<iterator_traits<T>>
3097 {
3098 private:
3099 using traits = iterator_traits<T>;
3100
3101 public:
3102 static constexpr auto value =
3103 is_detected<value_type_t, traits>::value &&
3104 is_detected<difference_type_t, traits>::value &&
3105 is_detected<pointer_t, traits>::value &&
3106 is_detected<iterator_category_t, traits>::value &&
3107 is_detected<reference_t, traits>::value;
3108 };
3109
3110 // source: https://stackoverflow.com/a/37193089/4116453
3111
3112 template<typename T, typename = void>
3113 struct is_complete_type : std::false_type {};
3114
3115 template<typename T>
3116 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3117
3118 template<typename BasicJsonType, typename CompatibleObjectType,
3119 typename = void>
3120 struct is_compatible_object_type_impl : std::false_type {};
3121
3122 template<typename BasicJsonType, typename CompatibleObjectType>
3123 struct is_compatible_object_type_impl <
3124 BasicJsonType, CompatibleObjectType,
3125 enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3126 is_detected<key_type_t, CompatibleObjectType>::value >>
3127 {
3128
3129 using object_t = typename BasicJsonType::object_t;
3130
3131 // macOS's is_constructible does not play well with nonesuch...
3132 static constexpr bool value =
3133 std::is_constructible<typename object_t::key_type,
3134 typename CompatibleObjectType::key_type>::value &&
3135 std::is_constructible<typename object_t::mapped_type,
3136 typename CompatibleObjectType::mapped_type>::value;
3137 };
3138
3139 template<typename BasicJsonType, typename CompatibleObjectType>
3140 struct is_compatible_object_type
3141 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3142
3143 template<typename BasicJsonType, typename ConstructibleObjectType,
3144 typename = void>
3145 struct is_constructible_object_type_impl : std::false_type {};
3146
3147 template<typename BasicJsonType, typename ConstructibleObjectType>
3148 struct is_constructible_object_type_impl <
3149 BasicJsonType, ConstructibleObjectType,
3150 enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3151 is_detected<key_type_t, ConstructibleObjectType>::value >>
3152 {
3153 using object_t = typename BasicJsonType::object_t;
3154
3155 static constexpr bool value =
3156 (std::is_default_constructible<ConstructibleObjectType>::value &&
3157 (std::is_move_assignable<ConstructibleObjectType>::value ||
3158 std::is_copy_assignable<ConstructibleObjectType>::value) &&
3159 (std::is_constructible<typename ConstructibleObjectType::key_type,
3160 typename object_t::key_type>::value &&
3161 std::is_same <
3162 typename object_t::mapped_type,
3163 typename ConstructibleObjectType::mapped_type >::value)) ||
3164 (has_from_json<BasicJsonType,
3165 typename ConstructibleObjectType::mapped_type>::value ||
3166 has_non_default_from_json <
3167 BasicJsonType,
3168 typename ConstructibleObjectType::mapped_type >::value);
3169 };
3170
3171 template<typename BasicJsonType, typename ConstructibleObjectType>
3172 struct is_constructible_object_type
3173 : is_constructible_object_type_impl<BasicJsonType,
3174 ConstructibleObjectType> {};
3175
3176 template<typename BasicJsonType, typename CompatibleStringType,
3177 typename = void>
3178 struct is_compatible_string_type_impl : std::false_type {};
3179
3180 template<typename BasicJsonType, typename CompatibleStringType>
3181 struct is_compatible_string_type_impl <
3182 BasicJsonType, CompatibleStringType,
3183 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3184 value_type_t, CompatibleStringType>::value >>
3185 {
3186 static constexpr auto value =
3187 std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
3188 };
3189
3190 template<typename BasicJsonType, typename ConstructibleStringType>
3191 struct is_compatible_string_type
3192 : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3193
3194 template<typename BasicJsonType, typename ConstructibleStringType,
3195 typename = void>
3196 struct is_constructible_string_type_impl : std::false_type {};
3197
3198 template<typename BasicJsonType, typename ConstructibleStringType>
3199 struct is_constructible_string_type_impl <
3200 BasicJsonType, ConstructibleStringType,
3201 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3202 value_type_t, ConstructibleStringType>::value >>
3203 {
3204 static constexpr auto value =
3205 std::is_constructible<ConstructibleStringType,
3206 typename BasicJsonType::string_t>::value;
3207 };
3208
3209 template<typename BasicJsonType, typename ConstructibleStringType>
3210 struct is_constructible_string_type
3211 : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3212
3213 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3214 struct is_compatible_array_type_impl : std::false_type {};
3215
3216 template<typename BasicJsonType, typename CompatibleArrayType>
3217 struct is_compatible_array_type_impl <
3218 BasicJsonType, CompatibleArrayType,
3219 enable_if_t < is_detected<value_type_t, CompatibleArrayType>::value&&
3220 is_detected<iterator_t, CompatibleArrayType>::value&&
3221 // This is needed because json_reverse_iterator has a ::iterator type...
3222 // Therefore it is detected as a CompatibleArrayType.
3223 // The real fix would be to have an Iterable concept.
3224 !is_iterator_traits <
3225 iterator_traits<CompatibleArrayType >>::value >>
3226 {
3227 static constexpr bool value =
3228 std::is_constructible<BasicJsonType,
3229 typename CompatibleArrayType::value_type>::value;
3230 };
3231
3232 template<typename BasicJsonType, typename CompatibleArrayType>
3233 struct is_compatible_array_type
3234 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3235
3236 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3237 struct is_constructible_array_type_impl : std::false_type {};
3238
3239 template<typename BasicJsonType, typename ConstructibleArrayType>
3240 struct is_constructible_array_type_impl <
3241 BasicJsonType, ConstructibleArrayType,
3242 enable_if_t<std::is_same<ConstructibleArrayType,
3243 typename BasicJsonType::value_type>::value >>
3244 : std::true_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::is_default_constructible<ConstructibleArrayType>::value&&
3252 (std::is_move_assignable<ConstructibleArrayType>::value ||
3253 std::is_copy_assignable<ConstructibleArrayType>::value)&&
3254 is_detected<value_type_t, ConstructibleArrayType>::value&&
3255 is_detected<iterator_t, ConstructibleArrayType>::value&&
3256 is_complete_type <
3257 detected_t<value_type_t, ConstructibleArrayType >>::value >>
3258 {
3259 static constexpr bool value =
3260 // This is needed because json_reverse_iterator has a ::iterator type,
3261 // furthermore, std::back_insert_iterator (and other iterators) have a
3262 // base class `iterator`... Therefore it is detected as a
3263 // ConstructibleArrayType. The real fix would be to have an Iterable
3264 // concept.
3265 !is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value &&
3266
3267 (std::is_same<typename ConstructibleArrayType::value_type,
3268 typename BasicJsonType::array_t::value_type>::value ||
3269 has_from_json<BasicJsonType,
3270 typename ConstructibleArrayType::value_type>::value ||
3271 has_non_default_from_json <
3272 BasicJsonType, typename ConstructibleArrayType::value_type >::value);
3273 };
3274
3275 template<typename BasicJsonType, typename ConstructibleArrayType>
3276 struct is_constructible_array_type
3277 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3278
3279 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3280 typename = void>
3281 struct is_compatible_integer_type_impl : std::false_type {};
3282
3283 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3284 struct is_compatible_integer_type_impl <
3285 RealIntegerType, CompatibleNumberIntegerType,
3286 enable_if_t < std::is_integral<RealIntegerType>::value&&
3287 std::is_integral<CompatibleNumberIntegerType>::value&&
3288 !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3289 {
3290 // is there an assert somewhere on overflows?
3291 using RealLimits = std::numeric_limits<RealIntegerType>;
3292 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3293
3294 static constexpr auto value =
3295 std::is_constructible<RealIntegerType,
3296 CompatibleNumberIntegerType>::value &&
3297 CompatibleLimits::is_integer &&
3298 RealLimits::is_signed == CompatibleLimits::is_signed;
3299 };
3300
3301 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3302 struct is_compatible_integer_type
3303 : is_compatible_integer_type_impl<RealIntegerType,
3304 CompatibleNumberIntegerType> {};
3305
3306 template<typename BasicJsonType, typename CompatibleType, typename = void>
3307 struct is_compatible_type_impl: std::false_type {};
3308
3309 template<typename BasicJsonType, typename CompatibleType>
3310 struct is_compatible_type_impl <
3311 BasicJsonType, CompatibleType,
3312 enable_if_t<is_complete_type<CompatibleType>::value >>
3313 {
3314 static constexpr bool value =
3315 has_to_json<BasicJsonType, CompatibleType>::value;
3316 };
3317
3318 template<typename BasicJsonType, typename CompatibleType>
3319 struct is_compatible_type
3320 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3321
3322 // https://en.cppreference.com/w/cpp/types/conjunction
3323 template<class...> struct conjunction : std::true_type { };
3324 template<class B1> struct conjunction<B1> : B1 { };
3325 template<class B1, class... Bn>
3326 struct conjunction<B1, Bn...>
3327 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3328
3329 template<typename T1, typename T2>
3330 struct is_constructible_tuple : std::false_type {};
3331
3332 template<typename T1, typename... Args>
3333 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<std::is_constructible<T1, Args>...> {};
3334 } // namespace detail
3335 } // namespace nlohmann
3336
3337 // #include <nlohmann/detail/value_t.hpp>
3338
3339
3340 #include <array> // array
3341 #include <cstddef> // size_t
3342 #include <cstdint> // uint8_t
3343 #include <string> // string
3344
3345 namespace nlohmann
3346 {
3347 namespace detail
3348 {
3350 // JSON type enumeration //
3352
3377 enum class value_t : std::uint8_t
3378 {
3379 null,
3380 object,
3381 array,
3382 string,
3383 boolean,
3384 number_integer,
3385 number_unsigned,
3386 number_float,
3387 binary,
3388 discarded
3389 };
3390
3404 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
3405 {
3406 static constexpr std::array<std::uint8_t, 9> order = {{
3407 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
3408 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
3409 6 /* binary */
3410 }
3411 };
3412
3413 const auto l_index = static_cast<std::size_t>(lhs);
3414 const auto r_index = static_cast<std::size_t>(rhs);
3415 return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
3416 }
3417 } // namespace detail
3418 } // namespace nlohmann
3419
3420
3421 namespace nlohmann
3422 {
3423 namespace detail
3424 {
3425 template<typename BasicJsonType>
3426 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3427 {
3428 if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
3429 {
3430 JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
3431 }
3432 n = nullptr;
3433 }
3434
3435 // overloads for basic_json template parameters
3436 template < typename BasicJsonType, typename ArithmeticType,
3437 enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
3438 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3439 int > = 0 >
3440 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3441 {
3442 switch (static_cast<value_t>(j))
3443 {
3444 case value_t::number_unsigned:
3445 {
3446 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3447 break;
3448 }
3449 case value_t::number_integer:
3450 {
3451 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3452 break;
3453 }
3454 case value_t::number_float:
3455 {
3456 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3457 break;
3458 }
3459
3460 default:
3461 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
3462 }
3463 }
3464
3465 template<typename BasicJsonType>
3466 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
3467 {
3468 if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
3469 {
3470 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
3471 }
3472 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
3473 }
3474
3475 template<typename BasicJsonType>
3476 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
3477 {
3478 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3479 {
3480 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
3481 }
3482 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3483 }
3484
3485 template <
3486 typename BasicJsonType, typename ConstructibleStringType,
3487 enable_if_t <
3488 is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&
3489 !std::is_same<typename BasicJsonType::string_t,
3490 ConstructibleStringType>::value,
3491 int > = 0 >
3492 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
3493 {
3494 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3495 {
3496 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
3497 }
3498
3499 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3500 }
3501
3502 template<typename BasicJsonType>
3503 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
3504 {
3505 get_arithmetic_value(j, val);
3506 }
3507
3508 template<typename BasicJsonType>
3509 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
3510 {
3511 get_arithmetic_value(j, val);
3512 }
3513
3514 template<typename BasicJsonType>
3515 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
3516 {
3517 get_arithmetic_value(j, val);
3518 }
3519
3520 template<typename BasicJsonType, typename EnumType,
3521 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
3522 void from_json(const BasicJsonType& j, EnumType& e)
3523 {
3524 typename std::underlying_type<EnumType>::type val;
3525 get_arithmetic_value(j, val);
3526 e = static_cast<EnumType>(val);
3527 }
3528
3529 // forward_list doesn't have an insert method
3530 template<typename BasicJsonType, typename T, typename Allocator,
3531 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
3532 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
3533 {
3534 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3535 {
3536 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3537 }
3538 l.clear();
3539 std::transform(j.rbegin(), j.rend(),
3540 std::front_inserter(l), [](const BasicJsonType & i)
3541 {
3542 return i.template get<T>();
3543 });
3544 }
3545
3546 // valarray doesn't have an insert method
3547 template<typename BasicJsonType, typename T,
3548 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
3549 void from_json(const BasicJsonType& j, std::valarray<T>& l)
3550 {
3551 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3552 {
3553 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3554 }
3555 l.resize(j.size());
3556 std::transform(j.begin(), j.end(), std::begin(l),
3557 [](const BasicJsonType & elem)
3558 {
3559 return elem.template get<T>();
3560 });
3561 }
3562
3563 template<typename BasicJsonType, typename T, std::size_t N>
3564 auto from_json(const BasicJsonType& j, T (&arr)[N])
3565 -> decltype(j.template get<T>(), void())
3566 {
3567 for (std::size_t i = 0; i < N; ++i)
3568 {
3569 arr[i] = j.at(i).template get<T>();
3570 }
3571 }
3572
3573 template<typename BasicJsonType>
3574 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
3575 {
3576 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
3577 }
3578
3579 template<typename BasicJsonType, typename T, std::size_t N>
3580 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
3581 priority_tag<2> /*unused*/)
3582 -> decltype(j.template get<T>(), void())
3583 {
3584 for (std::size_t i = 0; i < N; ++i)
3585 {
3586 arr[i] = j.at(i).template get<T>();
3587 }
3588 }
3589
3590 template<typename BasicJsonType, typename ConstructibleArrayType>
3591 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
3592 -> decltype(
3593 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
3594 j.template get<typename ConstructibleArrayType::value_type>(),
3595 void())
3596 {
3597 using std::end;
3598
3599 ConstructibleArrayType ret;
3600 ret.reserve(j.size());
3601 std::transform(j.begin(), j.end(),
3602 std::inserter(ret, end(ret)), [](const BasicJsonType & i)
3603 {
3604 // get<BasicJsonType>() returns *this, this won't call a from_json
3605 // method when value_type is BasicJsonType
3606 return i.template get<typename ConstructibleArrayType::value_type>();
3607 });
3608 arr = std::move(ret);
3609 }
3610
3611 template<typename BasicJsonType, typename ConstructibleArrayType>
3612 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
3613 priority_tag<0> /*unused*/)
3614 {
3615 using std::end;
3616
3617 ConstructibleArrayType ret;
3618 std::transform(
3619 j.begin(), j.end(), std::inserter(ret, end(ret)),
3620 [](const BasicJsonType & i)
3621 {
3622 // get<BasicJsonType>() returns *this, this won't call a from_json
3623 // method when value_type is BasicJsonType
3624 return i.template get<typename ConstructibleArrayType::value_type>();
3625 });
3626 arr = std::move(ret);
3627 }
3628
3629 template < typename BasicJsonType, typename ConstructibleArrayType,
3630 enable_if_t <
3631 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
3632 !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
3633 !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3634 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
3635 !is_basic_json<ConstructibleArrayType>::value,
3636 int > = 0 >
3637 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
3638 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
3639 j.template get<typename ConstructibleArrayType::value_type>(),
3640 void())
3641 {
3642 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3643 {
3644 JSON_THROW(type_error::create(302, "type must be array, but is " +
3645 std::string(j.type_name())));
3646 }
3647
3648 from_json_array_impl(j, arr, priority_tag<3> {});
3649 }
3650
3651 template<typename BasicJsonType>
3652 void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
3653 {
3654 if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
3655 {
3656 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name())));
3657 }
3658
3659 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
3660 }
3661
3662 template<typename BasicJsonType, typename ConstructibleObjectType,
3663 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
3664 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
3665 {
3666 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
3667 {
3668 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
3669 }
3670
3671 ConstructibleObjectType ret;
3672 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
3673 using value_type = typename ConstructibleObjectType::value_type;
3674 std::transform(
3675 inner_object->begin(), inner_object->end(),
3676 std::inserter(ret, ret.begin()),
3677 [](typename BasicJsonType::object_t::value_type const & p)
3678 {
3679 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
3680 });
3681 obj = std::move(ret);
3682 }
3683
3684 // overload for arithmetic types, not chosen for basic_json template arguments
3685 // (BooleanType, etc..); note: Is it really necessary to provide explicit
3686 // overloads for boolean_t etc. in case of a custom BooleanType which is not
3687 // an arithmetic type?
3688 template < typename BasicJsonType, typename ArithmeticType,
3689 enable_if_t <
3690 std::is_arithmetic<ArithmeticType>::value&&
3691 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
3692 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
3693 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
3694 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3695 int > = 0 >
3696 void from_json(const BasicJsonType& j, ArithmeticType& val)
3697 {
3698 switch (static_cast<value_t>(j))
3699 {
3700 case value_t::number_unsigned:
3701 {
3702 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3703 break;
3704 }
3705 case value_t::number_integer:
3706 {
3707 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3708 break;
3709 }
3710 case value_t::number_float:
3711 {
3712 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3713 break;
3714 }
3715 case value_t::boolean:
3716 {
3717 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
3718 break;
3719 }
3720
3721 default:
3722 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
3723 }
3724 }
3725
3726 template<typename BasicJsonType, typename A1, typename A2>
3727 void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
3728 {
3729 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
3730 }
3731
3732 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
3733 void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
3734 {
3735 t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
3736 }
3737
3738 template<typename BasicJsonType, typename... Args>
3739 void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
3740 {
3741 from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
3742 }
3743
3744 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
3745 typename = enable_if_t < !std::is_constructible <
3746 typename BasicJsonType::string_t, Key >::value >>
3747 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
3748 {
3749 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3750 {
3751 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3752 }
3753 m.clear();
3754 for (const auto& p : j)
3755 {
3756 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
3757 {
3758 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3759 }
3760 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3761 }
3762 }
3763
3764 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
3765 typename = enable_if_t < !std::is_constructible <
3766 typename BasicJsonType::string_t, Key >::value >>
3767 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
3768 {
3769 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3770 {
3771 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3772 }
3773 m.clear();
3774 for (const auto& p : j)
3775 {
3776 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
3777 {
3778 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3779 }
3780 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3781 }
3782 }
3783
3784 struct from_json_fn
3785 {
3786 template<typename BasicJsonType, typename T>
3787 auto operator()(const BasicJsonType& j, T& val) const
3788 noexcept(noexcept(from_json(j, val)))
3789 -> decltype(from_json(j, val), void())
3790 {
3791 return from_json(j, val);
3792 }
3793 };
3794 } // namespace detail
3795
3799 namespace
3800 {
3801 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
3802 } // namespace
3803 } // namespace nlohmann
3804
3805 // #include <nlohmann/detail/conversions/to_json.hpp>
3806
3807
3808 #include <algorithm> // copy
3809 #include <iterator> // begin, end
3810 #include <string> // string
3811 #include <tuple> // tuple, get
3812 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
3813 #include <utility> // move, forward, declval, pair
3814 #include <valarray> // valarray
3815 #include <vector> // vector
3816
3817 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
3818
3819
3820 #include <cstddef> // size_t
3821 #include <iterator> // input_iterator_tag
3822 #include <string> // string, to_string
3823 #include <tuple> // tuple_size, get, tuple_element
3824
3825 // #include <nlohmann/detail/meta/type_traits.hpp>
3826
3827 // #include <nlohmann/detail/value_t.hpp>
3828
3829
3830 namespace nlohmann
3831 {
3832 namespace detail
3833 {
3834 template<typename string_type>
3835 void int_to_string( string_type& target, std::size_t value )
3836 {
3837 // For ADL
3838 using std::to_string;
3839 target = to_string(value);
3840 }
3841 template<typename IteratorType> class iteration_proxy_value
3842 {
3843 public:
3844 using difference_type = std::ptrdiff_t;
3845 using value_type = iteration_proxy_value;
3846 using pointer = value_type * ;
3847 using reference = value_type & ;
3848 using iterator_category = std::input_iterator_tag;
3849 using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
3850
3851 private:
3853 IteratorType anchor;
3855 std::size_t array_index = 0;
3857 mutable std::size_t array_index_last = 0;
3859 mutable string_type array_index_str = "0";
3861 const string_type empty_str = "";
3862
3863 public:
3864 explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
3865
3867 iteration_proxy_value& operator*()
3868 {
3869 return *this;
3870 }
3871
3873 iteration_proxy_value& operator++()
3874 {
3875 ++anchor;
3876 ++array_index;
3877
3878 return *this;
3879 }
3880
3882 bool operator==(const iteration_proxy_value& o) const
3883 {
3884 return anchor == o.anchor;
3885 }
3886
3888 bool operator!=(const iteration_proxy_value& o) const
3889 {
3890 return anchor != o.anchor;
3891 }
3892
3894 const string_type& key() const
3895 {
3896 JSON_ASSERT(anchor.m_object != nullptr);
3897
3898 switch (anchor.m_object->type())
3899 {
3900 // use integer array index as key
3901 case value_t::array:
3902 {
3903 if (array_index != array_index_last)
3904 {
3905 int_to_string( array_index_str, array_index );
3906 array_index_last = array_index;
3907 }
3908 return array_index_str;
3909 }
3910
3911 // use key from the object
3912 case value_t::object:
3913 return anchor.key();
3914
3915 // use an empty key for all primitive types
3916 default:
3917 return empty_str;
3918 }
3919 }
3920
3922 typename IteratorType::reference value() const
3923 {
3924 return anchor.value();
3925 }
3926 };
3927
3929 template<typename IteratorType> class iteration_proxy
3930 {
3931 private:
3933 typename IteratorType::reference container;
3934
3935 public:
3937 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
3938 : container(cont) {}
3939
3941 iteration_proxy_value<IteratorType> begin() noexcept
3942 {
3943 return iteration_proxy_value<IteratorType>(container.begin());
3944 }
3945
3947 iteration_proxy_value<IteratorType> end() noexcept
3948 {
3949 return iteration_proxy_value<IteratorType>(container.end());
3950 }
3951 };
3952 // Structured Bindings Support
3953 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3954 // And see https://github.com/nlohmann/json/pull/1391
3955 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
3956 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
3957 {
3958 return i.key();
3959 }
3960 // Structured Bindings Support
3961 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3962 // And see https://github.com/nlohmann/json/pull/1391
3963 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
3964 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
3965 {
3966 return i.value();
3967 }
3968 } // namespace detail
3969 } // namespace nlohmann
3970
3971 // The Addition to the STD Namespace is required to add
3972 // Structured Bindings Support to the iteration_proxy_value class
3973 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3974 // And see https://github.com/nlohmann/json/pull/1391
3975 namespace std
3976 {
3977 #if defined(__clang__)
3978 // Fix: https://github.com/nlohmann/json/issues/1401
3979 #pragma clang diagnostic push
3980 #pragma clang diagnostic ignored "-Wmismatched-tags"
3981 #endif
3982 template<typename IteratorType>
3983 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
3984 : public std::integral_constant<std::size_t, 2> {};
3985
3986 template<std::size_t N, typename IteratorType>
3987 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
3988 {
3989 public:
3990 using type = decltype(
3991 get<N>(std::declval <
3992 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
3993 };
3994 #if defined(__clang__)
3995 #pragma clang diagnostic pop
3996 #endif
3997 } // namespace std
3998
3999 // #include <nlohmann/detail/meta/cpp_future.hpp>
4000
4001 // #include <nlohmann/detail/meta/type_traits.hpp>
4002
4003 // #include <nlohmann/detail/value_t.hpp>
4004
4005
4006 namespace nlohmann
4007 {
4008 namespace detail
4009 {
4011 // constructors //
4013
4014 template<value_t> struct external_constructor;
4015
4016 template<>
4017 struct external_constructor<value_t::boolean>
4018 {
4019 template<typename BasicJsonType>
4020 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4021 {
4022 j.m_type = value_t::boolean;
4023 j.m_value = b;
4024 j.assert_invariant();
4025 }
4026 };
4027
4028 template<>
4029 struct external_constructor<value_t::string>
4030 {
4031 template<typename BasicJsonType>
4032 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4033 {
4034 j.m_type = value_t::string;
4035 j.m_value = s;
4036 j.assert_invariant();
4037 }
4038
4039 template<typename BasicJsonType>
4040 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4041 {
4042 j.m_type = value_t::string;
4043 j.m_value = std::move(s);
4044 j.assert_invariant();
4045 }
4046
4047 template < typename BasicJsonType, typename CompatibleStringType,
4048 enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
4049 int > = 0 >
4050 static void construct(BasicJsonType& j, const CompatibleStringType& str)
4051 {
4052 j.m_type = value_t::string;
4053 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4054 j.assert_invariant();
4055 }
4056 };
4057
4058 template<>
4059 struct external_constructor<value_t::binary>
4060 {
4061 template<typename BasicJsonType>
4062 static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4063 {
4064 j.m_type = value_t::binary;
4065 typename BasicJsonType::binary_t value{b};
4066 j.m_value = value;
4067 j.assert_invariant();
4068 }
4069
4070 template<typename BasicJsonType>
4071 static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4072 {
4073 j.m_type = value_t::binary;
4074 typename BasicJsonType::binary_t value{std::move(b)};
4075 j.m_value = value;
4076 j.assert_invariant();
4077 }
4078 };
4079
4080 template<>
4081 struct external_constructor<value_t::number_float>
4082 {
4083 template<typename BasicJsonType>
4084 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4085 {
4086 j.m_type = value_t::number_float;
4087 j.m_value = val;
4088 j.assert_invariant();
4089 }
4090 };
4091
4092 template<>
4093 struct external_constructor<value_t::number_unsigned>
4094 {
4095 template<typename BasicJsonType>
4096 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4097 {
4098 j.m_type = value_t::number_unsigned;
4099 j.m_value = val;
4100 j.assert_invariant();
4101 }
4102 };
4103
4104 template<>
4105 struct external_constructor<value_t::number_integer>
4106 {
4107 template<typename BasicJsonType>
4108 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4109 {
4110 j.m_type = value_t::number_integer;
4111 j.m_value = val;
4112 j.assert_invariant();
4113 }
4114 };
4115
4116 template<>
4117 struct external_constructor<value_t::array>
4118 {
4119 template<typename BasicJsonType>
4120 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4121 {
4122 j.m_type = value_t::array;
4123 j.m_value = arr;
4124 j.assert_invariant();
4125 }
4126
4127 template<typename BasicJsonType>
4128 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4129 {
4130 j.m_type = value_t::array;
4131 j.m_value = std::move(arr);
4132 j.assert_invariant();
4133 }
4134
4135 template < typename BasicJsonType, typename CompatibleArrayType,
4136 enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
4137 int > = 0 >
4138 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4139 {
4140 using std::begin;
4141 using std::end;
4142 j.m_type = value_t::array;
4143 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4144 j.assert_invariant();
4145 }
4146
4147 template<typename BasicJsonType>
4148 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4149 {
4150 j.m_type = value_t::array;
4151 j.m_value = value_t::array;
4152 j.m_value.array->reserve(arr.size());
4153 for (const bool x : arr)
4154 {
4155 j.m_value.array->push_back(x);
4156 }
4157 j.assert_invariant();
4158 }
4159
4160 template<typename BasicJsonType, typename T,
4161 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4162 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4163 {
4164 j.m_type = value_t::array;
4165 j.m_value = value_t::array;
4166 j.m_value.array->resize(arr.size());
4167 if (arr.size() > 0)
4168 {
4169 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4170 }
4171 j.assert_invariant();
4172 }
4173 };
4174
4175 template<>
4176 struct external_constructor<value_t::object>
4177 {
4178 template<typename BasicJsonType>
4179 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
4180 {
4181 j.m_type = value_t::object;
4182 j.m_value = obj;
4183 j.assert_invariant();
4184 }
4185
4186 template<typename BasicJsonType>
4187 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4188 {
4189 j.m_type = value_t::object;
4190 j.m_value = std::move(obj);
4191 j.assert_invariant();
4192 }
4193
4194 template < typename BasicJsonType, typename CompatibleObjectType,
4195 enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
4196 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4197 {
4198 using std::begin;
4199 using std::end;
4200
4201 j.m_type = value_t::object;
4202 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4203 j.assert_invariant();
4204 }
4205 };
4206
4208 // to_json //
4210
4211 template<typename BasicJsonType, typename T,
4212 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
4213 void to_json(BasicJsonType& j, T b) noexcept
4214 {
4215 external_constructor<value_t::boolean>::construct(j, b);
4216 }
4217
4218 template<typename BasicJsonType, typename CompatibleString,
4219 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
4220 void to_json(BasicJsonType& j, const CompatibleString& s)
4221 {
4222 external_constructor<value_t::string>::construct(j, s);
4223 }
4224
4225 template<typename BasicJsonType>
4226 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4227 {
4228 external_constructor<value_t::string>::construct(j, std::move(s));
4229 }
4230
4231 template<typename BasicJsonType, typename FloatType,
4232 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
4233 void to_json(BasicJsonType& j, FloatType val) noexcept
4234 {
4235 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4236 }
4237
4238 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4239 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
4240 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4241 {
4242 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4243 }
4244
4245 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4246 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
4247 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4248 {
4249 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4250 }
4251
4252 template<typename BasicJsonType, typename EnumType,
4253 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4254 void to_json(BasicJsonType& j, EnumType e) noexcept
4255 {
4256 using underlying_type = typename std::underlying_type<EnumType>::type;
4257 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4258 }
4259
4260 template<typename BasicJsonType>
4261 void to_json(BasicJsonType& j, const std::vector<bool>& e)
4262 {
4263 external_constructor<value_t::array>::construct(j, e);
4264 }
4265
4266 template < typename BasicJsonType, typename CompatibleArrayType,
4267 enable_if_t < is_compatible_array_type<BasicJsonType,
4268 CompatibleArrayType>::value&&
4269 !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
4270 !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
4271 !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
4272 !is_basic_json<CompatibleArrayType>::value,
4273 int > = 0 >
4274 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4275 {
4276 external_constructor<value_t::array>::construct(j, arr);
4277 }
4278
4279 template<typename BasicJsonType>
4280 void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4281 {
4282 external_constructor<value_t::binary>::construct(j, bin);
4283 }
4284
4285 template<typename BasicJsonType, typename T,
4286 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4287 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4288 {
4289 external_constructor<value_t::array>::construct(j, std::move(arr));
4290 }
4291
4292 template<typename BasicJsonType>
4293 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4294 {
4295 external_constructor<value_t::array>::construct(j, std::move(arr));
4296 }
4297
4298 template < typename BasicJsonType, typename CompatibleObjectType,
4299 enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
4300 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4301 {
4302 external_constructor<value_t::object>::construct(j, obj);
4303 }
4304
4305 template<typename BasicJsonType>
4306 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4307 {
4308 external_constructor<value_t::object>::construct(j, std::move(obj));
4309 }
4310
4311 template <
4312 typename BasicJsonType, typename T, std::size_t N,
4313 enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4314 const T(&)[N]>::value,
4315 int > = 0 >
4316 void to_json(BasicJsonType& j, const T(&arr)[N])
4317 {
4318 external_constructor<value_t::array>::construct(j, arr);
4319 }
4320
4321 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
4322 void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4323 {
4324 j = { p.first, p.second };
4325 }
4326
4327 // for https://github.com/nlohmann/json/pull/1134
4328 template<typename BasicJsonType, typename T,
4329 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
4330 void to_json(BasicJsonType& j, const T& b)
4331 {
4332 j = { {b.key(), b.value()} };
4333 }
4334
4335 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
4336 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4337 {
4338 j = { std::get<Idx>(t)... };
4339 }
4340
4341 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
4342 void to_json(BasicJsonType& j, const T& t)
4343 {
4344 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
4345 }
4346
4347 struct to_json_fn
4348 {
4349 template<typename BasicJsonType, typename T>
4350 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
4351 -> decltype(to_json(j, std::forward<T>(val)), void())
4352 {
4353 return to_json(j, std::forward<T>(val));
4354 }
4355 };
4356 } // namespace detail
4357
4359 namespace
4360 {
4361 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
4362 } // namespace
4363 } // namespace nlohmann
4364
4365
4366 namespace nlohmann
4367 {
4368
4369 template<typename, typename>
4370 struct adl_serializer
4371 {
4381 template<typename BasicJsonType, typename ValueType>
4382 static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
4383 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
4384 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
4385 {
4386 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
4387 }
4388
4398 template<typename BasicJsonType, typename ValueType>
4399 static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
4400 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
4401 -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void())
4402 {
4403 ::nlohmann::to_json(j, std::forward<ValueType>(val));
4404 }
4405 };
4406
4407 } // namespace nlohmann
4408
4409 // #include <nlohmann/byte_container_with_subtype.hpp>
4410
4411
4412 #include <cstdint> // uint8_t
4413 #include <tuple> // tie
4414 #include <utility> // move
4415
4416 namespace nlohmann
4417 {
4418
4432 template<typename BinaryType>
4433 class byte_container_with_subtype : public BinaryType
4434 {
4435 public:
4437 using container_type = BinaryType;
4438
4439 byte_container_with_subtype() noexcept(noexcept(container_type()))
4440 : container_type()
4441 {}
4442
4443 byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))
4444 : container_type(b)
4445 {}
4446
4447 byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
4448 : container_type(std::move(b))
4449 {}
4450
4451 byte_container_with_subtype(const container_type& b, std::uint8_t subtype) noexcept(noexcept(container_type(b)))
4452 : container_type(b)
4453 , m_subtype(subtype)
4454 , m_has_subtype(true)
4455 {}
4456
4457 byte_container_with_subtype(container_type&& b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b))))
4458 : container_type(std::move(b))
4459 , m_subtype(subtype)
4460 , m_has_subtype(true)
4461 {}
4462
4463 bool operator==(const byte_container_with_subtype& rhs) const
4464 {
4465 return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
4466 std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
4467 }
4468
4469 bool operator!=(const byte_container_with_subtype& rhs) const
4470 {
4471 return !(rhs == *this);
4472 }
4473
4492 void set_subtype(std::uint8_t subtype) noexcept
4493 {
4494 m_subtype = subtype;
4495 m_has_subtype = true;
4496 }
4497
4519 constexpr std::uint8_t subtype() const noexcept
4520 {
4521 return m_subtype;
4522 }
4523
4540 constexpr bool has_subtype() const noexcept
4541 {
4542 return m_has_subtype;
4543 }
4544
4564 void clear_subtype() noexcept
4565 {
4566 m_subtype = 0;
4567 m_has_subtype = false;
4568 }
4569
4570 private:
4571 std::uint8_t m_subtype = 0;
4572 bool m_has_subtype = false;
4573 };
4574
4575 } // namespace nlohmann
4576
4577 // #include <nlohmann/detail/conversions/from_json.hpp>
4578
4579 // #include <nlohmann/detail/conversions/to_json.hpp>
4580
4581 // #include <nlohmann/detail/exceptions.hpp>
4582
4583 // #include <nlohmann/detail/hash.hpp>
4584
4585
4586 #include <cstddef> // size_t, uint8_t
4587 #include <functional> // hash
4588
4589 namespace nlohmann
4590 {
4591 namespace detail
4592 {
4593
4594 // boost::hash_combine
4595 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
4596 {
4597 seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
4598 return seed;
4599 }
4600
4612 template<typename BasicJsonType>
4613 std::size_t hash(const BasicJsonType& j)
4614 {
4615 using string_t = typename BasicJsonType::string_t;
4616 using number_integer_t = typename BasicJsonType::number_integer_t;
4617 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4618 using number_float_t = typename BasicJsonType::number_float_t;
4619
4620 const auto type = static_cast<std::size_t>(j.type());
4621 switch (j.type())
4622 {
4623 case BasicJsonType::value_t::null:
4624 case BasicJsonType::value_t::discarded:
4625 {
4626 return combine(type, 0);
4627 }
4628
4629 case BasicJsonType::value_t::object:
4630 {
4631 auto seed = combine(type, j.size());
4632 for (const auto& element : j.items())
4633 {
4634 const auto h = std::hash<string_t> {}(element.key());
4635 seed = combine(seed, h);
4636 seed = combine(seed, hash(element.value()));
4637 }
4638 return seed;
4639 }
4640
4641 case BasicJsonType::value_t::array:
4642 {
4643 auto seed = combine(type, j.size());
4644 for (const auto& element : j)
4645 {
4646 seed = combine(seed, hash(element));
4647 }
4648 return seed;
4649 }
4650
4651 case BasicJsonType::value_t::string:
4652 {
4653 const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
4654 return combine(type, h);
4655 }
4656
4657 case BasicJsonType::value_t::boolean:
4658 {
4659 const auto h = std::hash<bool> {}(j.template get<bool>());
4660 return combine(type, h);
4661 }
4662
4663 case BasicJsonType::value_t::number_integer:
4664 {
4665 const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
4666 return combine(type, h);
4667 }
4668
4669 case nlohmann::detail::value_t::number_unsigned:
4670 {
4671 const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
4672 return combine(type, h);
4673 }
4674
4675 case nlohmann::detail::value_t::number_float:
4676 {
4677 const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
4678 return combine(type, h);
4679 }
4680
4681 case nlohmann::detail::value_t::binary:
4682 {
4683 auto seed = combine(type, j.get_binary().size());
4684 const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
4685 seed = combine(seed, h);
4686 seed = combine(seed, j.get_binary().subtype());
4687 for (const auto byte : j.get_binary())
4688 {
4689 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
4690 }
4691 return seed;
4692 }
4693
4694 default: // LCOV_EXCL_LINE
4695 JSON_ASSERT(false); // LCOV_EXCL_LINE
4696 }
4697 }
4698
4699 } // namespace detail
4700 } // namespace nlohmann
4701
4702 // #include <nlohmann/detail/input/binary_reader.hpp>
4703
4704
4705 #include <algorithm> // generate_n
4706 #include <array> // array
4707 #include <cmath> // ldexp
4708 #include <cstddef> // size_t
4709 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
4710 #include <cstdio> // snprintf
4711 #include <cstring> // memcpy
4712 #include <iterator> // back_inserter
4713 #include <limits> // numeric_limits
4714 #include <string> // char_traits, string
4715 #include <utility> // make_pair, move
4716
4717 // #include <nlohmann/detail/exceptions.hpp>
4718
4719 // #include <nlohmann/detail/input/input_adapters.hpp>
4720
4721
4722 #include <array> // array
4723 #include <cstddef> // size_t
4724 #include <cstdio> //FILE *
4725 #include <cstring> // strlen
4726 #include <istream> // istream
4727 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
4728 #include <memory> // shared_ptr, make_shared, addressof
4729 #include <numeric> // accumulate
4730 #include <string> // string, char_traits
4731 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
4732 #include <utility> // pair, declval
4733
4734 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
4735
4736 // #include <nlohmann/detail/macro_scope.hpp>
4737
4738
4739 namespace nlohmann
4740 {
4741 namespace detail
4742 {
4744 enum class input_format_t { json, cbor, msgpack, ubjson, bson };
4745
4747 // input adapters //
4749
4754 class file_input_adapter
4755 {
4756 public:
4757 using char_type = char;
4758
4759 JSON_HEDLEY_NON_NULL(2)
4760 explicit file_input_adapter(std::FILE* f) noexcept
4761 : m_file(f)
4762 {}
4763
4764 // make class move-only
4765 file_input_adapter(const file_input_adapter&) = delete;
4766 file_input_adapter(file_input_adapter&&) = default;
4767 file_input_adapter& operator=(const file_input_adapter&) = delete;
4768 file_input_adapter& operator=(file_input_adapter&&) = delete;
4769
4770 std::char_traits<char>::int_type get_character() noexcept
4771 {
4772 return std::fgetc(m_file);
4773 }
4774
4775 private:
4777 std::FILE* m_file;
4778 };
4779
4780
4790 class input_stream_adapter
4791 {
4792 public:
4793 using char_type = char;
4794
4795 ~input_stream_adapter()
4796 {
4797 // clear stream flags; we use underlying streambuf I/O, do not
4798 // maintain ifstream flags, except eof
4799 if (is != nullptr)
4800 {
4801 is->clear(is->rdstate() & std::ios::eofbit);
4802 }
4803 }
4804
4805 explicit input_stream_adapter(std::istream& i)
4806 : is(&i), sb(i.rdbuf())
4807 {}
4808
4809 // delete because of pointer members
4810 input_stream_adapter(const input_stream_adapter&) = delete;
4811 input_stream_adapter& operator=(input_stream_adapter&) = delete;
4812 input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
4813
4814 input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs.is), sb(rhs.sb)
4815 {
4816 rhs.is = nullptr;
4817 rhs.sb = nullptr;
4818 }
4819
4820 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
4821 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
4822 // end up as the same value, eg. 0xFFFFFFFF.
4823 std::char_traits<char>::int_type get_character()
4824 {
4825 auto res = sb->sbumpc();
4826 // set eof manually, as we don't use the istream interface.
4827 if (JSON_HEDLEY_UNLIKELY(res == EOF))
4828 {
4829 is->clear(is->rdstate() | std::ios::eofbit);
4830 }
4831 return res;
4832 }
4833
4834 private:
4836 std::istream* is = nullptr;
4837 std::streambuf* sb = nullptr;
4838 };
4839
4840 // General-purpose iterator-based adapter. It might not be as fast as
4841 // theoretically possible for some containers, but it is extremely versatile.
4842 template<typename IteratorType>
4843 class iterator_input_adapter
4844 {
4845 public:
4846 using char_type = typename std::iterator_traits<IteratorType>::value_type;
4847
4848 iterator_input_adapter(IteratorType first, IteratorType last)
4849 : current(std::move(first)), end(std::move(last)) {}
4850
4851 typename std::char_traits<char_type>::int_type get_character()
4852 {
4853 if (JSON_HEDLEY_LIKELY(current != end))
4854 {
4855 auto result = std::char_traits<char_type>::to_int_type(*current);
4856 std::advance(current, 1);
4857 return result;
4858 }
4859 else
4860 {
4861 return std::char_traits<char_type>::eof();
4862 }
4863 }
4864
4865 private:
4866 IteratorType current;
4867 IteratorType end;
4868
4869 template<typename BaseInputAdapter, size_t T>
4870 friend struct wide_string_input_helper;
4871
4872 bool empty() const
4873 {
4874 return current == end;
4875 }
4876
4877 };
4878
4879
4880 template<typename BaseInputAdapter, size_t T>
4881 struct wide_string_input_helper;
4882
4883 template<typename BaseInputAdapter>
4884 struct wide_string_input_helper<BaseInputAdapter, 4>
4885 {
4886 // UTF-32
4887 static void fill_buffer(BaseInputAdapter& input,
4888 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4889 size_t& utf8_bytes_index,
4890 size_t& utf8_bytes_filled)
4891 {
4892 utf8_bytes_index = 0;
4893
4894 if (JSON_HEDLEY_UNLIKELY(input.empty()))
4895 {
4896 utf8_bytes[0] = std::char_traits<char>::eof();
4897 utf8_bytes_filled = 1;
4898 }
4899 else
4900 {
4901 // get the current character
4902 const auto wc = input.get_character();
4903
4904 // UTF-32 to UTF-8 encoding
4905 if (wc < 0x80)
4906 {
4907 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4908 utf8_bytes_filled = 1;
4909 }
4910 else if (wc <= 0x7FF)
4911 {
4912 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
4913 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4914 utf8_bytes_filled = 2;
4915 }
4916 else if (wc <= 0xFFFF)
4917 {
4918 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
4919 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4920 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4921 utf8_bytes_filled = 3;
4922 }
4923 else if (wc <= 0x10FFFF)
4924 {
4925 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
4926 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
4927 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4928 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4929 utf8_bytes_filled = 4;
4930 }
4931 else
4932 {
4933 // unknown character
4934 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4935 utf8_bytes_filled = 1;
4936 }
4937 }
4938 }
4939 };
4940
4941 template<typename BaseInputAdapter>
4942 struct wide_string_input_helper<BaseInputAdapter, 2>
4943 {
4944 // UTF-16
4945 static void fill_buffer(BaseInputAdapter& input,
4946 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4947 size_t& utf8_bytes_index,
4948 size_t& utf8_bytes_filled)
4949 {
4950 utf8_bytes_index = 0;
4951
4952 if (JSON_HEDLEY_UNLIKELY(input.empty()))
4953 {
4954 utf8_bytes[0] = std::char_traits<char>::eof();
4955 utf8_bytes_filled = 1;
4956 }
4957 else
4958 {
4959 // get the current character
4960 const auto wc = input.get_character();
4961
4962 // UTF-16 to UTF-8 encoding
4963 if (wc < 0x80)
4964 {
4965 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4966 utf8_bytes_filled = 1;
4967 }
4968 else if (wc <= 0x7FF)
4969 {
4970 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
4971 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4972 utf8_bytes_filled = 2;
4973 }
4974 else if (0xD800 > wc || wc >= 0xE000)
4975 {
4976 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
4977 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4978 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4979 utf8_bytes_filled = 3;
4980 }
4981 else
4982 {
4983 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
4984 {
4985 const auto wc2 = static_cast<unsigned int>(input.get_character());
4986 const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
4987 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
4988 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
4989 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
4990 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
4991 utf8_bytes_filled = 4;
4992 }
4993 else
4994 {
4995 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4996 utf8_bytes_filled = 1;
4997 }
4998 }
4999 }
5000 }
5001 };
5002
5003 // Wraps another input apdater to convert wide character types into individual bytes.
5004 template<typename BaseInputAdapter, typename WideCharType>
5005 class wide_string_input_adapter
5006 {
5007 public:
5008 using char_type = char;
5009
5010 wide_string_input_adapter(BaseInputAdapter base)
5011 : base_adapter(base) {}
5012
5013 typename std::char_traits<char>::int_type get_character() noexcept
5014 {
5015 // check if buffer needs to be filled
5016 if (utf8_bytes_index == utf8_bytes_filled)
5017 {
5018 fill_buffer<sizeof(WideCharType)>();
5019
5020 JSON_ASSERT(utf8_bytes_filled > 0);
5021 JSON_ASSERT(utf8_bytes_index == 0);
5022 }
5023
5024 // use buffer
5025 JSON_ASSERT(utf8_bytes_filled > 0);
5026 JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
5027 return utf8_bytes[utf8_bytes_index++];
5028 }
5029
5030 private:
5031 BaseInputAdapter base_adapter;
5032
5033 template<size_t T>
5034 void fill_buffer()
5035 {
5036 wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
5037 }
5038
5040 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5041
5043 std::size_t utf8_bytes_index = 0;
5045 std::size_t utf8_bytes_filled = 0;
5046 };
5047
5048
5049 template<typename IteratorType, typename Enable = void>
5050 struct iterator_input_adapter_factory
5051 {
5052 using iterator_type = IteratorType;
5053 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5054 using adapter_type = iterator_input_adapter<iterator_type>;
5055
5056 static adapter_type create(IteratorType first, IteratorType last)
5057 {
5058 return adapter_type(std::move(first), std::move(last));
5059 }
5060 };
5061
5062 template<typename T>
5063 struct is_iterator_of_multibyte
5064 {
5065 using value_type = typename std::iterator_traits<T>::value_type;
5066 enum
5067 {
5068 value = sizeof(value_type) > 1
5069 };
5070 };
5071
5072 template<typename IteratorType>
5073 struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
5074 {
5075 using iterator_type = IteratorType;
5076 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5077 using base_adapter_type = iterator_input_adapter<iterator_type>;
5078 using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
5079
5080 static adapter_type create(IteratorType first, IteratorType last)
5081 {
5082 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5083 }
5084 };
5085
5086 // General purpose iterator-based input
5087 template<typename IteratorType>
5088 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
5089 {
5090 using factory_type = iterator_input_adapter_factory<IteratorType>;
5091 return factory_type::create(first, last);
5092 }
5093
5094 // Convenience shorthand from container to iterator
5095 template<typename ContainerType>
5096 auto input_adapter(const ContainerType& container) -> decltype(input_adapter(begin(container), end(container)))
5097 {
5098 // Enable ADL
5099 using std::begin;
5100 using std::end;
5101
5102 return input_adapter(begin(container), end(container));
5103 }
5104
5105 // Special cases with fast paths
5106 inline file_input_adapter input_adapter(std::FILE* file)
5107 {
5108 return file_input_adapter(file);
5109 }
5110
5111 inline input_stream_adapter input_adapter(std::istream& stream)
5112 {
5113 return input_stream_adapter(stream);
5114 }
5115
5116 inline input_stream_adapter input_adapter(std::istream&& stream)
5117 {
5118 return input_stream_adapter(stream);
5119 }
5120
5121 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5122
5123 // Null-delimited strings, and the like.
5124 template < typename CharT,
5125 typename std::enable_if <
5126 std::is_pointer<CharT>::value&&
5127 !std::is_array<CharT>::value&&
5128 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5129 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5130 int >::type = 0 >
5131 contiguous_bytes_input_adapter input_adapter(CharT b)
5132 {
5133 auto length = std::strlen(reinterpret_cast<const char*>(b));
5134 const auto* ptr = reinterpret_cast<const char*>(b);
5135 return input_adapter(ptr, ptr + length);
5136 }
5137
5138 template<typename T, std::size_t N>
5139 auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N))
5140 {
5141 return input_adapter(array, array + N);
5142 }
5143
5144 // This class only handles inputs of input_buffer_adapter type.
5145 // It's required so that expressions like {ptr, len} can be implicitely casted
5146 // to the correct adapter.
5147 class span_input_adapter
5148 {
5149 public:
5150 template < typename CharT,
5151 typename std::enable_if <
5152 std::is_pointer<CharT>::value&&
5153 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5154 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5155 int >::type = 0 >
5156 span_input_adapter(CharT b, std::size_t l)
5157 : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5158
5159 template<class IteratorType,
5160 typename std::enable_if<
5161 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5162 int>::type = 0>
5163 span_input_adapter(IteratorType first, IteratorType last)
5164 : ia(input_adapter(first, last)) {}
5165
5166 contiguous_bytes_input_adapter&& get()
5167 {
5168 return std::move(ia);
5169 }
5170
5171 private:
5172 contiguous_bytes_input_adapter ia;
5173 };
5174 } // namespace detail
5175 } // namespace nlohmann
5176
5177 // #include <nlohmann/detail/input/json_sax.hpp>
5178
5179
5180 #include <cstddef>
5181 #include <string> // string
5182 #include <utility> // move
5183 #include <vector> // vector
5184
5185 // #include <nlohmann/detail/exceptions.hpp>
5186
5187 // #include <nlohmann/detail/macro_scope.hpp>
5188
5189
5190 namespace nlohmann
5191 {
5192
5201 template<typename BasicJsonType>
5202 struct json_sax
5203 {
5204 using number_integer_t = typename BasicJsonType::number_integer_t;
5205 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5206 using number_float_t = typename BasicJsonType::number_float_t;
5207 using string_t = typename BasicJsonType::string_t;
5208 using binary_t = typename BasicJsonType::binary_t;
5209
5214 virtual bool null() = 0;
5215
5221 virtual bool boolean(bool val) = 0;
5222
5228 virtual bool number_integer(number_integer_t val) = 0;
5229
5235 virtual bool number_unsigned(number_unsigned_t val) = 0;
5236
5243 virtual bool number_float(number_float_t val, const string_t& s) = 0;
5244
5251 virtual bool string(string_t& val) = 0;
5252
5259 virtual bool binary(binary_t& val) = 0;
5260
5267 virtual bool start_object(std::size_t elements) = 0;
5268
5275 virtual bool key(string_t& val) = 0;
5276
5281 virtual bool end_object() = 0;
5282
5289 virtual bool start_array(std::size_t elements) = 0;
5290
5295 virtual bool end_array() = 0;
5296
5304 virtual bool parse_error(std::size_t position,
5305 const std::string& last_token,
5306 const detail::exception& ex) = 0;
5307
5308 virtual ~json_sax() = default;
5309 };
5310
5311
5312 namespace detail
5313 {
5327 template<typename BasicJsonType>
5328 class json_sax_dom_parser
5329 {
5330 public:
5331 using number_integer_t = typename BasicJsonType::number_integer_t;
5332 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5333 using number_float_t = typename BasicJsonType::number_float_t;
5334 using string_t = typename BasicJsonType::string_t;
5335 using binary_t = typename BasicJsonType::binary_t;
5336
5342 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
5343 : root(r), allow_exceptions(allow_exceptions_)
5344 {}
5345
5346 // make class move-only
5347 json_sax_dom_parser(const json_sax_dom_parser&) = delete;
5348 json_sax_dom_parser(json_sax_dom_parser&&) = default;
5349 json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
5350 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
5351 ~json_sax_dom_parser() = default;
5352
5353 bool null()
5354 {
5355 handle_value(nullptr);
5356 return true;
5357 }
5358
5359 bool boolean(bool val)
5360 {
5361 handle_value(val);
5362 return true;
5363 }
5364
5365 bool number_integer(number_integer_t val)
5366 {
5367 handle_value(val);
5368 return true;
5369 }
5370
5371 bool number_unsigned(number_unsigned_t val)
5372 {
5373 handle_value(val);
5374 return true;
5375 }
5376
5377 bool number_float(number_float_t val, const string_t& /*unused*/)
5378 {
5379 handle_value(val);
5380 return true;
5381 }
5382
5383 bool string(string_t& val)
5384 {
5385 handle_value(val);
5386 return true;
5387 }
5388
5389 bool binary(binary_t& val)
5390 {
5391 handle_value(std::move(val));
5392 return true;
5393 }
5394
5395 bool start_object(std::size_t len)
5396 {
5397 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
5398
5399 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5400 {
5401 JSON_THROW(out_of_range::create(408,
5402 "excessive object size: " + std::to_string(len)));
5403 }
5404
5405 return true;
5406 }
5407
5408 bool key(string_t& val)
5409 {
5410 // add null at given key and store the reference for later
5411 object_element = &(ref_stack.back()->m_value.object->operator[](val));
5412 return true;
5413 }
5414
5415 bool end_object()
5416 {
5417 ref_stack.pop_back();
5418 return true;
5419 }
5420
5421 bool start_array(std::size_t len)
5422 {
5423 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
5424
5425 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5426 {
5427 JSON_THROW(out_of_range::create(408,
5428 "excessive array size: " + std::to_string(len)));
5429 }
5430
5431 return true;
5432 }
5433
5434 bool end_array()
5435 {
5436 ref_stack.pop_back();
5437 return true;
5438 }
5439
5440 template<class Exception>
5441 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5442 const Exception& ex)
5443 {
5444 errored = true;
5445 static_cast<void>(ex);
5446 if (allow_exceptions)
5447 {
5448 JSON_THROW(ex);
5449 }
5450 return false;
5451 }
5452
5453 constexpr bool is_errored() const
5454 {
5455 return errored;
5456 }
5457
5458 private:
5465 template<typename Value>
5466
5467 BasicJsonType* handle_value(Value&& v)
5468 {
5469 if (ref_stack.empty())
5470 {
5471 root = BasicJsonType(std::forward<Value>(v));
5472 return &root;
5473 }
5474
5475 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
5476
5477 if (ref_stack.back()->is_array())
5478 {
5479 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
5480 return &(ref_stack.back()->m_value.array->back());
5481 }
5482
5483 JSON_ASSERT(ref_stack.back()->is_object());
5484 JSON_ASSERT(object_element);
5485 *object_element = BasicJsonType(std::forward<Value>(v));
5486 return object_element;
5487 }
5488
5490 BasicJsonType& root;
5492 std::vector<BasicJsonType*> ref_stack {};
5494 BasicJsonType* object_element = nullptr;
5496 bool errored = false;
5498 const bool allow_exceptions = true;
5499 };
5500
5501 template<typename BasicJsonType>
5502 class json_sax_dom_callback_parser
5503 {
5504 public:
5505 using number_integer_t = typename BasicJsonType::number_integer_t;
5506 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5507 using number_float_t = typename BasicJsonType::number_float_t;
5508 using string_t = typename BasicJsonType::string_t;
5509 using binary_t = typename BasicJsonType::binary_t;
5510 using parser_callback_t = typename BasicJsonType::parser_callback_t;
5511 using parse_event_t = typename BasicJsonType::parse_event_t;
5512
5513 json_sax_dom_callback_parser(BasicJsonType& r,
5514 const parser_callback_t cb,
5515 const bool allow_exceptions_ = true)
5516 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
5517 {
5518 keep_stack.push_back(true);
5519 }
5520
5521 // make class move-only
5522 json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
5523 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default;
5524 json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
5525 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default;
5526 ~json_sax_dom_callback_parser() = default;
5527
5528 bool null()
5529 {
5530 handle_value(nullptr);
5531 return true;
5532 }
5533
5534 bool boolean(bool val)
5535 {
5536 handle_value(val);
5537 return true;
5538 }
5539
5540 bool number_integer(number_integer_t val)
5541 {
5542 handle_value(val);
5543 return true;
5544 }
5545
5546 bool number_unsigned(number_unsigned_t val)
5547 {
5548 handle_value(val);
5549 return true;
5550 }
5551
5552 bool number_float(number_float_t val, const string_t& /*unused*/)
5553 {
5554 handle_value(val);
5555 return true;
5556 }
5557
5558 bool string(string_t& val)
5559 {
5560 handle_value(val);
5561 return true;
5562 }
5563
5564 bool binary(binary_t& val)
5565 {
5566 handle_value(std::move(val));
5567 return true;
5568 }
5569
5570 bool start_object(std::size_t len)
5571 {
5572 // check callback for object start
5573 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
5574 keep_stack.push_back(keep);
5575
5576 auto val = handle_value(BasicJsonType::value_t::object, true);
5577 ref_stack.push_back(val.second);
5578
5579 // check object limit
5580 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5581 {
5582 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
5583 }
5584
5585 return true;
5586 }
5587
5588 bool key(string_t& val)
5589 {
5590 BasicJsonType k = BasicJsonType(val);
5591
5592 // check callback for key
5593 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
5594 key_keep_stack.push_back(keep);
5595
5596 // add discarded value at given key and store the reference for later
5597 if (keep && ref_stack.back())
5598 {
5599 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
5600 }
5601
5602 return true;
5603 }
5604
5605 bool end_object()
5606 {
5607 if (ref_stack.back() && !callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
5608 {
5609 // discard object
5610 *ref_stack.back() = discarded;
5611 }
5612
5613 JSON_ASSERT(!ref_stack.empty());
5614 JSON_ASSERT(!keep_stack.empty());
5615 ref_stack.pop_back();
5616 keep_stack.pop_back();
5617
5618 if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
5619 {
5620 // remove discarded value
5621 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
5622 {
5623 if (it->is_discarded())
5624 {
5625 ref_stack.back()->erase(it);
5626 break;
5627 }
5628 }
5629 }
5630
5631 return true;
5632 }
5633
5634 bool start_array(std::size_t len)
5635 {
5636 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
5637 keep_stack.push_back(keep);
5638
5639 auto val = handle_value(BasicJsonType::value_t::array, true);
5640 ref_stack.push_back(val.second);
5641
5642 // check array limit
5643 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5644 {
5645 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
5646 }
5647
5648 return true;
5649 }
5650
5651 bool end_array()
5652 {
5653 bool keep = true;
5654
5655 if (ref_stack.back())
5656 {
5657 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
5658 if (!keep)
5659 {
5660 // discard array
5661 *ref_stack.back() = discarded;
5662 }
5663 }
5664
5665 JSON_ASSERT(!ref_stack.empty());
5666 JSON_ASSERT(!keep_stack.empty());
5667 ref_stack.pop_back();
5668 keep_stack.pop_back();
5669
5670 // remove discarded value
5671 if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
5672 {
5673 ref_stack.back()->m_value.array->pop_back();
5674 }
5675
5676 return true;
5677 }
5678
5679 template<class Exception>
5680 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5681 const Exception& ex)
5682 {
5683 errored = true;
5684 static_cast<void>(ex);
5685 if (allow_exceptions)
5686 {
5687 JSON_THROW(ex);
5688 }
5689 return false;
5690 }
5691
5692 constexpr bool is_errored() const
5693 {
5694 return errored;
5695 }
5696
5697 private:
5713 template<typename Value>
5714 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
5715 {
5716 JSON_ASSERT(!keep_stack.empty());
5717
5718 // do not handle this value if we know it would be added to a discarded
5719 // container
5720 if (!keep_stack.back())
5721 {
5722 return {false, nullptr};
5723 }
5724
5725 // create value
5726 auto value = BasicJsonType(std::forward<Value>(v));
5727
5728 // check callback
5729 const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
5730
5731 // do not handle this value if we just learnt it shall be discarded
5732 if (!keep)
5733 {
5734 return {false, nullptr};
5735 }
5736
5737 if (ref_stack.empty())
5738 {
5739 root = std::move(value);
5740 return {true, &root};
5741 }
5742
5743 // skip this value if we already decided to skip the parent
5744 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
5745 if (!ref_stack.back())
5746 {
5747 return {false, nullptr};
5748 }
5749
5750 // we now only expect arrays and objects
5751 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
5752
5753 // array
5754 if (ref_stack.back()->is_array())
5755 {
5756 ref_stack.back()->m_value.array->push_back(std::move(value));
5757 return {true, &(ref_stack.back()->m_value.array->back())};
5758 }
5759
5760 // object
5761 JSON_ASSERT(ref_stack.back()->is_object());
5762 // check if we should store an element for the current key
5763 JSON_ASSERT(!key_keep_stack.empty());
5764 const bool store_element = key_keep_stack.back();
5765 key_keep_stack.pop_back();
5766
5767 if (!store_element)
5768 {
5769 return {false, nullptr};
5770 }
5771
5772 JSON_ASSERT(object_element);
5773 *object_element = std::move(value);
5774 return {true, object_element};
5775 }
5776
5778 BasicJsonType& root;
5780 std::vector<BasicJsonType*> ref_stack {};
5782 std::vector<bool> keep_stack {};
5784 std::vector<bool> key_keep_stack {};
5786 BasicJsonType* object_element = nullptr;
5788 bool errored = false;
5790 const parser_callback_t callback = nullptr;
5792 const bool allow_exceptions = true;
5794 BasicJsonType discarded = BasicJsonType::value_t::discarded;
5795 };
5796
5797 template<typename BasicJsonType>
5798 class json_sax_acceptor
5799 {
5800 public:
5801 using number_integer_t = typename BasicJsonType::number_integer_t;
5802 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5803 using number_float_t = typename BasicJsonType::number_float_t;
5804 using string_t = typename BasicJsonType::string_t;
5805 using binary_t = typename BasicJsonType::binary_t;
5806
5807 bool null()
5808 {
5809 return true;
5810 }
5811
5812 bool boolean(bool /*unused*/)
5813 {
5814 return true;
5815 }
5816
5817 bool number_integer(number_integer_t /*unused*/)
5818 {
5819 return true;
5820 }
5821
5822 bool number_unsigned(number_unsigned_t /*unused*/)
5823 {
5824 return true;
5825 }
5826
5827 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
5828 {
5829 return true;
5830 }
5831
5832 bool string(string_t& /*unused*/)
5833 {
5834 return true;
5835 }
5836
5837 bool binary(binary_t& /*unused*/)
5838 {
5839 return true;
5840 }
5841
5842 bool start_object(std::size_t /*unused*/ = std::size_t(-1))
5843 {
5844 return true;
5845 }
5846
5847 bool key(string_t& /*unused*/)
5848 {
5849 return true;
5850 }
5851
5852 bool end_object()
5853 {
5854 return true;
5855 }
5856
5857 bool start_array(std::size_t /*unused*/ = std::size_t(-1))
5858 {
5859 return true;
5860 }
5861
5862 bool end_array()
5863 {
5864 return true;
5865 }
5866
5867 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
5868 {
5869 return false;
5870 }
5871 };
5872 } // namespace detail
5873
5874 } // namespace nlohmann
5875
5876 // #include <nlohmann/detail/input/lexer.hpp>
5877
5878
5879 #include <array> // array
5880 #include <clocale> // localeconv
5881 #include <cstddef> // size_t
5882 #include <cstdio> // snprintf
5883 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
5884 #include <initializer_list> // initializer_list
5885 #include <string> // char_traits, string
5886 #include <utility> // move
5887 #include <vector> // vector
5888
5889 // #include <nlohmann/detail/input/input_adapters.hpp>
5890
5891 // #include <nlohmann/detail/input/position_t.hpp>
5892
5893 // #include <nlohmann/detail/macro_scope.hpp>
5894
5895
5896 namespace nlohmann
5897 {
5898 namespace detail
5899 {
5901 // lexer //
5903
5904 template<typename BasicJsonType>
5905 class lexer_base
5906 {
5907 public:
5909 enum class token_type
5910 {
5911 uninitialized,
5912 literal_true,
5913 literal_false,
5914 literal_null,
5915 value_string,
5916 value_unsigned,
5917 value_integer,
5918 value_float,
5919 begin_array,
5920 begin_object,
5921 end_array,
5922 end_object,
5923 name_separator,
5924 value_separator,
5925 parse_error,
5926 end_of_input,
5927 literal_or_value
5928 };
5929
5931
5932 JSON_HEDLEY_CONST
5933 static const char* token_type_name(const token_type t) noexcept
5934 {
5935 switch (t)
5936 {
5937 case token_type::uninitialized:
5938 return "<uninitialized>";
5939 case token_type::literal_true:
5940 return "true literal";
5941 case token_type::literal_false:
5942 return "false literal";
5943 case token_type::literal_null:
5944 return "null literal";
5945 case token_type::value_string:
5946 return "string literal";
5947 case token_type::value_unsigned:
5948 case token_type::value_integer:
5949 case token_type::value_float:
5950 return "number literal";
5951 case token_type::begin_array:
5952 return "'['";
5953 case token_type::begin_object:
5954 return "'{'";
5955 case token_type::end_array:
5956 return "']'";
5957 case token_type::end_object:
5958 return "'}'";
5959 case token_type::name_separator:
5960 return "':'";
5961 case token_type::value_separator:
5962 return "','";
5963 case token_type::parse_error:
5964 return "<parse error>";
5965 case token_type::end_of_input:
5966 return "end of input";
5967 case token_type::literal_or_value:
5968 return "'[', '{', or a literal";
5969 // LCOV_EXCL_START
5970 default: // catch non-enum values
5971 return "unknown token";
5972 // LCOV_EXCL_STOP
5973 }
5974 }
5975 };
5981 template<typename BasicJsonType, typename InputAdapterType>
5982 class lexer : public lexer_base<BasicJsonType>
5983 {
5984 using number_integer_t = typename BasicJsonType::number_integer_t;
5985 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5986 using number_float_t = typename BasicJsonType::number_float_t;
5987 using string_t = typename BasicJsonType::string_t;
5988 using char_type = typename InputAdapterType::char_type;
5989 using char_int_type = typename std::char_traits<char_type>::int_type;
5990
5991 public:
5992 using token_type = typename lexer_base<BasicJsonType>::token_type;
5993
5994 explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false)
5995 : ia(std::move(adapter))
5996 , ignore_comments(ignore_comments_)
5997 , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
5998 {}
5999
6000 // delete because of pointer members
6001 lexer(const lexer&) = delete;
6002 lexer(lexer&&) = default;
6003 lexer& operator=(lexer&) = delete;
6004 lexer& operator=(lexer&&) = default;
6005 ~lexer() = default;
6006
6007 private:
6009 // locales
6011
6013 JSON_HEDLEY_PURE
6014 static char get_decimal_point() noexcept
6015 {
6016 const auto* loc = localeconv();
6017 JSON_ASSERT(loc != nullptr);
6018 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6019 }
6020
6022 // scan functions
6024
6040 int get_codepoint()
6041 {
6042 // this function only makes sense after reading `\u`
6043 JSON_ASSERT(current == 'u');
6044 int codepoint = 0;
6045
6046 const auto factors = { 12u, 8u, 4u, 0u };
6047 for (const auto factor : factors)
6048 {
6049 get();
6050
6051 if (current >= '0' && current <= '9')
6052 {
6053 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6054 }
6055 else if (current >= 'A' && current <= 'F')
6056 {
6057 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6058 }
6059 else if (current >= 'a' && current <= 'f')
6060 {
6061 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6062 }
6063 else
6064 {
6065 return -1;
6066 }
6067 }
6068
6069 JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6070 return codepoint;
6071 }
6072
6088 bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6089 {
6090 JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6091 add(current);
6092
6093 for (auto range = ranges.begin(); range != ranges.end(); ++range)
6094 {
6095 get();
6096 if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6097 {
6098 add(current);
6099 }
6100 else
6101 {
6102 error_message = "invalid string: ill-formed UTF-8 byte";
6103 return false;
6104 }
6105 }
6106
6107 return true;
6108 }
6109
6125 token_type scan_string()
6126 {
6127 // reset token_buffer (ignore opening quote)
6128 reset();
6129
6130 // we entered the function by reading an open quote
6131 JSON_ASSERT(current == '\"');
6132
6133 while (true)
6134 {
6135 // get next character
6136 switch (get())
6137 {
6138 // end of file while parsing string
6139 case std::char_traits<char_type>::eof():
6140 {
6141 error_message = "invalid string: missing closing quote";
6142 return token_type::parse_error;
6143 }
6144
6145 // closing quote
6146 case '\"':
6147 {
6148 return token_type::value_string;
6149 }
6150
6151 // escapes
6152 case '\\':
6153 {
6154 switch (get())
6155 {
6156 // quotation mark
6157 case '\"':
6158 add('\"');
6159 break;
6160 // reverse solidus
6161 case '\\':
6162 add('\\');
6163 break;
6164 // solidus
6165 case '/':
6166 add('/');
6167 break;
6168 // backspace
6169 case 'b':
6170 add('\b');
6171 break;
6172 // form feed
6173 case 'f':
6174 add('\f');
6175 break;
6176 // line feed
6177 case 'n':
6178 add('\n');
6179 break;
6180 // carriage return
6181 case 'r':
6182 add('\r');
6183 break;
6184 // tab
6185 case 't':
6186 add('\t');
6187 break;
6188
6189 // unicode escapes
6190 case 'u':
6191 {
6192 const int codepoint1 = get_codepoint();
6193 int codepoint = codepoint1; // start with codepoint1
6194
6195 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
6196 {
6197 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6198 return token_type::parse_error;
6199 }
6200
6201 // check if code point is a high surrogate
6202 if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6203 {
6204 // expect next \uxxxx entry
6205 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6206 {
6207 const int codepoint2 = get_codepoint();
6208
6209 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
6210 {
6211 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6212 return token_type::parse_error;
6213 }
6214
6215 // check if codepoint2 is a low surrogate
6216 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6217 {
6218 // overwrite codepoint
6219 codepoint = static_cast<int>(
6220 // high surrogate occupies the most significant 22 bits
6221 (static_cast<unsigned int>(codepoint1) << 10u)
6222 // low surrogate occupies the least significant 15 bits
6223 + static_cast<unsigned int>(codepoint2)
6224 // there is still the 0xD800, 0xDC00 and 0x10000 noise
6225 // in the result so we have to subtract with:
6226 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6227 - 0x35FDC00u);
6228 }
6229 else
6230 {
6231 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6232 return token_type::parse_error;
6233 }
6234 }
6235 else
6236 {
6237 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6238 return token_type::parse_error;
6239 }
6240 }
6241 else
6242 {
6243 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6244 {
6245 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6246 return token_type::parse_error;
6247 }
6248 }
6249
6250 // result of the above calculation yields a proper codepoint
6251 JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
6252
6253 // translate codepoint into bytes
6254 if (codepoint < 0x80)
6255 {
6256 // 1-byte characters: 0xxxxxxx (ASCII)
6257 add(static_cast<char_int_type>(codepoint));
6258 }
6259 else if (codepoint <= 0x7FF)
6260 {
6261 // 2-byte characters: 110xxxxx 10xxxxxx
6262 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
6263 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6264 }
6265 else if (codepoint <= 0xFFFF)
6266 {
6267 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
6268 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
6269 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6270 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6271 }
6272 else
6273 {
6274 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
6275 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
6276 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
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
6281 break;
6282 }
6283
6284 // other characters after escape
6285 default:
6286 error_message = "invalid string: forbidden character after backslash";
6287 return token_type::parse_error;
6288 }
6289
6290 break;
6291 }
6292
6293 // invalid control characters
6294 case 0x00:
6295 {
6296 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
6297 return token_type::parse_error;
6298 }
6299
6300 case 0x01:
6301 {
6302 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
6303 return token_type::parse_error;
6304 }
6305
6306 case 0x02:
6307 {
6308 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
6309 return token_type::parse_error;
6310 }
6311
6312 case 0x03:
6313 {
6314 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
6315 return token_type::parse_error;
6316 }
6317
6318 case 0x04:
6319 {
6320 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
6321 return token_type::parse_error;
6322 }
6323
6324 case 0x05:
6325 {
6326 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
6327 return token_type::parse_error;
6328 }
6329
6330 case 0x06:
6331 {
6332 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
6333 return token_type::parse_error;
6334 }
6335
6336 case 0x07:
6337 {
6338 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
6339 return token_type::parse_error;
6340 }
6341
6342 case 0x08:
6343 {
6344 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
6345 return token_type::parse_error;
6346 }
6347
6348 case 0x09:
6349 {
6350 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
6351 return token_type::parse_error;
6352 }
6353
6354 case 0x0A:
6355 {
6356 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
6357 return token_type::parse_error;
6358 }
6359
6360 case 0x0B:
6361 {
6362 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
6363 return token_type::parse_error;
6364 }
6365
6366 case 0x0C:
6367 {
6368 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
6369 return token_type::parse_error;
6370 }
6371
6372 case 0x0D:
6373 {
6374 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
6375 return token_type::parse_error;
6376 }
6377
6378 case 0x0E:
6379 {
6380 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
6381 return token_type::parse_error;
6382 }
6383
6384 case 0x0F:
6385 {
6386 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
6387 return token_type::parse_error;
6388 }
6389
6390 case 0x10:
6391 {
6392 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
6393 return token_type::parse_error;
6394 }
6395
6396 case 0x11:
6397 {
6398 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
6399 return token_type::parse_error;
6400 }
6401
6402 case 0x12:
6403 {
6404 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
6405 return token_type::parse_error;
6406 }
6407
6408 case 0x13:
6409 {
6410 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
6411 return token_type::parse_error;
6412 }
6413
6414 case 0x14:
6415 {
6416 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
6417 return token_type::parse_error;
6418 }
6419
6420 case 0x15:
6421 {
6422 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
6423 return token_type::parse_error;
6424 }
6425
6426 case 0x16:
6427 {
6428 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
6429 return token_type::parse_error;
6430 }
6431
6432 case 0x17:
6433 {
6434 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
6435 return token_type::parse_error;
6436 }
6437
6438 case 0x18:
6439 {
6440 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
6441 return token_type::parse_error;
6442 }
6443
6444 case 0x19:
6445 {
6446 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
6447 return token_type::parse_error;
6448 }
6449
6450 case 0x1A:
6451 {
6452 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
6453 return token_type::parse_error;
6454 }
6455
6456 case 0x1B:
6457 {
6458 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
6459 return token_type::parse_error;
6460 }
6461
6462 case 0x1C:
6463 {
6464 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
6465 return token_type::parse_error;
6466 }
6467
6468 case 0x1D:
6469 {
6470 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
6471 return token_type::parse_error;
6472 }
6473
6474 case 0x1E:
6475 {
6476 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
6477 return token_type::parse_error;
6478 }
6479
6480 case 0x1F:
6481 {
6482 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
6483 return token_type::parse_error;
6484 }
6485
6486 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
6487 case 0x20:
6488 case 0x21:
6489 case 0x23:
6490 case 0x24:
6491 case 0x25:
6492 case 0x26:
6493 case 0x27:
6494 case 0x28:
6495 case 0x29:
6496 case 0x2A:
6497 case 0x2B:
6498 case 0x2C:
6499 case 0x2D:
6500 case 0x2E:
6501 case 0x2F:
6502 case 0x30:
6503 case 0x31:
6504 case 0x32:
6505 case 0x33:
6506 case 0x34:
6507 case 0x35:
6508 case 0x36:
6509 case 0x37:
6510 case 0x38:
6511 case 0x39:
6512 case 0x3A:
6513 case 0x3B:
6514 case 0x3C:
6515 case 0x3D:
6516 case 0x3E:
6517 case 0x3F:
6518 case 0x40:
6519 case 0x41:
6520 case 0x42:
6521 case 0x43:
6522 case 0x44:
6523 case 0x45:
6524 case 0x46:
6525 case 0x47:
6526 case 0x48:
6527 case 0x49:
6528 case 0x4A:
6529 case 0x4B:
6530 case 0x4C:
6531 case 0x4D:
6532 case 0x4E:
6533 case 0x4F:
6534 case 0x50:
6535 case 0x51:
6536 case 0x52:
6537 case 0x53:
6538 case 0x54:
6539 case 0x55:
6540 case 0x56:
6541 case 0x57:
6542 case 0x58:
6543 case 0x59:
6544 case 0x5A:
6545 case 0x5B:
6546 case 0x5D:
6547 case 0x5E:
6548 case 0x5F:
6549 case 0x60:
6550 case 0x61:
6551 case 0x62:
6552 case 0x63:
6553 case 0x64:
6554 case 0x65:
6555 case 0x66:
6556 case 0x67:
6557 case 0x68:
6558 case 0x69:
6559 case 0x6A:
6560 case 0x6B:
6561 case 0x6C:
6562 case 0x6D:
6563 case 0x6E:
6564 case 0x6F:
6565 case 0x70:
6566 case 0x71:
6567 case 0x72:
6568 case 0x73:
6569 case 0x74:
6570 case 0x75:
6571 case 0x76:
6572 case 0x77:
6573 case 0x78:
6574 case 0x79:
6575 case 0x7A:
6576 case 0x7B:
6577 case 0x7C:
6578 case 0x7D:
6579 case 0x7E:
6580 case 0x7F:
6581 {
6582 add(current);
6583 break;
6584 }
6585
6586 // U+0080..U+07FF: bytes C2..DF 80..BF
6587 case 0xC2:
6588 case 0xC3:
6589 case 0xC4:
6590 case 0xC5:
6591 case 0xC6:
6592 case 0xC7:
6593 case 0xC8:
6594 case 0xC9:
6595 case 0xCA:
6596 case 0xCB:
6597 case 0xCC:
6598 case 0xCD:
6599 case 0xCE:
6600 case 0xCF:
6601 case 0xD0:
6602 case 0xD1:
6603 case 0xD2:
6604 case 0xD3:
6605 case 0xD4:
6606 case 0xD5:
6607 case 0xD6:
6608 case 0xD7:
6609 case 0xD8:
6610 case 0xD9:
6611 case 0xDA:
6612 case 0xDB:
6613 case 0xDC:
6614 case 0xDD:
6615 case 0xDE:
6616 case 0xDF:
6617 {
6618 if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
6619 {
6620 return token_type::parse_error;
6621 }
6622 break;
6623 }
6624
6625 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
6626 case 0xE0:
6627 {
6628 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
6629 {
6630 return token_type::parse_error;
6631 }
6632 break;
6633 }
6634
6635 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
6636 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
6637 case 0xE1:
6638 case 0xE2:
6639 case 0xE3:
6640 case 0xE4:
6641 case 0xE5:
6642 case 0xE6:
6643 case 0xE7:
6644 case 0xE8:
6645 case 0xE9:
6646 case 0xEA:
6647 case 0xEB:
6648 case 0xEC:
6649 case 0xEE:
6650 case 0xEF:
6651 {
6652 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
6653 {
6654 return token_type::parse_error;
6655 }
6656 break;
6657 }
6658
6659 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
6660 case 0xED:
6661 {
6662 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
6663 {
6664 return token_type::parse_error;
6665 }
6666 break;
6667 }
6668
6669 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
6670 case 0xF0:
6671 {
6672 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6673 {
6674 return token_type::parse_error;
6675 }
6676 break;
6677 }
6678
6679 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
6680 case 0xF1:
6681 case 0xF2:
6682 case 0xF3:
6683 {
6684 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6685 {
6686 return token_type::parse_error;
6687 }
6688 break;
6689 }
6690
6691 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
6692 case 0xF4:
6693 {
6694 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
6695 {
6696 return token_type::parse_error;
6697 }
6698 break;
6699 }
6700
6701 // remaining bytes (80..C1 and F5..FF) are ill-formed
6702 default:
6703 {
6704 error_message = "invalid string: ill-formed UTF-8 byte";
6705 return token_type::parse_error;
6706 }
6707 }
6708 }
6709 }
6710
6715 bool scan_comment()
6716 {
6717 switch (get())
6718 {
6719 // single-line comments skip input until a newline or EOF is read
6720 case '/':
6721 {
6722 while (true)
6723 {
6724 switch (get())
6725 {
6726 case '\n':
6727 case '\r':
6728 case std::char_traits<char_type>::eof():
6729 case '\0':
6730 return true;
6731
6732 default:
6733 break;
6734 }
6735 }
6736 }
6737
6738 // multi-line comments skip input until */ is read
6739 case '*':
6740 {
6741 while (true)
6742 {
6743 switch (get())
6744 {
6745 case std::char_traits<char_type>::eof():
6746 case '\0':
6747 {
6748 error_message = "invalid comment; missing closing '*/'";
6749 return false;
6750 }
6751
6752 case '*':
6753 {
6754 switch (get())
6755 {
6756 case '/':
6757 return true;
6758
6759 default:
6760 {
6761 unget();
6762 break;
6763 }
6764 }
6765 }
6766
6767 default:
6768 break;
6769 }
6770 }
6771 }
6772
6773 // unexpected character after reading '/'
6774 default:
6775 {
6776 error_message = "invalid comment; expecting '/' or '*' after '/'";
6777 return false;
6778 }
6779 }
6780 }
6781
6782 JSON_HEDLEY_NON_NULL(2)
6783 static void strtof(float& f, const char* str, char** endptr) noexcept
6784 {
6785 f = std::strtof(str, endptr);
6786 }
6787
6788 JSON_HEDLEY_NON_NULL(2)
6789 static void strtof(double& f, const char* str, char** endptr) noexcept
6790 {
6791 f = std::strtod(str, endptr);
6792 }
6793
6794 JSON_HEDLEY_NON_NULL(2)
6795 static void strtof(long double& f, const char* str, char** endptr) noexcept
6796 {
6797 f = std::strtold(str, endptr);
6798 }
6799
6840 token_type scan_number() // lgtm [cpp/use-of-goto]
6841 {
6842 // reset token_buffer to store the number's bytes
6843 reset();
6844
6845 // the type of the parsed number; initially set to unsigned; will be
6846 // changed if minus sign, decimal point or exponent is read
6847 token_type number_type = token_type::value_unsigned;
6848
6849 // state (init): we just found out we need to scan a number
6850 switch (current)
6851 {
6852 case '-':
6853 {
6854 add(current);
6855 goto scan_number_minus;
6856 }
6857
6858 case '0':
6859 {
6860 add(current);
6861 goto scan_number_zero;
6862 }
6863
6864 case '1':
6865 case '2':
6866 case '3':
6867 case '4':
6868 case '5':
6869 case '6':
6870 case '7':
6871 case '8':
6872 case '9':
6873 {
6874 add(current);
6875 goto scan_number_any1;
6876 }
6877
6878 // all other characters are rejected outside scan_number()
6879 default: // LCOV_EXCL_LINE
6880 JSON_ASSERT(false); // LCOV_EXCL_LINE
6881 }
6882
6883 scan_number_minus:
6884 // state: we just parsed a leading minus sign
6885 number_type = token_type::value_integer;
6886 switch (get())
6887 {
6888 case '0':
6889 {
6890 add(current);
6891 goto scan_number_zero;
6892 }
6893
6894 case '1':
6895 case '2':
6896 case '3':
6897 case '4':
6898 case '5':
6899 case '6':
6900 case '7':
6901 case '8':
6902 case '9':
6903 {
6904 add(current);
6905 goto scan_number_any1;
6906 }
6907
6908 default:
6909 {
6910 error_message = "invalid number; expected digit after '-'";
6911 return token_type::parse_error;
6912 }
6913 }
6914
6915 scan_number_zero:
6916 // state: we just parse a zero (maybe with a leading minus sign)
6917 switch (get())
6918 {
6919 case '.':
6920 {
6921 add(decimal_point_char);
6922 goto scan_number_decimal1;
6923 }
6924
6925 case 'e':
6926 case 'E':
6927 {
6928 add(current);
6929 goto scan_number_exponent;
6930 }
6931
6932 default:
6933 goto scan_number_done;
6934 }
6935
6936 scan_number_any1:
6937 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
6938 switch (get())
6939 {
6940 case '0':
6941 case '1':
6942 case '2':
6943 case '3':
6944 case '4':
6945 case '5':
6946 case '6':
6947 case '7':
6948 case '8':
6949 case '9':
6950 {
6951 add(current);
6952 goto scan_number_any1;
6953 }
6954
6955 case '.':
6956 {
6957 add(decimal_point_char);
6958 goto scan_number_decimal1;
6959 }
6960
6961 case 'e':
6962 case 'E':
6963 {
6964 add(current);
6965 goto scan_number_exponent;
6966 }
6967
6968 default:
6969 goto scan_number_done;
6970 }
6971
6972 scan_number_decimal1:
6973 // state: we just parsed a decimal point
6974 number_type = token_type::value_float;
6975 switch (get())
6976 {
6977 case '0':
6978 case '1':
6979 case '2':
6980 case '3':
6981 case '4':
6982 case '5':
6983 case '6':
6984 case '7':
6985 case '8':
6986 case '9':
6987 {
6988 add(current);
6989 goto scan_number_decimal2;
6990 }
6991
6992 default:
6993 {
6994 error_message = "invalid number; expected digit after '.'";
6995 return token_type::parse_error;
6996 }
6997 }
6998
6999 scan_number_decimal2:
7000 // we just parsed at least one number after a decimal point
7001 switch (get())
7002 {
7003 case '0':
7004 case '1':
7005 case '2':
7006 case '3':
7007 case '4':
7008 case '5':
7009 case '6':
7010 case '7':
7011 case '8':
7012 case '9':
7013 {
7014 add(current);
7015 goto scan_number_decimal2;
7016 }
7017
7018 case 'e':
7019 case 'E':
7020 {
7021 add(current);
7022 goto scan_number_exponent;
7023 }
7024
7025 default:
7026 goto scan_number_done;
7027 }
7028
7029 scan_number_exponent:
7030 // we just parsed an exponent
7031 number_type = token_type::value_float;
7032 switch (get())
7033 {
7034 case '+':
7035 case '-':
7036 {
7037 add(current);
7038 goto scan_number_sign;
7039 }
7040
7041 case '0':
7042 case '1':
7043 case '2':
7044 case '3':
7045 case '4':
7046 case '5':
7047 case '6':
7048 case '7':
7049 case '8':
7050 case '9':
7051 {
7052 add(current);
7053 goto scan_number_any2;
7054 }
7055
7056 default:
7057 {
7058 error_message =
7059 "invalid number; expected '+', '-', or digit after exponent";
7060 return token_type::parse_error;
7061 }
7062 }
7063
7064 scan_number_sign:
7065 // we just parsed an exponent sign
7066 switch (get())
7067 {
7068 case '0':
7069 case '1':
7070 case '2':
7071 case '3':
7072 case '4':
7073 case '5':
7074 case '6':
7075 case '7':
7076 case '8':
7077 case '9':
7078 {
7079 add(current);
7080 goto scan_number_any2;
7081 }
7082
7083 default:
7084 {
7085 error_message = "invalid number; expected digit after exponent sign";
7086 return token_type::parse_error;
7087 }
7088 }
7089
7090 scan_number_any2:
7091 // we just parsed a number after the exponent or exponent sign
7092 switch (get())
7093 {
7094 case '0':
7095 case '1':
7096 case '2':
7097 case '3':
7098 case '4':
7099 case '5':
7100 case '6':
7101 case '7':
7102 case '8':
7103 case '9':
7104 {
7105 add(current);
7106 goto scan_number_any2;
7107 }
7108
7109 default:
7110 goto scan_number_done;
7111 }
7112
7113 scan_number_done:
7114 // unget the character after the number (we only read it to know that
7115 // we are done scanning a number)
7116 unget();
7117
7118 char* endptr = nullptr;
7119 errno = 0;
7120
7121 // try to parse integers first and fall back to floats
7122 if (number_type == token_type::value_unsigned)
7123 {
7124 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7125
7126 // we checked the number format before
7127 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7128
7129 if (errno == 0)
7130 {
7131 value_unsigned = static_cast<number_unsigned_t>(x);
7132 if (value_unsigned == x)
7133 {
7134 return token_type::value_unsigned;
7135 }
7136 }
7137 }
7138 else if (number_type == token_type::value_integer)
7139 {
7140 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7141
7142 // we checked the number format before
7143 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7144
7145 if (errno == 0)
7146 {
7147 value_integer = static_cast<number_integer_t>(x);
7148 if (value_integer == x)
7149 {
7150 return token_type::value_integer;
7151 }
7152 }
7153 }
7154
7155 // this code is reached if we parse a floating-point number or if an
7156 // integer conversion above failed
7157 strtof(value_float, token_buffer.data(), &endptr);
7158
7159 // we checked the number format before
7160 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7161
7162 return token_type::value_float;
7163 }
7164
7170 JSON_HEDLEY_NON_NULL(2)
7171 token_type scan_literal(const char_type* literal_text, const std::size_t length,
7172 token_type return_type)
7173 {
7174 JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
7175 for (std::size_t i = 1; i < length; ++i)
7176 {
7177 if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
7178 {
7179 error_message = "invalid literal";
7180 return token_type::parse_error;
7181 }
7182 }
7183 return return_type;
7184 }
7185
7187 // input management
7189
7191 void reset() noexcept
7192 {
7193 token_buffer.clear();
7194 token_string.clear();
7195 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7196 }
7197
7198 /*
7199 @brief get next character from the input
7200
7201 This function provides the interface to the used input adapter. It does
7202 not throw in case the input reached EOF, but returns a
7203 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
7204 for use in error messages.
7205
7206 @return character read from the input
7207 */
7208 char_int_type get()
7209 {
7210 ++position.chars_read_total;
7211 ++position.chars_read_current_line;
7212
7213 if (next_unget)
7214 {
7215 // just reset the next_unget variable and work with current
7216 next_unget = false;
7217 }
7218 else
7219 {
7220 current = ia.get_character();
7221 }
7222
7223 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7224 {
7225 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7226 }
7227
7228 if (current == '\n')
7229 {
7230 ++position.lines_read;
7231 position.chars_read_current_line = 0;
7232 }
7233
7234 return current;
7235 }
7236
7245 void unget()
7246 {
7247 next_unget = true;
7248
7249 --position.chars_read_total;
7250
7251 // in case we "unget" a newline, we have to also decrement the lines_read
7252 if (position.chars_read_current_line == 0)
7253 {
7254 if (position.lines_read > 0)
7255 {
7256 --position.lines_read;
7257 }
7258 }
7259 else
7260 {
7261 --position.chars_read_current_line;
7262 }
7263
7264 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7265 {
7266 JSON_ASSERT(!token_string.empty());
7267 token_string.pop_back();
7268 }
7269 }
7270
7272 void add(char_int_type c)
7273 {
7274 token_buffer.push_back(static_cast<typename string_t::value_type>(c));
7275 }
7276
7277 public:
7279 // value getters
7281
7283 constexpr number_integer_t get_number_integer() const noexcept
7284 {
7285 return value_integer;
7286 }
7287
7289 constexpr number_unsigned_t get_number_unsigned() const noexcept
7290 {
7291 return value_unsigned;
7292 }
7293
7295 constexpr number_float_t get_number_float() const noexcept
7296 {
7297 return value_float;
7298 }
7299
7301 string_t& get_string()
7302 {
7303 return token_buffer;
7304 }
7305
7307 // diagnostics
7309
7311 constexpr position_t get_position() const noexcept
7312 {
7313 return position;
7314 }
7315
7319 std::string get_token_string() const
7320 {
7321 // escape control characters
7322 std::string result;
7323 for (const auto c : token_string)
7324 {
7325 if (static_cast<unsigned char>(c) <= '\x1F')
7326 {
7327 // escape control characters
7328 std::array<char, 9> cs{{}};
7329 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c));
7330 result += cs.data();
7331 }
7332 else
7333 {
7334 // add character as is
7335 result.push_back(static_cast<std::string::value_type>(c));
7336 }
7337 }
7338
7339 return result;
7340 }
7341
7343
7344 constexpr const char* get_error_message() const noexcept
7345 {
7346 return error_message;
7347 }
7348
7350 // actual scanner
7352
7357 bool skip_bom()
7358 {
7359 if (get() == 0xEF)
7360 {
7361 // check if we completely parse the BOM
7362 return get() == 0xBB && get() == 0xBF;
7363 }
7364
7365 // the first character is not the beginning of the BOM; unget it to
7366 // process is later
7367 unget();
7368 return true;
7369 }
7370
7371 void skip_whitespace()
7372 {
7373 do
7374 {
7375 get();
7376 }
7377 while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
7378 }
7379
7380 token_type scan()
7381 {
7382 // initially, skip the BOM
7383 if (position.chars_read_total == 0 && !skip_bom())
7384 {
7385 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
7386 return token_type::parse_error;
7387 }
7388
7389 // read next character and ignore whitespace
7390 skip_whitespace();
7391
7392 // ignore comments
7393 if (ignore_comments && current == '/')
7394 {
7395 if (!scan_comment())
7396 {
7397 return token_type::parse_error;
7398 }
7399
7400 // skip following whitespace
7401 skip_whitespace();
7402 }
7403
7404 switch (current)
7405 {
7406 // structural characters
7407 case '[':
7408 return token_type::begin_array;
7409 case ']':
7410 return token_type::end_array;
7411 case '{':
7412 return token_type::begin_object;
7413 case '}':
7414 return token_type::end_object;
7415 case ':':
7416 return token_type::name_separator;
7417 case ',':
7418 return token_type::value_separator;
7419
7420 // literals
7421 case 't':
7422 {
7423 std::array<char_type, 4> true_literal = {{'t', 'r', 'u', 'e'}};
7424 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
7425 }
7426 case 'f':
7427 {
7428 std::array<char_type, 5> false_literal = {{'f', 'a', 'l', 's', 'e'}};
7429 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
7430 }
7431 case 'n':
7432 {
7433 std::array<char_type, 4> null_literal = {{'n', 'u', 'l', 'l'}};
7434 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
7435 }
7436
7437 // string
7438 case '\"':
7439 return scan_string();
7440
7441 // number
7442 case '-':
7443 case '0':
7444 case '1':
7445 case '2':
7446 case '3':
7447 case '4':
7448 case '5':
7449 case '6':
7450 case '7':
7451 case '8':
7452 case '9':
7453 return scan_number();
7454
7455 // end of input (the null byte is needed when parsing from
7456 // string literals)
7457 case '\0':
7458 case std::char_traits<char_type>::eof():
7459 return token_type::end_of_input;
7460
7461 // error
7462 default:
7463 error_message = "invalid literal";
7464 return token_type::parse_error;
7465 }
7466 }
7467
7468 private:
7470 InputAdapterType ia;
7471
7473 const bool ignore_comments = false;
7474
7476 char_int_type current = std::char_traits<char_type>::eof();
7477
7479 bool next_unget = false;
7480
7482 position_t position {};
7483
7485 std::vector<char_type> token_string {};
7486
7488 string_t token_buffer {};
7489
7491 const char* error_message = "";
7492
7493 // number values
7494 number_integer_t value_integer = 0;
7495 number_unsigned_t value_unsigned = 0;
7496 number_float_t value_float = 0;
7497
7499 const char_int_type decimal_point_char = '.';
7500 };
7501 } // namespace detail
7502 } // namespace nlohmann
7503
7504 // #include <nlohmann/detail/macro_scope.hpp>
7505
7506 // #include <nlohmann/detail/meta/is_sax.hpp>
7507
7508
7509 #include <cstdint> // size_t
7510 #include <utility> // declval
7511 #include <string> // string
7512
7513 // #include <nlohmann/detail/meta/detected.hpp>
7514
7515 // #include <nlohmann/detail/meta/type_traits.hpp>
7516
7517
7518 namespace nlohmann
7519 {
7520 namespace detail
7521 {
7522 template<typename T>
7523 using null_function_t = decltype(std::declval<T&>().null());
7524
7525 template<typename T>
7526 using boolean_function_t =
7527 decltype(std::declval<T&>().boolean(std::declval<bool>()));
7528
7529 template<typename T, typename Integer>
7530 using number_integer_function_t =
7531 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
7532
7533 template<typename T, typename Unsigned>
7534 using number_unsigned_function_t =
7535 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
7536
7537 template<typename T, typename Float, typename String>
7538 using number_float_function_t = decltype(std::declval<T&>().number_float(
7539 std::declval<Float>(), std::declval<const String&>()));
7540
7541 template<typename T, typename String>
7542 using string_function_t =
7543 decltype(std::declval<T&>().string(std::declval<String&>()));
7544
7545 template<typename T, typename Binary>
7546 using binary_function_t =
7547 decltype(std::declval<T&>().binary(std::declval<Binary&>()));
7548
7549 template<typename T>
7550 using start_object_function_t =
7551 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
7552
7553 template<typename T, typename String>
7554 using key_function_t =
7555 decltype(std::declval<T&>().key(std::declval<String&>()));
7556
7557 template<typename T>
7558 using end_object_function_t = decltype(std::declval<T&>().end_object());
7559
7560 template<typename T>
7561 using start_array_function_t =
7562 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
7563
7564 template<typename T>
7565 using end_array_function_t = decltype(std::declval<T&>().end_array());
7566
7567 template<typename T, typename Exception>
7568 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
7569 std::declval<std::size_t>(), std::declval<const std::string&>(),
7570 std::declval<const Exception&>()));
7571
7572 template<typename SAX, typename BasicJsonType>
7573 struct is_sax
7574 {
7575 private:
7576 static_assert(is_basic_json<BasicJsonType>::value,
7577 "BasicJsonType must be of type basic_json<...>");
7578
7579 using number_integer_t = typename BasicJsonType::number_integer_t;
7580 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7581 using number_float_t = typename BasicJsonType::number_float_t;
7582 using string_t = typename BasicJsonType::string_t;
7583 using binary_t = typename BasicJsonType::binary_t;
7584 using exception_t = typename BasicJsonType::exception;
7585
7586 public:
7587 static constexpr bool value =
7588 is_detected_exact<bool, null_function_t, SAX>::value &&
7589 is_detected_exact<bool, boolean_function_t, SAX>::value &&
7590 is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
7591 is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
7592 is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
7593 is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
7594 is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
7595 is_detected_exact<bool, start_object_function_t, SAX>::value &&
7596 is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
7597 is_detected_exact<bool, end_object_function_t, SAX>::value &&
7598 is_detected_exact<bool, start_array_function_t, SAX>::value &&
7599 is_detected_exact<bool, end_array_function_t, SAX>::value &&
7600 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
7601 };
7602
7603 template<typename SAX, typename BasicJsonType>
7604 struct is_sax_static_asserts
7605 {
7606 private:
7607 static_assert(is_basic_json<BasicJsonType>::value,
7608 "BasicJsonType must be of type basic_json<...>");
7609
7610 using number_integer_t = typename BasicJsonType::number_integer_t;
7611 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7612 using number_float_t = typename BasicJsonType::number_float_t;
7613 using string_t = typename BasicJsonType::string_t;
7614 using binary_t = typename BasicJsonType::binary_t;
7615 using exception_t = typename BasicJsonType::exception;
7616
7617 public:
7618 static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
7619 "Missing/invalid function: bool null()");
7620 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
7621 "Missing/invalid function: bool boolean(bool)");
7622 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
7623 "Missing/invalid function: bool boolean(bool)");
7624 static_assert(
7625 is_detected_exact<bool, number_integer_function_t, SAX,
7626 number_integer_t>::value,
7627 "Missing/invalid function: bool number_integer(number_integer_t)");
7628 static_assert(
7629 is_detected_exact<bool, number_unsigned_function_t, SAX,
7630 number_unsigned_t>::value,
7631 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
7632 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
7633 number_float_t, string_t>::value,
7634 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
7635 static_assert(
7636 is_detected_exact<bool, string_function_t, SAX, string_t>::value,
7637 "Missing/invalid function: bool string(string_t&)");
7638 static_assert(
7639 is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,
7640 "Missing/invalid function: bool binary(binary_t&)");
7641 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
7642 "Missing/invalid function: bool start_object(std::size_t)");
7643 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
7644 "Missing/invalid function: bool key(string_t&)");
7645 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
7646 "Missing/invalid function: bool end_object()");
7647 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
7648 "Missing/invalid function: bool start_array(std::size_t)");
7649 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
7650 "Missing/invalid function: bool end_array()");
7651 static_assert(
7652 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
7653 "Missing/invalid function: bool parse_error(std::size_t, const "
7654 "std::string&, const exception&)");
7655 };
7656 } // namespace detail
7657 } // namespace nlohmann
7658
7659 // #include <nlohmann/detail/value_t.hpp>
7660
7661
7662 namespace nlohmann
7663 {
7664 namespace detail
7665 {
7666
7668 enum class cbor_tag_handler_t
7669 {
7670 error,
7671 ignore
7672 };
7673
7681 static inline bool little_endianess(int num = 1) noexcept
7682 {
7683 return *reinterpret_cast<char*>(&num) == 1;
7684 }
7685
7686
7688 // binary reader //
7690
7694 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
7695 class binary_reader
7696 {
7697 using number_integer_t = typename BasicJsonType::number_integer_t;
7698 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7699 using number_float_t = typename BasicJsonType::number_float_t;
7700 using string_t = typename BasicJsonType::string_t;
7701 using binary_t = typename BasicJsonType::binary_t;
7702 using json_sax_t = SAX;
7703 using char_type = typename InputAdapterType::char_type;
7704 using char_int_type = typename std::char_traits<char_type>::int_type;
7705
7706 public:
7712 explicit binary_reader(InputAdapterType&& adapter) : ia(std::move(adapter))
7713 {
7714 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
7715 }
7716
7717 // make class move-only
7718 binary_reader(const binary_reader&) = delete;
7719 binary_reader(binary_reader&&) = default;
7720 binary_reader& operator=(const binary_reader&) = delete;
7721 binary_reader& operator=(binary_reader&&) = default;
7722 ~binary_reader() = default;
7723
7732 JSON_HEDLEY_NON_NULL(3)
7733 bool sax_parse(const input_format_t format,
7734 json_sax_t* sax_,
7735 const bool strict = true,
7736 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
7737 {
7738 sax = sax_;
7739 bool result = false;
7740
7741 switch (format)
7742 {
7743 case input_format_t::bson:
7744 result = parse_bson_internal();
7745 break;
7746
7747 case input_format_t::cbor:
7748 result = parse_cbor_internal(true, tag_handler);
7749 break;
7750
7751 case input_format_t::msgpack:
7752 result = parse_msgpack_internal();
7753 break;
7754
7755 case input_format_t::ubjson:
7756 result = parse_ubjson_internal();
7757 break;
7758
7759 default: // LCOV_EXCL_LINE
7760 JSON_ASSERT(false); // LCOV_EXCL_LINE
7761 }
7762
7763 // strict mode: next byte must be EOF
7764 if (result && strict)
7765 {
7766 if (format == input_format_t::ubjson)
7767 {
7768 get_ignore_noop();
7769 }
7770 else
7771 {
7772 get();
7773 }
7774
7775 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
7776 {
7777 return sax->parse_error(chars_read, get_token_string(),
7778 parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
7779 }
7780 }
7781
7782 return result;
7783 }
7784
7785 private:
7787 // BSON //
7789
7794 bool parse_bson_internal()
7795 {
7796 std::int32_t document_size{};
7797 get_number<std::int32_t, true>(input_format_t::bson, document_size);
7798
7799 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
7800 {
7801 return false;
7802 }
7803
7804 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
7805 {
7806 return false;
7807 }
7808
7809 return sax->end_object();
7810 }
7811
7819 bool get_bson_cstr(string_t& result)
7820 {
7821 auto out = std::back_inserter(result);
7822 while (true)
7823 {
7824 get();
7825 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
7826 {
7827 return false;
7828 }
7829 if (current == 0x00)
7830 {
7831 return true;
7832 }
7833 *out++ = static_cast<typename string_t::value_type>(current);
7834 }
7835 }
7836
7848 template<typename NumberType>
7849 bool get_bson_string(const NumberType len, string_t& result)
7850 {
7851 if (JSON_HEDLEY_UNLIKELY(len < 1))
7852 {
7853 auto last_token = get_token_string();
7854 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")));
7855 }
7856
7857 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
7858 }
7859
7869 template<typename NumberType>
7870 bool get_bson_binary(const NumberType len, binary_t& result)
7871 {
7872 if (JSON_HEDLEY_UNLIKELY(len < 0))
7873 {
7874 auto last_token = get_token_string();
7875 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")));
7876 }
7877
7878 // All BSON binary values have a subtype
7879 std::uint8_t subtype{};
7880 get_number<std::uint8_t>(input_format_t::bson, subtype);
7881 result.set_subtype(subtype);
7882
7883 return get_binary(input_format_t::bson, len, result);
7884 }
7885
7896 bool parse_bson_element_internal(const char_int_type element_type,
7897 const std::size_t element_type_parse_position)
7898 {
7899 switch (element_type)
7900 {
7901 case 0x01: // double
7902 {
7903 double number{};
7904 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
7905 }
7906
7907 case 0x02: // string
7908 {
7909 std::int32_t len{};
7910 string_t value;
7911 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
7912 }
7913
7914 case 0x03: // object
7915 {
7916 return parse_bson_internal();
7917 }
7918
7919 case 0x04: // array
7920 {
7921 return parse_bson_array();
7922 }
7923
7924 case 0x05: // binary
7925 {
7926 std::int32_t len{};
7927 binary_t value;
7928 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
7929 }
7930
7931 case 0x08: // boolean
7932 {
7933 return sax->boolean(get() != 0);
7934 }
7935
7936 case 0x0A: // null
7937 {
7938 return sax->null();
7939 }
7940
7941 case 0x10: // int32
7942 {
7943 std::int32_t value{};
7944 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
7945 }
7946
7947 case 0x12: // int64
7948 {
7949 std::int64_t value{};
7950 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
7951 }
7952
7953 default: // anything else not supported (yet)
7954 {
7955 std::array<char, 3> cr{{}};
7956 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type));
7957 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())));
7958 }
7959 }
7960 }
7961
7974 bool parse_bson_element_list(const bool is_array)
7975 {
7976 string_t key;
7977
7978 while (auto element_type = get())
7979 {
7980 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
7981 {
7982 return false;
7983 }
7984
7985 const std::size_t element_type_parse_position = chars_read;
7986 if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
7987 {
7988 return false;
7989 }
7990
7991 if (!is_array && !sax->key(key))
7992 {
7993 return false;
7994 }
7995
7996 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
7997 {
7998 return false;
7999 }
8000
8001 // get_bson_cstr only appends
8002 key.clear();
8003 }
8004
8005 return true;
8006 }
8007
8012 bool parse_bson_array()
8013 {
8014 std::int32_t document_size{};
8015 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8016
8017 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
8018 {
8019 return false;
8020 }
8021
8022 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8023 {
8024 return false;
8025 }
8026
8027 return sax->end_array();
8028 }
8029
8031 // CBOR //
8033
8042 bool parse_cbor_internal(const bool get_char,
8043 const cbor_tag_handler_t tag_handler)
8044 {
8045 switch (get_char ? get() : current)
8046 {
8047 // EOF
8048 case std::char_traits<char_type>::eof():
8049 return unexpect_eof(input_format_t::cbor, "value");
8050
8051 // Integer 0x00..0x17 (0..23)
8052 case 0x00:
8053 case 0x01:
8054 case 0x02:
8055 case 0x03:
8056 case 0x04:
8057 case 0x05:
8058 case 0x06:
8059 case 0x07:
8060 case 0x08:
8061 case 0x09:
8062 case 0x0A:
8063 case 0x0B:
8064 case 0x0C:
8065 case 0x0D:
8066 case 0x0E:
8067 case 0x0F:
8068 case 0x10:
8069 case 0x11:
8070 case 0x12:
8071 case 0x13:
8072 case 0x14:
8073 case 0x15:
8074 case 0x16:
8075 case 0x17:
8076 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8077
8078 case 0x18: // Unsigned integer (one-byte uint8_t follows)
8079 {
8080 std::uint8_t number{};
8081 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8082 }
8083
8084 case 0x19: // Unsigned integer (two-byte uint16_t follows)
8085 {
8086 std::uint16_t number{};
8087 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8088 }
8089
8090 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8091 {
8092 std::uint32_t number{};
8093 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8094 }
8095
8096 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8097 {
8098 std::uint64_t number{};
8099 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8100 }
8101
8102 // Negative integer -1-0x00..-1-0x17 (-1..-24)
8103 case 0x20:
8104 case 0x21:
8105 case 0x22:
8106 case 0x23:
8107 case 0x24:
8108 case 0x25:
8109 case 0x26:
8110 case 0x27:
8111 case 0x28:
8112 case 0x29:
8113 case 0x2A:
8114 case 0x2B:
8115 case 0x2C:
8116 case 0x2D:
8117 case 0x2E:
8118 case 0x2F:
8119 case 0x30:
8120 case 0x31:
8121 case 0x32:
8122 case 0x33:
8123 case 0x34:
8124 case 0x35:
8125 case 0x36:
8126 case 0x37:
8127 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8128
8129 case 0x38: // Negative integer (one-byte uint8_t follows)
8130 {
8131 std::uint8_t number{};
8132 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8133 }
8134
8135 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8136 {
8137 std::uint16_t number{};
8138 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8139 }
8140
8141 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8142 {
8143 std::uint32_t number{};
8144 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8145 }
8146
8147 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8148 {
8149 std::uint64_t number{};
8150 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8151 - static_cast<number_integer_t>(number));
8152 }
8153
8154 // Binary data (0x00..0x17 bytes follow)
8155 case 0x40:
8156 case 0x41:
8157 case 0x42:
8158 case 0x43:
8159 case 0x44:
8160 case 0x45:
8161 case 0x46:
8162 case 0x47:
8163 case 0x48:
8164 case 0x49:
8165 case 0x4A:
8166 case 0x4B:
8167 case 0x4C:
8168 case 0x4D:
8169 case 0x4E:
8170 case 0x4F:
8171 case 0x50:
8172 case 0x51:
8173 case 0x52:
8174 case 0x53:
8175 case 0x54:
8176 case 0x55:
8177 case 0x56:
8178 case 0x57:
8179 case 0x58: // Binary data (one-byte uint8_t for n follows)
8180 case 0x59: // Binary data (two-byte uint16_t for n follow)
8181 case 0x5A: // Binary data (four-byte uint32_t for n follow)
8182 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8183 case 0x5F: // Binary data (indefinite length)
8184 {
8185 binary_t b;
8186 return get_cbor_binary(b) && sax->binary(b);
8187 }
8188
8189 // UTF-8 string (0x00..0x17 bytes follow)
8190 case 0x60:
8191 case 0x61:
8192 case 0x62:
8193 case 0x63:
8194 case 0x64:
8195 case 0x65:
8196 case 0x66:
8197 case 0x67:
8198 case 0x68:
8199 case 0x69:
8200 case 0x6A:
8201 case 0x6B:
8202 case 0x6C:
8203 case 0x6D:
8204 case 0x6E:
8205 case 0x6F:
8206 case 0x70:
8207 case 0x71:
8208 case 0x72:
8209 case 0x73:
8210 case 0x74:
8211 case 0x75:
8212 case 0x76:
8213 case 0x77:
8214 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8215 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8216 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8217 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8218 case 0x7F: // UTF-8 string (indefinite length)
8219 {
8220 string_t s;
8221 return get_cbor_string(s) && sax->string(s);
8222 }
8223
8224 // array (0x00..0x17 data items follow)
8225 case 0x80:
8226 case 0x81:
8227 case 0x82:
8228 case 0x83:
8229 case 0x84:
8230 case 0x85:
8231 case 0x86:
8232 case 0x87:
8233 case 0x88:
8234 case 0x89:
8235 case 0x8A:
8236 case 0x8B:
8237 case 0x8C:
8238 case 0x8D:
8239 case 0x8E:
8240 case 0x8F:
8241 case 0x90:
8242 case 0x91:
8243 case 0x92:
8244 case 0x93:
8245 case 0x94:
8246 case 0x95:
8247 case 0x96:
8248 case 0x97:
8249 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8250
8251 case 0x98: // array (one-byte uint8_t for n follows)
8252 {
8253 std::uint8_t len{};
8254 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8255 }
8256
8257 case 0x99: // array (two-byte uint16_t for n follow)
8258 {
8259 std::uint16_t len{};
8260 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8261 }
8262
8263 case 0x9A: // array (four-byte uint32_t for n follow)
8264 {
8265 std::uint32_t len{};
8266 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8267 }
8268
8269 case 0x9B: // array (eight-byte uint64_t for n follow)
8270 {
8271 std::uint64_t len{};
8272 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8273 }
8274
8275 case 0x9F: // array (indefinite length)
8276 return get_cbor_array(std::size_t(-1), tag_handler);
8277
8278 // map (0x00..0x17 pairs of data items follow)
8279 case 0xA0:
8280 case 0xA1:
8281 case 0xA2:
8282 case 0xA3:
8283 case 0xA4:
8284 case 0xA5:
8285 case 0xA6:
8286 case 0xA7:
8287 case 0xA8:
8288 case 0xA9:
8289 case 0xAA:
8290 case 0xAB:
8291 case 0xAC:
8292 case 0xAD:
8293 case 0xAE:
8294 case 0xAF:
8295 case 0xB0:
8296 case 0xB1:
8297 case 0xB2:
8298 case 0xB3:
8299 case 0xB4:
8300 case 0xB5:
8301 case 0xB6:
8302 case 0xB7:
8303 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8304
8305 case 0xB8: // map (one-byte uint8_t for n follows)
8306 {
8307 std::uint8_t len{};
8308 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8309 }
8310
8311 case 0xB9: // map (two-byte uint16_t for n follow)
8312 {
8313 std::uint16_t len{};
8314 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8315 }
8316
8317 case 0xBA: // map (four-byte uint32_t for n follow)
8318 {
8319 std::uint32_t len{};
8320 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8321 }
8322
8323 case 0xBB: // map (eight-byte uint64_t for n follow)
8324 {
8325 std::uint64_t len{};
8326 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8327 }
8328
8329 case 0xBF: // map (indefinite length)
8330 return get_cbor_object(std::size_t(-1), tag_handler);
8331
8332 case 0xC6: // tagged item
8333 case 0xC7:
8334 case 0xC8:
8335 case 0xC9:
8336 case 0xCA:
8337 case 0xCB:
8338 case 0xCC:
8339 case 0xCD:
8340 case 0xCE:
8341 case 0xCF:
8342 case 0xD0:
8343 case 0xD1:
8344 case 0xD2:
8345 case 0xD3:
8346 case 0xD4:
8347 case 0xD8: // tagged item (1 bytes follow)
8348 case 0xD9: // tagged item (2 bytes follow)
8349 case 0xDA: // tagged item (4 bytes follow)
8350 case 0xDB: // tagged item (8 bytes follow)
8351 {
8352 switch (tag_handler)
8353 {
8354 case cbor_tag_handler_t::error:
8355 {
8356 auto last_token = get_token_string();
8357 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")));
8358 }
8359
8360 case cbor_tag_handler_t::ignore:
8361 {
8362 switch (current)
8363 {
8364 case 0xD8:
8365 {
8366 std::uint8_t len{};
8367 get_number(input_format_t::cbor, len);
8368 break;
8369 }
8370 case 0xD9:
8371 {
8372 std::uint16_t len{};
8373 get_number(input_format_t::cbor, len);
8374 break;
8375 }
8376 case 0xDA:
8377 {
8378 std::uint32_t len{};
8379 get_number(input_format_t::cbor, len);
8380 break;
8381 }
8382 case 0xDB:
8383 {
8384 std::uint64_t len{};
8385 get_number(input_format_t::cbor, len);
8386 break;
8387 }
8388 default:
8389 break;
8390 }
8391 return parse_cbor_internal(true, tag_handler);
8392 }
8393
8394 default: // LCOV_EXCL_LINE
8395 JSON_ASSERT(false); // LCOV_EXCL_LINE
8396 }
8397 }
8398
8399 case 0xF4: // false
8400 return sax->boolean(false);
8401
8402 case 0xF5: // true
8403 return sax->boolean(true);
8404
8405 case 0xF6: // null
8406 return sax->null();
8407
8408 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
8409 {
8410 const auto byte1_raw = get();
8411 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
8412 {
8413 return false;
8414 }
8415 const auto byte2_raw = get();
8416 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
8417 {
8418 return false;
8419 }
8420
8421 const auto byte1 = static_cast<unsigned char>(byte1_raw);
8422 const auto byte2 = static_cast<unsigned char>(byte2_raw);
8423
8424 // code from RFC 7049, Appendix D, Figure 3:
8425 // As half-precision floating-point numbers were only added
8426 // to IEEE 754 in 2008, today's programming platforms often
8427 // still only have limited support for them. It is very
8428 // easy to include at least decoding support for them even
8429 // without such support. An example of a small decoder for
8430 // half-precision floating-point numbers in the C language
8431 // is shown in Fig. 3.
8432 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
8433 const double val = [&half]
8434 {
8435 const int exp = (half >> 10u) & 0x1Fu;
8436 const unsigned int mant = half & 0x3FFu;
8437 JSON_ASSERT(0 <= exp&& exp <= 32);
8438 JSON_ASSERT(mant <= 1024);
8439 switch (exp)
8440 {
8441 case 0:
8442 return std::ldexp(mant, -24);
8443 case 31:
8444 return (mant == 0)
8445 ? std::numeric_limits<double>::infinity()
8446 : std::numeric_limits<double>::quiet_NaN();
8447 default:
8448 return std::ldexp(mant + 1024, exp - 25);
8449 }
8450 }();
8451 return sax->number_float((half & 0x8000u) != 0
8452 ? static_cast<number_float_t>(-val)
8453 : static_cast<number_float_t>(val), "");
8454 }
8455
8456 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
8457 {
8458 float number{};
8459 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
8460 }
8461
8462 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
8463 {
8464 double number{};
8465 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
8466 }
8467
8468 default: // anything else (0xFF is handled inside the other types)
8469 {
8470 auto last_token = get_token_string();
8471 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")));
8472 }
8473 }
8474 }
8475
8487 bool get_cbor_string(string_t& result)
8488 {
8489 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
8490 {
8491 return false;
8492 }
8493
8494 switch (current)
8495 {
8496 // UTF-8 string (0x00..0x17 bytes follow)
8497 case 0x60:
8498 case 0x61:
8499 case 0x62:
8500 case 0x63:
8501 case 0x64:
8502 case 0x65:
8503 case 0x66:
8504 case 0x67:
8505 case 0x68:
8506 case 0x69:
8507 case 0x6A:
8508 case 0x6B:
8509 case 0x6C:
8510 case 0x6D:
8511 case 0x6E:
8512 case 0x6F:
8513 case 0x70:
8514 case 0x71:
8515 case 0x72:
8516 case 0x73:
8517 case 0x74:
8518 case 0x75:
8519 case 0x76:
8520 case 0x77:
8521 {
8522 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
8523 }
8524
8525 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8526 {
8527 std::uint8_t len{};
8528 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8529 }
8530
8531 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8532 {
8533 std::uint16_t len{};
8534 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8535 }
8536
8537 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8538 {
8539 std::uint32_t len{};
8540 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8541 }
8542
8543 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8544 {
8545 std::uint64_t len{};
8546 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8547 }
8548
8549 case 0x7F: // UTF-8 string (indefinite length)
8550 {
8551 while (get() != 0xFF)
8552 {
8553 string_t chunk;
8554 if (!get_cbor_string(chunk))
8555 {
8556 return false;
8557 }
8558 result.append(chunk);
8559 }
8560 return true;
8561 }
8562
8563 default:
8564 {
8565 auto last_token = get_token_string();
8566 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")));
8567 }
8568 }
8569 }
8570
8582 bool get_cbor_binary(binary_t& result)
8583 {
8584 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
8585 {
8586 return false;
8587 }
8588
8589 switch (current)
8590 {
8591 // Binary data (0x00..0x17 bytes follow)
8592 case 0x40:
8593 case 0x41:
8594 case 0x42:
8595 case 0x43:
8596 case 0x44:
8597 case 0x45:
8598 case 0x46:
8599 case 0x47:
8600 case 0x48:
8601 case 0x49:
8602 case 0x4A:
8603 case 0x4B:
8604 case 0x4C:
8605 case 0x4D:
8606 case 0x4E:
8607 case 0x4F:
8608 case 0x50:
8609 case 0x51:
8610 case 0x52:
8611 case 0x53:
8612 case 0x54:
8613 case 0x55:
8614 case 0x56:
8615 case 0x57:
8616 {
8617 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
8618 }
8619
8620 case 0x58: // Binary data (one-byte uint8_t for n follows)
8621 {
8622 std::uint8_t len{};
8623 return get_number(input_format_t::cbor, len) &&
8624 get_binary(input_format_t::cbor, len, result);
8625 }
8626
8627 case 0x59: // Binary data (two-byte uint16_t for n follow)
8628 {
8629 std::uint16_t len{};
8630 return get_number(input_format_t::cbor, len) &&
8631 get_binary(input_format_t::cbor, len, result);
8632 }
8633
8634 case 0x5A: // Binary data (four-byte uint32_t for n follow)
8635 {
8636 std::uint32_t len{};
8637 return get_number(input_format_t::cbor, len) &&
8638 get_binary(input_format_t::cbor, len, result);
8639 }
8640
8641 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8642 {
8643 std::uint64_t len{};
8644 return get_number(input_format_t::cbor, len) &&
8645 get_binary(input_format_t::cbor, len, result);
8646 }
8647
8648 case 0x5F: // Binary data (indefinite length)
8649 {
8650 while (get() != 0xFF)
8651 {
8652 binary_t chunk;
8653 if (!get_cbor_binary(chunk))
8654 {
8655 return false;
8656 }
8657 result.insert(result.end(), chunk.begin(), chunk.end());
8658 }
8659 return true;
8660 }
8661
8662 default:
8663 {
8664 auto last_token = get_token_string();
8665 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")));
8666 }
8667 }
8668 }
8669
8676 bool get_cbor_array(const std::size_t len,
8677 const cbor_tag_handler_t tag_handler)
8678 {
8679 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
8680 {
8681 return false;
8682 }
8683
8684 if (len != std::size_t(-1))
8685 {
8686 for (std::size_t i = 0; i < len; ++i)
8687 {
8688 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8689 {
8690 return false;
8691 }
8692 }
8693 }
8694 else
8695 {
8696 while (get() != 0xFF)
8697 {
8698 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
8699 {
8700 return false;
8701 }
8702 }
8703 }
8704
8705 return sax->end_array();
8706 }
8707
8714 bool get_cbor_object(const std::size_t len,
8715 const cbor_tag_handler_t tag_handler)
8716 {
8717 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
8718 {
8719 return false;
8720 }
8721
8722 string_t key;
8723 if (len != std::size_t(-1))
8724 {
8725 for (std::size_t i = 0; i < len; ++i)
8726 {
8727 get();
8728 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
8729 {
8730 return false;
8731 }
8732
8733 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8734 {
8735 return false;
8736 }
8737 key.clear();
8738 }
8739 }
8740 else
8741 {
8742 while (get() != 0xFF)
8743 {
8744 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
8745 {
8746 return false;
8747 }
8748
8749 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8750 {
8751 return false;
8752 }
8753 key.clear();
8754 }
8755 }
8756
8757 return sax->end_object();
8758 }
8759
8761 // MsgPack //
8763
8767 bool parse_msgpack_internal()
8768 {
8769 switch (get())
8770 {
8771 // EOF
8772 case std::char_traits<char_type>::eof():
8773 return unexpect_eof(input_format_t::msgpack, "value");
8774
8775 // positive fixint
8776 case 0x00:
8777 case 0x01:
8778 case 0x02:
8779 case 0x03:
8780 case 0x04:
8781 case 0x05:
8782 case 0x06:
8783 case 0x07:
8784 case 0x08:
8785 case 0x09:
8786 case 0x0A:
8787 case 0x0B:
8788 case 0x0C:
8789 case 0x0D:
8790 case 0x0E:
8791 case 0x0F:
8792 case 0x10:
8793 case 0x11:
8794 case 0x12:
8795 case 0x13:
8796 case 0x14:
8797 case 0x15:
8798 case 0x16:
8799 case 0x17:
8800 case 0x18:
8801 case 0x19:
8802 case 0x1A:
8803 case 0x1B:
8804 case 0x1C:
8805 case 0x1D:
8806 case 0x1E:
8807 case 0x1F:
8808 case 0x20:
8809 case 0x21:
8810 case 0x22:
8811 case 0x23:
8812 case 0x24:
8813 case 0x25:
8814 case 0x26:
8815 case 0x27:
8816 case 0x28:
8817 case 0x29:
8818 case 0x2A:
8819 case 0x2B:
8820 case 0x2C:
8821 case 0x2D:
8822 case 0x2E:
8823 case 0x2F:
8824 case 0x30:
8825 case 0x31:
8826 case 0x32:
8827 case 0x33:
8828 case 0x34:
8829 case 0x35:
8830 case 0x36:
8831 case 0x37:
8832 case 0x38:
8833 case 0x39:
8834 case 0x3A:
8835 case 0x3B:
8836 case 0x3C:
8837 case 0x3D:
8838 case 0x3E:
8839 case 0x3F:
8840 case 0x40:
8841 case 0x41:
8842 case 0x42:
8843 case 0x43:
8844 case 0x44:
8845 case 0x45:
8846 case 0x46:
8847 case 0x47:
8848 case 0x48:
8849 case 0x49:
8850 case 0x4A:
8851 case 0x4B:
8852 case 0x4C:
8853 case 0x4D:
8854 case 0x4E:
8855 case 0x4F:
8856 case 0x50:
8857 case 0x51:
8858 case 0x52:
8859 case 0x53:
8860 case 0x54:
8861 case 0x55:
8862 case 0x56:
8863 case 0x57:
8864 case 0x58:
8865 case 0x59:
8866 case 0x5A:
8867 case 0x5B:
8868 case 0x5C:
8869 case 0x5D:
8870 case 0x5E:
8871 case 0x5F:
8872 case 0x60:
8873 case 0x61:
8874 case 0x62:
8875 case 0x63:
8876 case 0x64:
8877 case 0x65:
8878 case 0x66:
8879 case 0x67:
8880 case 0x68:
8881 case 0x69:
8882 case 0x6A:
8883 case 0x6B:
8884 case 0x6C:
8885 case 0x6D:
8886 case 0x6E:
8887 case 0x6F:
8888 case 0x70:
8889 case 0x71:
8890 case 0x72:
8891 case 0x73:
8892 case 0x74:
8893 case 0x75:
8894 case 0x76:
8895 case 0x77:
8896 case 0x78:
8897 case 0x79:
8898 case 0x7A:
8899 case 0x7B:
8900 case 0x7C:
8901 case 0x7D:
8902 case 0x7E:
8903 case 0x7F:
8904 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8905
8906 // fixmap
8907 case 0x80:
8908 case 0x81:
8909 case 0x82:
8910 case 0x83:
8911 case 0x84:
8912 case 0x85:
8913 case 0x86:
8914 case 0x87:
8915 case 0x88:
8916 case 0x89:
8917 case 0x8A:
8918 case 0x8B:
8919 case 0x8C:
8920 case 0x8D:
8921 case 0x8E:
8922 case 0x8F:
8923 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
8924
8925 // fixarray
8926 case 0x90:
8927 case 0x91:
8928 case 0x92:
8929 case 0x93:
8930 case 0x94:
8931 case 0x95:
8932 case 0x96:
8933 case 0x97:
8934 case 0x98:
8935 case 0x99:
8936 case 0x9A:
8937 case 0x9B:
8938 case 0x9C:
8939 case 0x9D:
8940 case 0x9E:
8941 case 0x9F:
8942 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
8943
8944 // fixstr
8945 case 0xA0:
8946 case 0xA1:
8947 case 0xA2:
8948 case 0xA3:
8949 case 0xA4:
8950 case 0xA5:
8951 case 0xA6:
8952 case 0xA7:
8953 case 0xA8:
8954 case 0xA9:
8955 case 0xAA:
8956 case 0xAB:
8957 case 0xAC:
8958 case 0xAD:
8959 case 0xAE:
8960 case 0xAF:
8961 case 0xB0:
8962 case 0xB1:
8963 case 0xB2:
8964 case 0xB3:
8965 case 0xB4:
8966 case 0xB5:
8967 case 0xB6:
8968 case 0xB7:
8969 case 0xB8:
8970 case 0xB9:
8971 case 0xBA:
8972 case 0xBB:
8973 case 0xBC:
8974 case 0xBD:
8975 case 0xBE:
8976 case 0xBF:
8977 case 0xD9: // str 8
8978 case 0xDA: // str 16
8979 case 0xDB: // str 32
8980 {
8981 string_t s;
8982 return get_msgpack_string(s) && sax->string(s);
8983 }
8984
8985 case 0xC0: // nil
8986 return sax->null();
8987
8988 case 0xC2: // false
8989 return sax->boolean(false);
8990
8991 case 0xC3: // true
8992 return sax->boolean(true);
8993
8994 case 0xC4: // bin 8
8995 case 0xC5: // bin 16
8996 case 0xC6: // bin 32
8997 case 0xC7: // ext 8
8998 case 0xC8: // ext 16
8999 case 0xC9: // ext 32
9000 case 0xD4: // fixext 1
9001 case 0xD5: // fixext 2
9002 case 0xD6: // fixext 4
9003 case 0xD7: // fixext 8
9004 case 0xD8: // fixext 16
9005 {
9006 binary_t b;
9007 return get_msgpack_binary(b) && sax->binary(b);
9008 }
9009
9010 case 0xCA: // float 32
9011 {
9012 float number{};
9013 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9014 }
9015
9016 case 0xCB: // float 64
9017 {
9018 double number{};
9019 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9020 }
9021
9022 case 0xCC: // uint 8
9023 {
9024 std::uint8_t number{};
9025 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9026 }
9027
9028 case 0xCD: // uint 16
9029 {
9030 std::uint16_t number{};
9031 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9032 }
9033
9034 case 0xCE: // uint 32
9035 {
9036 std::uint32_t number{};
9037 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9038 }
9039
9040 case 0xCF: // uint 64
9041 {
9042 std::uint64_t number{};
9043 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9044 }
9045
9046 case 0xD0: // int 8
9047 {
9048 std::int8_t number{};
9049 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9050 }
9051
9052 case 0xD1: // int 16
9053 {
9054 std::int16_t number{};
9055 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9056 }
9057
9058 case 0xD2: // int 32
9059 {
9060 std::int32_t number{};
9061 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9062 }
9063
9064 case 0xD3: // int 64
9065 {
9066 std::int64_t number{};
9067 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9068 }
9069
9070 case 0xDC: // array 16
9071 {
9072 std::uint16_t len{};
9073 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9074 }
9075
9076 case 0xDD: // array 32
9077 {
9078 std::uint32_t len{};
9079 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9080 }
9081
9082 case 0xDE: // map 16
9083 {
9084 std::uint16_t len{};
9085 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9086 }
9087
9088 case 0xDF: // map 32
9089 {
9090 std::uint32_t len{};
9091 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9092 }
9093
9094 // negative fixint
9095 case 0xE0:
9096 case 0xE1:
9097 case 0xE2:
9098 case 0xE3:
9099 case 0xE4:
9100 case 0xE5:
9101 case 0xE6:
9102 case 0xE7:
9103 case 0xE8:
9104 case 0xE9:
9105 case 0xEA:
9106 case 0xEB:
9107 case 0xEC:
9108 case 0xED:
9109 case 0xEE:
9110 case 0xEF:
9111 case 0xF0:
9112 case 0xF1:
9113 case 0xF2:
9114 case 0xF3:
9115 case 0xF4:
9116 case 0xF5:
9117 case 0xF6:
9118 case 0xF7:
9119 case 0xF8:
9120 case 0xF9:
9121 case 0xFA:
9122 case 0xFB:
9123 case 0xFC:
9124 case 0xFD:
9125 case 0xFE:
9126 case 0xFF:
9127 return sax->number_integer(static_cast<std::int8_t>(current));
9128
9129 default: // anything else
9130 {
9131 auto last_token = get_token_string();
9132 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")));
9133 }
9134 }
9135 }
9136
9147 bool get_msgpack_string(string_t& result)
9148 {
9149 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
9150 {
9151 return false;
9152 }
9153
9154 switch (current)
9155 {
9156 // fixstr
9157 case 0xA0:
9158 case 0xA1:
9159 case 0xA2:
9160 case 0xA3:
9161 case 0xA4:
9162 case 0xA5:
9163 case 0xA6:
9164 case 0xA7:
9165 case 0xA8:
9166 case 0xA9:
9167 case 0xAA:
9168 case 0xAB:
9169 case 0xAC:
9170 case 0xAD:
9171 case 0xAE:
9172 case 0xAF:
9173 case 0xB0:
9174 case 0xB1:
9175 case 0xB2:
9176 case 0xB3:
9177 case 0xB4:
9178 case 0xB5:
9179 case 0xB6:
9180 case 0xB7:
9181 case 0xB8:
9182 case 0xB9:
9183 case 0xBA:
9184 case 0xBB:
9185 case 0xBC:
9186 case 0xBD:
9187 case 0xBE:
9188 case 0xBF:
9189 {
9190 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
9191 }
9192
9193 case 0xD9: // str 8
9194 {
9195 std::uint8_t len{};
9196 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9197 }
9198
9199 case 0xDA: // str 16
9200 {
9201 std::uint16_t len{};
9202 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9203 }
9204
9205 case 0xDB: // str 32
9206 {
9207 std::uint32_t len{};
9208 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9209 }
9210
9211 default:
9212 {
9213 auto last_token = get_token_string();
9214 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")));
9215 }
9216 }
9217 }
9218
9229 bool get_msgpack_binary(binary_t& result)
9230 {
9231 // helper function to set the subtype
9232 auto assign_and_return_true = [&result](std::int8_t subtype)
9233 {
9234 result.set_subtype(static_cast<std::uint8_t>(subtype));
9235 return true;
9236 };
9237
9238 switch (current)
9239 {
9240 case 0xC4: // bin 8
9241 {
9242 std::uint8_t len{};
9243 return get_number(input_format_t::msgpack, len) &&
9244 get_binary(input_format_t::msgpack, len, result);
9245 }
9246
9247 case 0xC5: // bin 16
9248 {
9249 std::uint16_t len{};
9250 return get_number(input_format_t::msgpack, len) &&
9251 get_binary(input_format_t::msgpack, len, result);
9252 }
9253
9254 case 0xC6: // bin 32
9255 {
9256 std::uint32_t len{};
9257 return get_number(input_format_t::msgpack, len) &&
9258 get_binary(input_format_t::msgpack, len, result);
9259 }
9260
9261 case 0xC7: // ext 8
9262 {
9263 std::uint8_t len{};
9264 std::int8_t subtype{};
9265 return get_number(input_format_t::msgpack, len) &&
9266 get_number(input_format_t::msgpack, subtype) &&
9267 get_binary(input_format_t::msgpack, len, result) &&
9268 assign_and_return_true(subtype);
9269 }
9270
9271 case 0xC8: // ext 16
9272 {
9273 std::uint16_t len{};
9274 std::int8_t subtype{};
9275 return get_number(input_format_t::msgpack, len) &&
9276 get_number(input_format_t::msgpack, subtype) &&
9277 get_binary(input_format_t::msgpack, len, result) &&
9278 assign_and_return_true(subtype);
9279 }
9280
9281 case 0xC9: // ext 32
9282 {
9283 std::uint32_t len{};
9284 std::int8_t subtype{};
9285 return get_number(input_format_t::msgpack, len) &&
9286 get_number(input_format_t::msgpack, subtype) &&
9287 get_binary(input_format_t::msgpack, len, result) &&
9288 assign_and_return_true(subtype);
9289 }
9290
9291 case 0xD4: // fixext 1
9292 {
9293 std::int8_t subtype{};
9294 return get_number(input_format_t::msgpack, subtype) &&
9295 get_binary(input_format_t::msgpack, 1, result) &&
9296 assign_and_return_true(subtype);
9297 }
9298
9299 case 0xD5: // fixext 2
9300 {
9301 std::int8_t subtype{};
9302 return get_number(input_format_t::msgpack, subtype) &&
9303 get_binary(input_format_t::msgpack, 2, result) &&
9304 assign_and_return_true(subtype);
9305 }
9306
9307 case 0xD6: // fixext 4
9308 {
9309 std::int8_t subtype{};
9310 return get_number(input_format_t::msgpack, subtype) &&
9311 get_binary(input_format_t::msgpack, 4, result) &&
9312 assign_and_return_true(subtype);
9313 }
9314
9315 case 0xD7: // fixext 8
9316 {
9317 std::int8_t subtype{};
9318 return get_number(input_format_t::msgpack, subtype) &&
9319 get_binary(input_format_t::msgpack, 8, result) &&
9320 assign_and_return_true(subtype);
9321 }
9322
9323 case 0xD8: // fixext 16
9324 {
9325 std::int8_t subtype{};
9326 return get_number(input_format_t::msgpack, subtype) &&
9327 get_binary(input_format_t::msgpack, 16, result) &&
9328 assign_and_return_true(subtype);
9329 }
9330
9331 default: // LCOV_EXCL_LINE
9332 return false; // LCOV_EXCL_LINE
9333 }
9334 }
9335
9340 bool get_msgpack_array(const std::size_t len)
9341 {
9342 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9343 {
9344 return false;
9345 }
9346
9347 for (std::size_t i = 0; i < len; ++i)
9348 {
9349 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
9350 {
9351 return false;
9352 }
9353 }
9354
9355 return sax->end_array();
9356 }
9357
9362 bool get_msgpack_object(const std::size_t len)
9363 {
9364 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9365 {
9366 return false;
9367 }
9368
9369 string_t key;
9370 for (std::size_t i = 0; i < len; ++i)
9371 {
9372 get();
9373 if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
9374 {
9375 return false;
9376 }
9377
9378 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
9379 {
9380 return false;
9381 }
9382 key.clear();
9383 }
9384
9385 return sax->end_object();
9386 }
9387
9389 // UBJSON //
9391
9399 bool parse_ubjson_internal(const bool get_char = true)
9400 {
9401 return get_ubjson_value(get_char ? get_ignore_noop() : current);
9402 }
9403
9418 bool get_ubjson_string(string_t& result, const bool get_char = true)
9419 {
9420 if (get_char)
9421 {
9422 get(); // TODO(niels): may we ignore N here?
9423 }
9424
9425 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
9426 {
9427 return false;
9428 }
9429
9430 switch (current)
9431 {
9432 case 'U':
9433 {
9434 std::uint8_t len{};
9435 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9436 }
9437
9438 case 'i':
9439 {
9440 std::int8_t len{};
9441 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9442 }
9443
9444 case 'I':
9445 {
9446 std::int16_t len{};
9447 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9448 }
9449
9450 case 'l':
9451 {
9452 std::int32_t len{};
9453 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9454 }
9455
9456 case 'L':
9457 {
9458 std::int64_t len{};
9459 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9460 }
9461
9462 default:
9463 auto last_token = get_token_string();
9464 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")));
9465 }
9466 }
9467
9472 bool get_ubjson_size_value(std::size_t& result)
9473 {
9474 switch (get_ignore_noop())
9475 {
9476 case 'U':
9477 {
9478 std::uint8_t number{};
9479 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9480 {
9481 return false;
9482 }
9483 result = static_cast<std::size_t>(number);
9484 return true;
9485 }
9486
9487 case 'i':
9488 {
9489 std::int8_t number{};
9490 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9491 {
9492 return false;
9493 }
9494 result = static_cast<std::size_t>(number);
9495 return true;
9496 }
9497
9498 case 'I':
9499 {
9500 std::int16_t number{};
9501 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9502 {
9503 return false;
9504 }
9505 result = static_cast<std::size_t>(number);
9506 return true;
9507 }
9508
9509 case 'l':
9510 {
9511 std::int32_t number{};
9512 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9513 {
9514 return false;
9515 }
9516 result = static_cast<std::size_t>(number);
9517 return true;
9518 }
9519
9520 case 'L':
9521 {
9522 std::int64_t number{};
9523 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9524 {
9525 return false;
9526 }
9527 result = static_cast<std::size_t>(number);
9528 return true;
9529 }
9530
9531 default:
9532 {
9533 auto last_token = get_token_string();
9534 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")));
9535 }
9536 }
9537 }
9538
9549 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
9550 {
9551 result.first = string_t::npos; // size
9552 result.second = 0; // type
9553
9554 get_ignore_noop();
9555
9556 if (current == '$')
9557 {
9558 result.second = get(); // must not ignore 'N', because 'N' maybe the type
9559 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type")))
9560 {
9561 return false;
9562 }
9563
9564 get_ignore_noop();
9565 if (JSON_HEDLEY_UNLIKELY(current != '#'))
9566 {
9567 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
9568 {
9569 return false;
9570 }
9571 auto last_token = get_token_string();
9572 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")));
9573 }
9574
9575 return get_ubjson_size_value(result.first);
9576 }
9577
9578 if (current == '#')
9579 {
9580 return get_ubjson_size_value(result.first);
9581 }
9582
9583 return true;
9584 }
9585
9590 bool get_ubjson_value(const char_int_type prefix)
9591 {
9592 switch (prefix)
9593 {
9594 case std::char_traits<char_type>::eof(): // EOF
9595 return unexpect_eof(input_format_t::ubjson, "value");
9596
9597 case 'T': // true
9598 return sax->boolean(true);
9599 case 'F': // false
9600 return sax->boolean(false);
9601
9602 case 'Z': // null
9603 return sax->null();
9604
9605 case 'U':
9606 {
9607 std::uint8_t number{};
9608 return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
9609 }
9610
9611 case 'i':
9612 {
9613 std::int8_t number{};
9614 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9615 }
9616
9617 case 'I':
9618 {
9619 std::int16_t number{};
9620 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9621 }
9622
9623 case 'l':
9624 {
9625 std::int32_t number{};
9626 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9627 }
9628
9629 case 'L':
9630 {
9631 std::int64_t number{};
9632 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9633 }
9634
9635 case 'd':
9636 {
9637 float number{};
9638 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9639 }
9640
9641 case 'D':
9642 {
9643 double number{};
9644 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9645 }
9646
9647 case 'H':
9648 {
9649 return get_ubjson_high_precision_number();
9650 }
9651
9652 case 'C': // char
9653 {
9654 get();
9655 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char")))
9656 {
9657 return false;
9658 }
9659 if (JSON_HEDLEY_UNLIKELY(current > 127))
9660 {
9661 auto last_token = get_token_string();
9662 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")));
9663 }
9664 string_t s(1, static_cast<typename string_t::value_type>(current));
9665 return sax->string(s);
9666 }
9667
9668 case 'S': // string
9669 {
9670 string_t s;
9671 return get_ubjson_string(s) && sax->string(s);
9672 }
9673
9674 case '[': // array
9675 return get_ubjson_array();
9676
9677 case '{': // object
9678 return get_ubjson_object();
9679
9680 default: // anything else
9681 {
9682 auto last_token = get_token_string();
9683 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")));
9684 }
9685 }
9686 }
9687
9691 bool get_ubjson_array()
9692 {
9693 std::pair<std::size_t, char_int_type> size_and_type;
9694 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
9695 {
9696 return false;
9697 }
9698
9699 if (size_and_type.first != string_t::npos)
9700 {
9701 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
9702 {
9703 return false;
9704 }
9705
9706 if (size_and_type.second != 0)
9707 {
9708 if (size_and_type.second != 'N')
9709 {
9710 for (std::size_t i = 0; i < size_and_type.first; ++i)
9711 {
9712 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
9713 {
9714 return false;
9715 }
9716 }
9717 }
9718 }
9719 else
9720 {
9721 for (std::size_t i = 0; i < size_and_type.first; ++i)
9722 {
9723 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
9724 {
9725 return false;
9726 }
9727 }
9728 }
9729 }
9730 else
9731 {
9732 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
9733 {
9734 return false;
9735 }
9736
9737 while (current != ']')
9738 {
9739 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
9740 {
9741 return false;
9742 }
9743 get_ignore_noop();
9744 }
9745 }
9746
9747 return sax->end_array();
9748 }
9749
9753 bool get_ubjson_object()
9754 {
9755 std::pair<std::size_t, char_int_type> size_and_type;
9756 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
9757 {
9758 return false;
9759 }
9760
9761 string_t key;
9762 if (size_and_type.first != string_t::npos)
9763 {
9764 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
9765 {
9766 return false;
9767 }
9768
9769 if (size_and_type.second != 0)
9770 {
9771 for (std::size_t i = 0; i < size_and_type.first; ++i)
9772 {
9773 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
9774 {
9775 return false;
9776 }
9777 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
9778 {
9779 return false;
9780 }
9781 key.clear();
9782 }
9783 }
9784 else
9785 {
9786 for (std::size_t i = 0; i < size_and_type.first; ++i)
9787 {
9788 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
9789 {
9790 return false;
9791 }
9792 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
9793 {
9794 return false;
9795 }
9796 key.clear();
9797 }
9798 }
9799 }
9800 else
9801 {
9802 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
9803 {
9804 return false;
9805 }
9806
9807 while (current != '}')
9808 {
9809 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
9810 {
9811 return false;
9812 }
9813 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
9814 {
9815 return false;
9816 }
9817 get_ignore_noop();
9818 key.clear();
9819 }
9820 }
9821
9822 return sax->end_object();
9823 }
9824
9825 // Note, no reader for UBJSON binary types is implemented because they do
9826 // not exist
9827
9828 bool get_ubjson_high_precision_number()
9829 {
9830 // get size of following number string
9831 std::size_t size{};
9832 auto res = get_ubjson_size_value(size);
9833 if (JSON_HEDLEY_UNLIKELY(!res))
9834 {
9835 return res;
9836 }
9837
9838 // get number string
9839 std::vector<char> number_vector;
9840 for (std::size_t i = 0; i < size; ++i)
9841 {
9842 get();
9843 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number")))
9844 {
9845 return false;
9846 }
9847 number_vector.push_back(static_cast<char>(current));
9848 }
9849
9850 // parse number string
9851 auto number_ia = detail::input_adapter(std::forward<decltype(number_vector)>(number_vector));
9852 auto number_lexer = detail::lexer<BasicJsonType, decltype(number_ia)>(std::move(number_ia), false);
9853 const auto result_number = number_lexer.scan();
9854 const auto number_string = number_lexer.get_token_string();
9855 const auto result_remainder = number_lexer.scan();
9856
9857 using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
9858
9859 if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
9860 {
9861 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")));
9862 }
9863
9864 switch (result_number)
9865 {
9866 case token_type::value_integer:
9867 return sax->number_integer(number_lexer.get_number_integer());
9868 case token_type::value_unsigned:
9869 return sax->number_unsigned(number_lexer.get_number_unsigned());
9870 case token_type::value_float:
9871 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
9872 default:
9873 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")));
9874 }
9875 }
9876
9878 // Utility functions //
9880
9890 char_int_type get()
9891 {
9892 ++chars_read;
9893 return current = ia.get_character();
9894 }
9895
9899 char_int_type get_ignore_noop()
9900 {
9901 do
9902 {
9903 get();
9904 }
9905 while (current == 'N');
9906
9907 return current;
9908 }
9909
9910 /*
9911 @brief read a number from the input
9912
9913 @tparam NumberType the type of the number
9914 @param[in] format the current format (for diagnostics)
9915 @param[out] result number of type @a NumberType
9916
9917 @return whether conversion completed
9918
9919 @note This function needs to respect the system's endianess, because
9920 bytes in CBOR, MessagePack, and UBJSON are stored in network order
9921 (big endian) and therefore need reordering on little endian systems.
9922 */
9923 template<typename NumberType, bool InputIsLittleEndian = false>
9924 bool get_number(const input_format_t format, NumberType& result)
9925 {
9926 // step 1: read input into array with system's byte order
9927 std::array<std::uint8_t, sizeof(NumberType)> vec;
9928 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
9929 {
9930 get();
9931 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
9932 {
9933 return false;
9934 }
9935
9936 // reverse byte order prior to conversion if necessary
9937 if (is_little_endian != InputIsLittleEndian)
9938 {
9939 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
9940 }
9941 else
9942 {
9943 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
9944 }
9945 }
9946
9947 // step 2: convert array into number of type T and return
9948 std::memcpy(&result, vec.data(), sizeof(NumberType));
9949 return true;
9950 }
9951
9966 template<typename NumberType>
9967 bool get_string(const input_format_t format,
9968 const NumberType len,
9969 string_t& result)
9970 {
9971 bool success = true;
9972 for (NumberType i = 0; i < len; i++)
9973 {
9974 get();
9975 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
9976 {
9977 success = false;
9978 break;
9979 }
9980 result.push_back(static_cast<typename string_t::value_type>(current));
9981 };
9982 return success;
9983 }
9984
9999 template<typename NumberType>
10000 bool get_binary(const input_format_t format,
10001 const NumberType len,
10002 binary_t& result)
10003 {
10004 bool success = true;
10005 for (NumberType i = 0; i < len; i++)
10006 {
10007 get();
10008 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10009 {
10010 success = false;
10011 break;
10012 }
10013 result.push_back(static_cast<std::uint8_t>(current));
10014 }
10015 return success;
10016 }
10017
10023 JSON_HEDLEY_NON_NULL(3)
10024 bool unexpect_eof(const input_format_t format, const char* context) const
10025 {
10026 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
10027 {
10028 return sax->parse_error(chars_read, "<end of file>",
10029 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
10030 }
10031 return true;
10032 }
10033
10037 std::string get_token_string() const
10038 {
10039 std::array<char, 3> cr{{}};
10040 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current));
10041 return std::string{cr.data()};
10042 }
10043
10050 std::string exception_message(const input_format_t format,
10051 const std::string& detail,
10052 const std::string& context) const
10053 {
10054 std::string error_msg = "syntax error while parsing ";
10055
10056 switch (format)
10057 {
10058 case input_format_t::cbor:
10059 error_msg += "CBOR";
10060 break;
10061
10062 case input_format_t::msgpack:
10063 error_msg += "MessagePack";
10064 break;
10065
10066 case input_format_t::ubjson:
10067 error_msg += "UBJSON";
10068 break;
10069
10070 case input_format_t::bson:
10071 error_msg += "BSON";
10072 break;
10073
10074 default: // LCOV_EXCL_LINE
10075 JSON_ASSERT(false); // LCOV_EXCL_LINE
10076 }
10077
10078 return error_msg + " " + context + ": " + detail;
10079 }
10080
10081 private:
10083 InputAdapterType ia;
10084
10086 char_int_type current = std::char_traits<char_type>::eof();
10087
10089 std::size_t chars_read = 0;
10090
10092 const bool is_little_endian = little_endianess();
10093
10095 json_sax_t* sax = nullptr;
10096 };
10097 } // namespace detail
10098 } // namespace nlohmann
10099
10100 // #include <nlohmann/detail/input/input_adapters.hpp>
10101
10102 // #include <nlohmann/detail/input/lexer.hpp>
10103
10104 // #include <nlohmann/detail/input/parser.hpp>
10105
10106
10107 #include <cmath> // isfinite
10108 #include <cstdint> // uint8_t
10109 #include <functional> // function
10110 #include <string> // string
10111 #include <utility> // move
10112 #include <vector> // vector
10113
10114 // #include <nlohmann/detail/exceptions.hpp>
10115
10116 // #include <nlohmann/detail/input/input_adapters.hpp>
10117
10118 // #include <nlohmann/detail/input/json_sax.hpp>
10119
10120 // #include <nlohmann/detail/input/lexer.hpp>
10121
10122 // #include <nlohmann/detail/macro_scope.hpp>
10123
10124 // #include <nlohmann/detail/meta/is_sax.hpp>
10125
10126 // #include <nlohmann/detail/value_t.hpp>
10127
10128
10129 namespace nlohmann
10130 {
10131 namespace detail
10132 {
10134 // parser //
10136
10137 enum class parse_event_t : uint8_t
10138 {
10140 object_start,
10142 object_end,
10144 array_start,
10146 array_end,
10148 key,
10150 value
10151 };
10152
10153 template<typename BasicJsonType>
10154 using parser_callback_t =
10155 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
10156
10162 template<typename BasicJsonType, typename InputAdapterType>
10163 class parser
10164 {
10165 using number_integer_t = typename BasicJsonType::number_integer_t;
10166 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10167 using number_float_t = typename BasicJsonType::number_float_t;
10168 using string_t = typename BasicJsonType::string_t;
10169 using lexer_t = lexer<BasicJsonType, InputAdapterType>;
10170 using token_type = typename lexer_t::token_type;
10171
10172 public:
10174 explicit parser(InputAdapterType&& adapter,
10175 const parser_callback_t<BasicJsonType> cb = nullptr,
10176 const bool allow_exceptions_ = true,
10177 const bool skip_comments = false)
10178 : callback(cb)
10179 , m_lexer(std::move(adapter), skip_comments)
10180 , allow_exceptions(allow_exceptions_)
10181 {
10182 // read first token
10183 get_token();
10184 }
10185
10196 void parse(const bool strict, BasicJsonType& result)
10197 {
10198 if (callback)
10199 {
10200 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
10201 sax_parse_internal(&sdp);
10202 result.assert_invariant();
10203
10204 // in strict mode, input must be completely read
10205 if (strict && (get_token() != token_type::end_of_input))
10206 {
10207 sdp.parse_error(m_lexer.get_position(),
10208 m_lexer.get_token_string(),
10209 parse_error::create(101, m_lexer.get_position(),
10210 exception_message(token_type::end_of_input, "value")));
10211 }
10212
10213 // in case of an error, return discarded value
10214 if (sdp.is_errored())
10215 {
10216 result = value_t::discarded;
10217 return;
10218 }
10219
10220 // set top-level value to null if it was discarded by the callback
10221 // function
10222 if (result.is_discarded())
10223 {
10224 result = nullptr;
10225 }
10226 }
10227 else
10228 {
10229 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
10230 sax_parse_internal(&sdp);
10231 result.assert_invariant();
10232
10233 // in strict mode, input must be completely read
10234 if (strict && (get_token() != token_type::end_of_input))
10235 {
10236 sdp.parse_error(m_lexer.get_position(),
10237 m_lexer.get_token_string(),
10238 parse_error::create(101, m_lexer.get_position(),
10239 exception_message(token_type::end_of_input, "value")));
10240 }
10241
10242 // in case of an error, return discarded value
10243 if (sdp.is_errored())
10244 {
10245 result = value_t::discarded;
10246 return;
10247 }
10248 }
10249 }
10250
10257 bool accept(const bool strict = true)
10258 {
10259 json_sax_acceptor<BasicJsonType> sax_acceptor;
10260 return sax_parse(&sax_acceptor, strict);
10261 }
10262
10263 template<typename SAX>
10264 JSON_HEDLEY_NON_NULL(2)
10265 bool sax_parse(SAX* sax, const bool strict = true)
10266 {
10267 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
10268 const bool result = sax_parse_internal(sax);
10269
10270 // strict mode: next byte must be EOF
10271 if (result && strict && (get_token() != token_type::end_of_input))
10272 {
10273 return sax->parse_error(m_lexer.get_position(),
10274 m_lexer.get_token_string(),
10275 parse_error::create(101, m_lexer.get_position(),
10276 exception_message(token_type::end_of_input, "value")));
10277 }
10278
10279 return result;
10280 }
10281
10282 private:
10283 template<typename SAX>
10284 JSON_HEDLEY_NON_NULL(2)
10285 bool sax_parse_internal(SAX* sax)
10286 {
10287 // stack to remember the hierarchy of structured values we are parsing
10288 // true = array; false = object
10289 std::vector<bool> states;
10290 // value to avoid a goto (see comment where set to true)
10291 bool skip_to_state_evaluation = false;
10292
10293 while (true)
10294 {
10295 if (!skip_to_state_evaluation)
10296 {
10297 // invariant: get_token() was called before each iteration
10298 switch (last_token)
10299 {
10300 case token_type::begin_object:
10301 {
10302 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10303 {
10304 return false;
10305 }
10306
10307 // closing } -> we are done
10308 if (get_token() == token_type::end_object)
10309 {
10310 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
10311 {
10312 return false;
10313 }
10314 break;
10315 }
10316
10317 // parse key
10318 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
10319 {
10320 return sax->parse_error(m_lexer.get_position(),
10321 m_lexer.get_token_string(),
10322 parse_error::create(101, m_lexer.get_position(),
10323 exception_message(token_type::value_string, "object key")));
10324 }
10325 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
10326 {
10327 return false;
10328 }
10329
10330 // parse separator (:)
10331 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10332 {
10333 return sax->parse_error(m_lexer.get_position(),
10334 m_lexer.get_token_string(),
10335 parse_error::create(101, m_lexer.get_position(),
10336 exception_message(token_type::name_separator, "object separator")));
10337 }
10338
10339 // remember we are now inside an object
10340 states.push_back(false);
10341
10342 // parse values
10343 get_token();
10344 continue;
10345 }
10346
10347 case token_type::begin_array:
10348 {
10349 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10350 {
10351 return false;
10352 }
10353
10354 // closing ] -> we are done
10355 if (get_token() == token_type::end_array)
10356 {
10357 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
10358 {
10359 return false;
10360 }
10361 break;
10362 }
10363
10364 // remember we are now inside an array
10365 states.push_back(true);
10366
10367 // parse values (no need to call get_token)
10368 continue;
10369 }
10370
10371 case token_type::value_float:
10372 {
10373 const auto res = m_lexer.get_number_float();
10374
10375 if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
10376 {
10377 return sax->parse_error(m_lexer.get_position(),
10378 m_lexer.get_token_string(),
10379 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
10380 }
10381
10382 if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
10383 {
10384 return false;
10385 }
10386
10387 break;
10388 }
10389
10390 case token_type::literal_false:
10391 {
10392 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
10393 {
10394 return false;
10395 }
10396 break;
10397 }
10398
10399 case token_type::literal_null:
10400 {
10401 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
10402 {
10403 return false;
10404 }
10405 break;
10406 }
10407
10408 case token_type::literal_true:
10409 {
10410 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
10411 {
10412 return false;
10413 }
10414 break;
10415 }
10416
10417 case token_type::value_integer:
10418 {
10419 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
10420 {
10421 return false;
10422 }
10423 break;
10424 }
10425
10426 case token_type::value_string:
10427 {
10428 if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
10429 {
10430 return false;
10431 }
10432 break;
10433 }
10434
10435 case token_type::value_unsigned:
10436 {
10437 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
10438 {
10439 return false;
10440 }
10441 break;
10442 }
10443
10444 case token_type::parse_error:
10445 {
10446 // using "uninitialized" to avoid "expected" message
10447 return sax->parse_error(m_lexer.get_position(),
10448 m_lexer.get_token_string(),
10449 parse_error::create(101, m_lexer.get_position(),
10450 exception_message(token_type::uninitialized, "value")));
10451 }
10452
10453 default: // the last token was unexpected
10454 {
10455 return sax->parse_error(m_lexer.get_position(),
10456 m_lexer.get_token_string(),
10457 parse_error::create(101, m_lexer.get_position(),
10458 exception_message(token_type::literal_or_value, "value")));
10459 }
10460 }
10461 }
10462 else
10463 {
10464 skip_to_state_evaluation = false;
10465 }
10466
10467 // we reached this line after we successfully parsed a value
10468 if (states.empty())
10469 {
10470 // empty stack: we reached the end of the hierarchy: done
10471 return true;
10472 }
10473
10474 if (states.back()) // array
10475 {
10476 // comma -> next value
10477 if (get_token() == token_type::value_separator)
10478 {
10479 // parse a new value
10480 get_token();
10481 continue;
10482 }
10483
10484 // closing ]
10485 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
10486 {
10487 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
10488 {
10489 return false;
10490 }
10491
10492 // We are done with this array. Before we can parse a
10493 // new value, we need to evaluate the new state first.
10494 // By setting skip_to_state_evaluation to false, we
10495 // are effectively jumping to the beginning of this if.
10496 JSON_ASSERT(!states.empty());
10497 states.pop_back();
10498 skip_to_state_evaluation = true;
10499 continue;
10500 }
10501
10502 return sax->parse_error(m_lexer.get_position(),
10503 m_lexer.get_token_string(),
10504 parse_error::create(101, m_lexer.get_position(),
10505 exception_message(token_type::end_array, "array")));
10506 }
10507 else // object
10508 {
10509 // comma -> next value
10510 if (get_token() == token_type::value_separator)
10511 {
10512 // parse key
10513 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
10514 {
10515 return sax->parse_error(m_lexer.get_position(),
10516 m_lexer.get_token_string(),
10517 parse_error::create(101, m_lexer.get_position(),
10518 exception_message(token_type::value_string, "object key")));
10519 }
10520
10521 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
10522 {
10523 return false;
10524 }
10525
10526 // parse separator (:)
10527 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10528 {
10529 return sax->parse_error(m_lexer.get_position(),
10530 m_lexer.get_token_string(),
10531 parse_error::create(101, m_lexer.get_position(),
10532 exception_message(token_type::name_separator, "object separator")));
10533 }
10534
10535 // parse values
10536 get_token();
10537 continue;
10538 }
10539
10540 // closing }
10541 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
10542 {
10543 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
10544 {
10545 return false;
10546 }
10547
10548 // We are done with this object. Before we can parse a
10549 // new value, we need to evaluate the new state first.
10550 // By setting skip_to_state_evaluation to false, we
10551 // are effectively jumping to the beginning of this if.
10552 JSON_ASSERT(!states.empty());
10553 states.pop_back();
10554 skip_to_state_evaluation = true;
10555 continue;
10556 }
10557
10558 return sax->parse_error(m_lexer.get_position(),
10559 m_lexer.get_token_string(),
10560 parse_error::create(101, m_lexer.get_position(),
10561 exception_message(token_type::end_object, "object")));
10562 }
10563 }
10564 }
10565
10567 token_type get_token()
10568 {
10569 return last_token = m_lexer.scan();
10570 }
10571
10572 std::string exception_message(const token_type expected, const std::string& context)
10573 {
10574 std::string error_msg = "syntax error ";
10575
10576 if (!context.empty())
10577 {
10578 error_msg += "while parsing " + context + " ";
10579 }
10580
10581 error_msg += "- ";
10582
10583 if (last_token == token_type::parse_error)
10584 {
10585 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
10586 m_lexer.get_token_string() + "'";
10587 }
10588 else
10589 {
10590 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
10591 }
10592
10593 if (expected != token_type::uninitialized)
10594 {
10595 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
10596 }
10597
10598 return error_msg;
10599 }
10600
10601 private:
10603 const parser_callback_t<BasicJsonType> callback = nullptr;
10605 token_type last_token = token_type::uninitialized;
10607 lexer_t m_lexer;
10609 const bool allow_exceptions = true;
10610 };
10611 } // namespace detail
10612 } // namespace nlohmann
10613
10614 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
10615
10616
10617 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10618
10619
10620 #include <cstddef> // ptrdiff_t
10621 #include <limits> // numeric_limits
10622
10623 namespace nlohmann
10624 {
10625 namespace detail
10626 {
10627 /*
10628 @brief an iterator for primitive JSON types
10629
10630 This class models an iterator for primitive JSON types (boolean, number,
10631 string). It's only purpose is to allow the iterator/const_iterator classes
10632 to "iterate" over primitive values. Internally, the iterator is modeled by
10633 a `difference_type` variable. Value begin_value (`0`) models the begin,
10634 end_value (`1`) models past the end.
10635 */
10636 class primitive_iterator_t
10637 {
10638 private:
10639 using difference_type = std::ptrdiff_t;
10640 static constexpr difference_type begin_value = 0;
10641 static constexpr difference_type end_value = begin_value + 1;
10642
10644 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
10645
10646 public:
10647 constexpr difference_type get_value() const noexcept
10648 {
10649 return m_it;
10650 }
10651
10653 void set_begin() noexcept
10654 {
10655 m_it = begin_value;
10656 }
10657
10659 void set_end() noexcept
10660 {
10661 m_it = end_value;
10662 }
10663
10665 constexpr bool is_begin() const noexcept
10666 {
10667 return m_it == begin_value;
10668 }
10669
10671 constexpr bool is_end() const noexcept
10672 {
10673 return m_it == end_value;
10674 }
10675
10676 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10677 {
10678 return lhs.m_it == rhs.m_it;
10679 }
10680
10681 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10682 {
10683 return lhs.m_it < rhs.m_it;
10684 }
10685
10686 primitive_iterator_t operator+(difference_type n) noexcept
10687 {
10688 auto result = *this;
10689 result += n;
10690 return result;
10691 }
10692
10693 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10694 {
10695 return lhs.m_it - rhs.m_it;
10696 }
10697
10698 primitive_iterator_t& operator++() noexcept
10699 {
10700 ++m_it;
10701 return *this;
10702 }
10703
10704 primitive_iterator_t const operator++(int) noexcept
10705 {
10706 auto result = *this;
10707 ++m_it;
10708 return result;
10709 }
10710
10711 primitive_iterator_t& operator--() noexcept
10712 {
10713 --m_it;
10714 return *this;
10715 }
10716
10717 primitive_iterator_t const operator--(int) noexcept
10718 {
10719 auto result = *this;
10720 --m_it;
10721 return result;
10722 }
10723
10724 primitive_iterator_t& operator+=(difference_type n) noexcept
10725 {
10726 m_it += n;
10727 return *this;
10728 }
10729
10730 primitive_iterator_t& operator-=(difference_type n) noexcept
10731 {
10732 m_it -= n;
10733 return *this;
10734 }
10735 };
10736 } // namespace detail
10737 } // namespace nlohmann
10738
10739
10740 namespace nlohmann
10741 {
10742 namespace detail
10743 {
10750 template<typename BasicJsonType> struct internal_iterator
10751 {
10753 typename BasicJsonType::object_t::iterator object_iterator {};
10755 typename BasicJsonType::array_t::iterator array_iterator {};
10757 primitive_iterator_t primitive_iterator {};
10758 };
10759 } // namespace detail
10760 } // namespace nlohmann
10761
10762 // #include <nlohmann/detail/iterators/iter_impl.hpp>
10763
10764
10765 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
10766 #include <type_traits> // conditional, is_const, remove_const
10767
10768 // #include <nlohmann/detail/exceptions.hpp>
10769
10770 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
10771
10772 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10773
10774 // #include <nlohmann/detail/macro_scope.hpp>
10775
10776 // #include <nlohmann/detail/meta/cpp_future.hpp>
10777
10778 // #include <nlohmann/detail/meta/type_traits.hpp>
10779
10780 // #include <nlohmann/detail/value_t.hpp>
10781
10782
10783 namespace nlohmann
10784 {
10785 namespace detail
10786 {
10787 // forward declare, to be able to friend it later on
10788 template<typename IteratorType> class iteration_proxy;
10789 template<typename IteratorType> class iteration_proxy_value;
10790
10807 template<typename BasicJsonType>
10808 class iter_impl
10809 {
10811 friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
10812 friend BasicJsonType;
10813 friend iteration_proxy<iter_impl>;
10814 friend iteration_proxy_value<iter_impl>;
10815
10816 using object_t = typename BasicJsonType::object_t;
10817 using array_t = typename BasicJsonType::array_t;
10818 // make sure BasicJsonType is basic_json or const basic_json
10819 static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
10820 "iter_impl only accepts (const) basic_json");
10821
10822 public:
10823
10829 using iterator_category = std::bidirectional_iterator_tag;
10830
10832 using value_type = typename BasicJsonType::value_type;
10834 using difference_type = typename BasicJsonType::difference_type;
10836 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
10837 typename BasicJsonType::const_pointer,
10838 typename BasicJsonType::pointer>::type;
10840 using reference =
10841 typename std::conditional<std::is_const<BasicJsonType>::value,
10842 typename BasicJsonType::const_reference,
10843 typename BasicJsonType::reference>::type;
10844
10846 iter_impl() = default;
10847
10854 explicit iter_impl(pointer object) noexcept : m_object(object)
10855 {
10856 JSON_ASSERT(m_object != nullptr);
10857
10858 switch (m_object->m_type)
10859 {
10860 case value_t::object:
10861 {
10862 m_it.object_iterator = typename object_t::iterator();
10863 break;
10864 }
10865
10866 case value_t::array:
10867 {
10868 m_it.array_iterator = typename array_t::iterator();
10869 break;
10870 }
10871
10872 default:
10873 {
10874 m_it.primitive_iterator = primitive_iterator_t();
10875 break;
10876 }
10877 }
10878 }
10879
10896 iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
10897 : m_object(other.m_object), m_it(other.m_it)
10898 {}
10899
10906 iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
10907 {
10908 m_object = other.m_object;
10909 m_it = other.m_it;
10910 return *this;
10911 }
10912
10918 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
10919 : m_object(other.m_object), m_it(other.m_it)
10920 {}
10921
10928 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
10929 {
10930 m_object = other.m_object;
10931 m_it = other.m_it;
10932 return *this;
10933 }
10934
10935 private:
10940 void set_begin() noexcept
10941 {
10942 JSON_ASSERT(m_object != nullptr);
10943
10944 switch (m_object->m_type)
10945 {
10946 case value_t::object:
10947 {
10948 m_it.object_iterator = m_object->m_value.object->begin();
10949 break;
10950 }
10951
10952 case value_t::array:
10953 {
10954 m_it.array_iterator = m_object->m_value.array->begin();
10955 break;
10956 }
10957
10958 case value_t::null:
10959 {
10960 // set to end so begin()==end() is true: null is empty
10961 m_it.primitive_iterator.set_end();
10962 break;
10963 }
10964
10965 default:
10966 {
10967 m_it.primitive_iterator.set_begin();
10968 break;
10969 }
10970 }
10971 }
10972
10977 void set_end() noexcept
10978 {
10979 JSON_ASSERT(m_object != nullptr);
10980
10981 switch (m_object->m_type)
10982 {
10983 case value_t::object:
10984 {
10985 m_it.object_iterator = m_object->m_value.object->end();
10986 break;
10987 }
10988
10989 case value_t::array:
10990 {
10991 m_it.array_iterator = m_object->m_value.array->end();
10992 break;
10993 }
10994
10995 default:
10996 {
10997 m_it.primitive_iterator.set_end();
10998 break;
10999 }
11000 }
11001 }
11002
11003 public:
11008 reference operator*() const
11009 {
11010 JSON_ASSERT(m_object != nullptr);
11011
11012 switch (m_object->m_type)
11013 {
11014 case value_t::object:
11015 {
11016 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11017 return m_it.object_iterator->second;
11018 }
11019
11020 case value_t::array:
11021 {
11022 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11023 return *m_it.array_iterator;
11024 }
11025
11026 case value_t::null:
11027 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11028
11029 default:
11030 {
11031 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11032 {
11033 return *m_object;
11034 }
11035
11036 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11037 }
11038 }
11039 }
11040
11045 pointer operator->() const
11046 {
11047 JSON_ASSERT(m_object != nullptr);
11048
11049 switch (m_object->m_type)
11050 {
11051 case value_t::object:
11052 {
11053 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11054 return &(m_it.object_iterator->second);
11055 }
11056
11057 case value_t::array:
11058 {
11059 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11060 return &*m_it.array_iterator;
11061 }
11062
11063 default:
11064 {
11065 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11066 {
11067 return m_object;
11068 }
11069
11070 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11071 }
11072 }
11073 }
11074
11079 iter_impl const operator++(int)
11080 {
11081 auto result = *this;
11082 ++(*this);
11083 return result;
11084 }
11085
11090 iter_impl& operator++()
11091 {
11092 JSON_ASSERT(m_object != nullptr);
11093
11094 switch (m_object->m_type)
11095 {
11096 case value_t::object:
11097 {
11098 std::advance(m_it.object_iterator, 1);
11099 break;
11100 }
11101
11102 case value_t::array:
11103 {
11104 std::advance(m_it.array_iterator, 1);
11105 break;
11106 }
11107
11108 default:
11109 {
11110 ++m_it.primitive_iterator;
11111 break;
11112 }
11113 }
11114
11115 return *this;
11116 }
11117
11122 iter_impl const operator--(int)
11123 {
11124 auto result = *this;
11125 --(*this);
11126 return result;
11127 }
11128
11133 iter_impl& operator--()
11134 {
11135 JSON_ASSERT(m_object != nullptr);
11136
11137 switch (m_object->m_type)
11138 {
11139 case value_t::object:
11140 {
11141 std::advance(m_it.object_iterator, -1);
11142 break;
11143 }
11144
11145 case value_t::array:
11146 {
11147 std::advance(m_it.array_iterator, -1);
11148 break;
11149 }
11150
11151 default:
11152 {
11153 --m_it.primitive_iterator;
11154 break;
11155 }
11156 }
11157
11158 return *this;
11159 }
11160
11165 bool operator==(const iter_impl& other) const
11166 {
11167 // if objects are not the same, the comparison is undefined
11168 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11169 {
11170 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
11171 }
11172
11173 JSON_ASSERT(m_object != nullptr);
11174
11175 switch (m_object->m_type)
11176 {
11177 case value_t::object:
11178 return (m_it.object_iterator == other.m_it.object_iterator);
11179
11180 case value_t::array:
11181 return (m_it.array_iterator == other.m_it.array_iterator);
11182
11183 default:
11184 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
11185 }
11186 }
11187
11192 bool operator!=(const iter_impl& other) const
11193 {
11194 return !operator==(other);
11195 }
11196
11201 bool operator<(const iter_impl& other) const
11202 {
11203 // if objects are not the same, the comparison is undefined
11204 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11205 {
11206 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
11207 }
11208
11209 JSON_ASSERT(m_object != nullptr);
11210
11211 switch (m_object->m_type)
11212 {
11213 case value_t::object:
11214 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
11215
11216 case value_t::array:
11217 return (m_it.array_iterator < other.m_it.array_iterator);
11218
11219 default:
11220 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
11221 }
11222 }
11223
11228 bool operator<=(const iter_impl& other) const
11229 {
11230 return !other.operator < (*this);
11231 }
11232
11237 bool operator>(const iter_impl& other) const
11238 {
11239 return !operator<=(other);
11240 }
11241
11246 bool operator>=(const iter_impl& other) const
11247 {
11248 return !operator<(other);
11249 }
11250
11255 iter_impl& operator+=(difference_type i)
11256 {
11257 JSON_ASSERT(m_object != nullptr);
11258
11259 switch (m_object->m_type)
11260 {
11261 case value_t::object:
11262 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
11263
11264 case value_t::array:
11265 {
11266 std::advance(m_it.array_iterator, i);
11267 break;
11268 }
11269
11270 default:
11271 {
11272 m_it.primitive_iterator += i;
11273 break;
11274 }
11275 }
11276
11277 return *this;
11278 }
11279
11284 iter_impl& operator-=(difference_type i)
11285 {
11286 return operator+=(-i);
11287 }
11288
11293 iter_impl operator+(difference_type i) const
11294 {
11295 auto result = *this;
11296 result += i;
11297 return result;
11298 }
11299
11304 friend iter_impl operator+(difference_type i, const iter_impl& it)
11305 {
11306 auto result = it;
11307 result += i;
11308 return result;
11309 }
11310
11315 iter_impl operator-(difference_type i) const
11316 {
11317 auto result = *this;
11318 result -= i;
11319 return result;
11320 }
11321
11326 difference_type operator-(const iter_impl& other) const
11327 {
11328 JSON_ASSERT(m_object != nullptr);
11329
11330 switch (m_object->m_type)
11331 {
11332 case value_t::object:
11333 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
11334
11335 case value_t::array:
11336 return m_it.array_iterator - other.m_it.array_iterator;
11337
11338 default:
11339 return m_it.primitive_iterator - other.m_it.primitive_iterator;
11340 }
11341 }
11342
11347 reference operator[](difference_type n) const
11348 {
11349 JSON_ASSERT(m_object != nullptr);
11350
11351 switch (m_object->m_type)
11352 {
11353 case value_t::object:
11354 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
11355
11356 case value_t::array:
11357 return *std::next(m_it.array_iterator, n);
11358
11359 case value_t::null:
11360 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11361
11362 default:
11363 {
11364 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
11365 {
11366 return *m_object;
11367 }
11368
11369 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11370 }
11371 }
11372 }
11373
11378 const typename object_t::key_type& key() const
11379 {
11380 JSON_ASSERT(m_object != nullptr);
11381
11382 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
11383 {
11384 return m_it.object_iterator->first;
11385 }
11386
11387 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
11388 }
11389
11394 reference value() const
11395 {
11396 return operator*();
11397 }
11398
11399 private:
11401 pointer m_object = nullptr;
11403 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
11404 };
11405 } // namespace detail
11406 } // namespace nlohmann
11407
11408 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
11409
11410 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
11411
11412
11413 #include <cstddef> // ptrdiff_t
11414 #include <iterator> // reverse_iterator
11415 #include <utility> // declval
11416
11417 namespace nlohmann
11418 {
11419 namespace detail
11420 {
11422 // reverse_iterator //
11424
11443 template<typename Base>
11444 class json_reverse_iterator : public std::reverse_iterator<Base>
11445 {
11446 public:
11447 using difference_type = std::ptrdiff_t;
11449 using base_iterator = std::reverse_iterator<Base>;
11451 using reference = typename Base::reference;
11452
11454 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
11455 : base_iterator(it) {}
11456
11458 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
11459
11461 json_reverse_iterator const operator++(int)
11462 {
11463 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
11464 }
11465
11467 json_reverse_iterator& operator++()
11468 {
11469 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
11470 }
11471
11473 json_reverse_iterator const operator--(int)
11474 {
11475 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
11476 }
11477
11479 json_reverse_iterator& operator--()
11480 {
11481 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
11482 }
11483
11485 json_reverse_iterator& operator+=(difference_type i)
11486 {
11487 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
11488 }
11489
11491 json_reverse_iterator operator+(difference_type i) const
11492 {
11493 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
11494 }
11495
11497 json_reverse_iterator operator-(difference_type i) const
11498 {
11499 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
11500 }
11501
11503 difference_type operator-(const json_reverse_iterator& other) const
11504 {
11505 return base_iterator(*this) - base_iterator(other);
11506 }
11507
11509 reference operator[](difference_type n) const
11510 {
11511 return *(this->operator+(n));
11512 }
11513
11515 auto key() const -> decltype(std::declval<Base>().key())
11516 {
11517 auto it = --this->base();
11518 return it.key();
11519 }
11520
11522 reference value() const
11523 {
11524 auto it = --this->base();
11525 return it.operator * ();
11526 }
11527 };
11528 } // namespace detail
11529 } // namespace nlohmann
11530
11531 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11532
11533 // #include <nlohmann/detail/json_pointer.hpp>
11534
11535
11536 #include <algorithm> // all_of
11537 #include <cctype> // isdigit
11538 #include <limits> // max
11539 #include <numeric> // accumulate
11540 #include <string> // string
11541 #include <utility> // move
11542 #include <vector> // vector
11543
11544 // #include <nlohmann/detail/exceptions.hpp>
11545
11546 // #include <nlohmann/detail/macro_scope.hpp>
11547
11548 // #include <nlohmann/detail/value_t.hpp>
11549
11550
11551 namespace nlohmann
11552 {
11553 template<typename BasicJsonType>
11554 class json_pointer
11555 {
11556 // allow basic_json to access private members
11557 NLOHMANN_BASIC_JSON_TPL_DECLARATION
11558 friend class basic_json;
11559
11560 public:
11582 explicit json_pointer(const std::string& s = "")
11583 : reference_tokens(split(s))
11584 {}
11585
11600 std::string to_string() const
11601 {
11602 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
11603 std::string{},
11604 [](const std::string & a, const std::string & b)
11605 {
11606 return a + "/" + escape(b);
11607 });
11608 }
11609
11611 operator std::string() const
11612 {
11613 return to_string();
11614 }
11615
11632 json_pointer& operator/=(const json_pointer& ptr)
11633 {
11634 reference_tokens.insert(reference_tokens.end(),
11635 ptr.reference_tokens.begin(),
11636 ptr.reference_tokens.end());
11637 return *this;
11638 }
11639
11656 json_pointer& operator/=(std::string token)
11657 {
11658 push_back(std::move(token));
11659 return *this;
11660 }
11661
11678 json_pointer& operator/=(std::size_t array_idx)
11679 {
11680 return *this /= std::to_string(array_idx);
11681 }
11682
11698 friend json_pointer operator/(const json_pointer& lhs,
11699 const json_pointer& rhs)
11700 {
11701 return json_pointer(lhs) /= rhs;
11702 }
11703
11719 friend json_pointer operator/(const json_pointer& ptr, std::string token)
11720 {
11721 return json_pointer(ptr) /= std::move(token);
11722 }
11723
11739 friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
11740 {
11741 return json_pointer(ptr) /= array_idx;
11742 }
11743
11757 json_pointer parent_pointer() const
11758 {
11759 if (empty())
11760 {
11761 return *this;
11762 }
11763
11764 json_pointer res = *this;
11765 res.pop_back();
11766 return res;
11767 }
11768
11782 void pop_back()
11783 {
11784 if (JSON_HEDLEY_UNLIKELY(empty()))
11785 {
11786 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11787 }
11788
11789 reference_tokens.pop_back();
11790 }
11791
11806 const std::string& back() const
11807 {
11808 if (JSON_HEDLEY_UNLIKELY(empty()))
11809 {
11810 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11811 }
11812
11813 return reference_tokens.back();
11814 }
11815
11828 void push_back(const std::string& token)
11829 {
11830 reference_tokens.push_back(token);
11831 }
11832
11834 void push_back(std::string&& token)
11835 {
11836 reference_tokens.push_back(std::move(token));
11837 }
11838
11853 bool empty() const noexcept
11854 {
11855 return reference_tokens.empty();
11856 }
11857
11858 private:
11869 static typename BasicJsonType::size_type array_index(const std::string& s)
11870 {
11871 using size_type = typename BasicJsonType::size_type;
11872
11873 // error condition (cf. RFC 6901, Sect. 4)
11874 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
11875 {
11876 JSON_THROW(detail::parse_error::create(106, 0,
11877 "array index '" + s +
11878 "' must not begin with '0'"));
11879 }
11880
11881 // error condition (cf. RFC 6901, Sect. 4)
11882 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
11883 {
11884 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number"));
11885 }
11886
11887 std::size_t processed_chars = 0;
11888 unsigned long long res = 0;
11889 JSON_TRY
11890 {
11891 res = std::stoull(s, &processed_chars);
11892 }
11893 JSON_CATCH(std::out_of_range&)
11894 {
11895 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11896 }
11897
11898 // check if the string was completely read
11899 if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
11900 {
11901 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11902 }
11903
11904 // only triggered on special platforms (like 32bit), see also
11905 // https://github.com/nlohmann/json/pull/2203
11906 if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)()))
11907 {
11908 JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type")); // LCOV_EXCL_LINE
11909 }
11910
11911 return static_cast<size_type>(res);
11912 }
11913
11914 json_pointer top() const
11915 {
11916 if (JSON_HEDLEY_UNLIKELY(empty()))
11917 {
11918 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11919 }
11920
11921 json_pointer result = *this;
11922 result.reference_tokens = {reference_tokens[0]};
11923 return result;
11924 }
11925
11934 BasicJsonType& get_and_create(BasicJsonType& j) const
11935 {
11936 auto result = &j;
11937
11938 // in case no reference tokens exist, return a reference to the JSON value
11939 // j which will be overwritten by a primitive value
11940 for (const auto& reference_token : reference_tokens)
11941 {
11942 switch (result->type())
11943 {
11944 case detail::value_t::null:
11945 {
11946 if (reference_token == "0")
11947 {
11948 // start a new array if reference token is 0
11949 result = &result->operator[](0);
11950 }
11951 else
11952 {
11953 // start a new object otherwise
11954 result = &result->operator[](reference_token);
11955 }
11956 break;
11957 }
11958
11959 case detail::value_t::object:
11960 {
11961 // create an entry in the object
11962 result = &result->operator[](reference_token);
11963 break;
11964 }
11965
11966 case detail::value_t::array:
11967 {
11968 // create an entry in the array
11969 result = &result->operator[](array_index(reference_token));
11970 break;
11971 }
11972
11973 /*
11974 The following code is only reached if there exists a reference
11975 token _and_ the current value is primitive. In this case, we have
11976 an error situation, because primitive values may only occur as
11977 single value; that is, with an empty list of reference tokens.
11978 */
11979 default:
11980 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
11981 }
11982 }
11983
11984 return *result;
11985 }
11986
12006 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
12007 {
12008 for (const auto& reference_token : reference_tokens)
12009 {
12010 // convert null values to arrays or objects before continuing
12011 if (ptr->is_null())
12012 {
12013 // check if reference token is a number
12014 const bool nums =
12015 std::all_of(reference_token.begin(), reference_token.end(),
12016 [](const unsigned char x)
12017 {
12018 return std::isdigit(x);
12019 });
12020
12021 // change value to array for numbers or "-" or to object otherwise
12022 *ptr = (nums || reference_token == "-")
12023 ? detail::value_t::array
12024 : detail::value_t::object;
12025 }
12026
12027 switch (ptr->type())
12028 {
12029 case detail::value_t::object:
12030 {
12031 // use unchecked object access
12032 ptr = &ptr->operator[](reference_token);
12033 break;
12034 }
12035
12036 case detail::value_t::array:
12037 {
12038 if (reference_token == "-")
12039 {
12040 // explicitly treat "-" as index beyond the end
12041 ptr = &ptr->operator[](ptr->m_value.array->size());
12042 }
12043 else
12044 {
12045 // convert array index to number; unchecked access
12046 ptr = &ptr->operator[](array_index(reference_token));
12047 }
12048 break;
12049 }
12050
12051 default:
12052 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12053 }
12054 }
12055
12056 return *ptr;
12057 }
12058
12065 BasicJsonType& get_checked(BasicJsonType* ptr) const
12066 {
12067 for (const auto& reference_token : reference_tokens)
12068 {
12069 switch (ptr->type())
12070 {
12071 case detail::value_t::object:
12072 {
12073 // note: at performs range check
12074 ptr = &ptr->at(reference_token);
12075 break;
12076 }
12077
12078 case detail::value_t::array:
12079 {
12080 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12081 {
12082 // "-" always fails the range check
12083 JSON_THROW(detail::out_of_range::create(402,
12084 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12085 ") is out of range"));
12086 }
12087
12088 // note: at performs range check
12089 ptr = &ptr->at(array_index(reference_token));
12090 break;
12091 }
12092
12093 default:
12094 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12095 }
12096 }
12097
12098 return *ptr;
12099 }
12100
12114 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
12115 {
12116 for (const auto& reference_token : reference_tokens)
12117 {
12118 switch (ptr->type())
12119 {
12120 case detail::value_t::object:
12121 {
12122 // use unchecked object access
12123 ptr = &ptr->operator[](reference_token);
12124 break;
12125 }
12126
12127 case detail::value_t::array:
12128 {
12129 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12130 {
12131 // "-" cannot be used for const access
12132 JSON_THROW(detail::out_of_range::create(402,
12133 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12134 ") is out of range"));
12135 }
12136
12137 // use unchecked array access
12138 ptr = &ptr->operator[](array_index(reference_token));
12139 break;
12140 }
12141
12142 default:
12143 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12144 }
12145 }
12146
12147 return *ptr;
12148 }
12149
12156 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
12157 {
12158 for (const auto& reference_token : reference_tokens)
12159 {
12160 switch (ptr->type())
12161 {
12162 case detail::value_t::object:
12163 {
12164 // note: at performs range check
12165 ptr = &ptr->at(reference_token);
12166 break;
12167 }
12168
12169 case detail::value_t::array:
12170 {
12171 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12172 {
12173 // "-" always fails the range check
12174 JSON_THROW(detail::out_of_range::create(402,
12175 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12176 ") is out of range"));
12177 }
12178
12179 // note: at performs range check
12180 ptr = &ptr->at(array_index(reference_token));
12181 break;
12182 }
12183
12184 default:
12185 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12186 }
12187 }
12188
12189 return *ptr;
12190 }
12191
12196 bool contains(const BasicJsonType* ptr) const
12197 {
12198 for (const auto& reference_token : reference_tokens)
12199 {
12200 switch (ptr->type())
12201 {
12202 case detail::value_t::object:
12203 {
12204 if (!ptr->contains(reference_token))
12205 {
12206 // we did not find the key in the object
12207 return false;
12208 }
12209
12210 ptr = &ptr->operator[](reference_token);
12211 break;
12212 }
12213
12214 case detail::value_t::array:
12215 {
12216 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12217 {
12218 // "-" always fails the range check
12219 return false;
12220 }
12221 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
12222 {
12223 // invalid char
12224 return false;
12225 }
12226 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
12227 {
12228 if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
12229 {
12230 // first char should be between '1' and '9'
12231 return false;
12232 }
12233 for (std::size_t i = 1; i < reference_token.size(); i++)
12234 {
12235 if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
12236 {
12237 // other char should be between '0' and '9'
12238 return false;
12239 }
12240 }
12241 }
12242
12243 const auto idx = array_index(reference_token);
12244 if (idx >= ptr->size())
12245 {
12246 // index out of range
12247 return false;
12248 }
12249
12250 ptr = &ptr->operator[](idx);
12251 break;
12252 }
12253
12254 default:
12255 {
12256 // we do not expect primitive values if there is still a
12257 // reference token to process
12258 return false;
12259 }
12260 }
12261 }
12262
12263 // no reference token left means we found a primitive value
12264 return true;
12265 }
12266
12276 static std::vector<std::string> split(const std::string& reference_string)
12277 {
12278 std::vector<std::string> result;
12279
12280 // special case: empty reference string -> no reference tokens
12281 if (reference_string.empty())
12282 {
12283 return result;
12284 }
12285
12286 // check if nonempty reference string begins with slash
12287 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
12288 {
12289 JSON_THROW(detail::parse_error::create(107, 1,
12290 "JSON pointer must be empty or begin with '/' - was: '" +
12291 reference_string + "'"));
12292 }
12293
12294 // extract the reference tokens:
12295 // - slash: position of the last read slash (or end of string)
12296 // - start: position after the previous slash
12297 for (
12298 // search for the first slash after the first character
12299 std::size_t slash = reference_string.find_first_of('/', 1),
12300 // set the beginning of the first reference token
12301 start = 1;
12302 // we can stop if start == 0 (if slash == std::string::npos)
12303 start != 0;
12304 // set the beginning of the next reference token
12305 // (will eventually be 0 if slash == std::string::npos)
12306 start = (slash == std::string::npos) ? 0 : slash + 1,
12307 // find next slash
12308 slash = reference_string.find_first_of('/', start))
12309 {
12310 // use the text between the beginning of the reference token
12311 // (start) and the last slash (slash).
12312 auto reference_token = reference_string.substr(start, slash - start);
12313
12314 // check reference tokens are properly escaped
12315 for (std::size_t pos = reference_token.find_first_of('~');
12316 pos != std::string::npos;
12317 pos = reference_token.find_first_of('~', pos + 1))
12318 {
12319 JSON_ASSERT(reference_token[pos] == '~');
12320
12321 // ~ must be followed by 0 or 1
12322 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
12323 (reference_token[pos + 1] != '0' &&
12324 reference_token[pos + 1] != '1')))
12325 {
12326 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
12327 }
12328 }
12329
12330 // finally, store the reference token
12331 unescape(reference_token);
12332 result.push_back(reference_token);
12333 }
12334
12335 return result;
12336 }
12337
12351 static void replace_substring(std::string& s, const std::string& f,
12352 const std::string& t)
12353 {
12354 JSON_ASSERT(!f.empty());
12355 for (auto pos = s.find(f); // find first occurrence of f
12356 pos != std::string::npos; // make sure f was found
12357 s.replace(pos, f.size(), t), // replace with t, and
12358 pos = s.find(f, pos + t.size())) // find next occurrence of f
12359 {}
12360 }
12361
12363 static std::string escape(std::string s)
12364 {
12365 replace_substring(s, "~", "~0");
12366 replace_substring(s, "/", "~1");
12367 return s;
12368 }
12369
12371 static void unescape(std::string& s)
12372 {
12373 replace_substring(s, "~1", "/");
12374 replace_substring(s, "~0", "~");
12375 }
12376
12384 static void flatten(const std::string& reference_string,
12385 const BasicJsonType& value,
12386 BasicJsonType& result)
12387 {
12388 switch (value.type())
12389 {
12390 case detail::value_t::array:
12391 {
12392 if (value.m_value.array->empty())
12393 {
12394 // flatten empty array as null
12395 result[reference_string] = nullptr;
12396 }
12397 else
12398 {
12399 // iterate array and use index as reference string
12400 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
12401 {
12402 flatten(reference_string + "/" + std::to_string(i),
12403 value.m_value.array->operator[](i), result);
12404 }
12405 }
12406 break;
12407 }
12408
12409 case detail::value_t::object:
12410 {
12411 if (value.m_value.object->empty())
12412 {
12413 // flatten empty object as null
12414 result[reference_string] = nullptr;
12415 }
12416 else
12417 {
12418 // iterate object and use keys as reference string
12419 for (const auto& element : *value.m_value.object)
12420 {
12421 flatten(reference_string + "/" + escape(element.first), element.second, result);
12422 }
12423 }
12424 break;
12425 }
12426
12427 default:
12428 {
12429 // add primitive value with its reference string
12430 result[reference_string] = value;
12431 break;
12432 }
12433 }
12434 }
12435
12446 static BasicJsonType
12447 unflatten(const BasicJsonType& value)
12448 {
12449 if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
12450 {
12451 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
12452 }
12453
12454 BasicJsonType result;
12455
12456 // iterate the JSON object values
12457 for (const auto& element : *value.m_value.object)
12458 {
12459 if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
12460 {
12461 JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
12462 }
12463
12464 // assign value to reference pointed to by JSON pointer; Note that if
12465 // the JSON pointer is "" (i.e., points to the whole value), function
12466 // get_and_create returns a reference to result itself. An assignment
12467 // will then create a primitive value.
12468 json_pointer(element.first).get_and_create(result) = element.second;
12469 }
12470
12471 return result;
12472 }
12473
12485 friend bool operator==(json_pointer const& lhs,
12486 json_pointer const& rhs) noexcept
12487 {
12488 return lhs.reference_tokens == rhs.reference_tokens;
12489 }
12490
12502 friend bool operator!=(json_pointer const& lhs,
12503 json_pointer const& rhs) noexcept
12504 {
12505 return !(lhs == rhs);
12506 }
12507
12509 std::vector<std::string> reference_tokens;
12510 };
12511 } // namespace nlohmann
12512
12513 // #include <nlohmann/detail/json_ref.hpp>
12514
12515
12516 #include <initializer_list>
12517 #include <utility>
12518
12519 // #include <nlohmann/detail/meta/type_traits.hpp>
12520
12521
12522 namespace nlohmann
12523 {
12524 namespace detail
12525 {
12526 template<typename BasicJsonType>
12527 class json_ref
12528 {
12529 public:
12530 using value_type = BasicJsonType;
12531
12532 json_ref(value_type&& value)
12533 : owned_value(std::move(value))
12534 , value_ref(&owned_value)
12535 , is_rvalue(true)
12536 {}
12537
12538 json_ref(const value_type& value)
12539 : value_ref(const_cast<value_type*>(&value))
12540 , is_rvalue(false)
12541 {}
12542
12543 json_ref(std::initializer_list<json_ref> init)
12544 : owned_value(init)
12545 , value_ref(&owned_value)
12546 , is_rvalue(true)
12547 {}
12548
12549 template <
12550 class... Args,
12551 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
12552 json_ref(Args && ... args)
12553 : owned_value(std::forward<Args>(args)...)
12554 , value_ref(&owned_value)
12555 , is_rvalue(true)
12556 {}
12557
12558 // class should be movable only
12559 json_ref(json_ref&&) = default;
12560 json_ref(const json_ref&) = delete;
12561 json_ref& operator=(const json_ref&) = delete;
12562 json_ref& operator=(json_ref&&) = delete;
12563 ~json_ref() = default;
12564
12565 value_type moved_or_copied() const
12566 {
12567 if (is_rvalue)
12568 {
12569 return std::move(*value_ref);
12570 }
12571 return *value_ref;
12572 }
12573
12574 value_type const& operator*() const
12575 {
12576 return *static_cast<value_type const*>(value_ref);
12577 }
12578
12579 value_type const* operator->() const
12580 {
12581 return static_cast<value_type const*>(value_ref);
12582 }
12583
12584 private:
12585 mutable value_type owned_value = nullptr;
12586 value_type* value_ref = nullptr;
12587 const bool is_rvalue = true;
12588 };
12589 } // namespace detail
12590 } // namespace nlohmann
12591
12592 // #include <nlohmann/detail/macro_scope.hpp>
12593
12594 // #include <nlohmann/detail/meta/cpp_future.hpp>
12595
12596 // #include <nlohmann/detail/meta/type_traits.hpp>
12597
12598 // #include <nlohmann/detail/output/binary_writer.hpp>
12599
12600
12601 #include <algorithm> // reverse
12602 #include <array> // array
12603 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
12604 #include <cstring> // memcpy
12605 #include <limits> // numeric_limits
12606 #include <string> // string
12607 #include <cmath> // isnan, isinf
12608
12609 // #include <nlohmann/detail/input/binary_reader.hpp>
12610
12611 // #include <nlohmann/detail/macro_scope.hpp>
12612
12613 // #include <nlohmann/detail/output/output_adapters.hpp>
12614
12615
12616 #include <algorithm> // copy
12617 #include <cstddef> // size_t
12618 #include <ios> // streamsize
12619 #include <iterator> // back_inserter
12620 #include <memory> // shared_ptr, make_shared
12621 #include <ostream> // basic_ostream
12622 #include <string> // basic_string
12623 #include <vector> // vector
12624 // #include <nlohmann/detail/macro_scope.hpp>
12625
12626
12627 namespace nlohmann
12628 {
12629 namespace detail
12630 {
12632 template<typename CharType> struct output_adapter_protocol
12633 {
12634 virtual void write_character(CharType c) = 0;
12635 virtual void write_characters(const CharType* s, std::size_t length) = 0;
12636 virtual ~output_adapter_protocol() = default;
12637 };
12638
12640 template<typename CharType>
12641 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
12642
12644 template<typename CharType>
12645 class output_vector_adapter : public output_adapter_protocol<CharType>
12646 {
12647 public:
12648 explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
12649 : v(vec)
12650 {}
12651
12652 void write_character(CharType c) override
12653 {
12654 v.push_back(c);
12655 }
12656
12657 JSON_HEDLEY_NON_NULL(2)
12658 void write_characters(const CharType* s, std::size_t length) override
12659 {
12660 std::copy(s, s + length, std::back_inserter(v));
12661 }
12662
12663 private:
12664 std::vector<CharType>& v;
12665 };
12666
12668 template<typename CharType>
12669 class output_stream_adapter : public output_adapter_protocol<CharType>
12670 {
12671 public:
12672 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
12673 : stream(s)
12674 {}
12675
12676 void write_character(CharType c) override
12677 {
12678 stream.put(c);
12679 }
12680
12681 JSON_HEDLEY_NON_NULL(2)
12682 void write_characters(const CharType* s, std::size_t length) override
12683 {
12684 stream.write(s, static_cast<std::streamsize>(length));
12685 }
12686
12687 private:
12688 std::basic_ostream<CharType>& stream;
12689 };
12690
12692 template<typename CharType, typename StringType = std::basic_string<CharType>>
12693 class output_string_adapter : public output_adapter_protocol<CharType>
12694 {
12695 public:
12696 explicit output_string_adapter(StringType& s) noexcept
12697 : str(s)
12698 {}
12699
12700 void write_character(CharType c) override
12701 {
12702 str.push_back(c);
12703 }
12704
12705 JSON_HEDLEY_NON_NULL(2)
12706 void write_characters(const CharType* s, std::size_t length) override
12707 {
12708 str.append(s, length);
12709 }
12710
12711 private:
12712 StringType& str;
12713 };
12714
12715 template<typename CharType, typename StringType = std::basic_string<CharType>>
12716 class output_adapter
12717 {
12718 public:
12719 output_adapter(std::vector<CharType>& vec)
12720 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
12721
12722 output_adapter(std::basic_ostream<CharType>& s)
12723 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
12724
12725 output_adapter(StringType& s)
12726 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
12727
12728 operator output_adapter_t<CharType>()
12729 {
12730 return oa;
12731 }
12732
12733 private:
12734 output_adapter_t<CharType> oa = nullptr;
12735 };
12736 } // namespace detail
12737 } // namespace nlohmann
12738
12739
12740 namespace nlohmann
12741 {
12742 namespace detail
12743 {
12745 // binary writer //
12747
12751 template<typename BasicJsonType, typename CharType>
12752 class binary_writer
12753 {
12754 using string_t = typename BasicJsonType::string_t;
12755 using binary_t = typename BasicJsonType::binary_t;
12756 using number_float_t = typename BasicJsonType::number_float_t;
12757
12758 public:
12764 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
12765 {
12766 JSON_ASSERT(oa);
12767 }
12768
12773 void write_bson(const BasicJsonType& j)
12774 {
12775 switch (j.type())
12776 {
12777 case value_t::object:
12778 {
12779 write_bson_object(*j.m_value.object);
12780 break;
12781 }
12782
12783 default:
12784 {
12785 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
12786 }
12787 }
12788 }
12789
12793 void write_cbor(const BasicJsonType& j)
12794 {
12795 switch (j.type())
12796 {
12797 case value_t::null:
12798 {
12799 oa->write_character(to_char_type(0xF6));
12800 break;
12801 }
12802
12803 case value_t::boolean:
12804 {
12805 oa->write_character(j.m_value.boolean
12806 ? to_char_type(0xF5)
12807 : to_char_type(0xF4));
12808 break;
12809 }
12810
12811 case value_t::number_integer:
12812 {
12813 if (j.m_value.number_integer >= 0)
12814 {
12815 // CBOR does not differentiate between positive signed
12816 // integers and unsigned integers. Therefore, we used the
12817 // code from the value_t::number_unsigned case here.
12818 if (j.m_value.number_integer <= 0x17)
12819 {
12820 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12821 }
12822 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
12823 {
12824 oa->write_character(to_char_type(0x18));
12825 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12826 }
12827 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
12828 {
12829 oa->write_character(to_char_type(0x19));
12830 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
12831 }
12832 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
12833 {
12834 oa->write_character(to_char_type(0x1A));
12835 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
12836 }
12837 else
12838 {
12839 oa->write_character(to_char_type(0x1B));
12840 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
12841 }
12842 }
12843 else
12844 {
12845 // The conversions below encode the sign in the first
12846 // byte, and the value is converted to a positive number.
12847 const auto positive_number = -1 - j.m_value.number_integer;
12848 if (j.m_value.number_integer >= -24)
12849 {
12850 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
12851 }
12852 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
12853 {
12854 oa->write_character(to_char_type(0x38));
12855 write_number(static_cast<std::uint8_t>(positive_number));
12856 }
12857 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
12858 {
12859 oa->write_character(to_char_type(0x39));
12860 write_number(static_cast<std::uint16_t>(positive_number));
12861 }
12862 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
12863 {
12864 oa->write_character(to_char_type(0x3A));
12865 write_number(static_cast<std::uint32_t>(positive_number));
12866 }
12867 else
12868 {
12869 oa->write_character(to_char_type(0x3B));
12870 write_number(static_cast<std::uint64_t>(positive_number));
12871 }
12872 }
12873 break;
12874 }
12875
12876 case value_t::number_unsigned:
12877 {
12878 if (j.m_value.number_unsigned <= 0x17)
12879 {
12880 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
12881 }
12882 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12883 {
12884 oa->write_character(to_char_type(0x18));
12885 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
12886 }
12887 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12888 {
12889 oa->write_character(to_char_type(0x19));
12890 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
12891 }
12892 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12893 {
12894 oa->write_character(to_char_type(0x1A));
12895 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
12896 }
12897 else
12898 {
12899 oa->write_character(to_char_type(0x1B));
12900 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
12901 }
12902 break;
12903 }
12904
12905 case value_t::number_float:
12906 {
12907 if (std::isnan(j.m_value.number_float))
12908 {
12909 // NaN is 0xf97e00 in CBOR
12910 oa->write_character(to_char_type(0xF9));
12911 oa->write_character(to_char_type(0x7E));
12912 oa->write_character(to_char_type(0x00));
12913 }
12914 else if (std::isinf(j.m_value.number_float))
12915 {
12916 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
12917 oa->write_character(to_char_type(0xf9));
12918 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
12919 oa->write_character(to_char_type(0x00));
12920 }
12921 else
12922 {
12923 write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
12924 }
12925 break;
12926 }
12927
12928 case value_t::string:
12929 {
12930 // step 1: write control byte and the string length
12931 const auto N = j.m_value.string->size();
12932 if (N <= 0x17)
12933 {
12934 write_number(static_cast<std::uint8_t>(0x60 + N));
12935 }
12936 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12937 {
12938 oa->write_character(to_char_type(0x78));
12939 write_number(static_cast<std::uint8_t>(N));
12940 }
12941 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12942 {
12943 oa->write_character(to_char_type(0x79));
12944 write_number(static_cast<std::uint16_t>(N));
12945 }
12946 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12947 {
12948 oa->write_character(to_char_type(0x7A));
12949 write_number(static_cast<std::uint32_t>(N));
12950 }
12951 // LCOV_EXCL_START
12952 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12953 {
12954 oa->write_character(to_char_type(0x7B));
12955 write_number(static_cast<std::uint64_t>(N));
12956 }
12957 // LCOV_EXCL_STOP
12958
12959 // step 2: write the string
12960 oa->write_characters(
12961 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
12962 j.m_value.string->size());
12963 break;
12964 }
12965
12966 case value_t::array:
12967 {
12968 // step 1: write control byte and the array size
12969 const auto N = j.m_value.array->size();
12970 if (N <= 0x17)
12971 {
12972 write_number(static_cast<std::uint8_t>(0x80 + N));
12973 }
12974 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12975 {
12976 oa->write_character(to_char_type(0x98));
12977 write_number(static_cast<std::uint8_t>(N));
12978 }
12979 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12980 {
12981 oa->write_character(to_char_type(0x99));
12982 write_number(static_cast<std::uint16_t>(N));
12983 }
12984 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12985 {
12986 oa->write_character(to_char_type(0x9A));
12987 write_number(static_cast<std::uint32_t>(N));
12988 }
12989 // LCOV_EXCL_START
12990 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12991 {
12992 oa->write_character(to_char_type(0x9B));
12993 write_number(static_cast<std::uint64_t>(N));
12994 }
12995 // LCOV_EXCL_STOP
12996
12997 // step 2: write each element
12998 for (const auto& el : *j.m_value.array)
12999 {
13000 write_cbor(el);
13001 }
13002 break;
13003 }
13004
13005 case value_t::binary:
13006 {
13007 if (j.m_value.binary->has_subtype())
13008 {
13009 write_number(static_cast<std::uint8_t>(0xd8));
13010 write_number(j.m_value.binary->subtype());
13011 }
13012
13013 // step 1: write control byte and the binary array size
13014 const auto N = j.m_value.binary->size();
13015 if (N <= 0x17)
13016 {
13017 write_number(static_cast<std::uint8_t>(0x40 + N));
13018 }
13019 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13020 {
13021 oa->write_character(to_char_type(0x58));
13022 write_number(static_cast<std::uint8_t>(N));
13023 }
13024 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13025 {
13026 oa->write_character(to_char_type(0x59));
13027 write_number(static_cast<std::uint16_t>(N));
13028 }
13029 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13030 {
13031 oa->write_character(to_char_type(0x5A));
13032 write_number(static_cast<std::uint32_t>(N));
13033 }
13034 // LCOV_EXCL_START
13035 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13036 {
13037 oa->write_character(to_char_type(0x5B));
13038 write_number(static_cast<std::uint64_t>(N));
13039 }
13040 // LCOV_EXCL_STOP
13041
13042 // step 2: write each element
13043 oa->write_characters(
13044 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13045 N);
13046
13047 break;
13048 }
13049
13050 case value_t::object:
13051 {
13052 // step 1: write control byte and the object size
13053 const auto N = j.m_value.object->size();
13054 if (N <= 0x17)
13055 {
13056 write_number(static_cast<std::uint8_t>(0xA0 + N));
13057 }
13058 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13059 {
13060 oa->write_character(to_char_type(0xB8));
13061 write_number(static_cast<std::uint8_t>(N));
13062 }
13063 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13064 {
13065 oa->write_character(to_char_type(0xB9));
13066 write_number(static_cast<std::uint16_t>(N));
13067 }
13068 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13069 {
13070 oa->write_character(to_char_type(0xBA));
13071 write_number(static_cast<std::uint32_t>(N));
13072 }
13073 // LCOV_EXCL_START
13074 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13075 {
13076 oa->write_character(to_char_type(0xBB));
13077 write_number(static_cast<std::uint64_t>(N));
13078 }
13079 // LCOV_EXCL_STOP
13080
13081 // step 2: write each element
13082 for (const auto& el : *j.m_value.object)
13083 {
13084 write_cbor(el.first);
13085 write_cbor(el.second);
13086 }
13087 break;
13088 }
13089
13090 default:
13091 break;
13092 }
13093 }
13094
13098 void write_msgpack(const BasicJsonType& j)
13099 {
13100 switch (j.type())
13101 {
13102 case value_t::null: // nil
13103 {
13104 oa->write_character(to_char_type(0xC0));
13105 break;
13106 }
13107
13108 case value_t::boolean: // true and false
13109 {
13110 oa->write_character(j.m_value.boolean
13111 ? to_char_type(0xC3)
13112 : to_char_type(0xC2));
13113 break;
13114 }
13115
13116 case value_t::number_integer:
13117 {
13118 if (j.m_value.number_integer >= 0)
13119 {
13120 // MessagePack does not differentiate between positive
13121 // signed integers and unsigned integers. Therefore, we used
13122 // the code from the value_t::number_unsigned case here.
13123 if (j.m_value.number_unsigned < 128)
13124 {
13125 // positive fixnum
13126 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13127 }
13128 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13129 {
13130 // uint 8
13131 oa->write_character(to_char_type(0xCC));
13132 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13133 }
13134 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13135 {
13136 // uint 16
13137 oa->write_character(to_char_type(0xCD));
13138 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13139 }
13140 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13141 {
13142 // uint 32
13143 oa->write_character(to_char_type(0xCE));
13144 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13145 }
13146 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
13147 {
13148 // uint 64
13149 oa->write_character(to_char_type(0xCF));
13150 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13151 }
13152 }
13153 else
13154 {
13155 if (j.m_value.number_integer >= -32)
13156 {
13157 // negative fixnum
13158 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
13159 }
13160 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
13161 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
13162 {
13163 // int 8
13164 oa->write_character(to_char_type(0xD0));
13165 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
13166 }
13167 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
13168 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
13169 {
13170 // int 16
13171 oa->write_character(to_char_type(0xD1));
13172 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
13173 }
13174 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
13175 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
13176 {
13177 // int 32
13178 oa->write_character(to_char_type(0xD2));
13179 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
13180 }
13181 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
13182 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
13183 {
13184 // int 64
13185 oa->write_character(to_char_type(0xD3));
13186 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
13187 }
13188 }
13189 break;
13190 }
13191
13192 case value_t::number_unsigned:
13193 {
13194 if (j.m_value.number_unsigned < 128)
13195 {
13196 // positive fixnum
13197 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13198 }
13199 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13200 {
13201 // uint 8
13202 oa->write_character(to_char_type(0xCC));
13203 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13204 }
13205 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13206 {
13207 // uint 16
13208 oa->write_character(to_char_type(0xCD));
13209 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13210 }
13211 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13212 {
13213 // uint 32
13214 oa->write_character(to_char_type(0xCE));
13215 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13216 }
13217 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
13218 {
13219 // uint 64
13220 oa->write_character(to_char_type(0xCF));
13221 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13222 }
13223 break;
13224 }
13225
13226 case value_t::number_float:
13227 {
13228 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
13229 break;
13230 }
13231
13232 case value_t::string:
13233 {
13234 // step 1: write control byte and the string length
13235 const auto N = j.m_value.string->size();
13236 if (N <= 31)
13237 {
13238 // fixstr
13239 write_number(static_cast<std::uint8_t>(0xA0 | N));
13240 }
13241 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13242 {
13243 // str 8
13244 oa->write_character(to_char_type(0xD9));
13245 write_number(static_cast<std::uint8_t>(N));
13246 }
13247 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13248 {
13249 // str 16
13250 oa->write_character(to_char_type(0xDA));
13251 write_number(static_cast<std::uint16_t>(N));
13252 }
13253 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13254 {
13255 // str 32
13256 oa->write_character(to_char_type(0xDB));
13257 write_number(static_cast<std::uint32_t>(N));
13258 }
13259
13260 // step 2: write the string
13261 oa->write_characters(
13262 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13263 j.m_value.string->size());
13264 break;
13265 }
13266
13267 case value_t::array:
13268 {
13269 // step 1: write control byte and the array size
13270 const auto N = j.m_value.array->size();
13271 if (N <= 15)
13272 {
13273 // fixarray
13274 write_number(static_cast<std::uint8_t>(0x90 | N));
13275 }
13276 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13277 {
13278 // array 16
13279 oa->write_character(to_char_type(0xDC));
13280 write_number(static_cast<std::uint16_t>(N));
13281 }
13282 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13283 {
13284 // array 32
13285 oa->write_character(to_char_type(0xDD));
13286 write_number(static_cast<std::uint32_t>(N));
13287 }
13288
13289 // step 2: write each element
13290 for (const auto& el : *j.m_value.array)
13291 {
13292 write_msgpack(el);
13293 }
13294 break;
13295 }
13296
13297 case value_t::binary:
13298 {
13299 // step 0: determine if the binary type has a set subtype to
13300 // determine whether or not to use the ext or fixext types
13301 const bool use_ext = j.m_value.binary->has_subtype();
13302
13303 // step 1: write control byte and the byte string length
13304 const auto N = j.m_value.binary->size();
13305 if (N <= (std::numeric_limits<std::uint8_t>::max)())
13306 {
13307 std::uint8_t output_type{};
13308 bool fixed = true;
13309 if (use_ext)
13310 {
13311 switch (N)
13312 {
13313 case 1:
13314 output_type = 0xD4; // fixext 1
13315 break;
13316 case 2:
13317 output_type = 0xD5; // fixext 2
13318 break;
13319 case 4:
13320 output_type = 0xD6; // fixext 4
13321 break;
13322 case 8:
13323 output_type = 0xD7; // fixext 8
13324 break;
13325 case 16:
13326 output_type = 0xD8; // fixext 16
13327 break;
13328 default:
13329 output_type = 0xC7; // ext 8
13330 fixed = false;
13331 break;
13332 }
13333
13334 }
13335 else
13336 {
13337 output_type = 0xC4; // bin 8
13338 fixed = false;
13339 }
13340
13341 oa->write_character(to_char_type(output_type));
13342 if (!fixed)
13343 {
13344 write_number(static_cast<std::uint8_t>(N));
13345 }
13346 }
13347 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13348 {
13349 std::uint8_t output_type = use_ext
13350 ? 0xC8 // ext 16
13351 : 0xC5; // bin 16
13352
13353 oa->write_character(to_char_type(output_type));
13354 write_number(static_cast<std::uint16_t>(N));
13355 }
13356 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13357 {
13358 std::uint8_t output_type = use_ext
13359 ? 0xC9 // ext 32
13360 : 0xC6; // bin 32
13361
13362 oa->write_character(to_char_type(output_type));
13363 write_number(static_cast<std::uint32_t>(N));
13364 }
13365
13366 // step 1.5: if this is an ext type, write the subtype
13367 if (use_ext)
13368 {
13369 write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
13370 }
13371
13372 // step 2: write the byte string
13373 oa->write_characters(
13374 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13375 N);
13376
13377 break;
13378 }
13379
13380 case value_t::object:
13381 {
13382 // step 1: write control byte and the object size
13383 const auto N = j.m_value.object->size();
13384 if (N <= 15)
13385 {
13386 // fixmap
13387 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
13388 }
13389 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13390 {
13391 // map 16
13392 oa->write_character(to_char_type(0xDE));
13393 write_number(static_cast<std::uint16_t>(N));
13394 }
13395 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13396 {
13397 // map 32
13398 oa->write_character(to_char_type(0xDF));
13399 write_number(static_cast<std::uint32_t>(N));
13400 }
13401
13402 // step 2: write each element
13403 for (const auto& el : *j.m_value.object)
13404 {
13405 write_msgpack(el.first);
13406 write_msgpack(el.second);
13407 }
13408 break;
13409 }
13410
13411 default:
13412 break;
13413 }
13414 }
13415
13422 void write_ubjson(const BasicJsonType& j, const bool use_count,
13423 const bool use_type, const bool add_prefix = true)
13424 {
13425 switch (j.type())
13426 {
13427 case value_t::null:
13428 {
13429 if (add_prefix)
13430 {
13431 oa->write_character(to_char_type('Z'));
13432 }
13433 break;
13434 }
13435
13436 case value_t::boolean:
13437 {
13438 if (add_prefix)
13439 {
13440 oa->write_character(j.m_value.boolean
13441 ? to_char_type('T')
13442 : to_char_type('F'));
13443 }
13444 break;
13445 }
13446
13447 case value_t::number_integer:
13448 {
13449 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
13450 break;
13451 }
13452
13453 case value_t::number_unsigned:
13454 {
13455 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
13456 break;
13457 }
13458
13459 case value_t::number_float:
13460 {
13461 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
13462 break;
13463 }
13464
13465 case value_t::string:
13466 {
13467 if (add_prefix)
13468 {
13469 oa->write_character(to_char_type('S'));
13470 }
13471 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
13472 oa->write_characters(
13473 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13474 j.m_value.string->size());
13475 break;
13476 }
13477
13478 case value_t::array:
13479 {
13480 if (add_prefix)
13481 {
13482 oa->write_character(to_char_type('['));
13483 }
13484
13485 bool prefix_required = true;
13486 if (use_type && !j.m_value.array->empty())
13487 {
13488 JSON_ASSERT(use_count);
13489 const CharType first_prefix = ubjson_prefix(j.front());
13490 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
13491 [this, first_prefix](const BasicJsonType & v)
13492 {
13493 return ubjson_prefix(v) == first_prefix;
13494 });
13495
13496 if (same_prefix)
13497 {
13498 prefix_required = false;
13499 oa->write_character(to_char_type('$'));
13500 oa->write_character(first_prefix);
13501 }
13502 }
13503
13504 if (use_count)
13505 {
13506 oa->write_character(to_char_type('#'));
13507 write_number_with_ubjson_prefix(j.m_value.array->size(), true);
13508 }
13509
13510 for (const auto& el : *j.m_value.array)
13511 {
13512 write_ubjson(el, use_count, use_type, prefix_required);
13513 }
13514
13515 if (!use_count)
13516 {
13517 oa->write_character(to_char_type(']'));
13518 }
13519
13520 break;
13521 }
13522
13523 case value_t::binary:
13524 {
13525 if (add_prefix)
13526 {
13527 oa->write_character(to_char_type('['));
13528 }
13529
13530 if (use_type && !j.m_value.binary->empty())
13531 {
13532 JSON_ASSERT(use_count);
13533 oa->write_character(to_char_type('$'));
13534 oa->write_character('U');
13535 }
13536
13537 if (use_count)
13538 {
13539 oa->write_character(to_char_type('#'));
13540 write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
13541 }
13542
13543 if (use_type)
13544 {
13545 oa->write_characters(
13546 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13547 j.m_value.binary->size());
13548 }
13549 else
13550 {
13551 for (size_t i = 0; i < j.m_value.binary->size(); ++i)
13552 {
13553 oa->write_character(to_char_type('U'));
13554 oa->write_character(j.m_value.binary->data()[i]);
13555 }
13556 }
13557
13558 if (!use_count)
13559 {
13560 oa->write_character(to_char_type(']'));
13561 }
13562
13563 break;
13564 }
13565
13566 case value_t::object:
13567 {
13568 if (add_prefix)
13569 {
13570 oa->write_character(to_char_type('{'));
13571 }
13572
13573 bool prefix_required = true;
13574 if (use_type && !j.m_value.object->empty())
13575 {
13576 JSON_ASSERT(use_count);
13577 const CharType first_prefix = ubjson_prefix(j.front());
13578 const bool same_prefix = std::all_of(j.begin(), j.end(),
13579 [this, first_prefix](const BasicJsonType & v)
13580 {
13581 return ubjson_prefix(v) == first_prefix;
13582 });
13583
13584 if (same_prefix)
13585 {
13586 prefix_required = false;
13587 oa->write_character(to_char_type('$'));
13588 oa->write_character(first_prefix);
13589 }
13590 }
13591
13592 if (use_count)
13593 {
13594 oa->write_character(to_char_type('#'));
13595 write_number_with_ubjson_prefix(j.m_value.object->size(), true);
13596 }
13597
13598 for (const auto& el : *j.m_value.object)
13599 {
13600 write_number_with_ubjson_prefix(el.first.size(), true);
13601 oa->write_characters(
13602 reinterpret_cast<const CharType*>(el.first.c_str()),
13603 el.first.size());
13604 write_ubjson(el.second, use_count, use_type, prefix_required);
13605 }
13606
13607 if (!use_count)
13608 {
13609 oa->write_character(to_char_type('}'));
13610 }
13611
13612 break;
13613 }
13614
13615 default:
13616 break;
13617 }
13618 }
13619
13620 private:
13622 // BSON //
13624
13629 static std::size_t calc_bson_entry_header_size(const string_t& name)
13630 {
13631 const auto it = name.find(static_cast<typename string_t::value_type>(0));
13632 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
13633 {
13634 JSON_THROW(out_of_range::create(409,
13635 "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
13636 }
13637
13638 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
13639 }
13640
13644 void write_bson_entry_header(const string_t& name,
13645 const std::uint8_t element_type)
13646 {
13647 oa->write_character(to_char_type(element_type)); // boolean
13648 oa->write_characters(
13649 reinterpret_cast<const CharType*>(name.c_str()),
13650 name.size() + 1u);
13651 }
13652
13656 void write_bson_boolean(const string_t& name,
13657 const bool value)
13658 {
13659 write_bson_entry_header(name, 0x08);
13660 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
13661 }
13662
13666 void write_bson_double(const string_t& name,
13667 const double value)
13668 {
13669 write_bson_entry_header(name, 0x01);
13670 write_number<double, true>(value);
13671 }
13672
13676 static std::size_t calc_bson_string_size(const string_t& value)
13677 {
13678 return sizeof(std::int32_t) + value.size() + 1ul;
13679 }
13680
13684 void write_bson_string(const string_t& name,
13685 const string_t& value)
13686 {
13687 write_bson_entry_header(name, 0x02);
13688
13689 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
13690 oa->write_characters(
13691 reinterpret_cast<const CharType*>(value.c_str()),
13692 value.size() + 1);
13693 }
13694
13698 void write_bson_null(const string_t& name)
13699 {
13700 write_bson_entry_header(name, 0x0A);
13701 }
13702
13706 static std::size_t calc_bson_integer_size(const std::int64_t value)
13707 {
13708 return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
13709 ? sizeof(std::int32_t)
13710 : sizeof(std::int64_t);
13711 }
13712
13716 void write_bson_integer(const string_t& name,
13717 const std::int64_t value)
13718 {
13719 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
13720 {
13721 write_bson_entry_header(name, 0x10); // int32
13722 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
13723 }
13724 else
13725 {
13726 write_bson_entry_header(name, 0x12); // int64
13727 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
13728 }
13729 }
13730
13734 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
13735 {
13736 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13737 ? sizeof(std::int32_t)
13738 : sizeof(std::int64_t);
13739 }
13740
13744 void write_bson_unsigned(const string_t& name,
13745 const std::uint64_t value)
13746 {
13747 if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13748 {
13749 write_bson_entry_header(name, 0x10 /* int32 */);
13750 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
13751 }
13752 else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
13753 {
13754 write_bson_entry_header(name, 0x12 /* int64 */);
13755 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
13756 }
13757 else
13758 {
13759 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
13760 }
13761 }
13762
13766 void write_bson_object_entry(const string_t& name,
13767 const typename BasicJsonType::object_t& value)
13768 {
13769 write_bson_entry_header(name, 0x03); // object
13770 write_bson_object(value);
13771 }
13772
13776 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
13777 {
13778 std::size_t array_index = 0ul;
13779
13780 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)
13781 {
13782 return result + calc_bson_element_size(std::to_string(array_index++), el);
13783 });
13784
13785 return sizeof(std::int32_t) + embedded_document_size + 1ul;
13786 }
13787
13791 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
13792 {
13793 return sizeof(std::int32_t) + value.size() + 1ul;
13794 }
13795
13799 void write_bson_array(const string_t& name,
13800 const typename BasicJsonType::array_t& value)
13801 {
13802 write_bson_entry_header(name, 0x04); // array
13803 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
13804
13805 std::size_t array_index = 0ul;
13806
13807 for (const auto& el : value)
13808 {
13809 write_bson_element(std::to_string(array_index++), el);
13810 }
13811
13812 oa->write_character(to_char_type(0x00));
13813 }
13814
13818 void write_bson_binary(const string_t& name,
13819 const binary_t& value)
13820 {
13821 write_bson_entry_header(name, 0x05);
13822
13823 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
13824 write_number(value.has_subtype() ? value.subtype() : std::uint8_t(0x00));
13825
13826 oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
13827 }
13828
13833 static std::size_t calc_bson_element_size(const string_t& name,
13834 const BasicJsonType& j)
13835 {
13836 const auto header_size = calc_bson_entry_header_size(name);
13837 switch (j.type())
13838 {
13839 case value_t::object:
13840 return header_size + calc_bson_object_size(*j.m_value.object);
13841
13842 case value_t::array:
13843 return header_size + calc_bson_array_size(*j.m_value.array);
13844
13845 case value_t::binary:
13846 return header_size + calc_bson_binary_size(*j.m_value.binary);
13847
13848 case value_t::boolean:
13849 return header_size + 1ul;
13850
13851 case value_t::number_float:
13852 return header_size + 8ul;
13853
13854 case value_t::number_integer:
13855 return header_size + calc_bson_integer_size(j.m_value.number_integer);
13856
13857 case value_t::number_unsigned:
13858 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
13859
13860 case value_t::string:
13861 return header_size + calc_bson_string_size(*j.m_value.string);
13862
13863 case value_t::null:
13864 return header_size + 0ul;
13865
13866 // LCOV_EXCL_START
13867 default:
13868 JSON_ASSERT(false);
13869 return 0ul;
13870 // LCOV_EXCL_STOP
13871 }
13872 }
13873
13881 void write_bson_element(const string_t& name,
13882 const BasicJsonType& j)
13883 {
13884 switch (j.type())
13885 {
13886 case value_t::object:
13887 return write_bson_object_entry(name, *j.m_value.object);
13888
13889 case value_t::array:
13890 return write_bson_array(name, *j.m_value.array);
13891
13892 case value_t::binary:
13893 return write_bson_binary(name, *j.m_value.binary);
13894
13895 case value_t::boolean:
13896 return write_bson_boolean(name, j.m_value.boolean);
13897
13898 case value_t::number_float:
13899 return write_bson_double(name, j.m_value.number_float);
13900
13901 case value_t::number_integer:
13902 return write_bson_integer(name, j.m_value.number_integer);
13903
13904 case value_t::number_unsigned:
13905 return write_bson_unsigned(name, j.m_value.number_unsigned);
13906
13907 case value_t::string:
13908 return write_bson_string(name, *j.m_value.string);
13909
13910 case value_t::null:
13911 return write_bson_null(name);
13912
13913 // LCOV_EXCL_START
13914 default:
13915 JSON_ASSERT(false);
13916 return;
13917 // LCOV_EXCL_STOP
13918 }
13919 }
13920
13927 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
13928 {
13929 std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
13930 [](size_t result, const typename BasicJsonType::object_t::value_type & el)
13931 {
13932 return result += calc_bson_element_size(el.first, el.second);
13933 });
13934
13935 return sizeof(std::int32_t) + document_size + 1ul;
13936 }
13937
13942 void write_bson_object(const typename BasicJsonType::object_t& value)
13943 {
13944 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
13945
13946 for (const auto& el : value)
13947 {
13948 write_bson_element(el.first, el.second);
13949 }
13950
13951 oa->write_character(to_char_type(0x00));
13952 }
13953
13955 // CBOR //
13957
13958 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
13959 {
13960 return to_char_type(0xFA); // Single-Precision Float
13961 }
13962
13963 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
13964 {
13965 return to_char_type(0xFB); // Double-Precision Float
13966 }
13967
13969 // MsgPack //
13971
13972 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
13973 {
13974 return to_char_type(0xCA); // float 32
13975 }
13976
13977 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
13978 {
13979 return to_char_type(0xCB); // float 64
13980 }
13981
13983 // UBJSON //
13985
13986 // UBJSON: write number (floating point)
13987 template<typename NumberType, typename std::enable_if<
13988 std::is_floating_point<NumberType>::value, int>::type = 0>
13989 void write_number_with_ubjson_prefix(const NumberType n,
13990 const bool add_prefix)
13991 {
13992 if (add_prefix)
13993 {
13994 oa->write_character(get_ubjson_float_prefix(n));
13995 }
13996 write_number(n);
13997 }
13998
13999 // UBJSON: write number (unsigned integer)
14000 template<typename NumberType, typename std::enable_if<
14001 std::is_unsigned<NumberType>::value, int>::type = 0>
14002 void write_number_with_ubjson_prefix(const NumberType n,
14003 const bool add_prefix)
14004 {
14005 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14006 {
14007 if (add_prefix)
14008 {
14009 oa->write_character(to_char_type('i')); // int8
14010 }
14011 write_number(static_cast<std::uint8_t>(n));
14012 }
14013 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
14014 {
14015 if (add_prefix)
14016 {
14017 oa->write_character(to_char_type('U')); // uint8
14018 }
14019 write_number(static_cast<std::uint8_t>(n));
14020 }
14021 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14022 {
14023 if (add_prefix)
14024 {
14025 oa->write_character(to_char_type('I')); // int16
14026 }
14027 write_number(static_cast<std::int16_t>(n));
14028 }
14029 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14030 {
14031 if (add_prefix)
14032 {
14033 oa->write_character(to_char_type('l')); // int32
14034 }
14035 write_number(static_cast<std::int32_t>(n));
14036 }
14037 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14038 {
14039 if (add_prefix)
14040 {
14041 oa->write_character(to_char_type('L')); // int64
14042 }
14043 write_number(static_cast<std::int64_t>(n));
14044 }
14045 else
14046 {
14047 if (add_prefix)
14048 {
14049 oa->write_character(to_char_type('H')); // high-precision number
14050 }
14051
14052 const auto number = BasicJsonType(n).dump();
14053 write_number_with_ubjson_prefix(number.size(), true);
14054 for (std::size_t i = 0; i < number.size(); ++i)
14055 {
14056 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14057 }
14058 }
14059 }
14060
14061 // UBJSON: write number (signed integer)
14062 template < typename NumberType, typename std::enable_if <
14063 std::is_signed<NumberType>::value&&
14064 !std::is_floating_point<NumberType>::value, int >::type = 0 >
14065 void write_number_with_ubjson_prefix(const NumberType n,
14066 const bool add_prefix)
14067 {
14068 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
14069 {
14070 if (add_prefix)
14071 {
14072 oa->write_character(to_char_type('i')); // int8
14073 }
14074 write_number(static_cast<std::int8_t>(n));
14075 }
14076 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)()))
14077 {
14078 if (add_prefix)
14079 {
14080 oa->write_character(to_char_type('U')); // uint8
14081 }
14082 write_number(static_cast<std::uint8_t>(n));
14083 }
14084 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
14085 {
14086 if (add_prefix)
14087 {
14088 oa->write_character(to_char_type('I')); // int16
14089 }
14090 write_number(static_cast<std::int16_t>(n));
14091 }
14092 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
14093 {
14094 if (add_prefix)
14095 {
14096 oa->write_character(to_char_type('l')); // int32
14097 }
14098 write_number(static_cast<std::int32_t>(n));
14099 }
14100 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
14101 {
14102 if (add_prefix)
14103 {
14104 oa->write_character(to_char_type('L')); // int64
14105 }
14106 write_number(static_cast<std::int64_t>(n));
14107 }
14108 // LCOV_EXCL_START
14109 else
14110 {
14111 if (add_prefix)
14112 {
14113 oa->write_character(to_char_type('H')); // high-precision number
14114 }
14115
14116 const auto number = BasicJsonType(n).dump();
14117 write_number_with_ubjson_prefix(number.size(), true);
14118 for (std::size_t i = 0; i < number.size(); ++i)
14119 {
14120 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14121 }
14122 }
14123 // LCOV_EXCL_STOP
14124 }
14125
14129 CharType ubjson_prefix(const BasicJsonType& j) const noexcept
14130 {
14131 switch (j.type())
14132 {
14133 case value_t::null:
14134 return 'Z';
14135
14136 case value_t::boolean:
14137 return j.m_value.boolean ? 'T' : 'F';
14138
14139 case value_t::number_integer:
14140 {
14141 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)())
14142 {
14143 return 'i';
14144 }
14145 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)())
14146 {
14147 return 'U';
14148 }
14149 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)())
14150 {
14151 return 'I';
14152 }
14153 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)())
14154 {
14155 return 'l';
14156 }
14157 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)())
14158 {
14159 return 'L';
14160 }
14161 // anything else is treated as high-precision number
14162 return 'H'; // LCOV_EXCL_LINE
14163 }
14164
14165 case value_t::number_unsigned:
14166 {
14167 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14168 {
14169 return 'i';
14170 }
14171 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
14172 {
14173 return 'U';
14174 }
14175 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14176 {
14177 return 'I';
14178 }
14179 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14180 {
14181 return 'l';
14182 }
14183 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14184 {
14185 return 'L';
14186 }
14187 // anything else is treated as high-precision number
14188 return 'H'; // LCOV_EXCL_LINE
14189 }
14190
14191 case value_t::number_float:
14192 return get_ubjson_float_prefix(j.m_value.number_float);
14193
14194 case value_t::string:
14195 return 'S';
14196
14197 case value_t::array: // fallthrough
14198 case value_t::binary:
14199 return '[';
14200
14201 case value_t::object:
14202 return '{';
14203
14204 default: // discarded values
14205 return 'N';
14206 }
14207 }
14208
14209 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
14210 {
14211 return 'd'; // float 32
14212 }
14213
14214 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
14215 {
14216 return 'D'; // float 64
14217 }
14218
14220 // Utility functions //
14222
14223 /*
14224 @brief write a number to output input
14225 @param[in] n number of type @a NumberType
14226 @tparam NumberType the type of the number
14227 @tparam OutputIsLittleEndian Set to true if output data is
14228 required to be little endian
14229
14230 @note This function needs to respect the system's endianess, because bytes
14231 in CBOR, MessagePack, and UBJSON are stored in network order (big
14232 endian) and therefore need reordering on little endian systems.
14233 */
14234 template<typename NumberType, bool OutputIsLittleEndian = false>
14235 void write_number(const NumberType n)
14236 {
14237 // step 1: write number to array of length NumberType
14238 std::array<CharType, sizeof(NumberType)> vec;
14239 std::memcpy(vec.data(), &n, sizeof(NumberType));
14240
14241 // step 2: write array to output (with possible reordering)
14242 if (is_little_endian != OutputIsLittleEndian)
14243 {
14244 // reverse byte order prior to conversion if necessary
14245 std::reverse(vec.begin(), vec.end());
14246 }
14247
14248 oa->write_characters(vec.data(), sizeof(NumberType));
14249 }
14250
14251 void write_compact_float(const number_float_t n, detail::input_format_t format)
14252 {
14253 if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
14254 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
14255 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
14256 {
14257 oa->write_character(format == detail::input_format_t::cbor
14258 ? get_cbor_float_prefix(static_cast<float>(n))
14259 : get_msgpack_float_prefix(static_cast<float>(n)));
14260 write_number(static_cast<float>(n));
14261 }
14262 else
14263 {
14264 oa->write_character(format == detail::input_format_t::cbor
14265 ? get_cbor_float_prefix(n)
14266 : get_msgpack_float_prefix(n));
14267 write_number(n);
14268 }
14269 }
14270
14271 public:
14272 // The following to_char_type functions are implement the conversion
14273 // between uint8_t and CharType. In case CharType is not unsigned,
14274 // such a conversion is required to allow values greater than 128.
14275 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
14276 template < typename C = CharType,
14277 enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
14278 static constexpr CharType to_char_type(std::uint8_t x) noexcept
14279 {
14280 return *reinterpret_cast<char*>(&x);
14281 }
14282
14283 template < typename C = CharType,
14284 enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
14285 static CharType to_char_type(std::uint8_t x) noexcept
14286 {
14287 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
14288 static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
14289 CharType result;
14290 std::memcpy(&result, &x, sizeof(x));
14291 return result;
14292 }
14293
14294 template<typename C = CharType,
14295 enable_if_t<std::is_unsigned<C>::value>* = nullptr>
14296 static constexpr CharType to_char_type(std::uint8_t x) noexcept
14297 {
14298 return x;
14299 }
14300
14301 template < typename InputCharType, typename C = CharType,
14302 enable_if_t <
14303 std::is_signed<C>::value &&
14304 std::is_signed<char>::value &&
14305 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
14306 > * = nullptr >
14307 static constexpr CharType to_char_type(InputCharType x) noexcept
14308 {
14309 return x;
14310 }
14311
14312 private:
14314 const bool is_little_endian = little_endianess();
14315
14317 output_adapter_t<CharType> oa = nullptr;
14318 };
14319 } // namespace detail
14320 } // namespace nlohmann
14321
14322 // #include <nlohmann/detail/output/output_adapters.hpp>
14323
14324 // #include <nlohmann/detail/output/serializer.hpp>
14325
14326
14327 #include <algorithm> // reverse, remove, fill, find, none_of
14328 #include <array> // array
14329 #include <clocale> // localeconv, lconv
14330 #include <cmath> // labs, isfinite, isnan, signbit
14331 #include <cstddef> // size_t, ptrdiff_t
14332 #include <cstdint> // uint8_t
14333 #include <cstdio> // snprintf
14334 #include <limits> // numeric_limits
14335 #include <string> // string, char_traits
14336 #include <type_traits> // is_same
14337 #include <utility> // move
14338
14339 // #include <nlohmann/detail/conversions/to_chars.hpp>
14340
14341
14342 #include <array> // array
14343 #include <cmath> // signbit, isfinite
14344 #include <cstdint> // intN_t, uintN_t
14345 #include <cstring> // memcpy, memmove
14346 #include <limits> // numeric_limits
14347 #include <type_traits> // conditional
14348
14349 // #include <nlohmann/detail/macro_scope.hpp>
14350
14351
14352 namespace nlohmann
14353 {
14354 namespace detail
14355 {
14356
14376 namespace dtoa_impl
14377 {
14378
14379 template<typename Target, typename Source>
14380 Target reinterpret_bits(const Source source)
14381 {
14382 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
14383
14384 Target target;
14385 std::memcpy(&target, &source, sizeof(Source));
14386 return target;
14387 }
14388
14389 struct diyfp // f * 2^e
14390 {
14391 static constexpr int kPrecision = 64; // = q
14392
14393 std::uint64_t f = 0;
14394 int e = 0;
14395
14396 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
14397
14402 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
14403 {
14404 JSON_ASSERT(x.e == y.e);
14405 JSON_ASSERT(x.f >= y.f);
14406
14407 return {x.f - y.f, x.e};
14408 }
14409
14414 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
14415 {
14416 static_assert(kPrecision == 64, "internal error");
14417
14418 // Computes:
14419 // f = round((x.f * y.f) / 2^q)
14420 // e = x.e + y.e + q
14421
14422 // Emulate the 64-bit * 64-bit multiplication:
14423 //
14424 // p = u * v
14425 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
14426 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
14427 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
14428 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
14429 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
14430 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
14431 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
14432 //
14433 // (Since Q might be larger than 2^32 - 1)
14434 //
14435 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
14436 //
14437 // (Q_hi + H does not overflow a 64-bit int)
14438 //
14439 // = p_lo + 2^64 p_hi
14440
14441 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
14442 const std::uint64_t u_hi = x.f >> 32u;
14443 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
14444 const std::uint64_t v_hi = y.f >> 32u;
14445
14446 const std::uint64_t p0 = u_lo * v_lo;
14447 const std::uint64_t p1 = u_lo * v_hi;
14448 const std::uint64_t p2 = u_hi * v_lo;
14449 const std::uint64_t p3 = u_hi * v_hi;
14450
14451 const std::uint64_t p0_hi = p0 >> 32u;
14452 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
14453 const std::uint64_t p1_hi = p1 >> 32u;
14454 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
14455 const std::uint64_t p2_hi = p2 >> 32u;
14456
14457 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
14458
14459 // The full product might now be computed as
14460 //
14461 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
14462 // p_lo = p0_lo + (Q << 32)
14463 //
14464 // But in this particular case here, the full p_lo is not required.
14465 // Effectively we only need to add the highest bit in p_lo to p_hi (and
14466 // Q_hi + 1 does not overflow).
14467
14468 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
14469
14470 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
14471
14472 return {h, x.e + y.e + 64};
14473 }
14474
14479 static diyfp normalize(diyfp x) noexcept
14480 {
14481 JSON_ASSERT(x.f != 0);
14482
14483 while ((x.f >> 63u) == 0)
14484 {
14485 x.f <<= 1u;
14486 x.e--;
14487 }
14488
14489 return x;
14490 }
14491
14496 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
14497 {
14498 const int delta = x.e - target_exponent;
14499
14500 JSON_ASSERT(delta >= 0);
14501 JSON_ASSERT(((x.f << delta) >> delta) == x.f);
14502
14503 return {x.f << delta, target_exponent};
14504 }
14505 };
14506
14507 struct boundaries
14508 {
14509 diyfp w;
14510 diyfp minus;
14511 diyfp plus;
14512 };
14513
14520 template<typename FloatType>
14521 boundaries compute_boundaries(FloatType value)
14522 {
14523 JSON_ASSERT(std::isfinite(value));
14524 JSON_ASSERT(value > 0);
14525
14526 // Convert the IEEE representation into a diyfp.
14527 //
14528 // If v is denormal:
14529 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
14530 // If v is normalized:
14531 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
14532
14533 static_assert(std::numeric_limits<FloatType>::is_iec559,
14534 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
14535
14536 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
14537 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
14538 constexpr int kMinExp = 1 - kBias;
14539 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
14540
14541 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
14542
14543 const std::uint64_t bits = reinterpret_bits<bits_type>(value);
14544 const std::uint64_t E = bits >> (kPrecision - 1);
14545 const std::uint64_t F = bits & (kHiddenBit - 1);
14546
14547 const bool is_denormal = E == 0;
14548 const diyfp v = is_denormal
14549 ? diyfp(F, kMinExp)
14550 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
14551
14552 // Compute the boundaries m- and m+ of the floating-point value
14553 // v = f * 2^e.
14554 //
14555 // Determine v- and v+, the floating-point predecessor and successor if v,
14556 // respectively.
14557 //
14558 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
14559 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
14560 //
14561 // v+ = v + 2^e
14562 //
14563 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
14564 // between m- and m+ round to v, regardless of how the input rounding
14565 // algorithm breaks ties.
14566 //
14567 // ---+-------------+-------------+-------------+-------------+--- (A)
14568 // v- m- v m+ v+
14569 //
14570 // -----------------+------+------+-------------+-------------+--- (B)
14571 // v- m- v m+ v+
14572
14573 const bool lower_boundary_is_closer = F == 0 && E > 1;
14574 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
14575 const diyfp m_minus = lower_boundary_is_closer
14576 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
14577 : diyfp(2 * v.f - 1, v.e - 1); // (A)
14578
14579 // Determine the normalized w+ = m+.
14580 const diyfp w_plus = diyfp::normalize(m_plus);
14581
14582 // Determine w- = m- such that e_(w-) = e_(w+).
14583 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
14584
14585 return {diyfp::normalize(v), w_minus, w_plus};
14586 }
14587
14588 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
14589 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
14590 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
14591 //
14592 // alpha <= e = e_c + e_w + q <= gamma
14593 //
14594 // or
14595 //
14596 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
14597 // <= f_c * f_w * 2^gamma
14598 //
14599 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
14600 //
14601 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
14602 //
14603 // or
14604 //
14605 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
14606 //
14607 // The choice of (alpha,gamma) determines the size of the table and the form of
14608 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
14609 // in practice:
14610 //
14611 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
14612 // processed independently: An integral part p1, and a fractional part p2:
14613 //
14614 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
14615 // = (f div 2^-e) + (f mod 2^-e) * 2^e
14616 // = p1 + p2 * 2^e
14617 //
14618 // The conversion of p1 into decimal form requires a series of divisions and
14619 // modulos by (a power of) 10. These operations are faster for 32-bit than for
14620 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
14621 // achieved by choosing
14622 //
14623 // -e >= 32 or e <= -32 := gamma
14624 //
14625 // In order to convert the fractional part
14626 //
14627 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
14628 //
14629 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
14630 // d[-i] are extracted in order:
14631 //
14632 // (10 * p2) div 2^-e = d[-1]
14633 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
14634 //
14635 // The multiplication by 10 must not overflow. It is sufficient to choose
14636 //
14637 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
14638 //
14639 // Since p2 = f mod 2^-e < 2^-e,
14640 //
14641 // -e <= 60 or e >= -60 := alpha
14642
14643 constexpr int kAlpha = -60;
14644 constexpr int kGamma = -32;
14645
14646 struct cached_power // c = f * 2^e ~= 10^k
14647 {
14648 std::uint64_t f;
14649 int e;
14650 int k;
14651 };
14652
14660 inline cached_power get_cached_power_for_binary_exponent(int e)
14661 {
14662 // Now
14663 //
14664 // alpha <= e_c + e + q <= gamma (1)
14665 // ==> f_c * 2^alpha <= c * 2^e * 2^q
14666 //
14667 // and since the c's are normalized, 2^(q-1) <= f_c,
14668 //
14669 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
14670 // ==> 2^(alpha - e - 1) <= c
14671 //
14672 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
14673 //
14674 // k = ceil( log_10( 2^(alpha - e - 1) ) )
14675 // = ceil( (alpha - e - 1) * log_10(2) )
14676 //
14677 // From the paper:
14678 // "In theory the result of the procedure could be wrong since c is rounded,
14679 // and the computation itself is approximated [...]. In practice, however,
14680 // this simple function is sufficient."
14681 //
14682 // For IEEE double precision floating-point numbers converted into
14683 // normalized diyfp's w = f * 2^e, with q = 64,
14684 //
14685 // e >= -1022 (min IEEE exponent)
14686 // -52 (p - 1)
14687 // -52 (p - 1, possibly normalize denormal IEEE numbers)
14688 // -11 (normalize the diyfp)
14689 // = -1137
14690 //
14691 // and
14692 //
14693 // e <= +1023 (max IEEE exponent)
14694 // -52 (p - 1)
14695 // -11 (normalize the diyfp)
14696 // = 960
14697 //
14698 // This binary exponent range [-1137,960] results in a decimal exponent
14699 // range [-307,324]. One does not need to store a cached power for each
14700 // k in this range. For each such k it suffices to find a cached power
14701 // such that the exponent of the product lies in [alpha,gamma].
14702 // This implies that the difference of the decimal exponents of adjacent
14703 // table entries must be less than or equal to
14704 //
14705 // floor( (gamma - alpha) * log_10(2) ) = 8.
14706 //
14707 // (A smaller distance gamma-alpha would require a larger table.)
14708
14709 // NB:
14710 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
14711
14712 constexpr int kCachedPowersMinDecExp = -300;
14713 constexpr int kCachedPowersDecStep = 8;
14714
14715 static constexpr std::array<cached_power, 79> kCachedPowers =
14716 {
14717 {
14718 { 0xAB70FE17C79AC6CA, -1060, -300 },
14719 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
14720 { 0xBE5691EF416BD60C, -1007, -284 },
14721 { 0x8DD01FAD907FFC3C, -980, -276 },
14722 { 0xD3515C2831559A83, -954, -268 },
14723 { 0x9D71AC8FADA6C9B5, -927, -260 },
14724 { 0xEA9C227723EE8BCB, -901, -252 },
14725 { 0xAECC49914078536D, -874, -244 },
14726 { 0x823C12795DB6CE57, -847, -236 },
14727 { 0xC21094364DFB5637, -821, -228 },
14728 { 0x9096EA6F3848984F, -794, -220 },
14729 { 0xD77485CB25823AC7, -768, -212 },
14730 { 0xA086CFCD97BF97F4, -741, -204 },
14731 { 0xEF340A98172AACE5, -715, -196 },
14732 { 0xB23867FB2A35B28E, -688, -188 },
14733 { 0x84C8D4DFD2C63F3B, -661, -180 },
14734 { 0xC5DD44271AD3CDBA, -635, -172 },
14735 { 0x936B9FCEBB25C996, -608, -164 },
14736 { 0xDBAC6C247D62A584, -582, -156 },
14737 { 0xA3AB66580D5FDAF6, -555, -148 },
14738 { 0xF3E2F893DEC3F126, -529, -140 },
14739 { 0xB5B5ADA8AAFF80B8, -502, -132 },
14740 { 0x87625F056C7C4A8B, -475, -124 },
14741 { 0xC9BCFF6034C13053, -449, -116 },
14742 { 0x964E858C91BA2655, -422, -108 },
14743 { 0xDFF9772470297EBD, -396, -100 },
14744 { 0xA6DFBD9FB8E5B88F, -369, -92 },
14745 { 0xF8A95FCF88747D94, -343, -84 },
14746 { 0xB94470938FA89BCF, -316, -76 },
14747 { 0x8A08F0F8BF0F156B, -289, -68 },
14748 { 0xCDB02555653131B6, -263, -60 },
14749 { 0x993FE2C6D07B7FAC, -236, -52 },
14750 { 0xE45C10C42A2B3B06, -210, -44 },
14751 { 0xAA242499697392D3, -183, -36 },
14752 { 0xFD87B5F28300CA0E, -157, -28 },
14753 { 0xBCE5086492111AEB, -130, -20 },
14754 { 0x8CBCCC096F5088CC, -103, -12 },
14755 { 0xD1B71758E219652C, -77, -4 },
14756 { 0x9C40000000000000, -50, 4 },
14757 { 0xE8D4A51000000000, -24, 12 },
14758 { 0xAD78EBC5AC620000, 3, 20 },
14759 { 0x813F3978F8940984, 30, 28 },
14760 { 0xC097CE7BC90715B3, 56, 36 },
14761 { 0x8F7E32CE7BEA5C70, 83, 44 },
14762 { 0xD5D238A4ABE98068, 109, 52 },
14763 { 0x9F4F2726179A2245, 136, 60 },
14764 { 0xED63A231D4C4FB27, 162, 68 },
14765 { 0xB0DE65388CC8ADA8, 189, 76 },
14766 { 0x83C7088E1AAB65DB, 216, 84 },
14767 { 0xC45D1DF942711D9A, 242, 92 },
14768 { 0x924D692CA61BE758, 269, 100 },
14769 { 0xDA01EE641A708DEA, 295, 108 },
14770 { 0xA26DA3999AEF774A, 322, 116 },
14771 { 0xF209787BB47D6B85, 348, 124 },
14772 { 0xB454E4A179DD1877, 375, 132 },
14773 { 0x865B86925B9BC5C2, 402, 140 },
14774 { 0xC83553C5C8965D3D, 428, 148 },
14775 { 0x952AB45CFA97A0B3, 455, 156 },
14776 { 0xDE469FBD99A05FE3, 481, 164 },
14777 { 0xA59BC234DB398C25, 508, 172 },
14778 { 0xF6C69A72A3989F5C, 534, 180 },
14779 { 0xB7DCBF5354E9BECE, 561, 188 },
14780 { 0x88FCF317F22241E2, 588, 196 },
14781 { 0xCC20CE9BD35C78A5, 614, 204 },
14782 { 0x98165AF37B2153DF, 641, 212 },
14783 { 0xE2A0B5DC971F303A, 667, 220 },
14784 { 0xA8D9D1535CE3B396, 694, 228 },
14785 { 0xFB9B7CD9A4A7443C, 720, 236 },
14786 { 0xBB764C4CA7A44410, 747, 244 },
14787 { 0x8BAB8EEFB6409C1A, 774, 252 },
14788 { 0xD01FEF10A657842C, 800, 260 },
14789 { 0x9B10A4E5E9913129, 827, 268 },
14790 { 0xE7109BFBA19C0C9D, 853, 276 },
14791 { 0xAC2820D9623BF429, 880, 284 },
14792 { 0x80444B5E7AA7CF85, 907, 292 },
14793 { 0xBF21E44003ACDD2D, 933, 300 },
14794 { 0x8E679C2F5E44FF8F, 960, 308 },
14795 { 0xD433179D9C8CB841, 986, 316 },
14796 { 0x9E19DB92B4E31BA9, 1013, 324 },
14797 }
14798 };
14799
14800 // This computation gives exactly the same results for k as
14801 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
14802 // for |e| <= 1500, but doesn't require floating-point operations.
14803 // NB: log_10(2) ~= 78913 / 2^18
14804 JSON_ASSERT(e >= -1500);
14805 JSON_ASSERT(e <= 1500);
14806 const int f = kAlpha - e - 1;
14807 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
14808
14809 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
14810 JSON_ASSERT(index >= 0);
14811 JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
14812
14813 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
14814 JSON_ASSERT(kAlpha <= cached.e + e + 64);
14815 JSON_ASSERT(kGamma >= cached.e + e + 64);
14816
14817 return cached;
14818 }
14819
14824 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
14825 {
14826 // LCOV_EXCL_START
14827 if (n >= 1000000000)
14828 {
14829 pow10 = 1000000000;
14830 return 10;
14831 }
14832 // LCOV_EXCL_STOP
14833 else if (n >= 100000000)
14834 {
14835 pow10 = 100000000;
14836 return 9;
14837 }
14838 else if (n >= 10000000)
14839 {
14840 pow10 = 10000000;
14841 return 8;
14842 }
14843 else if (n >= 1000000)
14844 {
14845 pow10 = 1000000;
14846 return 7;
14847 }
14848 else if (n >= 100000)
14849 {
14850 pow10 = 100000;
14851 return 6;
14852 }
14853 else if (n >= 10000)
14854 {
14855 pow10 = 10000;
14856 return 5;
14857 }
14858 else if (n >= 1000)
14859 {
14860 pow10 = 1000;
14861 return 4;
14862 }
14863 else if (n >= 100)
14864 {
14865 pow10 = 100;
14866 return 3;
14867 }
14868 else if (n >= 10)
14869 {
14870 pow10 = 10;
14871 return 2;
14872 }
14873 else
14874 {
14875 pow10 = 1;
14876 return 1;
14877 }
14878 }
14879
14880 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
14881 std::uint64_t rest, std::uint64_t ten_k)
14882 {
14883 JSON_ASSERT(len >= 1);
14884 JSON_ASSERT(dist <= delta);
14885 JSON_ASSERT(rest <= delta);
14886 JSON_ASSERT(ten_k > 0);
14887
14888 // <--------------------------- delta ---->
14889 // <---- dist --------->
14890 // --------------[------------------+-------------------]--------------
14891 // M- w M+
14892 //
14893 // ten_k
14894 // <------>
14895 // <---- rest ---->
14896 // --------------[------------------+----+--------------]--------------
14897 // w V
14898 // = buf * 10^k
14899 //
14900 // ten_k represents a unit-in-the-last-place in the decimal representation
14901 // stored in buf.
14902 // Decrement buf by ten_k while this takes buf closer to w.
14903
14904 // The tests are written in this order to avoid overflow in unsigned
14905 // integer arithmetic.
14906
14907 while (rest < dist
14908 && delta - rest >= ten_k
14909 && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
14910 {
14911 JSON_ASSERT(buf[len - 1] != '0');
14912 buf[len - 1]--;
14913 rest += ten_k;
14914 }
14915 }
14916
14921 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
14922 diyfp M_minus, diyfp w, diyfp M_plus)
14923 {
14924 static_assert(kAlpha >= -60, "internal error");
14925 static_assert(kGamma <= -32, "internal error");
14926
14927 // Generates the digits (and the exponent) of a decimal floating-point
14928 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
14929 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
14930 //
14931 // <--------------------------- delta ---->
14932 // <---- dist --------->
14933 // --------------[------------------+-------------------]--------------
14934 // M- w M+
14935 //
14936 // Grisu2 generates the digits of M+ from left to right and stops as soon as
14937 // V is in [M-,M+].
14938
14939 JSON_ASSERT(M_plus.e >= kAlpha);
14940 JSON_ASSERT(M_plus.e <= kGamma);
14941
14942 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
14943 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
14944
14945 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
14946 //
14947 // M+ = f * 2^e
14948 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
14949 // = ((p1 ) * 2^-e + (p2 )) * 2^e
14950 // = p1 + p2 * 2^e
14951
14952 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
14953
14954 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.)
14955 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
14956
14957 // 1)
14958 //
14959 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
14960
14961 JSON_ASSERT(p1 > 0);
14962
14963 std::uint32_t pow10;
14964 const int k = find_largest_pow10(p1, pow10);
14965
14966 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
14967 //
14968 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
14969 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
14970 //
14971 // M+ = p1 + p2 * 2^e
14972 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
14973 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
14974 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
14975 //
14976 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
14977 //
14978 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
14979 //
14980 // but stop as soon as
14981 //
14982 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
14983
14984 int n = k;
14985 while (n > 0)
14986 {
14987 // Invariants:
14988 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
14989 // pow10 = 10^(n-1) <= p1 < 10^n
14990 //
14991 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
14992 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
14993 //
14994 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
14995 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
14996 //
14997 JSON_ASSERT(d <= 9);
14998 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
14999 //
15000 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
15001 //
15002 p1 = r;
15003 n--;
15004 //
15005 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
15006 // pow10 = 10^n
15007 //
15008
15009 // Now check if enough digits have been generated.
15010 // Compute
15011 //
15012 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
15013 //
15014 // Note:
15015 // Since rest and delta share the same exponent e, it suffices to
15016 // compare the significands.
15017 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
15018 if (rest <= delta)
15019 {
15020 // V = buffer * 10^n, with M- <= V <= M+.
15021
15022 decimal_exponent += n;
15023
15024 // We may now just stop. But instead look if the buffer could be
15025 // decremented to bring V closer to w.
15026 //
15027 // pow10 = 10^n is now 1 ulp in the decimal representation V.
15028 // The rounding procedure works with diyfp's with an implicit
15029 // exponent of e.
15030 //
15031 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
15032 //
15033 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
15034 grisu2_round(buffer, length, dist, delta, rest, ten_n);
15035
15036 return;
15037 }
15038
15039 pow10 /= 10;
15040 //
15041 // pow10 = 10^(n-1) <= p1 < 10^n
15042 // Invariants restored.
15043 }
15044
15045 // 2)
15046 //
15047 // The digits of the integral part have been generated:
15048 //
15049 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
15050 // = buffer + p2 * 2^e
15051 //
15052 // Now generate the digits of the fractional part p2 * 2^e.
15053 //
15054 // Note:
15055 // No decimal point is generated: the exponent is adjusted instead.
15056 //
15057 // p2 actually represents the fraction
15058 //
15059 // p2 * 2^e
15060 // = p2 / 2^-e
15061 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
15062 //
15063 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
15064 //
15065 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
15066 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
15067 //
15068 // using
15069 //
15070 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
15071 // = ( d) * 2^-e + ( r)
15072 //
15073 // or
15074 // 10^m * p2 * 2^e = d + r * 2^e
15075 //
15076 // i.e.
15077 //
15078 // M+ = buffer + p2 * 2^e
15079 // = buffer + 10^-m * (d + r * 2^e)
15080 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
15081 //
15082 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
15083
15084 JSON_ASSERT(p2 > delta);
15085
15086 int m = 0;
15087 for (;;)
15088 {
15089 // Invariant:
15090 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
15091 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
15092 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
15093 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
15094 //
15095 JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
15096 p2 *= 10;
15097 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
15098 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
15099 //
15100 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
15101 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
15102 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
15103 //
15104 JSON_ASSERT(d <= 9);
15105 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15106 //
15107 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
15108 //
15109 p2 = r;
15110 m++;
15111 //
15112 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
15113 // Invariant restored.
15114
15115 // Check if enough digits have been generated.
15116 //
15117 // 10^-m * p2 * 2^e <= delta * 2^e
15118 // p2 * 2^e <= 10^m * delta * 2^e
15119 // p2 <= 10^m * delta
15120 delta *= 10;
15121 dist *= 10;
15122 if (p2 <= delta)
15123 {
15124 break;
15125 }
15126 }
15127
15128 // V = buffer * 10^-m, with M- <= V <= M+.
15129
15130 decimal_exponent -= m;
15131
15132 // 1 ulp in the decimal representation is now 10^-m.
15133 // Since delta and dist are now scaled by 10^m, we need to do the
15134 // same with ulp in order to keep the units in sync.
15135 //
15136 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
15137 //
15138 const std::uint64_t ten_m = one.f;
15139 grisu2_round(buffer, length, dist, delta, p2, ten_m);
15140
15141 // By construction this algorithm generates the shortest possible decimal
15142 // number (Loitsch, Theorem 6.2) which rounds back to w.
15143 // For an input number of precision p, at least
15144 //
15145 // N = 1 + ceil(p * log_10(2))
15146 //
15147 // decimal digits are sufficient to identify all binary floating-point
15148 // numbers (Matula, "In-and-Out conversions").
15149 // This implies that the algorithm does not produce more than N decimal
15150 // digits.
15151 //
15152 // N = 17 for p = 53 (IEEE double precision)
15153 // N = 9 for p = 24 (IEEE single precision)
15154 }
15155
15161 JSON_HEDLEY_NON_NULL(1)
15162 inline void grisu2(char* buf, int& len, int& decimal_exponent,
15163 diyfp m_minus, diyfp v, diyfp m_plus)
15164 {
15165 JSON_ASSERT(m_plus.e == m_minus.e);
15166 JSON_ASSERT(m_plus.e == v.e);
15167
15168 // --------(-----------------------+-----------------------)-------- (A)
15169 // m- v m+
15170 //
15171 // --------------------(-----------+-----------------------)-------- (B)
15172 // m- v m+
15173 //
15174 // First scale v (and m- and m+) such that the exponent is in the range
15175 // [alpha, gamma].
15176
15177 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
15178
15179 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
15180
15181 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
15182 const diyfp w = diyfp::mul(v, c_minus_k);
15183 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
15184 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
15185
15186 // ----(---+---)---------------(---+---)---------------(---+---)----
15187 // w- w w+
15188 // = c*m- = c*v = c*m+
15189 //
15190 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
15191 // w+ are now off by a small amount.
15192 // In fact:
15193 //
15194 // w - v * 10^k < 1 ulp
15195 //
15196 // To account for this inaccuracy, add resp. subtract 1 ulp.
15197 //
15198 // --------+---[---------------(---+---)---------------]---+--------
15199 // w- M- w M+ w+
15200 //
15201 // Now any number in [M-, M+] (bounds included) will round to w when input,
15202 // regardless of how the input rounding algorithm breaks ties.
15203 //
15204 // And digit_gen generates the shortest possible such number in [M-, M+].
15205 // Note that this does not mean that Grisu2 always generates the shortest
15206 // possible number in the interval (m-, m+).
15207 const diyfp M_minus(w_minus.f + 1, w_minus.e);
15208 const diyfp M_plus (w_plus.f - 1, w_plus.e );
15209
15210 decimal_exponent = -cached.k; // = -(-k) = k
15211
15212 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
15213 }
15214
15220 template<typename FloatType>
15221 JSON_HEDLEY_NON_NULL(1)
15222 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
15223 {
15224 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
15225 "internal error: not enough precision");
15226
15227 JSON_ASSERT(std::isfinite(value));
15228 JSON_ASSERT(value > 0);
15229
15230 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
15231 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
15232 // decimal representations are not exactly "short".
15233 //
15234 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
15235 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
15236 // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
15237 // does.
15238 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
15239 // representation using the corresponding std::from_chars function recovers value exactly". That
15240 // indicates that single precision floating-point numbers should be recovered using
15241 // 'std::strtof'.
15242 //
15243 // NB: If the neighbors are computed for single-precision numbers, there is a single float
15244 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
15245 // value is off by 1 ulp.
15246 #if 0
15247 const boundaries w = compute_boundaries(static_cast<double>(value));
15248 #else
15249 const boundaries w = compute_boundaries(value);
15250 #endif
15251
15252 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
15253 }
15254
15260 JSON_HEDLEY_NON_NULL(1)
15261
15262 inline char* append_exponent(char* buf, int e)
15263 {
15264 JSON_ASSERT(e > -1000);
15265 JSON_ASSERT(e < 1000);
15266
15267 if (e < 0)
15268 {
15269 e = -e;
15270 *buf++ = '-';
15271 }
15272 else
15273 {
15274 *buf++ = '+';
15275 }
15276
15277 auto k = static_cast<std::uint32_t>(e);
15278 if (k < 10)
15279 {
15280 // Always print at least two digits in the exponent.
15281 // This is for compatibility with printf("%g").
15282 *buf++ = '0';
15283 *buf++ = static_cast<char>('0' + k);
15284 }
15285 else if (k < 100)
15286 {
15287 *buf++ = static_cast<char>('0' + k / 10);
15288 k %= 10;
15289 *buf++ = static_cast<char>('0' + k);
15290 }
15291 else
15292 {
15293 *buf++ = static_cast<char>('0' + k / 100);
15294 k %= 100;
15295 *buf++ = static_cast<char>('0' + k / 10);
15296 k %= 10;
15297 *buf++ = static_cast<char>('0' + k);
15298 }
15299
15300 return buf;
15301 }
15302
15312 JSON_HEDLEY_NON_NULL(1)
15313
15314 inline char* format_buffer(char* buf, int len, int decimal_exponent,
15315 int min_exp, int max_exp)
15316 {
15317 JSON_ASSERT(min_exp < 0);
15318 JSON_ASSERT(max_exp > 0);
15319
15320 const int k = len;
15321 const int n = len + decimal_exponent;
15322
15323 // v = buf * 10^(n-k)
15324 // k is the length of the buffer (number of decimal digits)
15325 // n is the position of the decimal point relative to the start of the buffer.
15326
15327 if (k <= n && n <= max_exp)
15328 {
15329 // digits[000]
15330 // len <= max_exp + 2
15331
15332 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
15333 // Make it look like a floating-point number (#362, #378)
15334 buf[n + 0] = '.';
15335 buf[n + 1] = '0';
15336 return buf + (static_cast<size_t>(n) + 2);
15337 }
15338
15339 if (0 < n && n <= max_exp)
15340 {
15341 // dig.its
15342 // len <= max_digits10 + 1
15343
15344 JSON_ASSERT(k > n);
15345
15346 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
15347 buf[n] = '.';
15348 return buf + (static_cast<size_t>(k) + 1U);
15349 }
15350
15351 if (min_exp < n && n <= 0)
15352 {
15353 // 0.[000]digits
15354 // len <= 2 + (-min_exp - 1) + max_digits10
15355
15356 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
15357 buf[0] = '0';
15358 buf[1] = '.';
15359 std::memset(buf + 2, '0', static_cast<size_t>(-n));
15360 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
15361 }
15362
15363 if (k == 1)
15364 {
15365 // dE+123
15366 // len <= 1 + 5
15367
15368 buf += 1;
15369 }
15370 else
15371 {
15372 // d.igitsE+123
15373 // len <= max_digits10 + 1 + 5
15374
15375 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
15376 buf[1] = '.';
15377 buf += 1 + static_cast<size_t>(k);
15378 }
15379
15380 *buf++ = 'e';
15381 return append_exponent(buf, n - 1);
15382 }
15383
15384 } // namespace dtoa_impl
15385
15396 template<typename FloatType>
15397 JSON_HEDLEY_NON_NULL(1, 2)
15398
15399 char* to_chars(char* first, const char* last, FloatType value)
15400 {
15401 static_cast<void>(last); // maybe unused - fix warning
15402 JSON_ASSERT(std::isfinite(value));
15403
15404 // Use signbit(value) instead of (value < 0) since signbit works for -0.
15405 if (std::signbit(value))
15406 {
15407 value = -value;
15408 *first++ = '-';
15409 }
15410
15411 if (value == 0) // +-0
15412 {
15413 *first++ = '0';
15414 // Make it look like a floating-point number (#362, #378)
15415 *first++ = '.';
15416 *first++ = '0';
15417 return first;
15418 }
15419
15420 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
15421
15422 // Compute v = buffer * 10^decimal_exponent.
15423 // The decimal digits are stored in the buffer, which needs to be interpreted
15424 // as an unsigned decimal integer.
15425 // len is the length of the buffer, i.e. the number of decimal digits.
15426 int len = 0;
15427 int decimal_exponent = 0;
15428 dtoa_impl::grisu2(first, len, decimal_exponent, value);
15429
15430 JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
15431
15432 // Format the buffer like printf("%.*g", prec, value)
15433 constexpr int kMinExp = -4;
15434 // Use digits10 here to increase compatibility with version 2.
15435 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
15436
15437 JSON_ASSERT(last - first >= kMaxExp + 2);
15438 JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
15439 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
15440
15441 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
15442 }
15443
15444 } // namespace detail
15445 } // namespace nlohmann
15446
15447 // #include <nlohmann/detail/exceptions.hpp>
15448
15449 // #include <nlohmann/detail/macro_scope.hpp>
15450
15451 // #include <nlohmann/detail/meta/cpp_future.hpp>
15452
15453 // #include <nlohmann/detail/output/binary_writer.hpp>
15454
15455 // #include <nlohmann/detail/output/output_adapters.hpp>
15456
15457 // #include <nlohmann/detail/value_t.hpp>
15458
15459
15460 namespace nlohmann
15461 {
15462 namespace detail
15463 {
15465 // serialization //
15467
15469 enum class error_handler_t
15470 {
15471 strict,
15472 replace,
15473 ignore
15474 };
15475
15476 template<typename BasicJsonType>
15477 class serializer
15478 {
15479 using string_t = typename BasicJsonType::string_t;
15480 using number_float_t = typename BasicJsonType::number_float_t;
15481 using number_integer_t = typename BasicJsonType::number_integer_t;
15482 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
15483 using binary_char_t = typename BasicJsonType::binary_t::value_type;
15484 static constexpr std::uint8_t UTF8_ACCEPT = 0;
15485 static constexpr std::uint8_t UTF8_REJECT = 1;
15486
15487 public:
15493 serializer(output_adapter_t<char> s, const char ichar,
15494 error_handler_t error_handler_ = error_handler_t::strict)
15495 : o(std::move(s))
15496 , loc(std::localeconv())
15497 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
15498 , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
15499 , indent_char(ichar)
15500 , indent_string(512, indent_char)
15501 , error_handler(error_handler_)
15502 {}
15503
15504 // delete because of pointer members
15505 serializer(const serializer&) = delete;
15506 serializer& operator=(const serializer&) = delete;
15507 serializer(serializer&&) = delete;
15508 serializer& operator=(serializer&&) = delete;
15509 ~serializer() = default;
15510
15533 void dump(const BasicJsonType& val,
15534 const bool pretty_print,
15535 const bool ensure_ascii,
15536 const unsigned int indent_step,
15537 const unsigned int current_indent = 0)
15538 {
15539 switch (val.m_type)
15540 {
15541 case value_t::object:
15542 {
15543 if (val.m_value.object->empty())
15544 {
15545 o->write_characters("{}", 2);
15546 return;
15547 }
15548
15549 if (pretty_print)
15550 {
15551 o->write_characters("{\n", 2);
15552
15553 // variable to hold indentation for recursive calls
15554 const auto new_indent = current_indent + indent_step;
15555 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15556 {
15557 indent_string.resize(indent_string.size() * 2, ' ');
15558 }
15559
15560 // first n-1 elements
15561 auto i = val.m_value.object->cbegin();
15562 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15563 {
15564 o->write_characters(indent_string.c_str(), new_indent);
15565 o->write_character('\"');
15566 dump_escaped(i->first, ensure_ascii);
15567 o->write_characters("\": ", 3);
15568 dump(i->second, true, ensure_ascii, indent_step, new_indent);
15569 o->write_characters(",\n", 2);
15570 }
15571
15572 // last element
15573 JSON_ASSERT(i != val.m_value.object->cend());
15574 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
15575 o->write_characters(indent_string.c_str(), new_indent);
15576 o->write_character('\"');
15577 dump_escaped(i->first, ensure_ascii);
15578 o->write_characters("\": ", 3);
15579 dump(i->second, true, ensure_ascii, indent_step, new_indent);
15580
15581 o->write_character('\n');
15582 o->write_characters(indent_string.c_str(), current_indent);
15583 o->write_character('}');
15584 }
15585 else
15586 {
15587 o->write_character('{');
15588
15589 // first n-1 elements
15590 auto i = val.m_value.object->cbegin();
15591 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15592 {
15593 o->write_character('\"');
15594 dump_escaped(i->first, ensure_ascii);
15595 o->write_characters("\":", 2);
15596 dump(i->second, false, ensure_ascii, indent_step, current_indent);
15597 o->write_character(',');
15598 }
15599
15600 // last element
15601 JSON_ASSERT(i != val.m_value.object->cend());
15602 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
15603 o->write_character('\"');
15604 dump_escaped(i->first, ensure_ascii);
15605 o->write_characters("\":", 2);
15606 dump(i->second, false, ensure_ascii, indent_step, current_indent);
15607
15608 o->write_character('}');
15609 }
15610
15611 return;
15612 }
15613
15614 case value_t::array:
15615 {
15616 if (val.m_value.array->empty())
15617 {
15618 o->write_characters("[]", 2);
15619 return;
15620 }
15621
15622 if (pretty_print)
15623 {
15624 o->write_characters("[\n", 2);
15625
15626 // variable to hold indentation for recursive calls
15627 const auto new_indent = current_indent + indent_step;
15628 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15629 {
15630 indent_string.resize(indent_string.size() * 2, ' ');
15631 }
15632
15633 // first n-1 elements
15634 for (auto i = val.m_value.array->cbegin();
15635 i != val.m_value.array->cend() - 1; ++i)
15636 {
15637 o->write_characters(indent_string.c_str(), new_indent);
15638 dump(*i, true, ensure_ascii, indent_step, new_indent);
15639 o->write_characters(",\n", 2);
15640 }
15641
15642 // last element
15643 JSON_ASSERT(!val.m_value.array->empty());
15644 o->write_characters(indent_string.c_str(), new_indent);
15645 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
15646
15647 o->write_character('\n');
15648 o->write_characters(indent_string.c_str(), current_indent);
15649 o->write_character(']');
15650 }
15651 else
15652 {
15653 o->write_character('[');
15654
15655 // first n-1 elements
15656 for (auto i = val.m_value.array->cbegin();
15657 i != val.m_value.array->cend() - 1; ++i)
15658 {
15659 dump(*i, false, ensure_ascii, indent_step, current_indent);
15660 o->write_character(',');
15661 }
15662
15663 // last element
15664 JSON_ASSERT(!val.m_value.array->empty());
15665 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
15666
15667 o->write_character(']');
15668 }
15669
15670 return;
15671 }
15672
15673 case value_t::string:
15674 {
15675 o->write_character('\"');
15676 dump_escaped(*val.m_value.string, ensure_ascii);
15677 o->write_character('\"');
15678 return;
15679 }
15680
15681 case value_t::binary:
15682 {
15683 if (pretty_print)
15684 {
15685 o->write_characters("{\n", 2);
15686
15687 // variable to hold indentation for recursive calls
15688 const auto new_indent = current_indent + indent_step;
15689 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15690 {
15691 indent_string.resize(indent_string.size() * 2, ' ');
15692 }
15693
15694 o->write_characters(indent_string.c_str(), new_indent);
15695
15696 o->write_characters("\"bytes\": [", 10);
15697
15698 if (!val.m_value.binary->empty())
15699 {
15700 for (auto i = val.m_value.binary->cbegin();
15701 i != val.m_value.binary->cend() - 1; ++i)
15702 {
15703 dump_integer(*i);
15704 o->write_characters(", ", 2);
15705 }
15706 dump_integer(val.m_value.binary->back());
15707 }
15708
15709 o->write_characters("],\n", 3);
15710 o->write_characters(indent_string.c_str(), new_indent);
15711
15712 o->write_characters("\"subtype\": ", 11);
15713 if (val.m_value.binary->has_subtype())
15714 {
15715 dump_integer(val.m_value.binary->subtype());
15716 }
15717 else
15718 {
15719 o->write_characters("null", 4);
15720 }
15721 o->write_character('\n');
15722 o->write_characters(indent_string.c_str(), current_indent);
15723 o->write_character('}');
15724 }
15725 else
15726 {
15727 o->write_characters("{\"bytes\":[", 10);
15728
15729 if (!val.m_value.binary->empty())
15730 {
15731 for (auto i = val.m_value.binary->cbegin();
15732 i != val.m_value.binary->cend() - 1; ++i)
15733 {
15734 dump_integer(*i);
15735 o->write_character(',');
15736 }
15737 dump_integer(val.m_value.binary->back());
15738 }
15739
15740 o->write_characters("],\"subtype\":", 12);
15741 if (val.m_value.binary->has_subtype())
15742 {
15743 dump_integer(val.m_value.binary->subtype());
15744 o->write_character('}');
15745 }
15746 else
15747 {
15748 o->write_characters("null}", 5);
15749 }
15750 }
15751 return;
15752 }
15753
15754 case value_t::boolean:
15755 {
15756 if (val.m_value.boolean)
15757 {
15758 o->write_characters("true", 4);
15759 }
15760 else
15761 {
15762 o->write_characters("false", 5);
15763 }
15764 return;
15765 }
15766
15767 case value_t::number_integer:
15768 {
15769 dump_integer(val.m_value.number_integer);
15770 return;
15771 }
15772
15773 case value_t::number_unsigned:
15774 {
15775 dump_integer(val.m_value.number_unsigned);
15776 return;
15777 }
15778
15779 case value_t::number_float:
15780 {
15781 dump_float(val.m_value.number_float);
15782 return;
15783 }
15784
15785 case value_t::discarded:
15786 {
15787 o->write_characters("<discarded>", 11);
15788 return;
15789 }
15790
15791 case value_t::null:
15792 {
15793 o->write_characters("null", 4);
15794 return;
15795 }
15796
15797 default: // LCOV_EXCL_LINE
15798 JSON_ASSERT(false); // LCOV_EXCL_LINE
15799 }
15800 }
15801
15802 private:
15817 void dump_escaped(const string_t& s, const bool ensure_ascii)
15818 {
15819 std::uint32_t codepoint;
15820 std::uint8_t state = UTF8_ACCEPT;
15821 std::size_t bytes = 0; // number of bytes written to string_buffer
15822
15823 // number of bytes written at the point of the last valid byte
15824 std::size_t bytes_after_last_accept = 0;
15825 std::size_t undumped_chars = 0;
15826
15827 for (std::size_t i = 0; i < s.size(); ++i)
15828 {
15829 const auto byte = static_cast<uint8_t>(s[i]);
15830
15831 switch (decode(state, codepoint, byte))
15832 {
15833 case UTF8_ACCEPT: // decode found a new code point
15834 {
15835 switch (codepoint)
15836 {
15837 case 0x08: // backspace
15838 {
15839 string_buffer[bytes++] = '\\';
15840 string_buffer[bytes++] = 'b';
15841 break;
15842 }
15843
15844 case 0x09: // horizontal tab
15845 {
15846 string_buffer[bytes++] = '\\';
15847 string_buffer[bytes++] = 't';
15848 break;
15849 }
15850
15851 case 0x0A: // newline
15852 {
15853 string_buffer[bytes++] = '\\';
15854 string_buffer[bytes++] = 'n';
15855 break;
15856 }
15857
15858 case 0x0C: // formfeed
15859 {
15860 string_buffer[bytes++] = '\\';
15861 string_buffer[bytes++] = 'f';
15862 break;
15863 }
15864
15865 case 0x0D: // carriage return
15866 {
15867 string_buffer[bytes++] = '\\';
15868 string_buffer[bytes++] = 'r';
15869 break;
15870 }
15871
15872 case 0x22: // quotation mark
15873 {
15874 string_buffer[bytes++] = '\\';
15875 string_buffer[bytes++] = '\"';
15876 break;
15877 }
15878
15879 case 0x5C: // reverse solidus
15880 {
15881 string_buffer[bytes++] = '\\';
15882 string_buffer[bytes++] = '\\';
15883 break;
15884 }
15885
15886 default:
15887 {
15888 // escape control characters (0x00..0x1F) or, if
15889 // ensure_ascii parameter is used, non-ASCII characters
15890 if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
15891 {
15892 if (codepoint <= 0xFFFF)
15893 {
15894 (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
15895 static_cast<std::uint16_t>(codepoint));
15896 bytes += 6;
15897 }
15898 else
15899 {
15900 (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
15901 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
15902 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
15903 bytes += 12;
15904 }
15905 }
15906 else
15907 {
15908 // copy byte to buffer (all previous bytes
15909 // been copied have in default case above)
15910 string_buffer[bytes++] = s[i];
15911 }
15912 break;
15913 }
15914 }
15915
15916 // write buffer and reset index; there must be 13 bytes
15917 // left, as this is the maximal number of bytes to be
15918 // written ("\uxxxx\uxxxx\0") for one code point
15919 if (string_buffer.size() - bytes < 13)
15920 {
15921 o->write_characters(string_buffer.data(), bytes);
15922 bytes = 0;
15923 }
15924
15925 // remember the byte position of this accept
15926 bytes_after_last_accept = bytes;
15927 undumped_chars = 0;
15928 break;
15929 }
15930
15931 case UTF8_REJECT: // decode found invalid UTF-8 byte
15932 {
15933 switch (error_handler)
15934 {
15935 case error_handler_t::strict:
15936 {
15937 std::string sn(3, '\0');
15938 (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
15939 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
15940 }
15941
15942 case error_handler_t::ignore:
15943 case error_handler_t::replace:
15944 {
15945 // in case we saw this character the first time, we
15946 // would like to read it again, because the byte
15947 // may be OK for itself, but just not OK for the
15948 // previous sequence
15949 if (undumped_chars > 0)
15950 {
15951 --i;
15952 }
15953
15954 // reset length buffer to the last accepted index;
15955 // thus removing/ignoring the invalid characters
15956 bytes = bytes_after_last_accept;
15957
15958 if (error_handler == error_handler_t::replace)
15959 {
15960 // add a replacement character
15961 if (ensure_ascii)
15962 {
15963 string_buffer[bytes++] = '\\';
15964 string_buffer[bytes++] = 'u';
15965 string_buffer[bytes++] = 'f';
15966 string_buffer[bytes++] = 'f';
15967 string_buffer[bytes++] = 'f';
15968 string_buffer[bytes++] = 'd';
15969 }
15970 else
15971 {
15972 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
15973 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
15974 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
15975 }
15976
15977 // write buffer and reset index; there must be 13 bytes
15978 // left, as this is the maximal number of bytes to be
15979 // written ("\uxxxx\uxxxx\0") for one code point
15980 if (string_buffer.size() - bytes < 13)
15981 {
15982 o->write_characters(string_buffer.data(), bytes);
15983 bytes = 0;
15984 }
15985
15986 bytes_after_last_accept = bytes;
15987 }
15988
15989 undumped_chars = 0;
15990
15991 // continue processing the string
15992 state = UTF8_ACCEPT;
15993 break;
15994 }
15995
15996 default: // LCOV_EXCL_LINE
15997 JSON_ASSERT(false); // LCOV_EXCL_LINE
15998 }
15999 break;
16000 }
16001
16002 default: // decode found yet incomplete multi-byte code point
16003 {
16004 if (!ensure_ascii)
16005 {
16006 // code point will not be escaped - copy byte to buffer
16007 string_buffer[bytes++] = s[i];
16008 }
16009 ++undumped_chars;
16010 break;
16011 }
16012 }
16013 }
16014
16015 // we finished processing the string
16016 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
16017 {
16018 // write buffer
16019 if (bytes > 0)
16020 {
16021 o->write_characters(string_buffer.data(), bytes);
16022 }
16023 }
16024 else
16025 {
16026 // we finish reading, but do not accept: string was incomplete
16027 switch (error_handler)
16028 {
16029 case error_handler_t::strict:
16030 {
16031 std::string sn(3, '\0');
16032 (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
16033 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
16034 }
16035
16036 case error_handler_t::ignore:
16037 {
16038 // write all accepted bytes
16039 o->write_characters(string_buffer.data(), bytes_after_last_accept);
16040 break;
16041 }
16042
16043 case error_handler_t::replace:
16044 {
16045 // write all accepted bytes
16046 o->write_characters(string_buffer.data(), bytes_after_last_accept);
16047 // add a replacement character
16048 if (ensure_ascii)
16049 {
16050 o->write_characters("\\ufffd", 6);
16051 }
16052 else
16053 {
16054 o->write_characters("\xEF\xBF\xBD", 3);
16055 }
16056 break;
16057 }
16058
16059 default: // LCOV_EXCL_LINE
16060 JSON_ASSERT(false); // LCOV_EXCL_LINE
16061 }
16062 }
16063 }
16064
16073 inline unsigned int count_digits(number_unsigned_t x) noexcept
16074 {
16075 unsigned int n_digits = 1;
16076 for (;;)
16077 {
16078 if (x < 10)
16079 {
16080 return n_digits;
16081 }
16082 if (x < 100)
16083 {
16084 return n_digits + 1;
16085 }
16086 if (x < 1000)
16087 {
16088 return n_digits + 2;
16089 }
16090 if (x < 10000)
16091 {
16092 return n_digits + 3;
16093 }
16094 x = x / 10000u;
16095 n_digits += 4;
16096 }
16097 }
16098
16108 template < typename NumberType, detail::enable_if_t <
16109 std::is_same<NumberType, number_unsigned_t>::value ||
16110 std::is_same<NumberType, number_integer_t>::value ||
16111 std::is_same<NumberType, binary_char_t>::value,
16112 int > = 0 >
16113 void dump_integer(NumberType x)
16114 {
16115 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
16116 {
16117 {
16118 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
16119 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
16120 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
16121 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
16122 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
16123 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
16124 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
16125 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
16126 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
16127 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
16128 }
16129 };
16130
16131 // special case for "0"
16132 if (x == 0)
16133 {
16134 o->write_character('0');
16135 return;
16136 }
16137
16138 // use a pointer to fill the buffer
16139 auto buffer_ptr = number_buffer.begin();
16140
16141 const bool is_negative = std::is_same<NumberType, number_integer_t>::value && !(x >= 0); // see issue #755
16142 number_unsigned_t abs_value;
16143
16144 unsigned int n_chars;
16145
16146 if (is_negative)
16147 {
16148 *buffer_ptr = '-';
16149 abs_value = remove_sign(static_cast<number_integer_t>(x));
16150
16151 // account one more byte for the minus sign
16152 n_chars = 1 + count_digits(abs_value);
16153 }
16154 else
16155 {
16156 abs_value = static_cast<number_unsigned_t>(x);
16157 n_chars = count_digits(abs_value);
16158 }
16159
16160 // spare 1 byte for '\0'
16161 JSON_ASSERT(n_chars < number_buffer.size() - 1);
16162
16163 // jump to the end to generate the string from backward
16164 // so we later avoid reversing the result
16165 buffer_ptr += n_chars;
16166
16167 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
16168 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
16169 while (abs_value >= 100)
16170 {
16171 const auto digits_index = static_cast<unsigned>((abs_value % 100));
16172 abs_value /= 100;
16173 *(--buffer_ptr) = digits_to_99[digits_index][1];
16174 *(--buffer_ptr) = digits_to_99[digits_index][0];
16175 }
16176
16177 if (abs_value >= 10)
16178 {
16179 const auto digits_index = static_cast<unsigned>(abs_value);
16180 *(--buffer_ptr) = digits_to_99[digits_index][1];
16181 *(--buffer_ptr) = digits_to_99[digits_index][0];
16182 }
16183 else
16184 {
16185 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
16186 }
16187
16188 o->write_characters(number_buffer.data(), n_chars);
16189 }
16190
16199 void dump_float(number_float_t x)
16200 {
16201 // NaN / inf
16202 if (!std::isfinite(x))
16203 {
16204 o->write_characters("null", 4);
16205 return;
16206 }
16207
16208 // If number_float_t is an IEEE-754 single or double precision number,
16209 // use the Grisu2 algorithm to produce short numbers which are
16210 // guaranteed to round-trip, using strtof and strtod, resp.
16211 //
16212 // NB: The test below works if <long double> == <double>.
16213 static constexpr bool is_ieee_single_or_double
16214 = (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) ||
16215 (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);
16216
16217 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
16218 }
16219
16220 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
16221 {
16222 char* begin = number_buffer.data();
16223 char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
16224
16225 o->write_characters(begin, static_cast<size_t>(end - begin));
16226 }
16227
16228 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
16229 {
16230 // get number of digits for a float -> text -> float round-trip
16231 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
16232
16233 // the actual conversion
16234 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
16235
16236 // negative value indicates an error
16237 JSON_ASSERT(len > 0);
16238 // check if buffer was large enough
16239 JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
16240
16241 // erase thousands separator
16242 if (thousands_sep != '\0')
16243 {
16244 const auto end = std::remove(number_buffer.begin(),
16245 number_buffer.begin() + len, thousands_sep);
16246 std::fill(end, number_buffer.end(), '\0');
16247 JSON_ASSERT((end - number_buffer.begin()) <= len);
16248 len = (end - number_buffer.begin());
16249 }
16250
16251 // convert decimal point to '.'
16252 if (decimal_point != '\0' && decimal_point != '.')
16253 {
16254 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
16255 if (dec_pos != number_buffer.end())
16256 {
16257 *dec_pos = '.';
16258 }
16259 }
16260
16261 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
16262
16263 // determine if need to append ".0"
16264 const bool value_is_int_like =
16265 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
16266 [](char c)
16267 {
16268 return c == '.' || c == 'e';
16269 });
16270
16271 if (value_is_int_like)
16272 {
16273 o->write_characters(".0", 2);
16274 }
16275 }
16276
16298 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
16299 {
16300 static const std::array<std::uint8_t, 400> utf8d =
16301 {
16302 {
16303 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
16304 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
16305 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
16306 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
16307 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
16308 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
16309 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
16310 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
16311 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
16312 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
16313 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
16314 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
16315 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
16316 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
16317 }
16318 };
16319
16320 const std::uint8_t type = utf8d[byte];
16321
16322 codep = (state != UTF8_ACCEPT)
16323 ? (byte & 0x3fu) | (codep << 6u)
16324 : (0xFFu >> type) & (byte);
16325
16326 std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
16327 JSON_ASSERT(index < 400);
16328 state = utf8d[index];
16329 return state;
16330 }
16331
16332 /*
16333 * Overload to make the compiler happy while it is instantiating
16334 * dump_integer for number_unsigned_t.
16335 * Must never be called.
16336 */
16337 number_unsigned_t remove_sign(number_unsigned_t x)
16338 {
16339 JSON_ASSERT(false); // LCOV_EXCL_LINE
16340 return x; // LCOV_EXCL_LINE
16341 }
16342
16343 /*
16344 * Helper function for dump_integer
16345 *
16346 * This function takes a negative signed integer and returns its absolute
16347 * value as unsigned integer. The plus/minus shuffling is necessary as we can
16348 * not directly remove the sign of an arbitrary signed integer as the
16349 * absolute values of INT_MIN and INT_MAX are usually not the same. See
16350 * #1708 for details.
16351 */
16352 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
16353 {
16354 JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)());
16355 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
16356 }
16357
16358 private:
16360 output_adapter_t<char> o = nullptr;
16361
16363 std::array<char, 64> number_buffer{{}};
16364
16366 const std::lconv* loc = nullptr;
16368 const char thousands_sep = '\0';
16370 const char decimal_point = '\0';
16371
16373 std::array<char, 512> string_buffer{{}};
16374
16376 const char indent_char;
16378 string_t indent_string;
16379
16381 const error_handler_t error_handler;
16382 };
16383 } // namespace detail
16384 } // namespace nlohmann
16385
16386 // #include <nlohmann/detail/value_t.hpp>
16387
16388 // #include <nlohmann/json_fwd.hpp>
16389
16390 // #include <nlohmann/ordered_map.hpp>
16391
16392
16393 #include <functional> // less
16394 #include <memory> // allocator
16395 #include <utility> // pair
16396 #include <vector> // vector
16397
16398 namespace nlohmann
16399 {
16400
16403 template <class Key, class T, class IgnoredLess = std::less<Key>,
16404 class Allocator = std::allocator<std::pair<const Key, T>>>
16405 struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
16406 {
16407 using key_type = Key;
16408 using mapped_type = T;
16409 using Container = std::vector<std::pair<const Key, T>, Allocator>;
16410 using typename Container::iterator;
16411 using typename Container::size_type;
16412 using typename Container::value_type;
16413
16414 // Explicit constructors instead of `using Container::Container`
16415 // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
16416 ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
16417 template <class It>
16418 ordered_map(It first, It last, const Allocator& alloc = Allocator())
16419 : Container{first, last, alloc} {}
16420 ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
16421 : Container{init, alloc} {}
16422
16423 std::pair<iterator, bool> emplace(key_type&& key, T&& t)
16424 {
16425 for (auto it = this->begin(); it != this->end(); ++it)
16426 {
16427 if (it->first == key)
16428 {
16429 return {it, false};
16430 }
16431 }
16432 Container::emplace_back(key, t);
16433 return {--this->end(), true};
16434 }
16435
16436 T& operator[](Key&& key)
16437 {
16438 return emplace(std::move(key), T{}).first->second;
16439 }
16440
16441 size_type erase(const Key& key)
16442 {
16443 for (auto it = this->begin(); it != this->end(); ++it)
16444 {
16445 if (it->first == key)
16446 {
16447 // Since we cannot move const Keys, re-construct them in place
16448 for (auto next = it; ++next != this->end(); ++it)
16449 {
16450 it->~value_type(); // Destroy but keep allocation
16451 new (&*it) value_type{std::move(*next)};
16452 }
16453 Container::pop_back();
16454 return 1;
16455 }
16456 }
16457 return 0;
16458 }
16459 };
16460
16461 } // namespace nlohmann
16462
16463
16469 namespace nlohmann
16470 {
16471
16556 NLOHMANN_BASIC_JSON_TPL_DECLARATION
16557 class basic_json
16558 {
16559 private:
16560 template<detail::value_t> friend struct detail::external_constructor;
16561 friend ::nlohmann::json_pointer<basic_json>;
16562
16563 template<typename BasicJsonType, typename InputType>
16564 friend class ::nlohmann::detail::parser;
16565 friend ::nlohmann::detail::serializer<basic_json>;
16566 template<typename BasicJsonType>
16567 friend class ::nlohmann::detail::iter_impl;
16568 template<typename BasicJsonType, typename CharType>
16569 friend class ::nlohmann::detail::binary_writer;
16570 template<typename BasicJsonType, typename InputType, typename SAX>
16571 friend class ::nlohmann::detail::binary_reader;
16572 template<typename BasicJsonType>
16573 friend class ::nlohmann::detail::json_sax_dom_parser;
16574 template<typename BasicJsonType>
16575 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
16576
16578 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
16579
16580 // convenience aliases for types residing in namespace detail;
16581 using lexer = ::nlohmann::detail::lexer_base<basic_json>;
16582
16583 template<typename InputAdapterType>
16584 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
16585 InputAdapterType adapter,
16586 detail::parser_callback_t<basic_json>cb = nullptr,
16587 const bool allow_exceptions = true,
16588 const bool ignore_comments = false
16589 )
16590 {
16591 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
16592 std::move(cb), allow_exceptions, ignore_comments);
16593 }
16594
16595 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
16596 template<typename BasicJsonType>
16597 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
16598 template<typename BasicJsonType>
16599 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
16600 template<typename Iterator>
16601 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
16602 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
16603
16604 template<typename CharType>
16605 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
16606
16607 template<typename InputType>
16608 using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
16609 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
16610
16611 using serializer = ::nlohmann::detail::serializer<basic_json>;
16612
16613 public:
16614 using value_t = detail::value_t;
16616 using json_pointer = ::nlohmann::json_pointer<basic_json>;
16617 template<typename T, typename SFINAE>
16618 using json_serializer = JSONSerializer<T, SFINAE>;
16620 using error_handler_t = detail::error_handler_t;
16622 using cbor_tag_handler_t = detail::cbor_tag_handler_t;
16624 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
16625
16626 using input_format_t = detail::input_format_t;
16628 using json_sax_t = json_sax<basic_json>;
16629
16631 // exceptions //
16633
16637
16639 using exception = detail::exception;
16641 using parse_error = detail::parse_error;
16643 using invalid_iterator = detail::invalid_iterator;
16645 using type_error = detail::type_error;
16647 using out_of_range = detail::out_of_range;
16649 using other_error = detail::other_error;
16650
16652
16653
16655 // container types //
16657
16662
16664 using value_type = basic_json;
16665
16667 using reference = value_type&;
16669 using const_reference = const value_type&;
16670
16672 using difference_type = std::ptrdiff_t;
16674 using size_type = std::size_t;
16675
16677 using allocator_type = AllocatorType<basic_json>;
16678
16680 using pointer = typename std::allocator_traits<allocator_type>::pointer;
16682 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
16683
16685 using iterator = iter_impl<basic_json>;
16687 using const_iterator = iter_impl<const basic_json>;
16689 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
16691 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
16692
16694
16695
16699 static allocator_type get_allocator()
16700 {
16701 return allocator_type();
16702 }
16703
16730
16731 static basic_json meta()
16732 {
16733 basic_json result;
16734
16735 result["copyright"] = "(C) 2013-2020 Niels Lohmann";
16736 result["name"] = "JSON for Modern C++";
16737 result["url"] = "https://github.com/nlohmann/json";
16738 result["version"]["string"] =
16739 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
16740 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
16741 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
16742 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
16743 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
16744 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
16745
16746 #ifdef _WIN32
16747 result["platform"] = "win32";
16748 #elif defined __linux__
16749 result["platform"] = "linux";
16750 #elif defined __APPLE__
16751 result["platform"] = "apple";
16752 #elif defined __unix__
16753 result["platform"] = "unix";
16754 #else
16755 result["platform"] = "unknown";
16756 #endif
16757
16758 #if defined(__ICC) || defined(__INTEL_COMPILER)
16759 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
16760 #elif defined(__clang__)
16761 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
16762 #elif defined(__GNUC__) || defined(__GNUG__)
16763 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
16764 #elif defined(__HP_cc) || defined(__HP_aCC)
16765 result["compiler"] = "hp"
16766 #elif defined(__IBMCPP__)
16767 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
16768 #elif defined(_MSC_VER)
16769 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
16770 #elif defined(__PGI)
16771 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
16772 #elif defined(__SUNPRO_CC)
16773 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
16774 #else
16775 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
16776 #endif
16777
16778 #ifdef __cplusplus
16779 result["compiler"]["c++"] = std::to_string(__cplusplus);
16780 #else
16781 result["compiler"]["c++"] = "unknown";
16782 #endif
16783 return result;
16784 }
16785
16786
16788 // JSON value data types //
16790
16795
16796 #if defined(JSON_HAS_CPP_14)
16797 // Use transparent comparator if possible, combined with perfect forwarding
16798 // on find() and count() calls prevents unnecessary string construction.
16799 using object_comparator_t = std::less<>;
16800 #else
16801 using object_comparator_t = std::less<StringType>;
16802 #endif
16803
16887 using object_t = ObjectType<StringType,
16888 basic_json,
16889 object_comparator_t,
16890 AllocatorType<std::pair<const StringType,
16891 basic_json>>>;
16892
16937 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
16938
16990 using string_t = StringType;
16991
17016 using boolean_t = BooleanType;
17017
17088 using number_integer_t = NumberIntegerType;
17089
17159 using number_unsigned_t = NumberUnsignedType;
17160
17227 using number_float_t = NumberFloatType;
17228
17298 using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
17300
17301 private:
17302
17304 template<typename T, typename... Args>
17305
17306 static T* create(Args&& ... args)
17307 {
17308 AllocatorType<T> alloc;
17309 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
17310
17311 auto deleter = [&](T * object)
17312 {
17313 AllocatorTraits::deallocate(alloc, object, 1);
17314 };
17315 std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
17316 AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
17317 JSON_ASSERT(object != nullptr);
17318 return object.release();
17319 }
17320
17322 // JSON value storage //
17324
17350 union json_value
17351 {
17353 object_t* object;
17355 array_t* array;
17357 string_t* string;
17359 binary_t* binary;
17361 boolean_t boolean;
17363 number_integer_t number_integer;
17365 number_unsigned_t number_unsigned;
17367 number_float_t number_float;
17368
17370 json_value() = default;
17372 json_value(boolean_t v) noexcept : boolean(v) {}
17374 json_value(number_integer_t v) noexcept : number_integer(v) {}
17376 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
17378 json_value(number_float_t v) noexcept : number_float(v) {}
17380 json_value(value_t t)
17381 {
17382 switch (t)
17383 {
17384 case value_t::object:
17385 {
17386 object = create<object_t>();
17387 break;
17388 }
17389
17390 case value_t::array:
17391 {
17392 array = create<array_t>();
17393 break;
17394 }
17395
17396 case value_t::string:
17397 {
17398 string = create<string_t>("");
17399 break;
17400 }
17401
17402 case value_t::binary:
17403 {
17404 binary = create<binary_t>();
17405 break;
17406 }
17407
17408 case value_t::boolean:
17409 {
17410 boolean = boolean_t(false);
17411 break;
17412 }
17413
17414 case value_t::number_integer:
17415 {
17416 number_integer = number_integer_t(0);
17417 break;
17418 }
17419
17420 case value_t::number_unsigned:
17421 {
17422 number_unsigned = number_unsigned_t(0);
17423 break;
17424 }
17425
17426 case value_t::number_float:
17427 {
17428 number_float = number_float_t(0.0);
17429 break;
17430 }
17431
17432 case value_t::null:
17433 {
17434 object = nullptr; // silence warning, see #821
17435 break;
17436 }
17437
17438 default:
17439 {
17440 object = nullptr; // silence warning, see #821
17441 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
17442 {
17443 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.8.0")); // LCOV_EXCL_LINE
17444 }
17445 break;
17446 }
17447 }
17448 }
17449
17451 json_value(const string_t& value)
17452 {
17453 string = create<string_t>(value);
17454 }
17455
17457 json_value(string_t&& value)
17458 {
17459 string = create<string_t>(std::move(value));
17460 }
17461
17463 json_value(const object_t& value)
17464 {
17465 object = create<object_t>(value);
17466 }
17467
17469 json_value(object_t&& value)
17470 {
17471 object = create<object_t>(std::move(value));
17472 }
17473
17475 json_value(const array_t& value)
17476 {
17477 array = create<array_t>(value);
17478 }
17479
17481 json_value(array_t&& value)
17482 {
17483 array = create<array_t>(std::move(value));
17484 }
17485
17487 json_value(const typename binary_t::container_type& value)
17488 {
17489 binary = create<binary_t>(value);
17490 }
17491
17493 json_value(typename binary_t::container_type&& value)
17494 {
17495 binary = create<binary_t>(std::move(value));
17496 }
17497
17499 json_value(const binary_t& value)
17500 {
17501 binary = create<binary_t>(value);
17502 }
17503
17505 json_value(binary_t&& value)
17506 {
17507 binary = create<binary_t>(std::move(value));
17508 }
17509
17510 void destroy(value_t t) noexcept
17511 {
17512 // flatten the current json_value to a heap-allocated stack
17513 std::vector<basic_json> stack;
17514
17515 // move the top-level items to stack
17516 if (t == value_t::array)
17517 {
17518 stack.reserve(array->size());
17519 std::move(array->begin(), array->end(), std::back_inserter(stack));
17520 }
17521 else if (t == value_t::object)
17522 {
17523 stack.reserve(object->size());
17524 for (auto&& it : *object)
17525 {
17526 stack.push_back(std::move(it.second));
17527 }
17528 }
17529
17530 while (!stack.empty())
17531 {
17532 // move the last item to local variable to be processed
17533 basic_json current_item(std::move(stack.back()));
17534 stack.pop_back();
17535
17536 // if current_item is array/object, move
17537 // its children to the stack to be processed later
17538 if (current_item.is_array())
17539 {
17540 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
17541 std::back_inserter(stack));
17542
17543 current_item.m_value.array->clear();
17544 }
17545 else if (current_item.is_object())
17546 {
17547 for (auto&& it : *current_item.m_value.object)
17548 {
17549 stack.push_back(std::move(it.second));
17550 }
17551
17552 current_item.m_value.object->clear();
17553 }
17554
17555 // it's now safe that current_item get destructed
17556 // since it doesn't have any children
17557 }
17558
17559 switch (t)
17560 {
17561 case value_t::object:
17562 {
17563 AllocatorType<object_t> alloc;
17564 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
17565 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
17566 break;
17567 }
17568
17569 case value_t::array:
17570 {
17571 AllocatorType<array_t> alloc;
17572 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
17573 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
17574 break;
17575 }
17576
17577 case value_t::string:
17578 {
17579 AllocatorType<string_t> alloc;
17580 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
17581 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
17582 break;
17583 }
17584
17585 case value_t::binary:
17586 {
17587 AllocatorType<binary_t> alloc;
17588 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
17589 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
17590 break;
17591 }
17592
17593 default:
17594 {
17595 break;
17596 }
17597 }
17598 }
17599 };
17600
17610 void assert_invariant() const noexcept
17611 {
17612 JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
17613 JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
17614 JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
17615 JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
17616 }
17617
17618 public:
17620 // JSON parser callback //
17622
17638 using parse_event_t = detail::parse_event_t;
17639
17689 using parser_callback_t = detail::parser_callback_t<basic_json>;
17690
17692 // constructors //
17694
17699
17730 basic_json(const value_t v)
17731 : m_type(v), m_value(v)
17732 {
17733 assert_invariant();
17734 }
17735
17754 basic_json(std::nullptr_t = nullptr) noexcept
17755 : basic_json(value_t::null)
17756 {
17757 assert_invariant();
17758 }
17759
17823 template < typename CompatibleType,
17824 typename U = detail::uncvref_t<CompatibleType>,
17825 detail::enable_if_t <
17826 !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
17827 basic_json(CompatibleType && val) noexcept(noexcept(
17828 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
17829 std::forward<CompatibleType>(val))))
17830 {
17831 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
17832 assert_invariant();
17833 }
17834
17861 template < typename BasicJsonType,
17862 detail::enable_if_t <
17863 detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
17864 basic_json(const BasicJsonType& val)
17865 {
17866 using other_boolean_t = typename BasicJsonType::boolean_t;
17867 using other_number_float_t = typename BasicJsonType::number_float_t;
17868 using other_number_integer_t = typename BasicJsonType::number_integer_t;
17869 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
17870 using other_string_t = typename BasicJsonType::string_t;
17871 using other_object_t = typename BasicJsonType::object_t;
17872 using other_array_t = typename BasicJsonType::array_t;
17873 using other_binary_t = typename BasicJsonType::binary_t;
17874
17875 switch (val.type())
17876 {
17877 case value_t::boolean:
17878 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
17879 break;
17880 case value_t::number_float:
17881 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
17882 break;
17883 case value_t::number_integer:
17884 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
17885 break;
17886 case value_t::number_unsigned:
17887 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
17888 break;
17889 case value_t::string:
17890 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
17891 break;
17892 case value_t::object:
17893 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
17894 break;
17895 case value_t::array:
17896 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
17897 break;
17898 case value_t::binary:
17899 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
17900 break;
17901 case value_t::null:
17902 *this = nullptr;
17903 break;
17904 case value_t::discarded:
17905 m_type = value_t::discarded;
17906 break;
17907 default: // LCOV_EXCL_LINE
17908 JSON_ASSERT(false); // LCOV_EXCL_LINE
17909 }
17910 assert_invariant();
17911 }
17912
17987 basic_json(initializer_list_t init,
17988 bool type_deduction = true,
17989 value_t manual_type = value_t::array)
17990 {
17991 // check if each element is an array with two elements whose first
17992 // element is a string
17993 bool is_an_object = std::all_of(init.begin(), init.end(),
17994 [](const detail::json_ref<basic_json>& element_ref)
17995 {
17996 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
17997 });
17998
17999 // adjust type if type deduction is not wanted
18000 if (!type_deduction)
18001 {
18002 // if array is wanted, do not create an object though possible
18003 if (manual_type == value_t::array)
18004 {
18005 is_an_object = false;
18006 }
18007
18008 // if object is wanted but impossible, throw an exception
18009 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
18010 {
18011 JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
18012 }
18013 }
18014
18015 if (is_an_object)
18016 {
18017 // the initializer list is a list of pairs -> create object
18018 m_type = value_t::object;
18019 m_value = value_t::object;
18020
18021 std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
18022 {
18023 auto element = element_ref.moved_or_copied();
18024 m_value.object->emplace(
18025 std::move(*((*element.m_value.array)[0].m_value.string)),
18026 std::move((*element.m_value.array)[1]));
18027 });
18028 }
18029 else
18030 {
18031 // the initializer list describes an array -> create array
18032 m_type = value_t::array;
18033 m_value.array = create<array_t>(init.begin(), init.end());
18034 }
18035
18036 assert_invariant();
18037 }
18038
18066
18067 static basic_json binary(const typename binary_t::container_type& init)
18068 {
18069 auto res = basic_json();
18070 res.m_type = value_t::binary;
18071 res.m_value = init;
18072 return res;
18073 }
18074
18103
18104 static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype)
18105 {
18106 auto res = basic_json();
18107 res.m_type = value_t::binary;
18108 res.m_value = binary_t(init, subtype);
18109 return res;
18110 }
18111
18113
18114 static basic_json binary(typename binary_t::container_type&& init)
18115 {
18116 auto res = basic_json();
18117 res.m_type = value_t::binary;
18118 res.m_value = std::move(init);
18119 return res;
18120 }
18121
18123
18124 static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype)
18125 {
18126 auto res = basic_json();
18127 res.m_type = value_t::binary;
18128 res.m_value = binary_t(std::move(init), subtype);
18129 return res;
18130 }
18131
18169
18170 static basic_json array(initializer_list_t init = {})
18171 {
18172 return basic_json(init, false, value_t::array);
18173 }
18174
18213
18214 static basic_json object(initializer_list_t init = {})
18215 {
18216 return basic_json(init, false, value_t::object);
18217 }
18218
18241 basic_json(size_type cnt, const basic_json& val)
18242 : m_type(value_t::array)
18243 {
18244 m_value.array = create<array_t>(cnt, val);
18245 assert_invariant();
18246 }
18247
18303 template < class InputIT, typename std::enable_if <
18304 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
18305 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
18306 basic_json(InputIT first, InputIT last)
18307 {
18308 JSON_ASSERT(first.m_object != nullptr);
18309 JSON_ASSERT(last.m_object != nullptr);
18310
18311 // make sure iterator fits the current value
18312 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
18313 {
18314 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
18315 }
18316
18317 // copy type from first iterator
18318 m_type = first.m_object->m_type;
18319
18320 // check if iterator range is complete for primitive values
18321 switch (m_type)
18322 {
18323 case value_t::boolean:
18324 case value_t::number_float:
18325 case value_t::number_integer:
18326 case value_t::number_unsigned:
18327 case value_t::string:
18328 {
18329 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
18330 || !last.m_it.primitive_iterator.is_end()))
18331 {
18332 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
18333 }
18334 break;
18335 }
18336
18337 default:
18338 break;
18339 }
18340
18341 switch (m_type)
18342 {
18343 case value_t::number_integer:
18344 {
18345 m_value.number_integer = first.m_object->m_value.number_integer;
18346 break;
18347 }
18348
18349 case value_t::number_unsigned:
18350 {
18351 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
18352 break;
18353 }
18354
18355 case value_t::number_float:
18356 {
18357 m_value.number_float = first.m_object->m_value.number_float;
18358 break;
18359 }
18360
18361 case value_t::boolean:
18362 {
18363 m_value.boolean = first.m_object->m_value.boolean;
18364 break;
18365 }
18366
18367 case value_t::string:
18368 {
18369 m_value = *first.m_object->m_value.string;
18370 break;
18371 }
18372
18373 case value_t::object:
18374 {
18375 m_value.object = create<object_t>(first.m_it.object_iterator,
18376 last.m_it.object_iterator);
18377 break;
18378 }
18379
18380 case value_t::array:
18381 {
18382 m_value.array = create<array_t>(first.m_it.array_iterator,
18383 last.m_it.array_iterator);
18384 break;
18385 }
18386
18387 case value_t::binary:
18388 {
18389 m_value = *first.m_object->m_value.binary;
18390 break;
18391 }
18392
18393 default:
18394 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
18395 std::string(first.m_object->type_name())));
18396 }
18397
18398 assert_invariant();
18399 }
18400
18401
18403 // other constructors and destructor //
18405
18406 template<typename JsonRef,
18407 detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
18408 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
18409 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
18410
18436 basic_json(const basic_json& other)
18437 : m_type(other.m_type)
18438 {
18439 // check of passed value is valid
18440 other.assert_invariant();
18441
18442 switch (m_type)
18443 {
18444 case value_t::object:
18445 {
18446 m_value = *other.m_value.object;
18447 break;
18448 }
18449
18450 case value_t::array:
18451 {
18452 m_value = *other.m_value.array;
18453 break;
18454 }
18455
18456 case value_t::string:
18457 {
18458 m_value = *other.m_value.string;
18459 break;
18460 }
18461
18462 case value_t::boolean:
18463 {
18464 m_value = other.m_value.boolean;
18465 break;
18466 }
18467
18468 case value_t::number_integer:
18469 {
18470 m_value = other.m_value.number_integer;
18471 break;
18472 }
18473
18474 case value_t::number_unsigned:
18475 {
18476 m_value = other.m_value.number_unsigned;
18477 break;
18478 }
18479
18480 case value_t::number_float:
18481 {
18482 m_value = other.m_value.number_float;
18483 break;
18484 }
18485
18486 case value_t::binary:
18487 {
18488 m_value = *other.m_value.binary;
18489 break;
18490 }
18491
18492 default:
18493 break;
18494 }
18495
18496 assert_invariant();
18497 }
18498
18525 basic_json(basic_json&& other) noexcept
18526 : m_type(std::move(other.m_type)),
18527 m_value(std::move(other.m_value))
18528 {
18529 // check that passed value is valid
18530 other.assert_invariant();
18531
18532 // invalidate payload
18533 other.m_type = value_t::null;
18534 other.m_value = {};
18535
18536 assert_invariant();
18537 }
18538
18562 basic_json& operator=(basic_json other) noexcept (
18563 std::is_nothrow_move_constructible<value_t>::value&&
18564 std::is_nothrow_move_assignable<value_t>::value&&
18565 std::is_nothrow_move_constructible<json_value>::value&&
18566 std::is_nothrow_move_assignable<json_value>::value
18567 )
18568 {
18569 // check that passed value is valid
18570 other.assert_invariant();
18571
18572 using std::swap;
18573 swap(m_type, other.m_type);
18574 swap(m_value, other.m_value);
18575
18576 assert_invariant();
18577 return *this;
18578 }
18579
18595 ~basic_json() noexcept
18596 {
18597 assert_invariant();
18598 m_value.destroy(m_type);
18599 }
18600
18602
18603 public:
18605 // object inspection //
18607
18611
18659 string_t dump(const int indent = -1,
18660 const char indent_char = ' ',
18661 const bool ensure_ascii = false,
18662 const error_handler_t error_handler = error_handler_t::strict) const
18663 {
18664 string_t result;
18665 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
18666
18667 if (indent >= 0)
18668 {
18669 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
18670 }
18671 else
18672 {
18673 s.dump(*this, false, ensure_ascii, 0);
18674 }
18675
18676 return result;
18677 }
18678
18712 constexpr value_t type() const noexcept
18713 {
18714 return m_type;
18715 }
18716
18743 constexpr bool is_primitive() const noexcept
18744 {
18745 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
18746 }
18747
18770 constexpr bool is_structured() const noexcept
18771 {
18772 return is_array() || is_object();
18773 }
18774
18792 constexpr bool is_null() const noexcept
18793 {
18794 return m_type == value_t::null;
18795 }
18796
18814 constexpr bool is_boolean() const noexcept
18815 {
18816 return m_type == value_t::boolean;
18817 }
18818
18844 constexpr bool is_number() const noexcept
18845 {
18846 return is_number_integer() || is_number_float();
18847 }
18848
18873 constexpr bool is_number_integer() const noexcept
18874 {
18875 return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
18876 }
18877
18901 constexpr bool is_number_unsigned() const noexcept
18902 {
18903 return m_type == value_t::number_unsigned;
18904 }
18905
18929 constexpr bool is_number_float() const noexcept
18930 {
18931 return m_type == value_t::number_float;
18932 }
18933
18951 constexpr bool is_object() const noexcept
18952 {
18953 return m_type == value_t::object;
18954 }
18955
18973 constexpr bool is_array() const noexcept
18974 {
18975 return m_type == value_t::array;
18976 }
18977
18995 constexpr bool is_string() const noexcept
18996 {
18997 return m_type == value_t::string;
18998 }
18999
19017 constexpr bool is_binary() const noexcept
19018 {
19019 return m_type == value_t::binary;
19020 }
19021
19044 constexpr bool is_discarded() const noexcept
19045 {
19046 return m_type == value_t::discarded;
19047 }
19048
19070 constexpr operator value_t() const noexcept
19071 {
19072 return m_type;
19073 }
19074
19076
19077 private:
19079 // value access //
19081
19083 boolean_t get_impl(boolean_t* /*unused*/) const
19084 {
19085 if (JSON_HEDLEY_LIKELY(is_boolean()))
19086 {
19087 return m_value.boolean;
19088 }
19089
19090 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
19091 }
19092
19094 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
19095 {
19096 return is_object() ? m_value.object : nullptr;
19097 }
19098
19100 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
19101 {
19102 return is_object() ? m_value.object : nullptr;
19103 }
19104
19106 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
19107 {
19108 return is_array() ? m_value.array : nullptr;
19109 }
19110
19112 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
19113 {
19114 return is_array() ? m_value.array : nullptr;
19115 }
19116
19118 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
19119 {
19120 return is_string() ? m_value.string : nullptr;
19121 }
19122
19124 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
19125 {
19126 return is_string() ? m_value.string : nullptr;
19127 }
19128
19130 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
19131 {
19132 return is_boolean() ? &m_value.boolean : nullptr;
19133 }
19134
19136 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
19137 {
19138 return is_boolean() ? &m_value.boolean : nullptr;
19139 }
19140
19142 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
19143 {
19144 return is_number_integer() ? &m_value.number_integer : nullptr;
19145 }
19146
19148 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
19149 {
19150 return is_number_integer() ? &m_value.number_integer : nullptr;
19151 }
19152
19154 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
19155 {
19156 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19157 }
19158
19160 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
19161 {
19162 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19163 }
19164
19166 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
19167 {
19168 return is_number_float() ? &m_value.number_float : nullptr;
19169 }
19170
19172 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
19173 {
19174 return is_number_float() ? &m_value.number_float : nullptr;
19175 }
19176
19178 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
19179 {
19180 return is_binary() ? m_value.binary : nullptr;
19181 }
19182
19184 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
19185 {
19186 return is_binary() ? m_value.binary : nullptr;
19187 }
19188
19200 template<typename ReferenceType, typename ThisType>
19201 static ReferenceType get_ref_impl(ThisType& obj)
19202 {
19203 // delegate the call to get_ptr<>()
19204 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
19205
19206 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
19207 {
19208 return *ptr;
19209 }
19210
19211 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
19212 }
19213
19214 public:
19218
19233 template<typename BasicJsonType, detail::enable_if_t<
19234 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
19235 int> = 0>
19236 basic_json get() const
19237 {
19238 return *this;
19239 }
19240
19256 template < typename BasicJsonType, detail::enable_if_t <
19257 !std::is_same<BasicJsonType, basic_json>::value&&
19258 detail::is_basic_json<BasicJsonType>::value, int > = 0 >
19259 BasicJsonType get() const
19260 {
19261 return *this;
19262 }
19263
19303 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
19304 detail::enable_if_t <
19305 !detail::is_basic_json<ValueType>::value &&
19306 detail::has_from_json<basic_json_t, ValueType>::value &&
19307 !detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19308 int > = 0 >
19309 ValueType get() const noexcept(noexcept(
19310 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
19311 {
19312 // we cannot static_assert on ValueTypeCV being non-const, because
19313 // there is support for get<const basic_json_t>(), which is why we
19314 // still need the uncvref
19315 static_assert(!std::is_reference<ValueTypeCV>::value,
19316 "get() cannot be used with reference types, you might want to use get_ref()");
19317 static_assert(std::is_default_constructible<ValueType>::value,
19318 "types must be DefaultConstructible when used with get()");
19319
19320 ValueType ret;
19321 JSONSerializer<ValueType>::from_json(*this, ret);
19322 return ret;
19323 }
19324
19356 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
19357 detail::enable_if_t < !std::is_same<basic_json_t, ValueType>::value &&
19358 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19359 int > = 0 >
19360 ValueType get() const noexcept(noexcept(
19361 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
19362 {
19363 static_assert(!std::is_reference<ValueTypeCV>::value,
19364 "get() cannot be used with reference types, you might want to use get_ref()");
19365 return JSONSerializer<ValueType>::from_json(*this);
19366 }
19367
19401 template < typename ValueType,
19402 detail::enable_if_t <
19403 !detail::is_basic_json<ValueType>::value&&
19404 detail::has_from_json<basic_json_t, ValueType>::value,
19405 int > = 0 >
19406 ValueType & get_to(ValueType& v) const noexcept(noexcept(
19407 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
19408 {
19409 JSONSerializer<ValueType>::from_json(*this, v);
19410 return v;
19411 }
19412
19413 // specialization to allow to call get_to with a basic_json value
19414 // see https://github.com/nlohmann/json/issues/2175
19415 template<typename ValueType,
19416 detail::enable_if_t <
19417 detail::is_basic_json<ValueType>::value,
19418 int> = 0>
19419 ValueType & get_to(ValueType& v) const
19420 {
19421 v = *this;
19422 return v;
19423 }
19424
19425 template <
19426 typename T, std::size_t N,
19427 typename Array = T (&)[N],
19428 detail::enable_if_t <
19429 detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
19430 Array get_to(T (&v)[N]) const
19431 noexcept(noexcept(JSONSerializer<Array>::from_json(
19432 std::declval<const basic_json_t&>(), v)))
19433 {
19434 JSONSerializer<Array>::from_json(*this, v);
19435 return v;
19436 }
19437
19438
19465 template<typename PointerType, typename std::enable_if<
19466 std::is_pointer<PointerType>::value, int>::type = 0>
19467 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19468 {
19469 // delegate the call to get_impl_ptr<>()
19470 return get_impl_ptr(static_cast<PointerType>(nullptr));
19471 }
19472
19477 template < typename PointerType, typename std::enable_if <
19478 std::is_pointer<PointerType>::value&&
19479 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
19480 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19481 {
19482 // delegate the call to get_impl_ptr<>() const
19483 return get_impl_ptr(static_cast<PointerType>(nullptr));
19484 }
19485
19513 template<typename PointerType, typename std::enable_if<
19514 std::is_pointer<PointerType>::value, int>::type = 0>
19515 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
19516 {
19517 // delegate the call to get_ptr
19518 return get_ptr<PointerType>();
19519 }
19520
19525 template<typename PointerType, typename std::enable_if<
19526 std::is_pointer<PointerType>::value, int>::type = 0>
19527 constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
19528 {
19529 // delegate the call to get_ptr
19530 return get_ptr<PointerType>();
19531 }
19532
19559 template<typename ReferenceType, typename std::enable_if<
19560 std::is_reference<ReferenceType>::value, int>::type = 0>
19561 ReferenceType get_ref()
19562 {
19563 // delegate call to get_ref_impl
19564 return get_ref_impl<ReferenceType>(*this);
19565 }
19566
19571 template < typename ReferenceType, typename std::enable_if <
19572 std::is_reference<ReferenceType>::value&&
19573 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
19574 ReferenceType get_ref() const
19575 {
19576 // delegate call to get_ref_impl
19577 return get_ref_impl<ReferenceType>(*this);
19578 }
19579
19609 template < typename ValueType, typename std::enable_if <
19610 !std::is_pointer<ValueType>::value&&
19611 !std::is_same<ValueType, detail::json_ref<basic_json>>::value&&
19612 !std::is_same<ValueType, typename string_t::value_type>::value&&
19613 !detail::is_basic_json<ValueType>::value
19614 && !std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
19615 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
19616 && !std::is_same<ValueType, typename std::string_view>::value
19617 #endif
19618 && detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
19619 , int >::type = 0 >
19620 JSON_EXPLICIT operator ValueType() const
19621 {
19622 // delegate the call to get<>() const
19623 return get<ValueType>();
19624 }
19625
19635 binary_t& get_binary()
19636 {
19637 if (!is_binary())
19638 {
19639 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19640 }
19641
19642 return *get_ptr<binary_t*>();
19643 }
19644
19646 const binary_t& get_binary() const
19647 {
19648 if (!is_binary())
19649 {
19650 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19651 }
19652
19653 return *get_ptr<const binary_t*>();
19654 }
19655
19657
19658
19660 // element access //
19662
19666
19693 reference at(size_type idx)
19694 {
19695 // at only works for arrays
19696 if (JSON_HEDLEY_LIKELY(is_array()))
19697 {
19698 JSON_TRY
19699 {
19700 return m_value.array->at(idx);
19701 }
19702 JSON_CATCH (std::out_of_range&)
19703 {
19704 // create better exception explanation
19705 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19706 }
19707 }
19708 else
19709 {
19710 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19711 }
19712 }
19713
19740 const_reference at(size_type idx) const
19741 {
19742 // at only works for arrays
19743 if (JSON_HEDLEY_LIKELY(is_array()))
19744 {
19745 JSON_TRY
19746 {
19747 return m_value.array->at(idx);
19748 }
19749 JSON_CATCH (std::out_of_range&)
19750 {
19751 // create better exception explanation
19752 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19753 }
19754 }
19755 else
19756 {
19757 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19758 }
19759 }
19760
19791 reference at(const typename object_t::key_type& key)
19792 {
19793 // at only works for objects
19794 if (JSON_HEDLEY_LIKELY(is_object()))
19795 {
19796 JSON_TRY
19797 {
19798 return m_value.object->at(key);
19799 }
19800 JSON_CATCH (std::out_of_range&)
19801 {
19802 // create better exception explanation
19803 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19804 }
19805 }
19806 else
19807 {
19808 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19809 }
19810 }
19811
19842 const_reference at(const typename object_t::key_type& key) const
19843 {
19844 // at only works for objects
19845 if (JSON_HEDLEY_LIKELY(is_object()))
19846 {
19847 JSON_TRY
19848 {
19849 return m_value.object->at(key);
19850 }
19851 JSON_CATCH (std::out_of_range&)
19852 {
19853 // create better exception explanation
19854 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19855 }
19856 }
19857 else
19858 {
19859 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19860 }
19861 }
19862
19888 reference operator[](size_type idx)
19889 {
19890 // implicitly convert null value to an empty array
19891 if (is_null())
19892 {
19893 m_type = value_t::array;
19894 m_value.array = create<array_t>();
19895 assert_invariant();
19896 }
19897
19898 // operator[] only works for arrays
19899 if (JSON_HEDLEY_LIKELY(is_array()))
19900 {
19901 // fill up array with null values if given idx is outside range
19902 if (idx >= m_value.array->size())
19903 {
19904 m_value.array->insert(m_value.array->end(),
19905 idx - m_value.array->size() + 1,
19906 basic_json());
19907 }
19908
19909 return m_value.array->operator[](idx);
19910 }
19911
19912 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
19913 }
19914
19934 const_reference operator[](size_type idx) const
19935 {
19936 // const operator[] only works for arrays
19937 if (JSON_HEDLEY_LIKELY(is_array()))
19938 {
19939 return m_value.array->operator[](idx);
19940 }
19941
19942 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
19943 }
19944
19972 reference operator[](const typename object_t::key_type& key)
19973 {
19974 // implicitly convert null value to an empty object
19975 if (is_null())
19976 {
19977 m_type = value_t::object;
19978 m_value.object = create<object_t>();
19979 assert_invariant();
19980 }
19981
19982 // operator[] only works for objects
19983 if (JSON_HEDLEY_LIKELY(is_object()))
19984 {
19985 return m_value.object->operator[](key);
19986 }
19987
19988 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
19989 }
19990
20021 const_reference operator[](const typename object_t::key_type& key) const
20022 {
20023 // const operator[] only works for objects
20024 if (JSON_HEDLEY_LIKELY(is_object()))
20025 {
20026 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20027 return m_value.object->find(key)->second;
20028 }
20029
20030 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20031 }
20032
20060 template<typename T>
20061 JSON_HEDLEY_NON_NULL(2)
20062 reference operator[](T* key)
20063 {
20064 // implicitly convert null to object
20065 if (is_null())
20066 {
20067 m_type = value_t::object;
20068 m_value = value_t::object;
20069 assert_invariant();
20070 }
20071
20072 // at only works for objects
20073 if (JSON_HEDLEY_LIKELY(is_object()))
20074 {
20075 return m_value.object->operator[](key);
20076 }
20077
20078 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20079 }
20080
20111 template<typename T>
20112 JSON_HEDLEY_NON_NULL(2)
20113 const_reference operator[](T* key) const
20114 {
20115 // at only works for objects
20116 if (JSON_HEDLEY_LIKELY(is_object()))
20117 {
20118 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20119 return m_value.object->find(key)->second;
20120 }
20121
20122 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20123 }
20124
20175 // using std::is_convertible in a std::enable_if will fail when using explicit conversions
20176 template < class ValueType, typename std::enable_if <
20177 detail::is_getable<basic_json_t, ValueType>::value
20178 && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
20179 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
20180 {
20181 // at only works for objects
20182 if (JSON_HEDLEY_LIKELY(is_object()))
20183 {
20184 // if key is found, return value and given default value otherwise
20185 const auto it = find(key);
20186 if (it != end())
20187 {
20188 return it->template get<ValueType>();
20189 }
20190
20191 return default_value;
20192 }
20193
20194 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
20195 }
20196
20201 string_t value(const typename object_t::key_type& key, const char* default_value) const
20202 {
20203 return value(key, string_t(default_value));
20204 }
20205
20249 template<class ValueType, typename std::enable_if<
20250 detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
20251 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
20252 {
20253 // at only works for objects
20254 if (JSON_HEDLEY_LIKELY(is_object()))
20255 {
20256 // if pointer resolves a value, return it or use default value
20257 JSON_TRY
20258 {
20259 return ptr.get_checked(this).template get<ValueType>();
20260 }
20261 JSON_INTERNAL_CATCH (out_of_range&)
20262 {
20263 return default_value;
20264 }
20265 }
20266
20267 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
20268 }
20269
20274 JSON_HEDLEY_NON_NULL(3)
20275 string_t value(const json_pointer& ptr, const char* default_value) const
20276 {
20277 return value(ptr, string_t(default_value));
20278 }
20279
20305 reference front()
20306 {
20307 return *begin();
20308 }
20309
20313 const_reference front() const
20314 {
20315 return *cbegin();
20316 }
20317
20349 reference back()
20350 {
20351 auto tmp = end();
20352 --tmp;
20353 return *tmp;
20354 }
20355
20359 const_reference back() const
20360 {
20361 auto tmp = cend();
20362 --tmp;
20363 return *tmp;
20364 }
20365
20412 template < class IteratorType, typename std::enable_if <
20413 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20414 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
20415 = 0 >
20416 IteratorType erase(IteratorType pos)
20417 {
20418 // make sure iterator fits the current value
20419 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
20420 {
20421 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
20422 }
20423
20424 IteratorType result = end();
20425
20426 switch (m_type)
20427 {
20428 case value_t::boolean:
20429 case value_t::number_float:
20430 case value_t::number_integer:
20431 case value_t::number_unsigned:
20432 case value_t::string:
20433 case value_t::binary:
20434 {
20435 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
20436 {
20437 JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
20438 }
20439
20440 if (is_string())
20441 {
20442 AllocatorType<string_t> alloc;
20443 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20444 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20445 m_value.string = nullptr;
20446 }
20447 else if (is_binary())
20448 {
20449 AllocatorType<binary_t> alloc;
20450 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20451 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20452 m_value.binary = nullptr;
20453 }
20454
20455 m_type = value_t::null;
20456 assert_invariant();
20457 break;
20458 }
20459
20460 case value_t::object:
20461 {
20462 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
20463 break;
20464 }
20465
20466 case value_t::array:
20467 {
20468 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
20469 break;
20470 }
20471
20472 default:
20473 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20474 }
20475
20476 return result;
20477 }
20478
20525 template < class IteratorType, typename std::enable_if <
20526 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20527 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
20528 = 0 >
20529 IteratorType erase(IteratorType first, IteratorType last)
20530 {
20531 // make sure iterator fits the current value
20532 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
20533 {
20534 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
20535 }
20536
20537 IteratorType result = end();
20538
20539 switch (m_type)
20540 {
20541 case value_t::boolean:
20542 case value_t::number_float:
20543 case value_t::number_integer:
20544 case value_t::number_unsigned:
20545 case value_t::string:
20546 case value_t::binary:
20547 {
20548 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
20549 || !last.m_it.primitive_iterator.is_end()))
20550 {
20551 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
20552 }
20553
20554 if (is_string())
20555 {
20556 AllocatorType<string_t> alloc;
20557 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20558 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20559 m_value.string = nullptr;
20560 }
20561 else if (is_binary())
20562 {
20563 AllocatorType<binary_t> alloc;
20564 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20565 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20566 m_value.binary = nullptr;
20567 }
20568
20569 m_type = value_t::null;
20570 assert_invariant();
20571 break;
20572 }
20573
20574 case value_t::object:
20575 {
20576 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
20577 last.m_it.object_iterator);
20578 break;
20579 }
20580
20581 case value_t::array:
20582 {
20583 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
20584 last.m_it.array_iterator);
20585 break;
20586 }
20587
20588 default:
20589 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20590 }
20591
20592 return result;
20593 }
20594
20624 size_type erase(const typename object_t::key_type& key)
20625 {
20626 // this erase only works for objects
20627 if (JSON_HEDLEY_LIKELY(is_object()))
20628 {
20629 return m_value.object->erase(key);
20630 }
20631
20632 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20633 }
20634
20659 void erase(const size_type idx)
20660 {
20661 // this erase only works for arrays
20662 if (JSON_HEDLEY_LIKELY(is_array()))
20663 {
20664 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
20665 {
20666 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
20667 }
20668
20669 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
20670 }
20671 else
20672 {
20673 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20674 }
20675 }
20676
20678
20679
20681 // lookup //
20683
20686
20711 template<typename KeyT>
20712 iterator find(KeyT&& key)
20713 {
20714 auto result = end();
20715
20716 if (is_object())
20717 {
20718 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20719 }
20720
20721 return result;
20722 }
20723
20728 template<typename KeyT>
20729 const_iterator find(KeyT&& key) const
20730 {
20731 auto result = cend();
20732
20733 if (is_object())
20734 {
20735 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20736 }
20737
20738 return result;
20739 }
20740
20762 template<typename KeyT>
20763 size_type count(KeyT&& key) const
20764 {
20765 // return 0 for all nonobject types
20766 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
20767 }
20768
20794 template < typename KeyT, typename std::enable_if <
20795 !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
20796 bool contains(KeyT && key) const
20797 {
20798 return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
20799 }
20800
20827 bool contains(const json_pointer& ptr) const
20828 {
20829 return ptr.contains(this);
20830 }
20831
20833
20834
20836 // iterators //
20838
20841
20866 iterator begin() noexcept
20867 {
20868 iterator result(this);
20869 result.set_begin();
20870 return result;
20871 }
20872
20876 const_iterator begin() const noexcept
20877 {
20878 return cbegin();
20879 }
20880
20906 const_iterator cbegin() const noexcept
20907 {
20908 const_iterator result(this);
20909 result.set_begin();
20910 return result;
20911 }
20912
20937 iterator end() noexcept
20938 {
20939 iterator result(this);
20940 result.set_end();
20941 return result;
20942 }
20943
20947 const_iterator end() const noexcept
20948 {
20949 return cend();
20950 }
20951
20977 const_iterator cend() const noexcept
20978 {
20979 const_iterator result(this);
20980 result.set_end();
20981 return result;
20982 }
20983
21007 reverse_iterator rbegin() noexcept
21008 {
21009 return reverse_iterator(end());
21010 }
21011
21015 const_reverse_iterator rbegin() const noexcept
21016 {
21017 return crbegin();
21018 }
21019
21044 reverse_iterator rend() noexcept
21045 {
21046 return reverse_iterator(begin());
21047 }
21048
21052 const_reverse_iterator rend() const noexcept
21053 {
21054 return crend();
21055 }
21056
21081 const_reverse_iterator crbegin() const noexcept
21082 {
21083 return const_reverse_iterator(cend());
21084 }
21085
21110 const_reverse_iterator crend() const noexcept
21111 {
21112 return const_reverse_iterator(cbegin());
21113 }
21114
21115 public:
21173 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21174 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
21175 {
21176 return ref.items();
21177 }
21178
21182 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21183 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
21184 {
21185 return ref.items();
21186 }
21187
21256 iteration_proxy<iterator> items() noexcept
21257 {
21258 return iteration_proxy<iterator>(*this);
21259 }
21260
21264 iteration_proxy<const_iterator> items() const noexcept
21265 {
21266 return iteration_proxy<const_iterator>(*this);
21267 }
21268
21270
21271
21273 // capacity //
21275
21278
21321 bool empty() const noexcept
21322 {
21323 switch (m_type)
21324 {
21325 case value_t::null:
21326 {
21327 // null values are empty
21328 return true;
21329 }
21330
21331 case value_t::array:
21332 {
21333 // delegate call to array_t::empty()
21334 return m_value.array->empty();
21335 }
21336
21337 case value_t::object:
21338 {
21339 // delegate call to object_t::empty()
21340 return m_value.object->empty();
21341 }
21342
21343 default:
21344 {
21345 // all other types are nonempty
21346 return false;
21347 }
21348 }
21349 }
21350
21394 size_type size() const noexcept
21395 {
21396 switch (m_type)
21397 {
21398 case value_t::null:
21399 {
21400 // null values are empty
21401 return 0;
21402 }
21403
21404 case value_t::array:
21405 {
21406 // delegate call to array_t::size()
21407 return m_value.array->size();
21408 }
21409
21410 case value_t::object:
21411 {
21412 // delegate call to object_t::size()
21413 return m_value.object->size();
21414 }
21415
21416 default:
21417 {
21418 // all other types have size 1
21419 return 1;
21420 }
21421 }
21422 }
21423
21465 size_type max_size() const noexcept
21466 {
21467 switch (m_type)
21468 {
21469 case value_t::array:
21470 {
21471 // delegate call to array_t::max_size()
21472 return m_value.array->max_size();
21473 }
21474
21475 case value_t::object:
21476 {
21477 // delegate call to object_t::max_size()
21478 return m_value.object->max_size();
21479 }
21480
21481 default:
21482 {
21483 // all other types have max_size() == size()
21484 return size();
21485 }
21486 }
21487 }
21488
21490
21491
21493 // modifiers //
21495
21498
21536 void clear() noexcept
21537 {
21538 switch (m_type)
21539 {
21540 case value_t::number_integer:
21541 {
21542 m_value.number_integer = 0;
21543 break;
21544 }
21545
21546 case value_t::number_unsigned:
21547 {
21548 m_value.number_unsigned = 0;
21549 break;
21550 }
21551
21552 case value_t::number_float:
21553 {
21554 m_value.number_float = 0.0;
21555 break;
21556 }
21557
21558 case value_t::boolean:
21559 {
21560 m_value.boolean = false;
21561 break;
21562 }
21563
21564 case value_t::string:
21565 {
21566 m_value.string->clear();
21567 break;
21568 }
21569
21570 case value_t::binary:
21571 {
21572 m_value.binary->clear();
21573 break;
21574 }
21575
21576 case value_t::array:
21577 {
21578 m_value.array->clear();
21579 break;
21580 }
21581
21582 case value_t::object:
21583 {
21584 m_value.object->clear();
21585 break;
21586 }
21587
21588 default:
21589 break;
21590 }
21591 }
21592
21613 void push_back(basic_json&& val)
21614 {
21615 // push_back only works for null objects or arrays
21616 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21617 {
21618 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21619 }
21620
21621 // transform null object into an array
21622 if (is_null())
21623 {
21624 m_type = value_t::array;
21625 m_value = value_t::array;
21626 assert_invariant();
21627 }
21628
21629 // add element to array (move semantics)
21630 m_value.array->push_back(std::move(val));
21631 // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
21632 }
21633
21638 reference operator+=(basic_json&& val)
21639 {
21640 push_back(std::move(val));
21641 return *this;
21642 }
21643
21648 void push_back(const basic_json& val)
21649 {
21650 // push_back only works for null objects or arrays
21651 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21652 {
21653 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21654 }
21655
21656 // transform null object into an array
21657 if (is_null())
21658 {
21659 m_type = value_t::array;
21660 m_value = value_t::array;
21661 assert_invariant();
21662 }
21663
21664 // add element to array
21665 m_value.array->push_back(val);
21666 }
21667
21672 reference operator+=(const basic_json& val)
21673 {
21674 push_back(val);
21675 return *this;
21676 }
21677
21698 void push_back(const typename object_t::value_type& val)
21699 {
21700 // push_back only works for null objects or objects
21701 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21702 {
21703 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21704 }
21705
21706 // transform null object into an object
21707 if (is_null())
21708 {
21709 m_type = value_t::object;
21710 m_value = value_t::object;
21711 assert_invariant();
21712 }
21713
21714 // add element to array
21715 m_value.object->insert(val);
21716 }
21717
21722 reference operator+=(const typename object_t::value_type& val)
21723 {
21724 push_back(val);
21725 return *this;
21726 }
21727
21753 void push_back(initializer_list_t init)
21754 {
21755 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
21756 {
21757 basic_json&& key = init.begin()->moved_or_copied();
21758 push_back(typename object_t::value_type(
21759 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
21760 }
21761 else
21762 {
21763 push_back(basic_json(init));
21764 }
21765 }
21766
21771 reference operator+=(initializer_list_t init)
21772 {
21773 push_back(init);
21774 return *this;
21775 }
21776
21800 template<class... Args>
21801 reference emplace_back(Args&& ... args)
21802 {
21803 // emplace_back only works for null objects or arrays
21804 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21805 {
21806 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
21807 }
21808
21809 // transform null object into an array
21810 if (is_null())
21811 {
21812 m_type = value_t::array;
21813 m_value = value_t::array;
21814 assert_invariant();
21815 }
21816
21817 // add element to array (perfect forwarding)
21818 #ifdef JSON_HAS_CPP_17
21819 return m_value.array->emplace_back(std::forward<Args>(args)...);
21820 #else
21821 m_value.array->emplace_back(std::forward<Args>(args)...);
21822 return m_value.array->back();
21823 #endif
21824 }
21825
21853 template<class... Args>
21854 std::pair<iterator, bool> emplace(Args&& ... args)
21855 {
21856 // emplace only works for null objects or arrays
21857 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21858 {
21859 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
21860 }
21861
21862 // transform null object into an object
21863 if (is_null())
21864 {
21865 m_type = value_t::object;
21866 m_value = value_t::object;
21867 assert_invariant();
21868 }
21869
21870 // add element to array (perfect forwarding)
21871 auto res = m_value.object->emplace(std::forward<Args>(args)...);
21872 // create result iterator and set iterator to the result of emplace
21873 auto it = begin();
21874 it.m_it.object_iterator = res.first;
21875
21876 // return pair of iterator and boolean
21877 return {it, res.second};
21878 }
21879
21883 template<typename... Args>
21884 iterator insert_iterator(const_iterator pos, Args&& ... args)
21885 {
21886 iterator result(this);
21887 JSON_ASSERT(m_value.array != nullptr);
21888
21889 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
21890 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
21891 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
21892
21893 // This could have been written as:
21894 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
21895 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
21896
21897 return result;
21898 }
21899
21922 iterator insert(const_iterator pos, const basic_json& val)
21923 {
21924 // insert only works for arrays
21925 if (JSON_HEDLEY_LIKELY(is_array()))
21926 {
21927 // check if iterator pos fits to this JSON value
21928 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21929 {
21930 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
21931 }
21932
21933 // insert to array and return iterator
21934 return insert_iterator(pos, val);
21935 }
21936
21937 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
21938 }
21939
21944 iterator insert(const_iterator pos, basic_json&& val)
21945 {
21946 return insert(pos, val);
21947 }
21948
21973 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
21974 {
21975 // insert only works for arrays
21976 if (JSON_HEDLEY_LIKELY(is_array()))
21977 {
21978 // check if iterator pos fits to this JSON value
21979 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21980 {
21981 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
21982 }
21983
21984 // insert to array and return iterator
21985 return insert_iterator(pos, cnt, val);
21986 }
21987
21988 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
21989 }
21990
22021 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
22022 {
22023 // insert only works for arrays
22024 if (JSON_HEDLEY_UNLIKELY(!is_array()))
22025 {
22026 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22027 }
22028
22029 // check if iterator pos fits to this JSON value
22030 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22031 {
22032 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22033 }
22034
22035 // check if range iterators belong to the same JSON object
22036 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22037 {
22038 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22039 }
22040
22041 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
22042 {
22043 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
22044 }
22045
22046 // insert to array and return iterator
22047 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
22048 }
22049
22074 iterator insert(const_iterator pos, initializer_list_t ilist)
22075 {
22076 // insert only works for arrays
22077 if (JSON_HEDLEY_UNLIKELY(!is_array()))
22078 {
22079 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22080 }
22081
22082 // check if iterator pos fits to this JSON value
22083 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22084 {
22085 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22086 }
22087
22088 // insert to array and return iterator
22089 return insert_iterator(pos, ilist.begin(), ilist.end());
22090 }
22091
22115 void insert(const_iterator first, const_iterator last)
22116 {
22117 // insert only works for objects
22118 if (JSON_HEDLEY_UNLIKELY(!is_object()))
22119 {
22120 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22121 }
22122
22123 // check if range iterators belong to the same JSON object
22124 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22125 {
22126 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22127 }
22128
22129 // passed iterators must belong to objects
22130 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22131 {
22132 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
22133 }
22134
22135 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
22136 }
22137
22157 void update(const_reference j)
22158 {
22159 // implicitly convert null value to an empty object
22160 if (is_null())
22161 {
22162 m_type = value_t::object;
22163 m_value.object = create<object_t>();
22164 assert_invariant();
22165 }
22166
22167 if (JSON_HEDLEY_UNLIKELY(!is_object()))
22168 {
22169 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
22170 }
22171 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
22172 {
22173 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
22174 }
22175
22176 for (auto it = j.cbegin(); it != j.cend(); ++it)
22177 {
22178 m_value.object->operator[](it.key()) = it.value();
22179 }
22180 }
22181
22208 void update(const_iterator first, const_iterator last)
22209 {
22210 // implicitly convert null value to an empty object
22211 if (is_null())
22212 {
22213 m_type = value_t::object;
22214 m_value.object = create<object_t>();
22215 assert_invariant();
22216 }
22217
22218 if (JSON_HEDLEY_UNLIKELY(!is_object()))
22219 {
22220 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
22221 }
22222
22223 // check if range iterators belong to the same JSON object
22224 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22225 {
22226 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22227 }
22228
22229 // passed iterators must belong to objects
22230 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
22231 || !last.m_object->is_object()))
22232 {
22233 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
22234 }
22235
22236 for (auto it = first; it != last; ++it)
22237 {
22238 m_value.object->operator[](it.key()) = it.value();
22239 }
22240 }
22241
22259 void swap(reference other) noexcept (
22260 std::is_nothrow_move_constructible<value_t>::value&&
22261 std::is_nothrow_move_assignable<value_t>::value&&
22262 std::is_nothrow_move_constructible<json_value>::value&&
22263 std::is_nothrow_move_assignable<json_value>::value
22264 )
22265 {
22266 std::swap(m_type, other.m_type);
22267 std::swap(m_value, other.m_value);
22268 assert_invariant();
22269 }
22270
22289 friend void swap(reference left, reference right) noexcept (
22290 std::is_nothrow_move_constructible<value_t>::value&&
22291 std::is_nothrow_move_assignable<value_t>::value&&
22292 std::is_nothrow_move_constructible<json_value>::value&&
22293 std::is_nothrow_move_assignable<json_value>::value
22294 )
22295 {
22296 left.swap(right);
22297 }
22298
22319 void swap(array_t& other)
22320 {
22321 // swap only works for arrays
22322 if (JSON_HEDLEY_LIKELY(is_array()))
22323 {
22324 std::swap(*(m_value.array), other);
22325 }
22326 else
22327 {
22328 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22329 }
22330 }
22331
22352 void swap(object_t& other)
22353 {
22354 // swap only works for objects
22355 if (JSON_HEDLEY_LIKELY(is_object()))
22356 {
22357 std::swap(*(m_value.object), other);
22358 }
22359 else
22360 {
22361 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22362 }
22363 }
22364
22385 void swap(string_t& other)
22386 {
22387 // swap only works for strings
22388 if (JSON_HEDLEY_LIKELY(is_string()))
22389 {
22390 std::swap(*(m_value.string), other);
22391 }
22392 else
22393 {
22394 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22395 }
22396 }
22397
22418 void swap(binary_t& other)
22419 {
22420 // swap only works for strings
22421 if (JSON_HEDLEY_LIKELY(is_binary()))
22422 {
22423 std::swap(*(m_value.binary), other);
22424 }
22425 else
22426 {
22427 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22428 }
22429 }
22430
22432 void swap(typename binary_t::container_type& other)
22433 {
22434 // swap only works for strings
22435 if (JSON_HEDLEY_LIKELY(is_binary()))
22436 {
22437 std::swap(*(m_value.binary), other);
22438 }
22439 else
22440 {
22441 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22442 }
22443 }
22444
22446
22447 public:
22449 // lexicographical comparison operators //
22451
22454
22510 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
22511 {
22512 const auto lhs_type = lhs.type();
22513 const auto rhs_type = rhs.type();
22514
22515 if (lhs_type == rhs_type)
22516 {
22517 switch (lhs_type)
22518 {
22519 case value_t::array:
22520 return *lhs.m_value.array == *rhs.m_value.array;
22521
22522 case value_t::object:
22523 return *lhs.m_value.object == *rhs.m_value.object;
22524
22525 case value_t::null:
22526 return true;
22527
22528 case value_t::string:
22529 return *lhs.m_value.string == *rhs.m_value.string;
22530
22531 case value_t::boolean:
22532 return lhs.m_value.boolean == rhs.m_value.boolean;
22533
22534 case value_t::number_integer:
22535 return lhs.m_value.number_integer == rhs.m_value.number_integer;
22536
22537 case value_t::number_unsigned:
22538 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
22539
22540 case value_t::number_float:
22541 return lhs.m_value.number_float == rhs.m_value.number_float;
22542
22543 case value_t::binary:
22544 return *lhs.m_value.binary == *rhs.m_value.binary;
22545
22546 default:
22547 return false;
22548 }
22549 }
22550 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
22551 {
22552 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
22553 }
22554 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
22555 {
22556 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
22557 }
22558 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
22559 {
22560 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
22561 }
22562 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
22563 {
22564 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
22565 }
22566 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
22567 {
22568 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
22569 }
22570 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
22571 {
22572 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22573 }
22574
22575 return false;
22576 }
22577
22582 template<typename ScalarType, typename std::enable_if<
22583 std::is_scalar<ScalarType>::value, int>::type = 0>
22584 friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
22585 {
22586 return lhs == basic_json(rhs);
22587 }
22588
22593 template<typename ScalarType, typename std::enable_if<
22594 std::is_scalar<ScalarType>::value, int>::type = 0>
22595 friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
22596 {
22597 return basic_json(lhs) == rhs;
22598 }
22599
22618 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
22619 {
22620 return !(lhs == rhs);
22621 }
22622
22627 template<typename ScalarType, typename std::enable_if<
22628 std::is_scalar<ScalarType>::value, int>::type = 0>
22629 friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
22630 {
22631 return lhs != basic_json(rhs);
22632 }
22633
22638 template<typename ScalarType, typename std::enable_if<
22639 std::is_scalar<ScalarType>::value, int>::type = 0>
22640 friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
22641 {
22642 return basic_json(lhs) != rhs;
22643 }
22644
22671 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
22672 {
22673 const auto lhs_type = lhs.type();
22674 const auto rhs_type = rhs.type();
22675
22676 if (lhs_type == rhs_type)
22677 {
22678 switch (lhs_type)
22679 {
22680 case value_t::array:
22681 // note parentheses are necessary, see
22682 // https://github.com/nlohmann/json/issues/1530
22683 return (*lhs.m_value.array) < (*rhs.m_value.array);
22684
22685 case value_t::object:
22686 return (*lhs.m_value.object) < (*rhs.m_value.object);
22687
22688 case value_t::null:
22689 return false;
22690
22691 case value_t::string:
22692 return (*lhs.m_value.string) < (*rhs.m_value.string);
22693
22694 case value_t::boolean:
22695 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
22696
22697 case value_t::number_integer:
22698 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
22699
22700 case value_t::number_unsigned:
22701 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
22702
22703 case value_t::number_float:
22704 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
22705
22706 case value_t::binary:
22707 return (*lhs.m_value.binary) < (*rhs.m_value.binary);
22708
22709 default:
22710 return false;
22711 }
22712 }
22713 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
22714 {
22715 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
22716 }
22717 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
22718 {
22719 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
22720 }
22721 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
22722 {
22723 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
22724 }
22725 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
22726 {
22727 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
22728 }
22729 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
22730 {
22731 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22732 }
22733 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
22734 {
22735 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
22736 }
22737
22738 // We only reach this line if we cannot compare values. In that case,
22739 // we compare types. Note we have to call the operator explicitly,
22740 // because MSVC has problems otherwise.
22741 return operator<(lhs_type, rhs_type);
22742 }
22743
22748 template<typename ScalarType, typename std::enable_if<
22749 std::is_scalar<ScalarType>::value, int>::type = 0>
22750 friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
22751 {
22752 return lhs < basic_json(rhs);
22753 }
22754
22759 template<typename ScalarType, typename std::enable_if<
22760 std::is_scalar<ScalarType>::value, int>::type = 0>
22761 friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
22762 {
22763 return basic_json(lhs) < rhs;
22764 }
22765
22785 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
22786 {
22787 return !(rhs < lhs);
22788 }
22789
22794 template<typename ScalarType, typename std::enable_if<
22795 std::is_scalar<ScalarType>::value, int>::type = 0>
22796 friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
22797 {
22798 return lhs <= basic_json(rhs);
22799 }
22800
22805 template<typename ScalarType, typename std::enable_if<
22806 std::is_scalar<ScalarType>::value, int>::type = 0>
22807 friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
22808 {
22809 return basic_json(lhs) <= rhs;
22810 }
22811
22831 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
22832 {
22833 return !(lhs <= rhs);
22834 }
22835
22840 template<typename ScalarType, typename std::enable_if<
22841 std::is_scalar<ScalarType>::value, int>::type = 0>
22842 friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
22843 {
22844 return lhs > basic_json(rhs);
22845 }
22846
22851 template<typename ScalarType, typename std::enable_if<
22852 std::is_scalar<ScalarType>::value, int>::type = 0>
22853 friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
22854 {
22855 return basic_json(lhs) > rhs;
22856 }
22857
22877 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
22878 {
22879 return !(lhs < rhs);
22880 }
22881
22886 template<typename ScalarType, typename std::enable_if<
22887 std::is_scalar<ScalarType>::value, int>::type = 0>
22888 friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
22889 {
22890 return lhs >= basic_json(rhs);
22891 }
22892
22897 template<typename ScalarType, typename std::enable_if<
22898 std::is_scalar<ScalarType>::value, int>::type = 0>
22899 friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
22900 {
22901 return basic_json(lhs) >= rhs;
22902 }
22903
22905
22907 // serialization //
22909
22912
22944 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
22945 {
22946 // read width member and use it as indentation parameter if nonzero
22947 const bool pretty_print = o.width() > 0;
22948 const auto indentation = pretty_print ? o.width() : 0;
22949
22950 // reset width to 0 for subsequent calls to this stream
22951 o.width(0);
22952
22953 // do the actual serialization
22954 serializer s(detail::output_adapter<char>(o), o.fill());
22955 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
22956 return o;
22957 }
22958
22967 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
22968 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
22969 {
22970 return o << j;
22971 }
22972
22974
22975
22977 // deserialization //
22979
22982
23034 template<typename InputType>
23035
23036 static basic_json parse(InputType&& i,
23037 const parser_callback_t cb = nullptr,
23038 const bool allow_exceptions = true,
23039 const bool ignore_comments = false)
23040 {
23041 basic_json result;
23042 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
23043 return result;
23044 }
23045
23072 template<typename IteratorType>
23073
23074 static basic_json parse(IteratorType first,
23075 IteratorType last,
23076 const parser_callback_t cb = nullptr,
23077 const bool allow_exceptions = true,
23078 const bool ignore_comments = false)
23079 {
23080 basic_json result;
23081 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
23082 return result;
23083 }
23084
23085
23086 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
23087 static basic_json parse(detail::span_input_adapter&& i,
23088 const parser_callback_t cb = nullptr,
23089 const bool allow_exceptions = true,
23090 const bool ignore_comments = false)
23091 {
23092 basic_json result;
23093 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
23094 return result;
23095 }
23096
23127 template<typename InputType>
23128 static bool accept(InputType&& i,
23129 const bool ignore_comments = false)
23130 {
23131 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
23132 }
23133
23134 template<typename IteratorType>
23135 static bool accept(IteratorType first, IteratorType last,
23136 const bool ignore_comments = false)
23137 {
23138 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
23139 }
23140
23141
23142 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
23143 static bool accept(detail::span_input_adapter&& i,
23144 const bool ignore_comments = false)
23145 {
23146 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
23147 }
23148
23189 template <typename InputType, typename SAX>
23190 JSON_HEDLEY_NON_NULL(2)
23191 static bool sax_parse(InputType&& i, SAX* sax,
23192 input_format_t format = input_format_t::json,
23193 const bool strict = true,
23194 const bool ignore_comments = false)
23195 {
23196 auto ia = detail::input_adapter(std::forward<InputType>(i));
23197 return format == input_format_t::json
23198 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23199 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23200 }
23201
23202 template<class IteratorType, class SAX>
23203 JSON_HEDLEY_NON_NULL(3)
23204 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
23205 input_format_t format = input_format_t::json,
23206 const bool strict = true,
23207 const bool ignore_comments = false)
23208 {
23209 auto ia = detail::input_adapter(std::move(first), std::move(last));
23210 return format == input_format_t::json
23211 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23212 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23213 }
23214
23215 template <typename SAX>
23216 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
23217 JSON_HEDLEY_NON_NULL(2)
23218 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
23219 input_format_t format = input_format_t::json,
23220 const bool strict = true,
23221 const bool ignore_comments = false)
23222 {
23223 auto ia = i.get();
23224 return format == input_format_t::json
23225 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23226 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23227 }
23228
23237 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
23238 friend std::istream& operator<<(basic_json& j, std::istream& i)
23239 {
23240 return operator>>(i, j);
23241 }
23242
23268 friend std::istream& operator>>(std::istream& i, basic_json& j)
23269 {
23270 parser(detail::input_adapter(i)).parse(false, j);
23271 return i;
23272 }
23273
23275
23277 // convenience functions //
23279
23311
23312 const char* type_name() const noexcept
23313 {
23314 {
23315 switch (m_type)
23316 {
23317 case value_t::null:
23318 return "null";
23319 case value_t::object:
23320 return "object";
23321 case value_t::array:
23322 return "array";
23323 case value_t::string:
23324 return "string";
23325 case value_t::boolean:
23326 return "boolean";
23327 case value_t::binary:
23328 return "binary";
23329 case value_t::discarded:
23330 return "discarded";
23331 default:
23332 return "number";
23333 }
23334 }
23335 }
23336
23337
23338 private:
23340 // member variables //
23342
23344 value_t m_type = value_t::null;
23345
23347 json_value m_value = {};
23348
23350 // binary serialization/deserialization //
23352
23355
23356 public:
23451 static std::vector<uint8_t> to_cbor(const basic_json& j)
23452 {
23453 std::vector<uint8_t> result;
23454 to_cbor(j, result);
23455 return result;
23456 }
23457
23458 static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
23459 {
23460 binary_writer<uint8_t>(o).write_cbor(j);
23461 }
23462
23463 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
23464 {
23465 binary_writer<char>(o).write_cbor(j);
23466 }
23467
23546 static std::vector<uint8_t> to_msgpack(const basic_json& j)
23547 {
23548 std::vector<uint8_t> result;
23549 to_msgpack(j, result);
23550 return result;
23551 }
23552
23553 static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
23554 {
23555 binary_writer<uint8_t>(o).write_msgpack(j);
23556 }
23557
23558 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
23559 {
23560 binary_writer<char>(o).write_msgpack(j);
23561 }
23562
23649 static std::vector<uint8_t> to_ubjson(const basic_json& j,
23650 const bool use_size = false,
23651 const bool use_type = false)
23652 {
23653 std::vector<uint8_t> result;
23654 to_ubjson(j, result, use_size, use_type);
23655 return result;
23656 }
23657
23658 static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
23659 const bool use_size = false, const bool use_type = false)
23660 {
23661 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
23662 }
23663
23664 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
23665 const bool use_size = false, const bool use_type = false)
23666 {
23667 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23668 }
23669
23670
23727 static std::vector<uint8_t> to_bson(const basic_json& j)
23728 {
23729 std::vector<uint8_t> result;
23730 to_bson(j, result);
23731 return result;
23732 }
23733
23742 static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
23743 {
23744 binary_writer<uint8_t>(o).write_bson(j);
23745 }
23746
23750 static void to_bson(const basic_json& j, detail::output_adapter<char> o)
23751 {
23752 binary_writer<char>(o).write_bson(j);
23753 }
23754
23755
23858 template<typename InputType>
23859
23860 static basic_json from_cbor(InputType&& i,
23861 const bool strict = true,
23862 const bool allow_exceptions = true,
23863 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23864 {
23865 basic_json result;
23866 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23867 auto ia = detail::input_adapter(std::forward<InputType>(i));
23868 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23869 return res ? result : basic_json(value_t::discarded);
23870 }
23871
23875 template<typename IteratorType>
23876
23877 static basic_json from_cbor(IteratorType first, IteratorType last,
23878 const bool strict = true,
23879 const bool allow_exceptions = true,
23880 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23881 {
23882 basic_json result;
23883 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23884 auto ia = detail::input_adapter(std::move(first), std::move(last));
23885 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23886 return res ? result : basic_json(value_t::discarded);
23887 }
23888
23889 template<typename T>
23890
23891 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23892 static basic_json from_cbor(const T* ptr, std::size_t len,
23893 const bool strict = true,
23894 const bool allow_exceptions = true,
23895 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23896 {
23897 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
23898 }
23899
23900
23901
23902 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23903 static basic_json from_cbor(detail::span_input_adapter&& i,
23904 const bool strict = true,
23905 const bool allow_exceptions = true,
23906 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23907 {
23908 basic_json result;
23909 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23910 auto ia = i.get();
23911 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23912 return res ? result : basic_json(value_t::discarded);
23913 }
23914
24001 template<typename InputType>
24002
24003 static basic_json from_msgpack(InputType&& i,
24004 const bool strict = true,
24005 const bool allow_exceptions = true)
24006 {
24007 basic_json result;
24008 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24009 auto ia = detail::input_adapter(std::forward<InputType>(i));
24010 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24011 return res ? result : basic_json(value_t::discarded);
24012 }
24013
24017 template<typename IteratorType>
24018
24019 static basic_json from_msgpack(IteratorType first, IteratorType last,
24020 const bool strict = true,
24021 const bool allow_exceptions = true)
24022 {
24023 basic_json result;
24024 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24025 auto ia = detail::input_adapter(std::move(first), std::move(last));
24026 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24027 return res ? result : basic_json(value_t::discarded);
24028 }
24029
24030
24031 template<typename T>
24032
24033 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
24034 static basic_json from_msgpack(const T* ptr, std::size_t len,
24035 const bool strict = true,
24036 const bool allow_exceptions = true)
24037 {
24038 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
24039 }
24040
24041
24042 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
24043 static basic_json from_msgpack(detail::span_input_adapter&& i,
24044 const bool strict = true,
24045 const bool allow_exceptions = true)
24046 {
24047 basic_json result;
24048 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24049 auto ia = i.get();
24050 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24051 return res ? result : basic_json(value_t::discarded);
24052 }
24053
24054
24117 template<typename InputType>
24118
24119 static basic_json from_ubjson(InputType&& i,
24120 const bool strict = true,
24121 const bool allow_exceptions = true)
24122 {
24123 basic_json result;
24124 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24125 auto ia = detail::input_adapter(std::forward<InputType>(i));
24126 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24127 return res ? result : basic_json(value_t::discarded);
24128 }
24129
24133 template<typename IteratorType>
24134
24135 static basic_json from_ubjson(IteratorType first, IteratorType last,
24136 const bool strict = true,
24137 const bool allow_exceptions = true)
24138 {
24139 basic_json result;
24140 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24141 auto ia = detail::input_adapter(std::move(first), std::move(last));
24142 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24143 return res ? result : basic_json(value_t::discarded);
24144 }
24145
24146 template<typename T>
24147
24148 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
24149 static basic_json from_ubjson(const T* ptr, std::size_t len,
24150 const bool strict = true,
24151 const bool allow_exceptions = true)
24152 {
24153 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
24154 }
24155
24156
24157 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
24158 static basic_json from_ubjson(detail::span_input_adapter&& i,
24159 const bool strict = true,
24160 const bool allow_exceptions = true)
24161 {
24162 basic_json result;
24163 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24164 auto ia = i.get();
24165 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24166 return res ? result : basic_json(value_t::discarded);
24167 }
24168
24169
24230 template<typename InputType>
24231
24232 static basic_json from_bson(InputType&& i,
24233 const bool strict = true,
24234 const bool allow_exceptions = true)
24235 {
24236 basic_json result;
24237 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24238 auto ia = detail::input_adapter(std::forward<InputType>(i));
24239 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24240 return res ? result : basic_json(value_t::discarded);
24241 }
24242
24246 template<typename IteratorType>
24247
24248 static basic_json from_bson(IteratorType first, IteratorType last,
24249 const bool strict = true,
24250 const bool allow_exceptions = true)
24251 {
24252 basic_json result;
24253 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24254 auto ia = detail::input_adapter(std::move(first), std::move(last));
24255 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24256 return res ? result : basic_json(value_t::discarded);
24257 }
24258
24259 template<typename T>
24260
24261 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
24262 static basic_json from_bson(const T* ptr, std::size_t len,
24263 const bool strict = true,
24264 const bool allow_exceptions = true)
24265 {
24266 return from_bson(ptr, ptr + len, strict, allow_exceptions);
24267 }
24268
24269
24270 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
24271 static basic_json from_bson(detail::span_input_adapter&& i,
24272 const bool strict = true,
24273 const bool allow_exceptions = true)
24274 {
24275 basic_json result;
24276 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24277 auto ia = i.get();
24278 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24279 return res ? result : basic_json(value_t::discarded);
24280 }
24282
24284 // JSON Pointer support //
24286
24289
24323 reference operator[](const json_pointer& ptr)
24324 {
24325 return ptr.get_unchecked(this);
24326 }
24327
24351 const_reference operator[](const json_pointer& ptr) const
24352 {
24353 return ptr.get_unchecked(this);
24354 }
24355
24394 reference at(const json_pointer& ptr)
24395 {
24396 return ptr.get_checked(this);
24397 }
24398
24437 const_reference at(const json_pointer& ptr) const
24438 {
24439 return ptr.get_checked(this);
24440 }
24441
24464 basic_json flatten() const
24465 {
24466 basic_json result(value_t::object);
24467 json_pointer::flatten("", *this, result);
24468 return result;
24469 }
24470
24501 basic_json unflatten() const
24502 {
24503 return json_pointer::unflatten(*this);
24504 }
24505
24507
24509 // JSON Patch functions //
24511
24514
24562 basic_json patch(const basic_json& json_patch) const
24563 {
24564 // make a working copy to apply the patch to
24565 basic_json result = *this;
24566
24567 // the valid JSON Patch operations
24568 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
24569
24570 const auto get_op = [](const std::string & op)
24571 {
24572 if (op == "add")
24573 {
24574 return patch_operations::add;
24575 }
24576 if (op == "remove")
24577 {
24578 return patch_operations::remove;
24579 }
24580 if (op == "replace")
24581 {
24582 return patch_operations::replace;
24583 }
24584 if (op == "move")
24585 {
24586 return patch_operations::move;
24587 }
24588 if (op == "copy")
24589 {
24590 return patch_operations::copy;
24591 }
24592 if (op == "test")
24593 {
24594 return patch_operations::test;
24595 }
24596
24597 return patch_operations::invalid;
24598 };
24599
24600 // wrapper for "add" operation; add value at ptr
24601 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
24602 {
24603 // adding to the root of the target document means replacing it
24604 if (ptr.empty())
24605 {
24606 result = val;
24607 return;
24608 }
24609
24610 // make sure the top element of the pointer exists
24611 json_pointer top_pointer = ptr.top();
24612 if (top_pointer != ptr)
24613 {
24614 result.at(top_pointer);
24615 }
24616
24617 // get reference to parent of JSON pointer ptr
24618 const auto last_path = ptr.back();
24619 ptr.pop_back();
24620 basic_json& parent = result[ptr];
24621
24622 switch (parent.m_type)
24623 {
24624 case value_t::null:
24625 case value_t::object:
24626 {
24627 // use operator[] to add value
24628 parent[last_path] = val;
24629 break;
24630 }
24631
24632 case value_t::array:
24633 {
24634 if (last_path == "-")
24635 {
24636 // special case: append to back
24637 parent.push_back(val);
24638 }
24639 else
24640 {
24641 const auto idx = json_pointer::array_index(last_path);
24642 if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
24643 {
24644 // avoid undefined behavior
24645 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
24646 }
24647
24648 // default case: insert add offset
24649 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
24650 }
24651 break;
24652 }
24653
24654 // if there exists a parent it cannot be primitive
24655 default: // LCOV_EXCL_LINE
24656 JSON_ASSERT(false); // LCOV_EXCL_LINE
24657 }
24658 };
24659
24660 // wrapper for "remove" operation; remove value at ptr
24661 const auto operation_remove = [&result](json_pointer & ptr)
24662 {
24663 // get reference to parent of JSON pointer ptr
24664 const auto last_path = ptr.back();
24665 ptr.pop_back();
24666 basic_json& parent = result.at(ptr);
24667
24668 // remove child
24669 if (parent.is_object())
24670 {
24671 // perform range check
24672 auto it = parent.find(last_path);
24673 if (JSON_HEDLEY_LIKELY(it != parent.end()))
24674 {
24675 parent.erase(it);
24676 }
24677 else
24678 {
24679 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
24680 }
24681 }
24682 else if (parent.is_array())
24683 {
24684 // note erase performs range check
24685 parent.erase(json_pointer::array_index(last_path));
24686 }
24687 };
24688
24689 // type check: top level value must be an array
24690 if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
24691 {
24692 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24693 }
24694
24695 // iterate and apply the operations
24696 for (const auto& val : json_patch)
24697 {
24698 // wrapper to get a value for an operation
24699 const auto get_value = [&val](const std::string & op,
24700 const std::string & member,
24701 bool string_type) -> basic_json &
24702 {
24703 // find value
24704 auto it = val.m_value.object->find(member);
24705
24706 // context-sensitive error message
24707 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
24708
24709 // check if desired value is present
24710 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
24711 {
24712 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
24713 }
24714
24715 // check if result is of type string
24716 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
24717 {
24718 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
24719 }
24720
24721 // no error: return value
24722 return it->second;
24723 };
24724
24725 // type check: every element of the array must be an object
24726 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
24727 {
24728 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24729 }
24730
24731 // collect mandatory members
24732 const auto op = get_value("op", "op", true).template get<std::string>();
24733 const auto path = get_value(op, "path", true).template get<std::string>();
24734 json_pointer ptr(path);
24735
24736 switch (get_op(op))
24737 {
24738 case patch_operations::add:
24739 {
24740 operation_add(ptr, get_value("add", "value", false));
24741 break;
24742 }
24743
24744 case patch_operations::remove:
24745 {
24746 operation_remove(ptr);
24747 break;
24748 }
24749
24750 case patch_operations::replace:
24751 {
24752 // the "path" location must exist - use at()
24753 result.at(ptr) = get_value("replace", "value", false);
24754 break;
24755 }
24756
24757 case patch_operations::move:
24758 {
24759 const auto from_path = get_value("move", "from", true).template get<std::string>();
24760 json_pointer from_ptr(from_path);
24761
24762 // the "from" location must exist - use at()
24763 basic_json v = result.at(from_ptr);
24764
24765 // The move operation is functionally identical to a
24766 // "remove" operation on the "from" location, followed
24767 // immediately by an "add" operation at the target
24768 // location with the value that was just removed.
24769 operation_remove(from_ptr);
24770 operation_add(ptr, v);
24771 break;
24772 }
24773
24774 case patch_operations::copy:
24775 {
24776 const auto from_path = get_value("copy", "from", true).template get<std::string>();
24777 const json_pointer from_ptr(from_path);
24778
24779 // the "from" location must exist - use at()
24780 basic_json v = result.at(from_ptr);
24781
24782 // The copy is functionally identical to an "add"
24783 // operation at the target location using the value
24784 // specified in the "from" member.
24785 operation_add(ptr, v);
24786 break;
24787 }
24788
24789 case patch_operations::test:
24790 {
24791 bool success = false;
24792 JSON_TRY
24793 {
24794 // check if "value" matches the one at "path"
24795 // the "path" location must exist - use at()
24796 success = (result.at(ptr) == get_value("test", "value", false));
24797 }
24798 JSON_INTERNAL_CATCH (out_of_range&)
24799 {
24800 // ignore out of range errors: success remains false
24801 }
24802
24803 // throw an exception if test fails
24804 if (JSON_HEDLEY_UNLIKELY(!success))
24805 {
24806 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
24807 }
24808
24809 break;
24810 }
24811
24812 default:
24813 {
24814 // op must be "add", "remove", "replace", "move", "copy", or
24815 // "test"
24816 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
24817 }
24818 }
24819 }
24820
24821 return result;
24822 }
24823
24857
24858 static basic_json diff(const basic_json& source, const basic_json& target,
24859 const std::string& path = "")
24860 {
24861 // the patch
24862 basic_json result(value_t::array);
24863
24864 // if the values are the same, return empty patch
24865 if (source == target)
24866 {
24867 return result;
24868 }
24869
24870 if (source.type() != target.type())
24871 {
24872 // different types: replace value
24873 result.push_back(
24874 {
24875 {"op", "replace"}, {"path", path}, {"value", target}
24876 });
24877 return result;
24878 }
24879
24880 switch (source.type())
24881 {
24882 case value_t::array:
24883 {
24884 // first pass: traverse common elements
24885 std::size_t i = 0;
24886 while (i < source.size() && i < target.size())
24887 {
24888 // recursive call to compare array values at index i
24889 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
24890 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24891 ++i;
24892 }
24893
24894 // i now reached the end of at least one array
24895 // in a second pass, traverse the remaining elements
24896
24897 // remove my remaining elements
24898 const auto end_index = static_cast<difference_type>(result.size());
24899 while (i < source.size())
24900 {
24901 // add operations in reverse order to avoid invalid
24902 // indices
24903 result.insert(result.begin() + end_index, object(
24904 {
24905 {"op", "remove"},
24906 {"path", path + "/" + std::to_string(i)}
24907 }));
24908 ++i;
24909 }
24910
24911 // add other remaining elements
24912 while (i < target.size())
24913 {
24914 result.push_back(
24915 {
24916 {"op", "add"},
24917 {"path", path + "/-"},
24918 {"value", target[i]}
24919 });
24920 ++i;
24921 }
24922
24923 break;
24924 }
24925
24926 case value_t::object:
24927 {
24928 // first pass: traverse this object's elements
24929 for (auto it = source.cbegin(); it != source.cend(); ++it)
24930 {
24931 // escape the key name to be used in a JSON patch
24932 const auto key = json_pointer::escape(it.key());
24933
24934 if (target.find(it.key()) != target.end())
24935 {
24936 // recursive call to compare object values at key it
24937 auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
24938 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24939 }
24940 else
24941 {
24942 // found a key that is not in o -> remove it
24943 result.push_back(object(
24944 {
24945 {"op", "remove"}, {"path", path + "/" + key}
24946 }));
24947 }
24948 }
24949
24950 // second pass: traverse other object's elements
24951 for (auto it = target.cbegin(); it != target.cend(); ++it)
24952 {
24953 if (source.find(it.key()) == source.end())
24954 {
24955 // found a key that is not in this -> add it
24956 const auto key = json_pointer::escape(it.key());
24957 result.push_back(
24958 {
24959 {"op", "add"}, {"path", path + "/" + key},
24960 {"value", it.value()}
24961 });
24962 }
24963 }
24964
24965 break;
24966 }
24967
24968 default:
24969 {
24970 // both primitive type: replace value
24971 result.push_back(
24972 {
24973 {"op", "replace"}, {"path", path}, {"value", target}
24974 });
24975 break;
24976 }
24977 }
24978
24979 return result;
24980 }
24981
24983
24985 // JSON Merge Patch functions //
24987
24990
25033 void merge_patch(const basic_json& apply_patch)
25034 {
25035 if (apply_patch.is_object())
25036 {
25037 if (!is_object())
25038 {
25039 *this = object();
25040 }
25041 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
25042 {
25043 if (it.value().is_null())
25044 {
25045 erase(it.key());
25046 }
25047 else
25048 {
25049 operator[](it.key()).merge_patch(it.value());
25050 }
25051 }
25052 }
25053 else
25054 {
25055 *this = apply_patch;
25056 }
25057 }
25058
25060 };
25061
25071 NLOHMANN_BASIC_JSON_TPL_DECLARATION
25072 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
25073 {
25074 return j.dump();
25075 }
25076 } // namespace nlohmann
25077
25079 // nonmember support //
25081
25082 // specialization of std::swap, and std::hash
25083 namespace std
25084 {
25085
25087 template<>
25088 struct hash<nlohmann::json>
25089 {
25095 std::size_t operator()(const nlohmann::json& j) const
25096 {
25097 return nlohmann::detail::hash(j);
25098 }
25099 };
25100
25104 template<>
25105 struct less<::nlohmann::detail::value_t>
25106 {
25111 bool operator()(nlohmann::detail::value_t lhs,
25112 nlohmann::detail::value_t rhs) const noexcept
25113 {
25114 return nlohmann::detail::operator<(lhs, rhs);
25115 }
25116 };
25117
25118 // C++20 prohibit function specialization in the std namespace.
25119 #ifndef JSON_HAS_CPP_20
25120
25126 template<>
25127 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
25128 is_nothrow_move_constructible<nlohmann::json>::value&&
25129 is_nothrow_move_assignable<nlohmann::json>::value
25130 )
25131 {
25132 j1.swap(j2);
25133 }
25134
25135 #endif
25136
25137 } // namespace std
25138
25152 JSON_HEDLEY_NON_NULL(1)
25153 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
25154 {
25155 return nlohmann::json::parse(s, s + n);
25156 }
25157
25171 JSON_HEDLEY_NON_NULL(1)
25172 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
25173 {
25174 return nlohmann::json::json_pointer(std::string(s, n));
25175 }
25176
25177 // #include <nlohmann/detail/macro_unscope.hpp>
25178
25179
25180 // restore GCC/clang diagnostic settings
25181 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
25182 #pragma GCC diagnostic pop
25183 #endif
25184 #if defined(__clang__)
25185 #pragma GCC diagnostic pop
25186 #endif
25187
25188 // clean up
25189 #undef JSON_ASSERT
25190 #undef JSON_INTERNAL_CATCH
25191 #undef JSON_CATCH
25192 #undef JSON_THROW
25193 #undef JSON_TRY
25194 #undef JSON_HAS_CPP_14
25195 #undef JSON_HAS_CPP_17
25196 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
25197 #undef NLOHMANN_BASIC_JSON_TPL
25198 #undef JSON_EXPLICIT
25199
25200 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
25201 #undef JSON_HEDLEY_ALWAYS_INLINE
25202 #undef JSON_HEDLEY_ARM_VERSION
25203 #undef JSON_HEDLEY_ARM_VERSION_CHECK
25204 #undef JSON_HEDLEY_ARRAY_PARAM
25205 #undef JSON_HEDLEY_ASSUME
25206 #undef JSON_HEDLEY_BEGIN_C_DECLS
25207 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
25208 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
25209 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
25210 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
25211 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
25212 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
25213 #undef JSON_HEDLEY_CLANG_HAS_WARNING
25214 #undef JSON_HEDLEY_COMPCERT_VERSION
25215 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
25216 #undef JSON_HEDLEY_CONCAT
25217 #undef JSON_HEDLEY_CONCAT3
25218 #undef JSON_HEDLEY_CONCAT3_EX
25219 #undef JSON_HEDLEY_CONCAT_EX
25220 #undef JSON_HEDLEY_CONST
25221 #undef JSON_HEDLEY_CONSTEXPR
25222 #undef JSON_HEDLEY_CONST_CAST
25223 #undef JSON_HEDLEY_CPP_CAST
25224 #undef JSON_HEDLEY_CRAY_VERSION
25225 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
25226 #undef JSON_HEDLEY_C_DECL
25227 #undef JSON_HEDLEY_DEPRECATED
25228 #undef JSON_HEDLEY_DEPRECATED_FOR
25229 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
25230 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
25231 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
25232 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
25233 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
25234 #undef JSON_HEDLEY_DIAGNOSTIC_POP
25235 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
25236 #undef JSON_HEDLEY_DMC_VERSION
25237 #undef JSON_HEDLEY_DMC_VERSION_CHECK
25238 #undef JSON_HEDLEY_EMPTY_BASES
25239 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
25240 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
25241 #undef JSON_HEDLEY_END_C_DECLS
25242 #undef JSON_HEDLEY_FLAGS
25243 #undef JSON_HEDLEY_FLAGS_CAST
25244 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
25245 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
25246 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
25247 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
25248 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
25249 #undef JSON_HEDLEY_GCC_HAS_FEATURE
25250 #undef JSON_HEDLEY_GCC_HAS_WARNING
25251 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
25252 #undef JSON_HEDLEY_GCC_VERSION
25253 #undef JSON_HEDLEY_GCC_VERSION_CHECK
25254 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
25255 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
25256 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
25257 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
25258 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
25259 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
25260 #undef JSON_HEDLEY_GNUC_HAS_WARNING
25261 #undef JSON_HEDLEY_GNUC_VERSION
25262 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
25263 #undef JSON_HEDLEY_HAS_ATTRIBUTE
25264 #undef JSON_HEDLEY_HAS_BUILTIN
25265 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
25266 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
25267 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
25268 #undef JSON_HEDLEY_HAS_EXTENSION
25269 #undef JSON_HEDLEY_HAS_FEATURE
25270 #undef JSON_HEDLEY_HAS_WARNING
25271 #undef JSON_HEDLEY_IAR_VERSION
25272 #undef JSON_HEDLEY_IAR_VERSION_CHECK
25273 #undef JSON_HEDLEY_IBM_VERSION
25274 #undef JSON_HEDLEY_IBM_VERSION_CHECK
25275 #undef JSON_HEDLEY_IMPORT
25276 #undef JSON_HEDLEY_INLINE
25277 #undef JSON_HEDLEY_INTEL_VERSION
25278 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
25279 #undef JSON_HEDLEY_IS_CONSTANT
25280 #undef JSON_HEDLEY_IS_CONSTEXPR_
25281 #undef JSON_HEDLEY_LIKELY
25282 #undef JSON_HEDLEY_MALLOC
25283 #undef JSON_HEDLEY_MESSAGE
25284 #undef JSON_HEDLEY_MSVC_VERSION
25285 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
25286 #undef JSON_HEDLEY_NEVER_INLINE
25287 #undef JSON_HEDLEY_NON_NULL
25288 #undef JSON_HEDLEY_NO_ESCAPE
25289 #undef JSON_HEDLEY_NO_RETURN
25290 #undef JSON_HEDLEY_NO_THROW
25291 #undef JSON_HEDLEY_NULL
25292 #undef JSON_HEDLEY_PELLES_VERSION
25293 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
25294 #undef JSON_HEDLEY_PGI_VERSION
25295 #undef JSON_HEDLEY_PGI_VERSION_CHECK
25296 #undef JSON_HEDLEY_PREDICT
25297 #undef JSON_HEDLEY_PRINTF_FORMAT
25298 #undef JSON_HEDLEY_PRIVATE
25299 #undef JSON_HEDLEY_PUBLIC
25300 #undef JSON_HEDLEY_PURE
25301 #undef JSON_HEDLEY_REINTERPRET_CAST
25302 #undef JSON_HEDLEY_REQUIRE
25303 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
25304 #undef JSON_HEDLEY_REQUIRE_MSG
25305 #undef JSON_HEDLEY_RESTRICT
25306 #undef
25307 #undef JSON_HEDLEY_SENTINEL
25308 #undef JSON_HEDLEY_STATIC_ASSERT
25309 #undef JSON_HEDLEY_STATIC_CAST
25310 #undef JSON_HEDLEY_STRINGIFY
25311 #undef JSON_HEDLEY_STRINGIFY_EX
25312 #undef JSON_HEDLEY_SUNPRO_VERSION
25313 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
25314 #undef JSON_HEDLEY_TINYC_VERSION
25315 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
25316 #undef JSON_HEDLEY_TI_ARMCL_VERSION
25317 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
25318 #undef JSON_HEDLEY_TI_CL2000_VERSION
25319 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
25320 #undef JSON_HEDLEY_TI_CL430_VERSION
25321 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
25322 #undef JSON_HEDLEY_TI_CL6X_VERSION
25323 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
25324 #undef JSON_HEDLEY_TI_CL7X_VERSION
25325 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
25326 #undef JSON_HEDLEY_TI_CLPRU_VERSION
25327 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
25328 #undef JSON_HEDLEY_TI_VERSION
25329 #undef JSON_HEDLEY_TI_VERSION_CHECK
25330 #undef JSON_HEDLEY_UNAVAILABLE
25331 #undef JSON_HEDLEY_UNLIKELY
25332 #undef JSON_HEDLEY_UNPREDICTABLE
25333 #undef JSON_HEDLEY_UNREACHABLE
25334 #undef JSON_HEDLEY_UNREACHABLE_RETURN
25335 #undef JSON_HEDLEY_VERSION
25336 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
25337 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
25338 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
25339 #undef JSON_HEDLEY_VERSION_ENCODE
25340 #undef JSON_HEDLEY_WARNING
25341 #undef
25342 #undef _MSG
25343 #undef JSON_HEDLEY_FALL_THROUGH
25344
25345
25346
25347 #endif // INCLUDE_NLOHMANN_JSON_HPP_
nlohmann::basic_json::to_msgpack
static std::vector< uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:23556
nlohmann::basic_json::erase
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:20426
nlohmann::basic_json::accept
static bool accept(InputType &&i, const bool ignore_comments=false)
check if the input is valid JSON
Definition: json.hpp:23138
nlohmann::basic_json::value_t
detail::value_t value_t
Definition: json.hpp:16614
nlohmann::json_sax::boolean
virtual bool boolean(bool val)=0
a boolean value was read
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:23870
nlohmann::basic_json::begin
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:20876
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:4463
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:18659
nlohmann::basic_json::contains
bool contains(KeyT &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:20806
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:23046
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:18241
nlohmann::basic_json::const_iterator
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.hpp:16687
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:24013
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:19360
nlohmann::basic_json::meta
static basic_json meta()
returns version information on the library
Definition: json.hpp:16731
nlohmann::basic_json::number_unsigned_t
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:17159
nlohmann::basic_json::unflatten
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:24511
nlohmann::basic_json::operator>>
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:22978
nlohmann::byte_container_with_subtype::set_subtype
void set_subtype(std::uint8_t subtype) noexcept
sets the binary subtype
Definition: json.hpp:4492
nlohmann::basic_json::other_error
detail::other_error other_error
exception indicating other library errors
Definition: json.hpp:16649
nlohmann::basic_json::number_integer_t
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:17088
nlohmann::basic_json::allocator_type
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:16677
nlohmann::basic_json::object
static basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:18214
nlohmann::basic_json::array_t
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:16937
nlohmann::basic_json::basic_json
basic_json(const JsonRef &ref)
Definition: json.hpp:18409
nlohmann::basic_json::operator>
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:22841
nlohmann::ordered_map::Container
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.hpp:16409
nlohmann::basic_json::size
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:21404
nlohmann::basic_json::basic_json
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:17864
nlohmann::json_sax::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:5208
nlohmann::basic_json::invalid_iterator
detail::invalid_iterator invalid_iterator
exception indicating errors with iterators
Definition: json.hpp:16643
nlohmann::json_pointer::back
const std::string & back() const
return last reference token
Definition: json.hpp:11806
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:11600
nlohmann::basic_json::operator==
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:22520
nlohmann::basic_json::difference_type
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:16672
nlohmann::basic_json::at
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:19693
nlohmann::ordered_map
Definition: json.hpp:16406
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:19406
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:16891
nlohmann::basic_json::type_name
const char * type_name() const noexcept
return the type as string
Definition: json.hpp:23322
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:23659
nlohmann::basic_json::input_format_t
detail::input_format_t input_format_t
Definition: json.hpp:16626
nlohmann::basic_json::is_primitive
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:18743
nlohmann::ordered_map::mapped_type
T mapped_type
Definition: json.hpp:16408
nlohmann::basic_json::rend
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:21054
nlohmann::basic_json::crbegin
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:21091
nlohmann
namespace for Niels Lohmann
Definition: json.hpp:82
nlohmann::basic_json::find
iterator find(KeyT &&key)
find an element in a JSON object
Definition: json.hpp:20722
nlohmann::byte_container_with_subtype::has_subtype
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:4540
nlohmann::basic_json::basic_json
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:18436
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:20189
nlohmann::basic_json::get_allocator
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:16699
nlohmann::json_sax::parse_error
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
nlohmann::basic_json::is_number_integer
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:18873
nlohmann::json_pointer
JSON Pointer.
Definition: json.hpp:11555
nlohmann::basic_json::size_type
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:16674
nlohmann::byte_container_with_subtype::operator!=
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:4469
nlohmann::basic_json::operator!=
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:22628
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:17987
nlohmann::json_pointer::empty
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:11853
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:19527
nlohmann::basic_json::type_error
detail::type_error type_error
exception indicating executing a member function with a wrong type
Definition: json.hpp:16645
nlohmann::anonymous_namespace{json.hpp}::from_json
constexpr const auto & from_json
Definition: json.hpp:3801
nlohmann::basic_json::is_boolean
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:18814
nlohmann::basic_json::object_comparator_t
std::less< StringType > object_comparator_t
Definition: json.hpp:16801
nlohmann::basic_json::crend
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:21120
nlohmann::basic_json::rbegin
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:21017
nlohmann::basic_json::is_discarded
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:19044
nlohmann::basic_json::get_binary
binary_t & get_binary()
Definition: json.hpp:19635
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:18124
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:12485
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:16624
nlohmann::basic_json::is_number_float
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:18929
nlohmann::basic_json::boolean_t
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:17016
nlohmann::ordered_map::ordered_map
ordered_map(std::initializer_list< T > init, const Allocator &alloc=Allocator())
Definition: json.hpp:16420
nlohmann::basic_json::external_constructor
friend struct detail::external_constructor
Definition: json.hpp:16560
nlohmann::basic_json::binary_t
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:17298
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:24242
nlohmann::basic_json::back
reference back()
access the last element
Definition: json.hpp:20359
nlohmann::basic_json::const_reference
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:16669
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:4457
nlohmann::adl_serializer
default JSONSerializer template argument
Definition: json.hpp:4371
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:25082
nlohmann::basic_json::cbegin
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:20916
nlohmann::basic_json::array
static basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:18170
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:4382
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:21864
nlohmann::basic_json::json_pointer
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:16616
nlohmann::basic_json::get
BasicJsonType get() const
get special-case overload
Definition: json.hpp:19259
nlohmann::basic_json::operator>=
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:22887
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:5204
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:16689
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:20773
nlohmann::basic_json::parser_callback_t
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:17689
nlohmann::basic_json::is_null
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:18792
nlohmann::basic_json::operator<=
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:22795
nlohmann::basic_json::cend
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:20987
nlohmann::basic_json::flatten
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:24474
nlohmann::basic_json::empty
bool empty() const noexcept
checks whether the container is empty.
Definition: json.hpp:21331
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:24868
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:11698
nlohmann::ordered_map::erase
size_type erase(const Key &key)
Definition: json.hpp:16441
nlohmann::basic_json::basic_json
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:17754
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:18562
nlohmann::basic_json::operator+=
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:21648
nlohmann::basic_json::get_ref
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:19574
nlohmann::json_sax::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:5206
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:16682
nlohmann::ordered_map::key_type
Key key_type
Definition: json.hpp:16407
nlohmann::basic_json::is_string
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:18995
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:19515
nlohmann::basic_json::is_array
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:18973
nlohmann::basic_json::operator<<
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:22954
nlohmann::json_sax::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:5205
nlohmann::basic_json::out_of_range
detail::out_of_range out_of_range
exception indicating access out of the defined range
Definition: json.hpp:16647
nlohmann::basic_json::front
reference front()
access the first element
Definition: json.hpp:20315
nlohmann::json_sax::start_array
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
nlohmann::basic_json::pointer
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:16680
nlohmann::basic_json::string_t
StringType string_t
a type for a string
Definition: json.hpp:16990
nlohmann::json_sax::~json_sax
virtual ~json_sax()=default
nlohmann::basic_json::type
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:18712
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:18067
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:4447
nlohmann::basic_json::insert
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:21932
nlohmann::basic_json::get_ref
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:19561
nlohmann::basic_json::is_number
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:18844
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:11828
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:11678
nlohmann::basic_json::clear
void clear() noexcept
clears the contents
Definition: json.hpp:21546
nlohmann::ordered_map::ordered_map
ordered_map(const Allocator &alloc=Allocator())
Definition: json.hpp:16416
nlohmann::basic_json::basic_json
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:18306
nlohmann::basic_json::number_float_t
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:17227
nlohmann::basic_json::items
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:21266
nlohmann::basic_json::is_structured
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:18770
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:11632
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:11834
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:23737
nlohmann::basic_json::update
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:22167
nlohmann::basic_json::basic_json
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:18525
nlohmann::json_sax::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:5207
nlohmann::basic_json::get_to
ValueType & get_to(ValueType &v) const
Definition: json.hpp:19419
nlohmann::basic_json
a class to store JSON values
Definition: json.hpp:16558
nlohmann::json_sax::end_object
virtual bool end_object()=0
the end of an object was read
nlohmann::basic_json::operator[]
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:19898
nlohmann::byte_container_with_subtype::clear_subtype
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:4564
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:17827
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:11739
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:12502
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:16418
nlohmann::basic_json::push_back
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:21623
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:19309
nlohmann::byte_container_with_subtype::subtype
constexpr std::uint8_t subtype() const noexcept
return the binary subtype
Definition: json.hpp:4519
nlohmann::ordered_map::emplace
std::pair< iterator, bool > emplace(key_type &&key, T &&t)
Definition: json.hpp:16423
nlohmann::basic_json::end
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:20947
nlohmann::basic_json::merge_patch
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:25043
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:19467
nlohmann::basic_json::parse_error
detail::parse_error parse_error
exception indicating a parse error
Definition: json.hpp:16641
nlohmann::basic_json::insert_iterator
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.hpp:21894
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:19480
nlohmann::anonymous_namespace{json.hpp}::to_json
constexpr const auto & to_json
Definition: json.hpp:4361
nlohmann::byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:4439
nlohmann::basic_json::exception
detail::exception exception
general exception of the basic_json class
Definition: json.hpp:16639
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:4443
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:23201
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:19430
nlohmann::json_pointer::json_pointer
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.hpp:11582
nlohmann::json_pointer::pop_back
void pop_back()
remove last reference token
Definition: json.hpp:11782
nlohmann::ordered_map::operator[]
T & operator[](Key &&key)
Definition: json.hpp:16436
nlohmann::basic_json::reference
value_type & reference
the type of an element reference
Definition: json.hpp:16667
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:11656
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:21184
nlohmann::basic_json::json_serializer
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:16618
nlohmann::basic_json::iterator
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.hpp:16685
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:16691
nlohmann::json_pointer::parent_pointer
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:11757
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:11719
nlohmann::basic_json::max_size
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:21475
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:18104
nlohmann::json
basic_json<> json
default JSON class
Definition: json.hpp:2933
nlohmann::json_sax
SAX interface.
Definition: json.hpp:5203
nlohmann::basic_json::is_number_unsigned
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:18901
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:4451
nlohmann::basic_json::get
basic_json get() const
get special-case overload
Definition: json.hpp:19236
nlohmann::basic_json::push_back
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:21763
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:24129
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:4399
nlohmann::byte_container_with_subtype
an internal type for a backed binary type
Definition: json.hpp:4434
nlohmann::basic_json::operator<
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:22681
nlohmann::basic_json::cbor_tag_handler_t
detail::cbor_tag_handler_t cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:16622
nlohmann::basic_json::get_binary
const binary_t & get_binary() const
Definition: json.hpp:19646
nlohmann::basic_json::basic_json
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:17730
nlohmann::basic_json::emplace_back
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:21811
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:23461
nlohmann::basic_json::is_binary
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:19017
nlohmann::basic_json::~basic_json
~basic_json() noexcept
destructor
Definition: json.hpp:18595
nlohmann::basic_json::binary
static basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array (without subtype)
Definition: json.hpp:18114
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:22269
nlohmann::basic_json::patch
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:24572
nlohmann::basic_json::is_object
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:18951
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:23902
nlohmann::byte_container_with_subtype::container_type
BinaryType container_type
the type of the underlying container
Definition: json.hpp:4437