Ditto 3.0.11
Loading...
Searching...
No Matches
json.hpp
1/*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4| | |__ | | | | | | version 3.9.1
5|_____|_____|_____|_|___| https://github.com/nlohmann/json
6
7Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8SPDX-License-Identifier: MIT
9Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10
11Permission is hereby granted, free of charge, to any person obtaining a copy
12of this software and associated documentation files (the "Software"), to deal
13in the Software without restriction, including without limitation the rights
14to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15copies of the Software, and to permit persons to whom the Software is
16furnished to do so, subject to the following conditions:
17
18The above copyright notice and this permission notice shall be included in all
19copies or substantial portions of the Software.
20
21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27SOFTWARE.
28*/
29
30#ifndef INCLUDE_NLOHMANN_JSON_HPP_
31#define INCLUDE_NLOHMANN_JSON_HPP_
32
33#define NLOHMANN_JSON_VERSION_MAJOR 3
34#define NLOHMANN_JSON_VERSION_MINOR 9
35#define NLOHMANN_JSON_VERSION_PATCH 1
36
37#include <algorithm> // all_of, find, for_each
38#include <cstddef> // nullptr_t, ptrdiff_t, size_t
39#include <functional> // hash, less
40#include <initializer_list> // initializer_list
41#include <iosfwd> // istream, ostream
42#include <iterator> // random_access_iterator_tag
43#include <memory> // unique_ptr
44#include <numeric> // accumulate
45#include <string> // string, stoi, to_string
46#include <utility> // declval, forward, move, pair, swap
47#include <vector> // vector
48
49// #include <nlohmann/adl_serializer.hpp>
50
51
52#include <utility>
53
54// #include <nlohmann/detail/conversions/from_json.hpp>
55
56
57#include <algorithm> // transform
58#include <array> // array
59#include <forward_list> // forward_list
60#include <iterator> // inserter, front_inserter, end
61#include <map> // map
62#include <string> // string
63#include <tuple> // tuple, make_tuple
64#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
65#include <unordered_map> // unordered_map
66#include <utility> // pair, declval
67#include <valarray> // valarray
68
69// #include <nlohmann/detail/exceptions.hpp>
70
71
72#include <exception> // exception
73#include <stdexcept> // runtime_error
74#include <string> // to_string
75
76// #include <nlohmann/detail/input/position_t.hpp>
77
78
79#include <cstddef> // size_t
80
81namespace nlohmann
82{
83namespace detail
84{
86struct 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(JSON_HEDLEY_WARN_UNUSED_RESULT)
1113 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1114#endif
1115#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1116 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1117#endif
1118#if (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1119 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1120 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1121#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1122 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1123 #define JSON_HEDLEY_WARN_UNUSED_RESULT_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 JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1142 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1143#elif defined(_Check_return_) /* SAL */
1144 #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1145 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1146#else
1147 #define JSON_HEDLEY_WARN_UNUSED_RESULT
1148 #define JSON_HEDLEY_WARN_UNUSED_RESULT_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
1272JSON_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
1298JSON_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(JSON_HEDLEY_RETURNS_NON_NULL)
1703 #undef JSON_HEDLEY_RETURNS_NON_NULL
1704#endif
1705#if \
1706 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1707 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
1708 #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
1709#elif defined(_Ret_notnull_) /* SAL */
1710 #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
1711#else
1712 #define JSON_HEDLEY_RETURNS_NON_NULL
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
2316namespace nlohmann
2317{
2318namespace detail
2319{
2321// exceptions //
2323
2352class exception : public std::exception
2353{
2354 public:
2356 JSON_HEDLEY_RETURNS_NON_NULL
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
2424class 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
2510class 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
2564class 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
2611class 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
2649class 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
2673namespace nlohmann
2674{
2675namespace detail
2676{
2677// alias templates to reduce boilerplate
2678template<bool B, typename T = void>
2679using enable_if_t = typename std::enable_if<B, T>::type;
2680
2681template<typename T>
2682using 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
2686template<std::size_t... Ints>
2687struct 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
2697template<class Sequence1, class Sequence2>
2698struct merge_and_renumber;
2699
2700template<std::size_t... I1, std::size_t... I2>
2701struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
2702 : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
2703
2704template<std::size_t N>
2705struct make_index_sequence
2706 : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
2707 typename make_index_sequence < N - N / 2 >::type > {};
2708
2709template<> struct make_index_sequence<0> : index_sequence<> {};
2710template<> struct make_index_sequence<1> : index_sequence<0> {};
2711
2712template<typename... Ts>
2713using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
2714
2715// dispatch utility (taken from ranges-v3)
2716template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
2717template<> struct priority_tag<0> {};
2718
2719// taken from ranges-v3
2720template<typename T>
2721struct static_const
2722{
2723 static constexpr T value{};
2724};
2725
2726template<typename T>
2727constexpr 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
2746namespace nlohmann
2747{
2748namespace detail
2749{
2750template<typename ...Ts> struct make_void
2751{
2752 using type = void;
2753};
2754template<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
2761namespace nlohmann
2762{
2763namespace detail
2764{
2765template<typename It, typename = void>
2766struct iterator_types {};
2767
2768template<typename It>
2769struct 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.
2783template<typename T, typename = void>
2784struct iterator_traits
2785{
2786};
2787
2788template<typename T>
2789struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
2790 : iterator_types<T>
2791{
2792};
2793
2794template<typename T>
2795struct 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
2819namespace nlohmann
2820{
2821namespace detail
2822{
2823struct 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
2833template<class Default,
2834 class AlwaysVoid,
2835 template<class...> class Op,
2836 class... Args>
2837struct detector
2838{
2839 using value_t = std::false_type;
2840 using type = Default;
2841};
2842
2843template<class Default, template<class...> class Op, class... Args>
2844struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2845{
2846 using value_t = std::true_type;
2847 using type = Op<Args...>;
2848};
2849
2850template<template<class...> class Op, class... Args>
2851using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2852
2853template<template<class...> class Op, class... Args>
2854using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2855
2856template<class Default, template<class...> class Op, class... Args>
2857using detected_or = detector<Default, void, Op, Args...>;
2858
2859template<class Default, template<class...> class Op, class... Args>
2860using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2861
2862template<class Expected, template<class...> class Op, class... Args>
2863using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2864
2865template<class To, template<class...> class Op, class... Args>
2866using 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
2886namespace nlohmann
2887{
2895template<typename T = void, typename SFINAE = void>
2896struct adl_serializer;
2897
2898template<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>>
2909class basic_json;
2910
2922template<typename BasicJsonType>
2923class json_pointer;
2924
2933using json = basic_json<>;
2934
2935template<class Key, class T, class IgnoredLess, class Allocator>
2936struct ordered_map;
2937
2945using ordered_json = basic_json<nlohmann::ordered_map>;
2946
2947} // namespace nlohmann
2948
2949#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
2950
2951
2952namespace nlohmann
2953{
2962namespace 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
2977template<typename> struct is_basic_json : std::false_type {};
2978
2979NLOHMANN_BASIC_JSON_TPL_DECLARATION
2980struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
2981
2983// json_ref helpers //
2985
2986template<typename>
2987class json_ref;
2988
2989template<typename>
2990struct is_json_ref : std::false_type {};
2991
2992template<typename T>
2993struct is_json_ref<json_ref<T>> : std::true_type {};
2994
2996// aliases for detected //
2998
2999template<typename T>
3000using mapped_type_t = typename T::mapped_type;
3001
3002template<typename T>
3003using key_type_t = typename T::key_type;
3004
3005template<typename T>
3006using value_type_t = typename T::value_type;
3007
3008template<typename T>
3009using difference_type_t = typename T::difference_type;
3010
3011template<typename T>
3012using pointer_t = typename T::pointer;
3013
3014template<typename T>
3015using reference_t = typename T::reference;
3016
3017template<typename T>
3018using iterator_category_t = typename T::iterator_category;
3019
3020template<typename T>
3021using iterator_t = typename T::iterator;
3022
3023template<typename T, typename... Args>
3024using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3025
3026template<typename T, typename... Args>
3027using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3028
3029template<typename T, typename U>
3030using get_template_function = decltype(std::declval<T>().template get<U>());
3031
3032// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3033template<typename BasicJsonType, typename T, typename = void>
3034struct 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)
3040template <typename BasicJsonType, typename T>
3041struct is_getable
3042{
3043 static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
3044};
3045
3046template<typename BasicJsonType, typename T>
3047struct 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
3059template<typename BasicJsonType, typename T, typename = void>
3060struct has_non_default_from_json : std::false_type {};
3061
3062template<typename BasicJsonType, typename T>
3063struct 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.
3074template<typename BasicJsonType, typename T, typename = void>
3075struct has_to_json : std::false_type {};
3076
3077template<typename BasicJsonType, typename T>
3078struct 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
3092template<typename T, typename = void>
3093struct is_iterator_traits : std::false_type {};
3094
3095template<typename T>
3096struct 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
3112template<typename T, typename = void>
3113struct is_complete_type : std::false_type {};
3114
3115template<typename T>
3116struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3117
3118template<typename BasicJsonType, typename CompatibleObjectType,
3119 typename = void>
3120struct is_compatible_object_type_impl : std::false_type {};
3121
3122template<typename BasicJsonType, typename CompatibleObjectType>
3123struct 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
3139template<typename BasicJsonType, typename CompatibleObjectType>
3140struct is_compatible_object_type
3141 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3142
3143template<typename BasicJsonType, typename ConstructibleObjectType,
3144 typename = void>
3145struct is_constructible_object_type_impl : std::false_type {};
3146
3147template<typename BasicJsonType, typename ConstructibleObjectType>
3148struct 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
3171template<typename BasicJsonType, typename ConstructibleObjectType>
3172struct is_constructible_object_type
3173 : is_constructible_object_type_impl<BasicJsonType,
3174 ConstructibleObjectType> {};
3175
3176template<typename BasicJsonType, typename CompatibleStringType,
3177 typename = void>
3178struct is_compatible_string_type_impl : std::false_type {};
3179
3180template<typename BasicJsonType, typename CompatibleStringType>
3181struct 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
3190template<typename BasicJsonType, typename ConstructibleStringType>
3191struct is_compatible_string_type
3192 : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3193
3194template<typename BasicJsonType, typename ConstructibleStringType,
3195 typename = void>
3196struct is_constructible_string_type_impl : std::false_type {};
3197
3198template<typename BasicJsonType, typename ConstructibleStringType>
3199struct 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
3209template<typename BasicJsonType, typename ConstructibleStringType>
3210struct is_constructible_string_type
3211 : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3212
3213template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3214struct is_compatible_array_type_impl : std::false_type {};
3215
3216template<typename BasicJsonType, typename CompatibleArrayType>
3217struct 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
3232template<typename BasicJsonType, typename CompatibleArrayType>
3233struct is_compatible_array_type
3234 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3235
3236template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3237struct is_constructible_array_type_impl : std::false_type {};
3238
3239template<typename BasicJsonType, typename ConstructibleArrayType>
3240struct 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
3246template<typename BasicJsonType, typename ConstructibleArrayType>
3247struct 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)&&
3254is_detected<value_type_t, ConstructibleArrayType>::value&&
3255is_detected<iterator_t, ConstructibleArrayType>::value&&
3256is_complete_type <
3257detected_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
3275template<typename BasicJsonType, typename ConstructibleArrayType>
3276struct is_constructible_array_type
3277 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3278
3279template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3280 typename = void>
3281struct is_compatible_integer_type_impl : std::false_type {};
3282
3283template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3284struct 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
3301template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3302struct is_compatible_integer_type
3303 : is_compatible_integer_type_impl<RealIntegerType,
3304 CompatibleNumberIntegerType> {};
3305
3306template<typename BasicJsonType, typename CompatibleType, typename = void>
3307struct is_compatible_type_impl: std::false_type {};
3308
3309template<typename BasicJsonType, typename CompatibleType>
3310struct 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
3318template<typename BasicJsonType, typename CompatibleType>
3319struct is_compatible_type
3320 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3321
3322// https://en.cppreference.com/w/cpp/types/conjunction
3323template<class...> struct conjunction : std::true_type { };
3324template<class B1> struct conjunction<B1> : B1 { };
3325template<class B1, class... Bn>
3326struct conjunction<B1, Bn...>
3327: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3328
3329template<typename T1, typename T2>
3330struct is_constructible_tuple : std::false_type {};
3331
3332template<typename T1, typename... Args>
3333struct 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
3345namespace nlohmann
3346{
3347namespace detail
3348{
3350// JSON type enumeration //
3352
3377enum 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
3404inline 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
3421namespace nlohmann
3422{
3423namespace detail
3424{
3425template<typename BasicJsonType>
3426void 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
3436template < 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 >
3440void 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
3465template<typename BasicJsonType>
3466void 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
3475template<typename BasicJsonType>
3476void 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
3485template <
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 >
3492void 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
3502template<typename BasicJsonType>
3503void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
3504{
3505 get_arithmetic_value(j, val);
3506}
3507
3508template<typename BasicJsonType>
3509void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
3510{
3511 get_arithmetic_value(j, val);
3512}
3513
3514template<typename BasicJsonType>
3515void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
3516{
3517 get_arithmetic_value(j, val);
3518}
3519
3520template<typename BasicJsonType, typename EnumType,
3521 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
3522void 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
3530template<typename BasicJsonType, typename T, typename Allocator,
3531 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
3532void 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
3547template<typename BasicJsonType, typename T,
3548 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
3549void 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
3563template<typename BasicJsonType, typename T, std::size_t N>
3564auto 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
3573template<typename BasicJsonType>
3574void 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
3579template<typename BasicJsonType, typename T, std::size_t N>
3580auto 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
3590template<typename BasicJsonType, typename ConstructibleArrayType>
3591auto 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
3611template<typename BasicJsonType, typename ConstructibleArrayType>
3612void 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
3629template < 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 >
3637auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
3638-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
3639j.template get<typename ConstructibleArrayType::value_type>(),
3640void())
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
3651template<typename BasicJsonType>
3652void 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
3662template<typename BasicJsonType, typename ConstructibleObjectType,
3663 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
3664void 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?
3688template < 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 >
3696void 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
3726template<typename BasicJsonType, typename A1, typename A2>
3727void 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
3732template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
3733void 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
3738template<typename BasicJsonType, typename... Args>
3739void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
3740{
3741 from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
3742}
3743
3744template < 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 >>
3747void 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
3764template < 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 >>
3767void 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
3784struct 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
3799namespace
3800{
3801constexpr 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
3830namespace nlohmann
3831{
3832namespace detail
3833{
3834template<typename string_type>
3835void 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}
3841template<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
3929template<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
3955template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
3956auto 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
3963template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
3964auto 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
3975namespace 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
3982template<typename IteratorType>
3983class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
3984 : public std::integral_constant<std::size_t, 2> {};
3985
3986template<std::size_t N, typename IteratorType>
3987class 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
4006namespace nlohmann
4007{
4008namespace detail
4009{
4011// constructors //
4013
4014template<value_t> struct external_constructor;
4015
4016template<>
4017struct 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
4028template<>
4029struct 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
4058template<>
4059struct 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
4080template<>
4081struct 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
4092template<>
4093struct 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
4104template<>
4105struct 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
4116template<>
4117struct 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
4175template<>
4176struct 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
4211template<typename BasicJsonType, typename T,
4212 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
4213void to_json(BasicJsonType& j, T b) noexcept
4214{
4215 external_constructor<value_t::boolean>::construct(j, b);
4216}
4217
4218template<typename BasicJsonType, typename CompatibleString,
4219 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
4220void to_json(BasicJsonType& j, const CompatibleString& s)
4221{
4222 external_constructor<value_t::string>::construct(j, s);
4223}
4224
4225template<typename BasicJsonType>
4226void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4227{
4228 external_constructor<value_t::string>::construct(j, std::move(s));
4229}
4230
4231template<typename BasicJsonType, typename FloatType,
4232 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
4233void 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
4238template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4239 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
4240void 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
4245template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4246 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
4247void 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
4252template<typename BasicJsonType, typename EnumType,
4253 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4254void 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
4260template<typename BasicJsonType>
4261void to_json(BasicJsonType& j, const std::vector<bool>& e)
4262{
4263 external_constructor<value_t::array>::construct(j, e);
4264}
4265
4266template < 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 >
4274void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4275{
4276 external_constructor<value_t::array>::construct(j, arr);
4277}
4278
4279template<typename BasicJsonType>
4280void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4281{
4282 external_constructor<value_t::binary>::construct(j, bin);
4283}
4284
4285template<typename BasicJsonType, typename T,
4286 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4287void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4288{
4289 external_constructor<value_t::array>::construct(j, std::move(arr));
4290}
4291
4292template<typename BasicJsonType>
4293void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4294{
4295 external_constructor<value_t::array>::construct(j, std::move(arr));
4296}
4297
4298template < typename BasicJsonType, typename CompatibleObjectType,
4299 enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
4300void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4301{
4302 external_constructor<value_t::object>::construct(j, obj);
4303}
4304
4305template<typename BasicJsonType>
4306void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4307{
4308 external_constructor<value_t::object>::construct(j, std::move(obj));
4309}
4310
4311template <
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 >
4316void to_json(BasicJsonType& j, const T(&arr)[N])
4317{
4318 external_constructor<value_t::array>::construct(j, arr);
4319}
4320
4321template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
4322void 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
4328template<typename BasicJsonType, typename T,
4329 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
4330void to_json(BasicJsonType& j, const T& b)
4331{
4332 j = { {b.key(), b.value()} };
4333}
4334
4335template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
4336void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4337{
4338 j = { std::get<Idx>(t)... };
4339}
4340
4341template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
4342void 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
4347struct 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
4359namespace
4360{
4361constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
4362} // namespace
4363} // namespace nlohmann
4364
4365
4366namespace nlohmann
4367{
4368
4369template<typename, typename>
4370struct 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
4416namespace nlohmann
4417{
4418
4432template<typename BinaryType>
4433class 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
4589namespace nlohmann
4590{
4591namespace detail
4592{
4593
4594// boost::hash_combine
4595inline 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
4612template<typename BasicJsonType>
4613std::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
4739namespace nlohmann
4740{
4741namespace detail
4742{
4744enum class input_format_t { json, cbor, msgpack, ubjson, bson };
4745
4747// input adapters //
4749
4754class 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
4790class 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.
4842template<typename IteratorType>
4843class 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
4880template<typename BaseInputAdapter, size_t T>
4881struct wide_string_input_helper;
4882
4883template<typename BaseInputAdapter>
4884struct 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
4941template<typename BaseInputAdapter>
4942struct 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.
5004template<typename BaseInputAdapter, typename WideCharType>
5005class 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
5049template<typename IteratorType, typename Enable = void>
5050struct 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
5062template<typename T>
5063struct 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
5072template<typename IteratorType>
5073struct 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
5087template<typename IteratorType>
5088typename 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
5095template<typename ContainerType>
5096auto 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
5106inline file_input_adapter input_adapter(std::FILE* file)
5107{
5108 return file_input_adapter(file);
5109}
5110
5111inline input_stream_adapter input_adapter(std::istream& stream)
5112{
5113 return input_stream_adapter(stream);
5114}
5115
5116inline input_stream_adapter input_adapter(std::istream&& stream)
5117{
5118 return input_stream_adapter(stream);
5119}
5120
5121using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5122
5123// Null-delimited strings, and the like.
5124template < 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 >
5131contiguous_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
5138template<typename T, std::size_t N>
5139auto 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.
5147class 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
5190namespace nlohmann
5191{
5192
5201template<typename BasicJsonType>
5202struct 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
5312namespace detail
5313{
5327template<typename BasicJsonType>
5328class 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 JSON_HEDLEY_RETURNS_NON_NULL
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
5501template<typename BasicJsonType>
5502class 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
5797template<typename BasicJsonType>
5798class 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
5896namespace nlohmann
5897{
5898namespace detail
5899{
5901// lexer //
5903
5904template<typename BasicJsonType>
5905class 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 JSON_HEDLEY_RETURNS_NON_NULL
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};
5981template<typename BasicJsonType, typename InputAdapterType>
5982class 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 continue;
6763 }
6764 }
6765 }
6766
6767 default:
6768 continue;
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
6883scan_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
6915scan_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
6936scan_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
6972scan_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
6999scan_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
7029scan_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
7064scan_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
7090scan_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
7113scan_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 JSON_HEDLEY_RETURNS_NON_NULL
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 while (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
7518namespace nlohmann
7519{
7520namespace detail
7521{
7522template<typename T>
7523using null_function_t = decltype(std::declval<T&>().null());
7524
7525template<typename T>
7526using boolean_function_t =
7527 decltype(std::declval<T&>().boolean(std::declval<bool>()));
7528
7529template<typename T, typename Integer>
7530using number_integer_function_t =
7531 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
7532
7533template<typename T, typename Unsigned>
7534using number_unsigned_function_t =
7535 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
7536
7537template<typename T, typename Float, typename String>
7538using number_float_function_t = decltype(std::declval<T&>().number_float(
7539 std::declval<Float>(), std::declval<const String&>()));
7540
7541template<typename T, typename String>
7542using string_function_t =
7543 decltype(std::declval<T&>().string(std::declval<String&>()));
7544
7545template<typename T, typename Binary>
7546using binary_function_t =
7547 decltype(std::declval<T&>().binary(std::declval<Binary&>()));
7548
7549template<typename T>
7550using start_object_function_t =
7551 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
7552
7553template<typename T, typename String>
7554using key_function_t =
7555 decltype(std::declval<T&>().key(std::declval<String&>()));
7556
7557template<typename T>
7558using end_object_function_t = decltype(std::declval<T&>().end_object());
7559
7560template<typename T>
7561using start_array_function_t =
7562 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
7563
7564template<typename T>
7565using end_array_function_t = decltype(std::declval<T&>().end_array());
7566
7567template<typename T, typename Exception>
7568using 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
7572template<typename SAX, typename BasicJsonType>
7573struct 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
7603template<typename SAX, typename BasicJsonType>
7604struct 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
7662namespace nlohmann
7663{
7664namespace detail
7665{
7666
7668enum class cbor_tag_handler_t
7669{
7670 error,
7671 ignore
7672};
7673
7681static inline bool little_endianess(int num = 1) noexcept
7682{
7683 return *reinterpret_cast<char*>(&num) == 1;
7684}
7685
7686
7688// binary reader //
7690
7694template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
7695class 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
10129namespace nlohmann
10130{
10131namespace detail
10132{
10134// parser //
10136
10137enum 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
10153template<typename BasicJsonType>
10154using parser_callback_t =
10155 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
10156
10162template<typename BasicJsonType, typename InputAdapterType>
10163class 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
10623namespace nlohmann
10624{
10625namespace detail
10626{
10627/*
10628@brief an iterator for primitive JSON types
10629
10630This class models an iterator for primitive JSON types (boolean, number,
10631string). It's only purpose is to allow the iterator/const_iterator classes
10632to "iterate" over primitive values. Internally, the iterator is modeled by
10633a `difference_type` variable. Value begin_value (`0`) models the begin,
10634end_value (`1`) models past the end.
10635*/
10636class 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
10740namespace nlohmann
10741{
10742namespace detail
10743{
10750template<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
10783namespace nlohmann
10784{
10785namespace detail
10786{
10787// forward declare, to be able to friend it later on
10788template<typename IteratorType> class iteration_proxy;
10789template<typename IteratorType> class iteration_proxy_value;
10790
10807template<typename BasicJsonType>
10808class 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
11417namespace nlohmann
11418{
11419namespace detail
11420{
11422// reverse_iterator //
11424
11443template<typename Base>
11444class 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
11551namespace nlohmann
11552{
11553template<typename BasicJsonType>
11554class 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
12522namespace nlohmann
12523{
12524namespace detail
12525{
12526template<typename BasicJsonType>
12527class 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
12627namespace nlohmann
12628{
12629namespace detail
12630{
12632template<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
12640template<typename CharType>
12641using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
12642
12644template<typename CharType>
12645class 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
12668template<typename CharType>
12669class 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
12692template<typename CharType, typename StringType = std::basic_string<CharType>>
12693class 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
12715template<typename CharType, typename StringType = std::basic_string<CharType>>
12716class 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
12740namespace nlohmann
12741{
12742namespace detail
12743{
12745// binary writer //
12747
12751template<typename BasicJsonType, typename CharType>
12752class 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
14352namespace nlohmann
14353{
14354namespace detail
14355{
14356
14376namespace dtoa_impl
14377{
14378
14379template<typename Target, typename Source>
14380Target 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
14389struct 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
14507struct boundaries
14508{
14509 diyfp w;
14510 diyfp minus;
14511 diyfp plus;
14512};
14513
14520template<typename FloatType>
14521boundaries 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
14643constexpr int kAlpha = -60;
14644constexpr int kGamma = -32;
14645
14646struct cached_power // c = f * 2^e ~= 10^k
14647{
14648 std::uint64_t f;
14649 int e;
14650 int k;
14651};
14652
14660inline 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
14824inline 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
14880inline 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
14921inline 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
15161JSON_HEDLEY_NON_NULL(1)
15162inline 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
15220template<typename FloatType>
15221JSON_HEDLEY_NON_NULL(1)
15222void 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
15260JSON_HEDLEY_NON_NULL(1)
15261JSON_HEDLEY_RETURNS_NON_NULL
15262inline 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
15312JSON_HEDLEY_NON_NULL(1)
15313JSON_HEDLEY_RETURNS_NON_NULL
15314inline 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
15396template<typename FloatType>
15397JSON_HEDLEY_NON_NULL(1, 2)
15398JSON_HEDLEY_RETURNS_NON_NULL
15399char* 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
15460namespace nlohmann
15461{
15462namespace detail
15463{
15465// serialization //
15467
15469enum class error_handler_t
15470{
15471 strict,
15472 replace,
15473 ignore
15474};
15475
15476template<typename BasicJsonType>
15477class 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
16398namespace nlohmann
16399{
16400
16403template <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::const_iterator;
16412 using typename Container::size_type;
16413 using typename Container::value_type;
16414
16415 // Explicit constructors instead of `using Container::Container`
16416 // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
16417 ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
16418 template <class It>
16419 ordered_map(It first, It last, const Allocator& alloc = Allocator())
16420 : Container{first, last, alloc} {}
16421 ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
16422 : Container{init, alloc} {}
16423
16424 std::pair<iterator, bool> emplace(const key_type& key, T&& t)
16425 {
16426 for (auto it = this->begin(); it != this->end(); ++it)
16427 {
16428 if (it->first == key)
16429 {
16430 return {it, false};
16431 }
16432 }
16433 Container::emplace_back(key, t);
16434 return {--this->end(), true};
16435 }
16436
16437 T& operator[](const Key& key)
16438 {
16439 return emplace(key, T{}).first->second;
16440 }
16441
16442 const T& operator[](const Key& key) const
16443 {
16444 return at(key);
16445 }
16446
16447 T& at(const Key& key)
16448 {
16449 for (auto it = this->begin(); it != this->end(); ++it)
16450 {
16451 if (it->first == key)
16452 {
16453 return it->second;
16454 }
16455 }
16456
16457 throw std::out_of_range("key not found");
16458 }
16459
16460 const T& at(const Key& key) const
16461 {
16462 for (auto it = this->begin(); it != this->end(); ++it)
16463 {
16464 if (it->first == key)
16465 {
16466 return it->second;
16467 }
16468 }
16469
16470 throw std::out_of_range("key not found");
16471 }
16472
16473 size_type erase(const Key& key)
16474 {
16475 for (auto it = this->begin(); it != this->end(); ++it)
16476 {
16477 if (it->first == key)
16478 {
16479 // Since we cannot move const Keys, re-construct them in place
16480 for (auto next = it; ++next != this->end(); ++it)
16481 {
16482 it->~value_type(); // Destroy but keep allocation
16483 new (&*it) value_type{std::move(*next)};
16484 }
16485 Container::pop_back();
16486 return 1;
16487 }
16488 }
16489 return 0;
16490 }
16491
16492 iterator erase(iterator pos)
16493 {
16494 auto it = pos;
16495
16496 // Since we cannot move const Keys, re-construct them in place
16497 for (auto next = it; ++next != this->end(); ++it)
16498 {
16499 it->~value_type(); // Destroy but keep allocation
16500 new (&*it) value_type{std::move(*next)};
16501 }
16502 Container::pop_back();
16503 return pos;
16504 }
16505
16506 size_type count(const Key& key) const
16507 {
16508 for (auto it = this->begin(); it != this->end(); ++it)
16509 {
16510 if (it->first == key)
16511 {
16512 return 1;
16513 }
16514 }
16515 return 0;
16516 }
16517
16518 iterator find(const Key& key)
16519 {
16520 for (auto it = this->begin(); it != this->end(); ++it)
16521 {
16522 if (it->first == key)
16523 {
16524 return it;
16525 }
16526 }
16527 return Container::end();
16528 }
16529
16530 const_iterator find(const Key& key) const
16531 {
16532 for (auto it = this->begin(); it != this->end(); ++it)
16533 {
16534 if (it->first == key)
16535 {
16536 return it;
16537 }
16538 }
16539 return Container::end();
16540 }
16541
16542 std::pair<iterator, bool> insert( value_type&& value )
16543 {
16544 return emplace(value.first, std::move(value.second));
16545 }
16546
16547 std::pair<iterator, bool> insert( const value_type& value )
16548 {
16549 for (auto it = this->begin(); it != this->end(); ++it)
16550 {
16551 if (it->first == value.first)
16552 {
16553 return {it, false};
16554 }
16555 }
16556 Container::push_back(value);
16557 return {--this->end(), true};
16558 }
16559};
16560
16561} // namespace nlohmann
16562
16563
16569namespace nlohmann
16570{
16571
16656NLOHMANN_BASIC_JSON_TPL_DECLARATION
16657class basic_json
16658{
16659 private:
16660 template<detail::value_t> friend struct detail::external_constructor;
16661 friend ::nlohmann::json_pointer<basic_json>;
16662
16663 template<typename BasicJsonType, typename InputType>
16664 friend class ::nlohmann::detail::parser;
16665 friend ::nlohmann::detail::serializer<basic_json>;
16666 template<typename BasicJsonType>
16667 friend class ::nlohmann::detail::iter_impl;
16668 template<typename BasicJsonType, typename CharType>
16669 friend class ::nlohmann::detail::binary_writer;
16670 template<typename BasicJsonType, typename InputType, typename SAX>
16671 friend class ::nlohmann::detail::binary_reader;
16672 template<typename BasicJsonType>
16673 friend class ::nlohmann::detail::json_sax_dom_parser;
16674 template<typename BasicJsonType>
16675 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
16676
16678 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
16679
16680 // convenience aliases for types residing in namespace detail;
16681 using lexer = ::nlohmann::detail::lexer_base<basic_json>;
16682
16683 template<typename InputAdapterType>
16684 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
16685 InputAdapterType adapter,
16686 detail::parser_callback_t<basic_json>cb = nullptr,
16687 const bool allow_exceptions = true,
16688 const bool ignore_comments = false
16689 )
16690 {
16691 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
16692 std::move(cb), allow_exceptions, ignore_comments);
16693 }
16694
16695 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
16696 template<typename BasicJsonType>
16697 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
16698 template<typename BasicJsonType>
16699 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
16700 template<typename Iterator>
16701 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
16702 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
16703
16704 template<typename CharType>
16705 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
16706
16707 template<typename InputType>
16708 using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
16709 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
16710
16711 using serializer = ::nlohmann::detail::serializer<basic_json>;
16712
16713 public:
16714 using value_t = detail::value_t;
16716 using json_pointer = ::nlohmann::json_pointer<basic_json>;
16717 template<typename T, typename SFINAE>
16718 using json_serializer = JSONSerializer<T, SFINAE>;
16720 using error_handler_t = detail::error_handler_t;
16722 using cbor_tag_handler_t = detail::cbor_tag_handler_t;
16724 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
16725
16726 using input_format_t = detail::input_format_t;
16728 using json_sax_t = json_sax<basic_json>;
16729
16731 // exceptions //
16733
16737
16739 using exception = detail::exception;
16741 using parse_error = detail::parse_error;
16743 using invalid_iterator = detail::invalid_iterator;
16745 using type_error = detail::type_error;
16747 using out_of_range = detail::out_of_range;
16749 using other_error = detail::other_error;
16750
16752
16753
16755 // container types //
16757
16762
16764 using value_type = basic_json;
16765
16767 using reference = value_type&;
16769 using const_reference = const value_type&;
16770
16772 using difference_type = std::ptrdiff_t;
16774 using size_type = std::size_t;
16775
16777 using allocator_type = AllocatorType<basic_json>;
16778
16780 using pointer = typename std::allocator_traits<allocator_type>::pointer;
16782 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
16783
16785 using iterator = iter_impl<basic_json>;
16787 using const_iterator = iter_impl<const basic_json>;
16789 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
16791 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
16792
16794
16795
16799 static allocator_type get_allocator()
16800 {
16801 return allocator_type();
16802 }
16803
16830 JSON_HEDLEY_WARN_UNUSED_RESULT
16831 static basic_json meta()
16832 {
16833 basic_json result;
16834
16835 result["copyright"] = "(C) 2013-2020 Niels Lohmann";
16836 result["name"] = "JSON for Modern C++";
16837 result["url"] = "https://github.com/nlohmann/json";
16838 result["version"]["string"] =
16839 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
16840 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
16841 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
16842 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
16843 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
16844 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
16845
16846#ifdef _WIN32
16847 result["platform"] = "win32";
16848#elif defined __linux__
16849 result["platform"] = "linux";
16850#elif defined __APPLE__
16851 result["platform"] = "apple";
16852#elif defined __unix__
16853 result["platform"] = "unix";
16854#else
16855 result["platform"] = "unknown";
16856#endif
16857
16858#if defined(__ICC) || defined(__INTEL_COMPILER)
16859 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
16860#elif defined(__clang__)
16861 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
16862#elif defined(__GNUC__) || defined(__GNUG__)
16863 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
16864#elif defined(__HP_cc) || defined(__HP_aCC)
16865 result["compiler"] = "hp"
16866#elif defined(__IBMCPP__)
16867 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
16868#elif defined(_MSC_VER)
16869 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
16870#elif defined(__PGI)
16871 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
16872#elif defined(__SUNPRO_CC)
16873 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
16874#else
16875 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
16876#endif
16877
16878#ifdef __cplusplus
16879 result["compiler"]["c++"] = std::to_string(__cplusplus);
16880#else
16881 result["compiler"]["c++"] = "unknown";
16882#endif
16883 return result;
16884 }
16885
16886
16888 // JSON value data types //
16890
16895
16896#if defined(JSON_HAS_CPP_14)
16897 // Use transparent comparator if possible, combined with perfect forwarding
16898 // on find() and count() calls prevents unnecessary string construction.
16899 using object_comparator_t = std::less<>;
16900#else
16901 using object_comparator_t = std::less<StringType>;
16902#endif
16903
16987 using object_t = ObjectType<StringType,
16988 basic_json,
16989 object_comparator_t,
16990 AllocatorType<std::pair<const StringType,
16991 basic_json>>>;
16992
17037 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
17038
17090 using string_t = StringType;
17091
17116 using boolean_t = BooleanType;
17117
17188 using number_integer_t = NumberIntegerType;
17189
17259 using number_unsigned_t = NumberUnsignedType;
17260
17327 using number_float_t = NumberFloatType;
17328
17398 using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
17400
17401 private:
17402
17404 template<typename T, typename... Args>
17405 JSON_HEDLEY_RETURNS_NON_NULL
17406 static T* create(Args&& ... args)
17407 {
17408 AllocatorType<T> alloc;
17409 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
17410
17411 auto deleter = [&](T * object)
17412 {
17413 AllocatorTraits::deallocate(alloc, object, 1);
17414 };
17415 std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
17416 AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
17417 JSON_ASSERT(object != nullptr);
17418 return object.release();
17419 }
17420
17422 // JSON value storage //
17424
17450 union json_value
17451 {
17453 object_t* object;
17455 array_t* array;
17457 string_t* string;
17459 binary_t* binary;
17461 boolean_t boolean;
17463 number_integer_t number_integer;
17465 number_unsigned_t number_unsigned;
17467 number_float_t number_float;
17468
17470 json_value() = default;
17472 json_value(boolean_t v) noexcept : boolean(v) {}
17474 json_value(number_integer_t v) noexcept : number_integer(v) {}
17476 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
17478 json_value(number_float_t v) noexcept : number_float(v) {}
17480 json_value(value_t t)
17481 {
17482 switch (t)
17483 {
17484 case value_t::object:
17485 {
17486 object = create<object_t>();
17487 break;
17488 }
17489
17490 case value_t::array:
17491 {
17492 array = create<array_t>();
17493 break;
17494 }
17495
17496 case value_t::string:
17497 {
17498 string = create<string_t>("");
17499 break;
17500 }
17501
17502 case value_t::binary:
17503 {
17504 binary = create<binary_t>();
17505 break;
17506 }
17507
17508 case value_t::boolean:
17509 {
17510 boolean = boolean_t(false);
17511 break;
17512 }
17513
17514 case value_t::number_integer:
17515 {
17516 number_integer = number_integer_t(0);
17517 break;
17518 }
17519
17520 case value_t::number_unsigned:
17521 {
17522 number_unsigned = number_unsigned_t(0);
17523 break;
17524 }
17525
17526 case value_t::number_float:
17527 {
17528 number_float = number_float_t(0.0);
17529 break;
17530 }
17531
17532 case value_t::null:
17533 {
17534 object = nullptr; // silence warning, see #821
17535 break;
17536 }
17537
17538 default:
17539 {
17540 object = nullptr; // silence warning, see #821
17541 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
17542 {
17543 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.9.1")); // LCOV_EXCL_LINE
17544 }
17545 break;
17546 }
17547 }
17548 }
17549
17551 json_value(const string_t& value)
17552 {
17553 string = create<string_t>(value);
17554 }
17555
17557 json_value(string_t&& value)
17558 {
17559 string = create<string_t>(std::move(value));
17560 }
17561
17563 json_value(const object_t& value)
17564 {
17565 object = create<object_t>(value);
17566 }
17567
17569 json_value(object_t&& value)
17570 {
17571 object = create<object_t>(std::move(value));
17572 }
17573
17575 json_value(const array_t& value)
17576 {
17577 array = create<array_t>(value);
17578 }
17579
17581 json_value(array_t&& value)
17582 {
17583 array = create<array_t>(std::move(value));
17584 }
17585
17587 json_value(const typename binary_t::container_type& value)
17588 {
17589 binary = create<binary_t>(value);
17590 }
17591
17593 json_value(typename binary_t::container_type&& value)
17594 {
17595 binary = create<binary_t>(std::move(value));
17596 }
17597
17599 json_value(const binary_t& value)
17600 {
17601 binary = create<binary_t>(value);
17602 }
17603
17605 json_value(binary_t&& value)
17606 {
17607 binary = create<binary_t>(std::move(value));
17608 }
17609
17610 void destroy(value_t t) noexcept
17611 {
17612 // flatten the current json_value to a heap-allocated stack
17613 std::vector<basic_json> stack;
17614
17615 // move the top-level items to stack
17616 if (t == value_t::array)
17617 {
17618 stack.reserve(array->size());
17619 std::move(array->begin(), array->end(), std::back_inserter(stack));
17620 }
17621 else if (t == value_t::object)
17622 {
17623 stack.reserve(object->size());
17624 for (auto&& it : *object)
17625 {
17626 stack.push_back(std::move(it.second));
17627 }
17628 }
17629
17630 while (!stack.empty())
17631 {
17632 // move the last item to local variable to be processed
17633 basic_json current_item(std::move(stack.back()));
17634 stack.pop_back();
17635
17636 // if current_item is array/object, move
17637 // its children to the stack to be processed later
17638 if (current_item.is_array())
17639 {
17640 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
17641 std::back_inserter(stack));
17642
17643 current_item.m_value.array->clear();
17644 }
17645 else if (current_item.is_object())
17646 {
17647 for (auto&& it : *current_item.m_value.object)
17648 {
17649 stack.push_back(std::move(it.second));
17650 }
17651
17652 current_item.m_value.object->clear();
17653 }
17654
17655 // it's now safe that current_item get destructed
17656 // since it doesn't have any children
17657 }
17658
17659 switch (t)
17660 {
17661 case value_t::object:
17662 {
17663 AllocatorType<object_t> alloc;
17664 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
17665 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
17666 break;
17667 }
17668
17669 case value_t::array:
17670 {
17671 AllocatorType<array_t> alloc;
17672 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
17673 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
17674 break;
17675 }
17676
17677 case value_t::string:
17678 {
17679 AllocatorType<string_t> alloc;
17680 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
17681 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
17682 break;
17683 }
17684
17685 case value_t::binary:
17686 {
17687 AllocatorType<binary_t> alloc;
17688 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
17689 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
17690 break;
17691 }
17692
17693 default:
17694 {
17695 break;
17696 }
17697 }
17698 }
17699 };
17700
17710 void assert_invariant() const noexcept
17711 {
17712 JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
17713 JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
17714 JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
17715 JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
17716 }
17717
17718 public:
17720 // JSON parser callback //
17722
17738 using parse_event_t = detail::parse_event_t;
17739
17789 using parser_callback_t = detail::parser_callback_t<basic_json>;
17790
17792 // constructors //
17794
17799
17830 basic_json(const value_t v)
17831 : m_type(v), m_value(v)
17832 {
17833 assert_invariant();
17834 }
17835
17854 basic_json(std::nullptr_t = nullptr) noexcept
17855 : basic_json(value_t::null)
17856 {
17857 assert_invariant();
17858 }
17859
17923 template < typename CompatibleType,
17924 typename U = detail::uncvref_t<CompatibleType>,
17925 detail::enable_if_t <
17926 !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
17927 basic_json(CompatibleType && val) noexcept(noexcept(
17928 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
17929 std::forward<CompatibleType>(val))))
17930 {
17931 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
17932 assert_invariant();
17933 }
17934
17961 template < typename BasicJsonType,
17962 detail::enable_if_t <
17963 detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
17964 basic_json(const BasicJsonType& val)
17965 {
17966 using other_boolean_t = typename BasicJsonType::boolean_t;
17967 using other_number_float_t = typename BasicJsonType::number_float_t;
17968 using other_number_integer_t = typename BasicJsonType::number_integer_t;
17969 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
17970 using other_string_t = typename BasicJsonType::string_t;
17971 using other_object_t = typename BasicJsonType::object_t;
17972 using other_array_t = typename BasicJsonType::array_t;
17973 using other_binary_t = typename BasicJsonType::binary_t;
17974
17975 switch (val.type())
17976 {
17977 case value_t::boolean:
17978 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
17979 break;
17980 case value_t::number_float:
17981 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
17982 break;
17983 case value_t::number_integer:
17984 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
17985 break;
17986 case value_t::number_unsigned:
17987 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
17988 break;
17989 case value_t::string:
17990 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
17991 break;
17992 case value_t::object:
17993 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
17994 break;
17995 case value_t::array:
17996 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
17997 break;
17998 case value_t::binary:
17999 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
18000 break;
18001 case value_t::null:
18002 *this = nullptr;
18003 break;
18004 case value_t::discarded:
18005 m_type = value_t::discarded;
18006 break;
18007 default: // LCOV_EXCL_LINE
18008 JSON_ASSERT(false); // LCOV_EXCL_LINE
18009 }
18010 assert_invariant();
18011 }
18012
18087 basic_json(initializer_list_t init,
18088 bool type_deduction = true,
18089 value_t manual_type = value_t::array)
18090 {
18091 // check if each element is an array with two elements whose first
18092 // element is a string
18093 bool is_an_object = std::all_of(init.begin(), init.end(),
18094 [](const detail::json_ref<basic_json>& element_ref)
18095 {
18096 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
18097 });
18098
18099 // adjust type if type deduction is not wanted
18100 if (!type_deduction)
18101 {
18102 // if array is wanted, do not create an object though possible
18103 if (manual_type == value_t::array)
18104 {
18105 is_an_object = false;
18106 }
18107
18108 // if object is wanted but impossible, throw an exception
18109 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
18110 {
18111 JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
18112 }
18113 }
18114
18115 if (is_an_object)
18116 {
18117 // the initializer list is a list of pairs -> create object
18118 m_type = value_t::object;
18119 m_value = value_t::object;
18120
18121 std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
18122 {
18123 auto element = element_ref.moved_or_copied();
18124 m_value.object->emplace(
18125 std::move(*((*element.m_value.array)[0].m_value.string)),
18126 std::move((*element.m_value.array)[1]));
18127 });
18128 }
18129 else
18130 {
18131 // the initializer list describes an array -> create array
18132 m_type = value_t::array;
18133 m_value.array = create<array_t>(init.begin(), init.end());
18134 }
18135
18136 assert_invariant();
18137 }
18138
18166 JSON_HEDLEY_WARN_UNUSED_RESULT
18167 static basic_json binary(const typename binary_t::container_type& init)
18168 {
18169 auto res = basic_json();
18170 res.m_type = value_t::binary;
18171 res.m_value = init;
18172 return res;
18173 }
18174
18203 JSON_HEDLEY_WARN_UNUSED_RESULT
18204 static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype)
18205 {
18206 auto res = basic_json();
18207 res.m_type = value_t::binary;
18208 res.m_value = binary_t(init, subtype);
18209 return res;
18210 }
18211
18213 JSON_HEDLEY_WARN_UNUSED_RESULT
18214 static basic_json binary(typename binary_t::container_type&& init)
18215 {
18216 auto res = basic_json();
18217 res.m_type = value_t::binary;
18218 res.m_value = std::move(init);
18219 return res;
18220 }
18221
18223 JSON_HEDLEY_WARN_UNUSED_RESULT
18224 static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype)
18225 {
18226 auto res = basic_json();
18227 res.m_type = value_t::binary;
18228 res.m_value = binary_t(std::move(init), subtype);
18229 return res;
18230 }
18231
18269 JSON_HEDLEY_WARN_UNUSED_RESULT
18270 static basic_json array(initializer_list_t init = {})
18271 {
18272 return basic_json(init, false, value_t::array);
18273 }
18274
18313 JSON_HEDLEY_WARN_UNUSED_RESULT
18314 static basic_json object(initializer_list_t init = {})
18315 {
18316 return basic_json(init, false, value_t::object);
18317 }
18318
18341 basic_json(size_type cnt, const basic_json& val)
18342 : m_type(value_t::array)
18343 {
18344 m_value.array = create<array_t>(cnt, val);
18345 assert_invariant();
18346 }
18347
18403 template < class InputIT, typename std::enable_if <
18404 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
18405 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
18406 basic_json(InputIT first, InputIT last)
18407 {
18408 JSON_ASSERT(first.m_object != nullptr);
18409 JSON_ASSERT(last.m_object != nullptr);
18410
18411 // make sure iterator fits the current value
18412 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
18413 {
18414 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
18415 }
18416
18417 // copy type from first iterator
18418 m_type = first.m_object->m_type;
18419
18420 // check if iterator range is complete for primitive values
18421 switch (m_type)
18422 {
18423 case value_t::boolean:
18424 case value_t::number_float:
18425 case value_t::number_integer:
18426 case value_t::number_unsigned:
18427 case value_t::string:
18428 {
18429 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
18430 || !last.m_it.primitive_iterator.is_end()))
18431 {
18432 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
18433 }
18434 break;
18435 }
18436
18437 default:
18438 break;
18439 }
18440
18441 switch (m_type)
18442 {
18443 case value_t::number_integer:
18444 {
18445 m_value.number_integer = first.m_object->m_value.number_integer;
18446 break;
18447 }
18448
18449 case value_t::number_unsigned:
18450 {
18451 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
18452 break;
18453 }
18454
18455 case value_t::number_float:
18456 {
18457 m_value.number_float = first.m_object->m_value.number_float;
18458 break;
18459 }
18460
18461 case value_t::boolean:
18462 {
18463 m_value.boolean = first.m_object->m_value.boolean;
18464 break;
18465 }
18466
18467 case value_t::string:
18468 {
18469 m_value = *first.m_object->m_value.string;
18470 break;
18471 }
18472
18473 case value_t::object:
18474 {
18475 m_value.object = create<object_t>(first.m_it.object_iterator,
18476 last.m_it.object_iterator);
18477 break;
18478 }
18479
18480 case value_t::array:
18481 {
18482 m_value.array = create<array_t>(first.m_it.array_iterator,
18483 last.m_it.array_iterator);
18484 break;
18485 }
18486
18487 case value_t::binary:
18488 {
18489 m_value = *first.m_object->m_value.binary;
18490 break;
18491 }
18492
18493 default:
18494 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
18495 std::string(first.m_object->type_name())));
18496 }
18497
18498 assert_invariant();
18499 }
18500
18501
18503 // other constructors and destructor //
18505
18506 template<typename JsonRef,
18507 detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
18508 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
18509 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
18510
18536 basic_json(const basic_json& other)
18537 : m_type(other.m_type)
18538 {
18539 // check of passed value is valid
18540 other.assert_invariant();
18541
18542 switch (m_type)
18543 {
18544 case value_t::object:
18545 {
18546 m_value = *other.m_value.object;
18547 break;
18548 }
18549
18550 case value_t::array:
18551 {
18552 m_value = *other.m_value.array;
18553 break;
18554 }
18555
18556 case value_t::string:
18557 {
18558 m_value = *other.m_value.string;
18559 break;
18560 }
18561
18562 case value_t::boolean:
18563 {
18564 m_value = other.m_value.boolean;
18565 break;
18566 }
18567
18568 case value_t::number_integer:
18569 {
18570 m_value = other.m_value.number_integer;
18571 break;
18572 }
18573
18574 case value_t::number_unsigned:
18575 {
18576 m_value = other.m_value.number_unsigned;
18577 break;
18578 }
18579
18580 case value_t::number_float:
18581 {
18582 m_value = other.m_value.number_float;
18583 break;
18584 }
18585
18586 case value_t::binary:
18587 {
18588 m_value = *other.m_value.binary;
18589 break;
18590 }
18591
18592 default:
18593 break;
18594 }
18595
18596 assert_invariant();
18597 }
18598
18625 basic_json(basic_json&& other) noexcept
18626 : m_type(std::move(other.m_type)),
18627 m_value(std::move(other.m_value))
18628 {
18629 // check that passed value is valid
18630 other.assert_invariant();
18631
18632 // invalidate payload
18633 other.m_type = value_t::null;
18634 other.m_value = {};
18635
18636 assert_invariant();
18637 }
18638
18662 basic_json& operator=(basic_json other) noexcept (
18663 std::is_nothrow_move_constructible<value_t>::value&&
18664 std::is_nothrow_move_assignable<value_t>::value&&
18665 std::is_nothrow_move_constructible<json_value>::value&&
18666 std::is_nothrow_move_assignable<json_value>::value
18667 )
18668 {
18669 // check that passed value is valid
18670 other.assert_invariant();
18671
18672 using std::swap;
18673 swap(m_type, other.m_type);
18674 swap(m_value, other.m_value);
18675
18676 assert_invariant();
18677 return *this;
18678 }
18679
18695 ~basic_json() noexcept
18696 {
18697 assert_invariant();
18698 m_value.destroy(m_type);
18699 }
18700
18702
18703 public:
18705 // object inspection //
18707
18711
18759 string_t dump(const int indent = -1,
18760 const char indent_char = ' ',
18761 const bool ensure_ascii = false,
18762 const error_handler_t error_handler = error_handler_t::strict) const
18763 {
18764 string_t result;
18765 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
18766
18767 if (indent >= 0)
18768 {
18769 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
18770 }
18771 else
18772 {
18773 s.dump(*this, false, ensure_ascii, 0);
18774 }
18775
18776 return result;
18777 }
18778
18812 constexpr value_t type() const noexcept
18813 {
18814 return m_type;
18815 }
18816
18843 constexpr bool is_primitive() const noexcept
18844 {
18845 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
18846 }
18847
18870 constexpr bool is_structured() const noexcept
18871 {
18872 return is_array() || is_object();
18873 }
18874
18892 constexpr bool is_null() const noexcept
18893 {
18894 return m_type == value_t::null;
18895 }
18896
18914 constexpr bool is_boolean() const noexcept
18915 {
18916 return m_type == value_t::boolean;
18917 }
18918
18944 constexpr bool is_number() const noexcept
18945 {
18946 return is_number_integer() || is_number_float();
18947 }
18948
18973 constexpr bool is_number_integer() const noexcept
18974 {
18975 return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
18976 }
18977
19001 constexpr bool is_number_unsigned() const noexcept
19002 {
19003 return m_type == value_t::number_unsigned;
19004 }
19005
19029 constexpr bool is_number_float() const noexcept
19030 {
19031 return m_type == value_t::number_float;
19032 }
19033
19051 constexpr bool is_object() const noexcept
19052 {
19053 return m_type == value_t::object;
19054 }
19055
19073 constexpr bool is_array() const noexcept
19074 {
19075 return m_type == value_t::array;
19076 }
19077
19095 constexpr bool is_string() const noexcept
19096 {
19097 return m_type == value_t::string;
19098 }
19099
19117 constexpr bool is_binary() const noexcept
19118 {
19119 return m_type == value_t::binary;
19120 }
19121
19144 constexpr bool is_discarded() const noexcept
19145 {
19146 return m_type == value_t::discarded;
19147 }
19148
19170 constexpr operator value_t() const noexcept
19171 {
19172 return m_type;
19173 }
19174
19176
19177 private:
19179 // value access //
19181
19183 boolean_t get_impl(boolean_t* /*unused*/) const
19184 {
19185 if (JSON_HEDLEY_LIKELY(is_boolean()))
19186 {
19187 return m_value.boolean;
19188 }
19189
19190 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
19191 }
19192
19194 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
19195 {
19196 return is_object() ? m_value.object : nullptr;
19197 }
19198
19200 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
19201 {
19202 return is_object() ? m_value.object : nullptr;
19203 }
19204
19206 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
19207 {
19208 return is_array() ? m_value.array : nullptr;
19209 }
19210
19212 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
19213 {
19214 return is_array() ? m_value.array : nullptr;
19215 }
19216
19218 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
19219 {
19220 return is_string() ? m_value.string : nullptr;
19221 }
19222
19224 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
19225 {
19226 return is_string() ? m_value.string : nullptr;
19227 }
19228
19230 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
19231 {
19232 return is_boolean() ? &m_value.boolean : nullptr;
19233 }
19234
19236 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
19237 {
19238 return is_boolean() ? &m_value.boolean : nullptr;
19239 }
19240
19242 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
19243 {
19244 return is_number_integer() ? &m_value.number_integer : nullptr;
19245 }
19246
19248 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
19249 {
19250 return is_number_integer() ? &m_value.number_integer : nullptr;
19251 }
19252
19254 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
19255 {
19256 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19257 }
19258
19260 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
19261 {
19262 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19263 }
19264
19266 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
19267 {
19268 return is_number_float() ? &m_value.number_float : nullptr;
19269 }
19270
19272 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
19273 {
19274 return is_number_float() ? &m_value.number_float : nullptr;
19275 }
19276
19278 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
19279 {
19280 return is_binary() ? m_value.binary : nullptr;
19281 }
19282
19284 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
19285 {
19286 return is_binary() ? m_value.binary : nullptr;
19287 }
19288
19300 template<typename ReferenceType, typename ThisType>
19301 static ReferenceType get_ref_impl(ThisType& obj)
19302 {
19303 // delegate the call to get_ptr<>()
19304 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
19305
19306 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
19307 {
19308 return *ptr;
19309 }
19310
19311 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
19312 }
19313
19314 public:
19318
19333 template<typename BasicJsonType, detail::enable_if_t<
19334 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
19335 int> = 0>
19336 basic_json get() const
19337 {
19338 return *this;
19339 }
19340
19356 template < typename BasicJsonType, detail::enable_if_t <
19357 !std::is_same<BasicJsonType, basic_json>::value&&
19358 detail::is_basic_json<BasicJsonType>::value, int > = 0 >
19359 BasicJsonType get() const
19360 {
19361 return *this;
19362 }
19363
19403 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
19404 detail::enable_if_t <
19405 !detail::is_basic_json<ValueType>::value &&
19406 detail::has_from_json<basic_json_t, ValueType>::value &&
19407 !detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19408 int > = 0 >
19409 ValueType get() const noexcept(noexcept(
19410 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
19411 {
19412 // we cannot static_assert on ValueTypeCV being non-const, because
19413 // there is support for get<const basic_json_t>(), which is why we
19414 // still need the uncvref
19415 static_assert(!std::is_reference<ValueTypeCV>::value,
19416 "get() cannot be used with reference types, you might want to use get_ref()");
19417 static_assert(std::is_default_constructible<ValueType>::value,
19418 "types must be DefaultConstructible when used with get()");
19419
19420 ValueType ret;
19421 JSONSerializer<ValueType>::from_json(*this, ret);
19422 return ret;
19423 }
19424
19456 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
19457 detail::enable_if_t < !std::is_same<basic_json_t, ValueType>::value &&
19458 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19459 int > = 0 >
19460 ValueType get() const noexcept(noexcept(
19461 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
19462 {
19463 static_assert(!std::is_reference<ValueTypeCV>::value,
19464 "get() cannot be used with reference types, you might want to use get_ref()");
19465 return JSONSerializer<ValueType>::from_json(*this);
19466 }
19467
19501 template < typename ValueType,
19502 detail::enable_if_t <
19503 !detail::is_basic_json<ValueType>::value&&
19504 detail::has_from_json<basic_json_t, ValueType>::value,
19505 int > = 0 >
19506 ValueType & get_to(ValueType& v) const noexcept(noexcept(
19507 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
19508 {
19509 JSONSerializer<ValueType>::from_json(*this, v);
19510 return v;
19511 }
19512
19513 // specialization to allow to call get_to with a basic_json value
19514 // see https://github.com/nlohmann/json/issues/2175
19515 template<typename ValueType,
19516 detail::enable_if_t <
19517 detail::is_basic_json<ValueType>::value,
19518 int> = 0>
19519 ValueType & get_to(ValueType& v) const
19520 {
19521 v = *this;
19522 return v;
19523 }
19524
19525 template <
19526 typename T, std::size_t N,
19527 typename Array = T (&)[N],
19528 detail::enable_if_t <
19529 detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
19530 Array get_to(T (&v)[N]) const
19531 noexcept(noexcept(JSONSerializer<Array>::from_json(
19532 std::declval<const basic_json_t&>(), v)))
19533 {
19534 JSONSerializer<Array>::from_json(*this, v);
19535 return v;
19536 }
19537
19538
19565 template<typename PointerType, typename std::enable_if<
19566 std::is_pointer<PointerType>::value, int>::type = 0>
19567 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19568 {
19569 // delegate the call to get_impl_ptr<>()
19570 return get_impl_ptr(static_cast<PointerType>(nullptr));
19571 }
19572
19577 template < typename PointerType, typename std::enable_if <
19578 std::is_pointer<PointerType>::value&&
19579 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
19580 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19581 {
19582 // delegate the call to get_impl_ptr<>() const
19583 return get_impl_ptr(static_cast<PointerType>(nullptr));
19584 }
19585
19613 template<typename PointerType, typename std::enable_if<
19614 std::is_pointer<PointerType>::value, int>::type = 0>
19615 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
19616 {
19617 // delegate the call to get_ptr
19618 return get_ptr<PointerType>();
19619 }
19620
19625 template<typename PointerType, typename std::enable_if<
19626 std::is_pointer<PointerType>::value, int>::type = 0>
19627 constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
19628 {
19629 // delegate the call to get_ptr
19630 return get_ptr<PointerType>();
19631 }
19632
19659 template<typename ReferenceType, typename std::enable_if<
19660 std::is_reference<ReferenceType>::value, int>::type = 0>
19661 ReferenceType get_ref()
19662 {
19663 // delegate call to get_ref_impl
19664 return get_ref_impl<ReferenceType>(*this);
19665 }
19666
19671 template < typename ReferenceType, typename std::enable_if <
19672 std::is_reference<ReferenceType>::value&&
19673 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
19674 ReferenceType get_ref() const
19675 {
19676 // delegate call to get_ref_impl
19677 return get_ref_impl<ReferenceType>(*this);
19678 }
19679
19709 template < typename ValueType, typename std::enable_if <
19710 !std::is_pointer<ValueType>::value&&
19711 !std::is_same<ValueType, detail::json_ref<basic_json>>::value&&
19712 !std::is_same<ValueType, typename string_t::value_type>::value&&
19713 !detail::is_basic_json<ValueType>::value
19714 && !std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
19715#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
19716 && !std::is_same<ValueType, typename std::string_view>::value
19717#endif
19718 && detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
19719 , int >::type = 0 >
19720 JSON_EXPLICIT operator ValueType() const
19721 {
19722 // delegate the call to get<>() const
19723 return get<ValueType>();
19724 }
19725
19735 binary_t& get_binary()
19736 {
19737 if (!is_binary())
19738 {
19739 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19740 }
19741
19742 return *get_ptr<binary_t*>();
19743 }
19744
19746 const binary_t& get_binary() const
19747 {
19748 if (!is_binary())
19749 {
19750 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19751 }
19752
19753 return *get_ptr<const binary_t*>();
19754 }
19755
19757
19758
19760 // element access //
19762
19766
19793 reference at(size_type idx)
19794 {
19795 // at only works for arrays
19796 if (JSON_HEDLEY_LIKELY(is_array()))
19797 {
19798 JSON_TRY
19799 {
19800 return m_value.array->at(idx);
19801 }
19802 JSON_CATCH (std::out_of_range&)
19803 {
19804 // create better exception explanation
19805 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19806 }
19807 }
19808 else
19809 {
19810 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19811 }
19812 }
19813
19840 const_reference at(size_type idx) const
19841 {
19842 // at only works for arrays
19843 if (JSON_HEDLEY_LIKELY(is_array()))
19844 {
19845 JSON_TRY
19846 {
19847 return m_value.array->at(idx);
19848 }
19849 JSON_CATCH (std::out_of_range&)
19850 {
19851 // create better exception explanation
19852 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19853 }
19854 }
19855 else
19856 {
19857 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19858 }
19859 }
19860
19891 reference at(const typename object_t::key_type& key)
19892 {
19893 // at only works for objects
19894 if (JSON_HEDLEY_LIKELY(is_object()))
19895 {
19896 JSON_TRY
19897 {
19898 return m_value.object->at(key);
19899 }
19900 JSON_CATCH (std::out_of_range&)
19901 {
19902 // create better exception explanation
19903 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19904 }
19905 }
19906 else
19907 {
19908 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19909 }
19910 }
19911
19942 const_reference at(const typename object_t::key_type& key) const
19943 {
19944 // at only works for objects
19945 if (JSON_HEDLEY_LIKELY(is_object()))
19946 {
19947 JSON_TRY
19948 {
19949 return m_value.object->at(key);
19950 }
19951 JSON_CATCH (std::out_of_range&)
19952 {
19953 // create better exception explanation
19954 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19955 }
19956 }
19957 else
19958 {
19959 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19960 }
19961 }
19962
19988 reference operator[](size_type idx)
19989 {
19990 // implicitly convert null value to an empty array
19991 if (is_null())
19992 {
19993 m_type = value_t::array;
19994 m_value.array = create<array_t>();
19995 assert_invariant();
19996 }
19997
19998 // operator[] only works for arrays
19999 if (JSON_HEDLEY_LIKELY(is_array()))
20000 {
20001 // fill up array with null values if given idx is outside range
20002 if (idx >= m_value.array->size())
20003 {
20004 m_value.array->insert(m_value.array->end(),
20005 idx - m_value.array->size() + 1,
20006 basic_json());
20007 }
20008
20009 return m_value.array->operator[](idx);
20010 }
20011
20012 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
20013 }
20014
20034 const_reference operator[](size_type idx) const
20035 {
20036 // const operator[] only works for arrays
20037 if (JSON_HEDLEY_LIKELY(is_array()))
20038 {
20039 return m_value.array->operator[](idx);
20040 }
20041
20042 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
20043 }
20044
20072 reference operator[](const typename object_t::key_type& key)
20073 {
20074 // implicitly convert null value to an empty object
20075 if (is_null())
20076 {
20077 m_type = value_t::object;
20078 m_value.object = create<object_t>();
20079 assert_invariant();
20080 }
20081
20082 // operator[] only works for objects
20083 if (JSON_HEDLEY_LIKELY(is_object()))
20084 {
20085 return m_value.object->operator[](key);
20086 }
20087
20088 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20089 }
20090
20121 const_reference operator[](const typename object_t::key_type& key) const
20122 {
20123 // const operator[] only works for objects
20124 if (JSON_HEDLEY_LIKELY(is_object()))
20125 {
20126 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20127 return m_value.object->find(key)->second;
20128 }
20129
20130 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20131 }
20132
20160 template<typename T>
20161 JSON_HEDLEY_NON_NULL(2)
20162 reference operator[](T* key)
20163 {
20164 // implicitly convert null to object
20165 if (is_null())
20166 {
20167 m_type = value_t::object;
20168 m_value = value_t::object;
20169 assert_invariant();
20170 }
20171
20172 // at only works for objects
20173 if (JSON_HEDLEY_LIKELY(is_object()))
20174 {
20175 return m_value.object->operator[](key);
20176 }
20177
20178 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20179 }
20180
20211 template<typename T>
20212 JSON_HEDLEY_NON_NULL(2)
20213 const_reference operator[](T* key) const
20214 {
20215 // at only works for objects
20216 if (JSON_HEDLEY_LIKELY(is_object()))
20217 {
20218 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20219 return m_value.object->find(key)->second;
20220 }
20221
20222 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20223 }
20224
20275 // using std::is_convertible in a std::enable_if will fail when using explicit conversions
20276 template < class ValueType, typename std::enable_if <
20277 detail::is_getable<basic_json_t, ValueType>::value
20278 && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
20279 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
20280 {
20281 // at only works for objects
20282 if (JSON_HEDLEY_LIKELY(is_object()))
20283 {
20284 // if key is found, return value and given default value otherwise
20285 const auto it = find(key);
20286 if (it != end())
20287 {
20288 return it->template get<ValueType>();
20289 }
20290
20291 return default_value;
20292 }
20293
20294 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
20295 }
20296
20301 string_t value(const typename object_t::key_type& key, const char* default_value) const
20302 {
20303 return value(key, string_t(default_value));
20304 }
20305
20349 template<class ValueType, typename std::enable_if<
20350 detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
20351 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
20352 {
20353 // at only works for objects
20354 if (JSON_HEDLEY_LIKELY(is_object()))
20355 {
20356 // if pointer resolves a value, return it or use default value
20357 JSON_TRY
20358 {
20359 return ptr.get_checked(this).template get<ValueType>();
20360 }
20361 JSON_INTERNAL_CATCH (out_of_range&)
20362 {
20363 return default_value;
20364 }
20365 }
20366
20367 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
20368 }
20369
20374 JSON_HEDLEY_NON_NULL(3)
20375 string_t value(const json_pointer& ptr, const char* default_value) const
20376 {
20377 return value(ptr, string_t(default_value));
20378 }
20379
20405 reference front()
20406 {
20407 return *begin();
20408 }
20409
20413 const_reference front() const
20414 {
20415 return *cbegin();
20416 }
20417
20449 reference back()
20450 {
20451 auto tmp = end();
20452 --tmp;
20453 return *tmp;
20454 }
20455
20459 const_reference back() const
20460 {
20461 auto tmp = cend();
20462 --tmp;
20463 return *tmp;
20464 }
20465
20512 template < class IteratorType, typename std::enable_if <
20513 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20514 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
20515 = 0 >
20516 IteratorType erase(IteratorType pos)
20517 {
20518 // make sure iterator fits the current value
20519 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
20520 {
20521 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
20522 }
20523
20524 IteratorType result = end();
20525
20526 switch (m_type)
20527 {
20528 case value_t::boolean:
20529 case value_t::number_float:
20530 case value_t::number_integer:
20531 case value_t::number_unsigned:
20532 case value_t::string:
20533 case value_t::binary:
20534 {
20535 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
20536 {
20537 JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
20538 }
20539
20540 if (is_string())
20541 {
20542 AllocatorType<string_t> alloc;
20543 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20544 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20545 m_value.string = nullptr;
20546 }
20547 else if (is_binary())
20548 {
20549 AllocatorType<binary_t> alloc;
20550 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20551 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20552 m_value.binary = nullptr;
20553 }
20554
20555 m_type = value_t::null;
20556 assert_invariant();
20557 break;
20558 }
20559
20560 case value_t::object:
20561 {
20562 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
20563 break;
20564 }
20565
20566 case value_t::array:
20567 {
20568 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
20569 break;
20570 }
20571
20572 default:
20573 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20574 }
20575
20576 return result;
20577 }
20578
20625 template < class IteratorType, typename std::enable_if <
20626 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20627 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
20628 = 0 >
20629 IteratorType erase(IteratorType first, IteratorType last)
20630 {
20631 // make sure iterator fits the current value
20632 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
20633 {
20634 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
20635 }
20636
20637 IteratorType result = end();
20638
20639 switch (m_type)
20640 {
20641 case value_t::boolean:
20642 case value_t::number_float:
20643 case value_t::number_integer:
20644 case value_t::number_unsigned:
20645 case value_t::string:
20646 case value_t::binary:
20647 {
20648 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
20649 || !last.m_it.primitive_iterator.is_end()))
20650 {
20651 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
20652 }
20653
20654 if (is_string())
20655 {
20656 AllocatorType<string_t> alloc;
20657 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20658 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20659 m_value.string = nullptr;
20660 }
20661 else if (is_binary())
20662 {
20663 AllocatorType<binary_t> alloc;
20664 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20665 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20666 m_value.binary = nullptr;
20667 }
20668
20669 m_type = value_t::null;
20670 assert_invariant();
20671 break;
20672 }
20673
20674 case value_t::object:
20675 {
20676 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
20677 last.m_it.object_iterator);
20678 break;
20679 }
20680
20681 case value_t::array:
20682 {
20683 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
20684 last.m_it.array_iterator);
20685 break;
20686 }
20687
20688 default:
20689 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20690 }
20691
20692 return result;
20693 }
20694
20724 size_type erase(const typename object_t::key_type& key)
20725 {
20726 // this erase only works for objects
20727 if (JSON_HEDLEY_LIKELY(is_object()))
20728 {
20729 return m_value.object->erase(key);
20730 }
20731
20732 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20733 }
20734
20759 void erase(const size_type idx)
20760 {
20761 // this erase only works for arrays
20762 if (JSON_HEDLEY_LIKELY(is_array()))
20763 {
20764 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
20765 {
20766 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
20767 }
20768
20769 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
20770 }
20771 else
20772 {
20773 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20774 }
20775 }
20776
20778
20779
20781 // lookup //
20783
20786
20811 template<typename KeyT>
20812 iterator find(KeyT&& key)
20813 {
20814 auto result = end();
20815
20816 if (is_object())
20817 {
20818 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20819 }
20820
20821 return result;
20822 }
20823
20828 template<typename KeyT>
20829 const_iterator find(KeyT&& key) const
20830 {
20831 auto result = cend();
20832
20833 if (is_object())
20834 {
20835 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20836 }
20837
20838 return result;
20839 }
20840
20862 template<typename KeyT>
20863 size_type count(KeyT&& key) const
20864 {
20865 // return 0 for all nonobject types
20866 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
20867 }
20868
20894 template < typename KeyT, typename std::enable_if <
20895 !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
20896 bool contains(KeyT && key) const
20897 {
20898 return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
20899 }
20900
20927 bool contains(const json_pointer& ptr) const
20928 {
20929 return ptr.contains(this);
20930 }
20931
20933
20934
20936 // iterators //
20938
20941
20966 iterator begin() noexcept
20967 {
20968 iterator result(this);
20969 result.set_begin();
20970 return result;
20971 }
20972
20976 const_iterator begin() const noexcept
20977 {
20978 return cbegin();
20979 }
20980
21006 const_iterator cbegin() const noexcept
21007 {
21008 const_iterator result(this);
21009 result.set_begin();
21010 return result;
21011 }
21012
21037 iterator end() noexcept
21038 {
21039 iterator result(this);
21040 result.set_end();
21041 return result;
21042 }
21043
21047 const_iterator end() const noexcept
21048 {
21049 return cend();
21050 }
21051
21077 const_iterator cend() const noexcept
21078 {
21079 const_iterator result(this);
21080 result.set_end();
21081 return result;
21082 }
21083
21107 reverse_iterator rbegin() noexcept
21108 {
21109 return reverse_iterator(end());
21110 }
21111
21115 const_reverse_iterator rbegin() const noexcept
21116 {
21117 return crbegin();
21118 }
21119
21144 reverse_iterator rend() noexcept
21145 {
21146 return reverse_iterator(begin());
21147 }
21148
21152 const_reverse_iterator rend() const noexcept
21153 {
21154 return crend();
21155 }
21156
21181 const_reverse_iterator crbegin() const noexcept
21182 {
21183 return const_reverse_iterator(cend());
21184 }
21185
21210 const_reverse_iterator crend() const noexcept
21211 {
21212 return const_reverse_iterator(cbegin());
21213 }
21214
21215 public:
21273 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21274 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
21275 {
21276 return ref.items();
21277 }
21278
21282 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21283 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
21284 {
21285 return ref.items();
21286 }
21287
21356 iteration_proxy<iterator> items() noexcept
21357 {
21358 return iteration_proxy<iterator>(*this);
21359 }
21360
21364 iteration_proxy<const_iterator> items() const noexcept
21365 {
21366 return iteration_proxy<const_iterator>(*this);
21367 }
21368
21370
21371
21373 // capacity //
21375
21378
21421 bool empty() const noexcept
21422 {
21423 switch (m_type)
21424 {
21425 case value_t::null:
21426 {
21427 // null values are empty
21428 return true;
21429 }
21430
21431 case value_t::array:
21432 {
21433 // delegate call to array_t::empty()
21434 return m_value.array->empty();
21435 }
21436
21437 case value_t::object:
21438 {
21439 // delegate call to object_t::empty()
21440 return m_value.object->empty();
21441 }
21442
21443 default:
21444 {
21445 // all other types are nonempty
21446 return false;
21447 }
21448 }
21449 }
21450
21494 size_type size() const noexcept
21495 {
21496 switch (m_type)
21497 {
21498 case value_t::null:
21499 {
21500 // null values are empty
21501 return 0;
21502 }
21503
21504 case value_t::array:
21505 {
21506 // delegate call to array_t::size()
21507 return m_value.array->size();
21508 }
21509
21510 case value_t::object:
21511 {
21512 // delegate call to object_t::size()
21513 return m_value.object->size();
21514 }
21515
21516 default:
21517 {
21518 // all other types have size 1
21519 return 1;
21520 }
21521 }
21522 }
21523
21565 size_type max_size() const noexcept
21566 {
21567 switch (m_type)
21568 {
21569 case value_t::array:
21570 {
21571 // delegate call to array_t::max_size()
21572 return m_value.array->max_size();
21573 }
21574
21575 case value_t::object:
21576 {
21577 // delegate call to object_t::max_size()
21578 return m_value.object->max_size();
21579 }
21580
21581 default:
21582 {
21583 // all other types have max_size() == size()
21584 return size();
21585 }
21586 }
21587 }
21588
21590
21591
21593 // modifiers //
21595
21598
21636 void clear() noexcept
21637 {
21638 switch (m_type)
21639 {
21640 case value_t::number_integer:
21641 {
21642 m_value.number_integer = 0;
21643 break;
21644 }
21645
21646 case value_t::number_unsigned:
21647 {
21648 m_value.number_unsigned = 0;
21649 break;
21650 }
21651
21652 case value_t::number_float:
21653 {
21654 m_value.number_float = 0.0;
21655 break;
21656 }
21657
21658 case value_t::boolean:
21659 {
21660 m_value.boolean = false;
21661 break;
21662 }
21663
21664 case value_t::string:
21665 {
21666 m_value.string->clear();
21667 break;
21668 }
21669
21670 case value_t::binary:
21671 {
21672 m_value.binary->clear();
21673 break;
21674 }
21675
21676 case value_t::array:
21677 {
21678 m_value.array->clear();
21679 break;
21680 }
21681
21682 case value_t::object:
21683 {
21684 m_value.object->clear();
21685 break;
21686 }
21687
21688 default:
21689 break;
21690 }
21691 }
21692
21713 void push_back(basic_json&& val)
21714 {
21715 // push_back only works for null objects or arrays
21716 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21717 {
21718 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21719 }
21720
21721 // transform null object into an array
21722 if (is_null())
21723 {
21724 m_type = value_t::array;
21725 m_value = value_t::array;
21726 assert_invariant();
21727 }
21728
21729 // add element to array (move semantics)
21730 m_value.array->push_back(std::move(val));
21731 // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
21732 }
21733
21738 reference operator+=(basic_json&& val)
21739 {
21740 push_back(std::move(val));
21741 return *this;
21742 }
21743
21748 void push_back(const basic_json& val)
21749 {
21750 // push_back only works for null objects or arrays
21751 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21752 {
21753 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21754 }
21755
21756 // transform null object into an array
21757 if (is_null())
21758 {
21759 m_type = value_t::array;
21760 m_value = value_t::array;
21761 assert_invariant();
21762 }
21763
21764 // add element to array
21765 m_value.array->push_back(val);
21766 }
21767
21772 reference operator+=(const basic_json& val)
21773 {
21774 push_back(val);
21775 return *this;
21776 }
21777
21798 void push_back(const typename object_t::value_type& val)
21799 {
21800 // push_back only works for null objects or objects
21801 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21802 {
21803 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21804 }
21805
21806 // transform null object into an object
21807 if (is_null())
21808 {
21809 m_type = value_t::object;
21810 m_value = value_t::object;
21811 assert_invariant();
21812 }
21813
21814 // add element to array
21815 m_value.object->insert(val);
21816 }
21817
21822 reference operator+=(const typename object_t::value_type& val)
21823 {
21824 push_back(val);
21825 return *this;
21826 }
21827
21853 void push_back(initializer_list_t init)
21854 {
21855 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
21856 {
21857 basic_json&& key = init.begin()->moved_or_copied();
21858 push_back(typename object_t::value_type(
21859 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
21860 }
21861 else
21862 {
21863 push_back(basic_json(init));
21864 }
21865 }
21866
21871 reference operator+=(initializer_list_t init)
21872 {
21873 push_back(init);
21874 return *this;
21875 }
21876
21900 template<class... Args>
21901 reference emplace_back(Args&& ... args)
21902 {
21903 // emplace_back only works for null objects or arrays
21904 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21905 {
21906 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
21907 }
21908
21909 // transform null object into an array
21910 if (is_null())
21911 {
21912 m_type = value_t::array;
21913 m_value = value_t::array;
21914 assert_invariant();
21915 }
21916
21917 // add element to array (perfect forwarding)
21918#ifdef JSON_HAS_CPP_17
21919 return m_value.array->emplace_back(std::forward<Args>(args)...);
21920#else
21921 m_value.array->emplace_back(std::forward<Args>(args)...);
21922 return m_value.array->back();
21923#endif
21924 }
21925
21953 template<class... Args>
21954 std::pair<iterator, bool> emplace(Args&& ... args)
21955 {
21956 // emplace only works for null objects or arrays
21957 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21958 {
21959 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
21960 }
21961
21962 // transform null object into an object
21963 if (is_null())
21964 {
21965 m_type = value_t::object;
21966 m_value = value_t::object;
21967 assert_invariant();
21968 }
21969
21970 // add element to array (perfect forwarding)
21971 auto res = m_value.object->emplace(std::forward<Args>(args)...);
21972 // create result iterator and set iterator to the result of emplace
21973 auto it = begin();
21974 it.m_it.object_iterator = res.first;
21975
21976 // return pair of iterator and boolean
21977 return {it, res.second};
21978 }
21979
21983 template<typename... Args>
21984 iterator insert_iterator(const_iterator pos, Args&& ... args)
21985 {
21986 iterator result(this);
21987 JSON_ASSERT(m_value.array != nullptr);
21988
21989 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
21990 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
21991 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
21992
21993 // This could have been written as:
21994 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
21995 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
21996
21997 return result;
21998 }
21999
22022 iterator insert(const_iterator pos, const basic_json& val)
22023 {
22024 // insert only works for arrays
22025 if (JSON_HEDLEY_LIKELY(is_array()))
22026 {
22027 // check if iterator pos fits to this JSON value
22028 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22029 {
22030 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22031 }
22032
22033 // insert to array and return iterator
22034 return insert_iterator(pos, val);
22035 }
22036
22037 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22038 }
22039
22044 iterator insert(const_iterator pos, basic_json&& val)
22045 {
22046 return insert(pos, val);
22047 }
22048
22073 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
22074 {
22075 // insert only works for arrays
22076 if (JSON_HEDLEY_LIKELY(is_array()))
22077 {
22078 // check if iterator pos fits to this JSON value
22079 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22080 {
22081 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22082 }
22083
22084 // insert to array and return iterator
22085 return insert_iterator(pos, cnt, val);
22086 }
22087
22088 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22089 }
22090
22121 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
22122 {
22123 // insert only works for arrays
22124 if (JSON_HEDLEY_UNLIKELY(!is_array()))
22125 {
22126 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22127 }
22128
22129 // check if iterator pos fits to this JSON value
22130 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22131 {
22132 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22133 }
22134
22135 // check if range iterators belong to the same JSON object
22136 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22137 {
22138 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22139 }
22140
22141 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
22142 {
22143 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
22144 }
22145
22146 // insert to array and return iterator
22147 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
22148 }
22149
22174 iterator insert(const_iterator pos, initializer_list_t ilist)
22175 {
22176 // insert only works for arrays
22177 if (JSON_HEDLEY_UNLIKELY(!is_array()))
22178 {
22179 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22180 }
22181
22182 // check if iterator pos fits to this JSON value
22183 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22184 {
22185 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22186 }
22187
22188 // insert to array and return iterator
22189 return insert_iterator(pos, ilist.begin(), ilist.end());
22190 }
22191
22215 void insert(const_iterator first, const_iterator last)
22216 {
22217 // insert only works for objects
22218 if (JSON_HEDLEY_UNLIKELY(!is_object()))
22219 {
22220 JSON_THROW(type_error::create(309, "cannot use insert() 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 {
22232 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
22233 }
22234
22235 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
22236 }
22237
22257 void update(const_reference j)
22258 {
22259 // implicitly convert null value to an empty object
22260 if (is_null())
22261 {
22262 m_type = value_t::object;
22263 m_value.object = create<object_t>();
22264 assert_invariant();
22265 }
22266
22267 if (JSON_HEDLEY_UNLIKELY(!is_object()))
22268 {
22269 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
22270 }
22271 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
22272 {
22273 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
22274 }
22275
22276 for (auto it = j.cbegin(); it != j.cend(); ++it)
22277 {
22278 m_value.object->operator[](it.key()) = it.value();
22279 }
22280 }
22281
22308 void update(const_iterator first, const_iterator last)
22309 {
22310 // implicitly convert null value to an empty object
22311 if (is_null())
22312 {
22313 m_type = value_t::object;
22314 m_value.object = create<object_t>();
22315 assert_invariant();
22316 }
22317
22318 if (JSON_HEDLEY_UNLIKELY(!is_object()))
22319 {
22320 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
22321 }
22322
22323 // check if range iterators belong to the same JSON object
22324 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22325 {
22326 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22327 }
22328
22329 // passed iterators must belong to objects
22330 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
22331 || !last.m_object->is_object()))
22332 {
22333 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
22334 }
22335
22336 for (auto it = first; it != last; ++it)
22337 {
22338 m_value.object->operator[](it.key()) = it.value();
22339 }
22340 }
22341
22359 void swap(reference other) noexcept (
22360 std::is_nothrow_move_constructible<value_t>::value&&
22361 std::is_nothrow_move_assignable<value_t>::value&&
22362 std::is_nothrow_move_constructible<json_value>::value&&
22363 std::is_nothrow_move_assignable<json_value>::value
22364 )
22365 {
22366 std::swap(m_type, other.m_type);
22367 std::swap(m_value, other.m_value);
22368 assert_invariant();
22369 }
22370
22389 friend void swap(reference left, reference right) noexcept (
22390 std::is_nothrow_move_constructible<value_t>::value&&
22391 std::is_nothrow_move_assignable<value_t>::value&&
22392 std::is_nothrow_move_constructible<json_value>::value&&
22393 std::is_nothrow_move_assignable<json_value>::value
22394 )
22395 {
22396 left.swap(right);
22397 }
22398
22419 void swap(array_t& other)
22420 {
22421 // swap only works for arrays
22422 if (JSON_HEDLEY_LIKELY(is_array()))
22423 {
22424 std::swap(*(m_value.array), other);
22425 }
22426 else
22427 {
22428 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22429 }
22430 }
22431
22452 void swap(object_t& other)
22453 {
22454 // swap only works for objects
22455 if (JSON_HEDLEY_LIKELY(is_object()))
22456 {
22457 std::swap(*(m_value.object), other);
22458 }
22459 else
22460 {
22461 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22462 }
22463 }
22464
22485 void swap(string_t& other)
22486 {
22487 // swap only works for strings
22488 if (JSON_HEDLEY_LIKELY(is_string()))
22489 {
22490 std::swap(*(m_value.string), other);
22491 }
22492 else
22493 {
22494 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22495 }
22496 }
22497
22518 void swap(binary_t& other)
22519 {
22520 // swap only works for strings
22521 if (JSON_HEDLEY_LIKELY(is_binary()))
22522 {
22523 std::swap(*(m_value.binary), other);
22524 }
22525 else
22526 {
22527 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22528 }
22529 }
22530
22532 void swap(typename binary_t::container_type& other)
22533 {
22534 // swap only works for strings
22535 if (JSON_HEDLEY_LIKELY(is_binary()))
22536 {
22537 std::swap(*(m_value.binary), other);
22538 }
22539 else
22540 {
22541 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22542 }
22543 }
22544
22546
22547 public:
22549 // lexicographical comparison operators //
22551
22554
22610 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
22611 {
22612 const auto lhs_type = lhs.type();
22613 const auto rhs_type = rhs.type();
22614
22615 if (lhs_type == rhs_type)
22616 {
22617 switch (lhs_type)
22618 {
22619 case value_t::array:
22620 return *lhs.m_value.array == *rhs.m_value.array;
22621
22622 case value_t::object:
22623 return *lhs.m_value.object == *rhs.m_value.object;
22624
22625 case value_t::null:
22626 return true;
22627
22628 case value_t::string:
22629 return *lhs.m_value.string == *rhs.m_value.string;
22630
22631 case value_t::boolean:
22632 return lhs.m_value.boolean == rhs.m_value.boolean;
22633
22634 case value_t::number_integer:
22635 return lhs.m_value.number_integer == rhs.m_value.number_integer;
22636
22637 case value_t::number_unsigned:
22638 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
22639
22640 case value_t::number_float:
22641 return lhs.m_value.number_float == rhs.m_value.number_float;
22642
22643 case value_t::binary:
22644 return *lhs.m_value.binary == *rhs.m_value.binary;
22645
22646 default:
22647 return false;
22648 }
22649 }
22650 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
22651 {
22652 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
22653 }
22654 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
22655 {
22656 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
22657 }
22658 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
22659 {
22660 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
22661 }
22662 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
22663 {
22664 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
22665 }
22666 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
22667 {
22668 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
22669 }
22670 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
22671 {
22672 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22673 }
22674
22675 return false;
22676 }
22677
22682 template<typename ScalarType, typename std::enable_if<
22683 std::is_scalar<ScalarType>::value, int>::type = 0>
22684 friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
22685 {
22686 return lhs == basic_json(rhs);
22687 }
22688
22693 template<typename ScalarType, typename std::enable_if<
22694 std::is_scalar<ScalarType>::value, int>::type = 0>
22695 friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
22696 {
22697 return basic_json(lhs) == rhs;
22698 }
22699
22718 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
22719 {
22720 return !(lhs == rhs);
22721 }
22722
22727 template<typename ScalarType, typename std::enable_if<
22728 std::is_scalar<ScalarType>::value, int>::type = 0>
22729 friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
22730 {
22731 return lhs != basic_json(rhs);
22732 }
22733
22738 template<typename ScalarType, typename std::enable_if<
22739 std::is_scalar<ScalarType>::value, int>::type = 0>
22740 friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
22741 {
22742 return basic_json(lhs) != rhs;
22743 }
22744
22771 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
22772 {
22773 const auto lhs_type = lhs.type();
22774 const auto rhs_type = rhs.type();
22775
22776 if (lhs_type == rhs_type)
22777 {
22778 switch (lhs_type)
22779 {
22780 case value_t::array:
22781 // note parentheses are necessary, see
22782 // https://github.com/nlohmann/json/issues/1530
22783 return (*lhs.m_value.array) < (*rhs.m_value.array);
22784
22785 case value_t::object:
22786 return (*lhs.m_value.object) < (*rhs.m_value.object);
22787
22788 case value_t::null:
22789 return false;
22790
22791 case value_t::string:
22792 return (*lhs.m_value.string) < (*rhs.m_value.string);
22793
22794 case value_t::boolean:
22795 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
22796
22797 case value_t::number_integer:
22798 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
22799
22800 case value_t::number_unsigned:
22801 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
22802
22803 case value_t::number_float:
22804 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
22805
22806 case value_t::binary:
22807 return (*lhs.m_value.binary) < (*rhs.m_value.binary);
22808
22809 default:
22810 return false;
22811 }
22812 }
22813 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
22814 {
22815 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
22816 }
22817 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
22818 {
22819 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
22820 }
22821 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
22822 {
22823 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
22824 }
22825 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
22826 {
22827 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
22828 }
22829 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
22830 {
22831 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22832 }
22833 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
22834 {
22835 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
22836 }
22837
22838 // We only reach this line if we cannot compare values. In that case,
22839 // we compare types. Note we have to call the operator explicitly,
22840 // because MSVC has problems otherwise.
22841 return operator<(lhs_type, rhs_type);
22842 }
22843
22848 template<typename ScalarType, typename std::enable_if<
22849 std::is_scalar<ScalarType>::value, int>::type = 0>
22850 friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
22851 {
22852 return lhs < basic_json(rhs);
22853 }
22854
22859 template<typename ScalarType, typename std::enable_if<
22860 std::is_scalar<ScalarType>::value, int>::type = 0>
22861 friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
22862 {
22863 return basic_json(lhs) < rhs;
22864 }
22865
22885 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
22886 {
22887 return !(rhs < lhs);
22888 }
22889
22894 template<typename ScalarType, typename std::enable_if<
22895 std::is_scalar<ScalarType>::value, int>::type = 0>
22896 friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
22897 {
22898 return lhs <= basic_json(rhs);
22899 }
22900
22905 template<typename ScalarType, typename std::enable_if<
22906 std::is_scalar<ScalarType>::value, int>::type = 0>
22907 friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
22908 {
22909 return basic_json(lhs) <= rhs;
22910 }
22911
22931 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
22932 {
22933 return !(lhs <= rhs);
22934 }
22935
22940 template<typename ScalarType, typename std::enable_if<
22941 std::is_scalar<ScalarType>::value, int>::type = 0>
22942 friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
22943 {
22944 return lhs > basic_json(rhs);
22945 }
22946
22951 template<typename ScalarType, typename std::enable_if<
22952 std::is_scalar<ScalarType>::value, int>::type = 0>
22953 friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
22954 {
22955 return basic_json(lhs) > rhs;
22956 }
22957
22977 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
22978 {
22979 return !(lhs < rhs);
22980 }
22981
22986 template<typename ScalarType, typename std::enable_if<
22987 std::is_scalar<ScalarType>::value, int>::type = 0>
22988 friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
22989 {
22990 return lhs >= basic_json(rhs);
22991 }
22992
22997 template<typename ScalarType, typename std::enable_if<
22998 std::is_scalar<ScalarType>::value, int>::type = 0>
22999 friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
23000 {
23001 return basic_json(lhs) >= rhs;
23002 }
23003
23005
23007 // serialization //
23009
23012
23044 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
23045 {
23046 // read width member and use it as indentation parameter if nonzero
23047 const bool pretty_print = o.width() > 0;
23048 const auto indentation = pretty_print ? o.width() : 0;
23049
23050 // reset width to 0 for subsequent calls to this stream
23051 o.width(0);
23052
23053 // do the actual serialization
23054 serializer s(detail::output_adapter<char>(o), o.fill());
23055 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
23056 return o;
23057 }
23058
23067 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
23068 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
23069 {
23070 return o << j;
23071 }
23072
23074
23075
23077 // deserialization //
23079
23082
23134 template<typename InputType>
23135 JSON_HEDLEY_WARN_UNUSED_RESULT
23136 static basic_json parse(InputType&& i,
23137 const parser_callback_t cb = nullptr,
23138 const bool allow_exceptions = true,
23139 const bool ignore_comments = false)
23140 {
23141 basic_json result;
23142 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
23143 return result;
23144 }
23145
23172 template<typename IteratorType>
23173 JSON_HEDLEY_WARN_UNUSED_RESULT
23174 static basic_json parse(IteratorType first,
23175 IteratorType last,
23176 const parser_callback_t cb = nullptr,
23177 const bool allow_exceptions = true,
23178 const bool ignore_comments = false)
23179 {
23180 basic_json result;
23181 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
23182 return result;
23183 }
23184
23185 JSON_HEDLEY_WARN_UNUSED_RESULT
23186 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
23187 static basic_json parse(detail::span_input_adapter&& i,
23188 const parser_callback_t cb = nullptr,
23189 const bool allow_exceptions = true,
23190 const bool ignore_comments = false)
23191 {
23192 basic_json result;
23193 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
23194 return result;
23195 }
23196
23227 template<typename InputType>
23228 static bool accept(InputType&& i,
23229 const bool ignore_comments = false)
23230 {
23231 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
23232 }
23233
23234 template<typename IteratorType>
23235 static bool accept(IteratorType first, IteratorType last,
23236 const bool ignore_comments = false)
23237 {
23238 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
23239 }
23240
23241 JSON_HEDLEY_WARN_UNUSED_RESULT
23242 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
23243 static bool accept(detail::span_input_adapter&& i,
23244 const bool ignore_comments = false)
23245 {
23246 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
23247 }
23248
23289 template <typename InputType, typename SAX>
23290 JSON_HEDLEY_NON_NULL(2)
23291 static bool sax_parse(InputType&& i, SAX* sax,
23292 input_format_t format = input_format_t::json,
23293 const bool strict = true,
23294 const bool ignore_comments = false)
23295 {
23296 auto ia = detail::input_adapter(std::forward<InputType>(i));
23297 return format == input_format_t::json
23298 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23299 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23300 }
23301
23302 template<class IteratorType, class SAX>
23303 JSON_HEDLEY_NON_NULL(3)
23304 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
23305 input_format_t format = input_format_t::json,
23306 const bool strict = true,
23307 const bool ignore_comments = false)
23308 {
23309 auto ia = detail::input_adapter(std::move(first), std::move(last));
23310 return format == input_format_t::json
23311 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23312 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23313 }
23314
23315 template <typename SAX>
23316 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
23317 JSON_HEDLEY_NON_NULL(2)
23318 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
23319 input_format_t format = input_format_t::json,
23320 const bool strict = true,
23321 const bool ignore_comments = false)
23322 {
23323 auto ia = i.get();
23324 return format == input_format_t::json
23325 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23326 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23327 }
23328
23337 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
23338 friend std::istream& operator<<(basic_json& j, std::istream& i)
23339 {
23340 return operator>>(i, j);
23341 }
23342
23368 friend std::istream& operator>>(std::istream& i, basic_json& j)
23369 {
23370 parser(detail::input_adapter(i)).parse(false, j);
23371 return i;
23372 }
23373
23375
23377 // convenience functions //
23379
23411 JSON_HEDLEY_RETURNS_NON_NULL
23412 const char* type_name() const noexcept
23413 {
23414 {
23415 switch (m_type)
23416 {
23417 case value_t::null:
23418 return "null";
23419 case value_t::object:
23420 return "object";
23421 case value_t::array:
23422 return "array";
23423 case value_t::string:
23424 return "string";
23425 case value_t::boolean:
23426 return "boolean";
23427 case value_t::binary:
23428 return "binary";
23429 case value_t::discarded:
23430 return "discarded";
23431 default:
23432 return "number";
23433 }
23434 }
23435 }
23436
23437
23438 private:
23440 // member variables //
23442
23444 value_t m_type = value_t::null;
23445
23447 json_value m_value = {};
23448
23450 // binary serialization/deserialization //
23452
23455
23456 public:
23551 static std::vector<uint8_t> to_cbor(const basic_json& j)
23552 {
23553 std::vector<uint8_t> result;
23554 to_cbor(j, result);
23555 return result;
23556 }
23557
23558 static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
23559 {
23560 binary_writer<uint8_t>(o).write_cbor(j);
23561 }
23562
23563 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
23564 {
23565 binary_writer<char>(o).write_cbor(j);
23566 }
23567
23646 static std::vector<uint8_t> to_msgpack(const basic_json& j)
23647 {
23648 std::vector<uint8_t> result;
23649 to_msgpack(j, result);
23650 return result;
23651 }
23652
23653 static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
23654 {
23655 binary_writer<uint8_t>(o).write_msgpack(j);
23656 }
23657
23658 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
23659 {
23660 binary_writer<char>(o).write_msgpack(j);
23661 }
23662
23749 static std::vector<uint8_t> to_ubjson(const basic_json& j,
23750 const bool use_size = false,
23751 const bool use_type = false)
23752 {
23753 std::vector<uint8_t> result;
23754 to_ubjson(j, result, use_size, use_type);
23755 return result;
23756 }
23757
23758 static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
23759 const bool use_size = false, const bool use_type = false)
23760 {
23761 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
23762 }
23763
23764 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
23765 const bool use_size = false, const bool use_type = false)
23766 {
23767 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23768 }
23769
23770
23827 static std::vector<uint8_t> to_bson(const basic_json& j)
23828 {
23829 std::vector<uint8_t> result;
23830 to_bson(j, result);
23831 return result;
23832 }
23833
23842 static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
23843 {
23844 binary_writer<uint8_t>(o).write_bson(j);
23845 }
23846
23850 static void to_bson(const basic_json& j, detail::output_adapter<char> o)
23851 {
23852 binary_writer<char>(o).write_bson(j);
23853 }
23854
23855
23958 template<typename InputType>
23959 JSON_HEDLEY_WARN_UNUSED_RESULT
23960 static basic_json from_cbor(InputType&& i,
23961 const bool strict = true,
23962 const bool allow_exceptions = true,
23963 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23964 {
23965 basic_json result;
23966 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23967 auto ia = detail::input_adapter(std::forward<InputType>(i));
23968 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23969 return res ? result : basic_json(value_t::discarded);
23970 }
23971
23975 template<typename IteratorType>
23976 JSON_HEDLEY_WARN_UNUSED_RESULT
23977 static basic_json from_cbor(IteratorType first, IteratorType last,
23978 const bool strict = true,
23979 const bool allow_exceptions = true,
23980 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23981 {
23982 basic_json result;
23983 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23984 auto ia = detail::input_adapter(std::move(first), std::move(last));
23985 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23986 return res ? result : basic_json(value_t::discarded);
23987 }
23988
23989 template<typename T>
23990 JSON_HEDLEY_WARN_UNUSED_RESULT
23991 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23992 static basic_json from_cbor(const T* ptr, std::size_t len,
23993 const bool strict = true,
23994 const bool allow_exceptions = true,
23995 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23996 {
23997 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
23998 }
23999
24000
24001 JSON_HEDLEY_WARN_UNUSED_RESULT
24002 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
24003 static basic_json from_cbor(detail::span_input_adapter&& i,
24004 const bool strict = true,
24005 const bool allow_exceptions = true,
24006 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24007 {
24008 basic_json result;
24009 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24010 auto ia = i.get();
24011 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24012 return res ? result : basic_json(value_t::discarded);
24013 }
24014
24101 template<typename InputType>
24102 JSON_HEDLEY_WARN_UNUSED_RESULT
24103 static basic_json from_msgpack(InputType&& i,
24104 const bool strict = true,
24105 const bool allow_exceptions = true)
24106 {
24107 basic_json result;
24108 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24109 auto ia = detail::input_adapter(std::forward<InputType>(i));
24110 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24111 return res ? result : basic_json(value_t::discarded);
24112 }
24113
24117 template<typename IteratorType>
24118 JSON_HEDLEY_WARN_UNUSED_RESULT
24119 static basic_json from_msgpack(IteratorType first, IteratorType last,
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::move(first), std::move(last));
24126 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24127 return res ? result : basic_json(value_t::discarded);
24128 }
24129
24130
24131 template<typename T>
24132 JSON_HEDLEY_WARN_UNUSED_RESULT
24133 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
24134 static basic_json from_msgpack(const T* ptr, std::size_t len,
24135 const bool strict = true,
24136 const bool allow_exceptions = true)
24137 {
24138 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
24139 }
24140
24141 JSON_HEDLEY_WARN_UNUSED_RESULT
24142 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
24143 static basic_json from_msgpack(detail::span_input_adapter&& i,
24144 const bool strict = true,
24145 const bool allow_exceptions = true)
24146 {
24147 basic_json result;
24148 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24149 auto ia = i.get();
24150 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24151 return res ? result : basic_json(value_t::discarded);
24152 }
24153
24154
24217 template<typename InputType>
24218 JSON_HEDLEY_WARN_UNUSED_RESULT
24219 static basic_json from_ubjson(InputType&& i,
24220 const bool strict = true,
24221 const bool allow_exceptions = true)
24222 {
24223 basic_json result;
24224 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24225 auto ia = detail::input_adapter(std::forward<InputType>(i));
24226 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24227 return res ? result : basic_json(value_t::discarded);
24228 }
24229
24233 template<typename IteratorType>
24234 JSON_HEDLEY_WARN_UNUSED_RESULT
24235 static basic_json from_ubjson(IteratorType first, IteratorType last,
24236 const bool strict = true,
24237 const bool allow_exceptions = true)
24238 {
24239 basic_json result;
24240 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24241 auto ia = detail::input_adapter(std::move(first), std::move(last));
24242 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24243 return res ? result : basic_json(value_t::discarded);
24244 }
24245
24246 template<typename T>
24247 JSON_HEDLEY_WARN_UNUSED_RESULT
24248 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
24249 static basic_json from_ubjson(const T* ptr, std::size_t len,
24250 const bool strict = true,
24251 const bool allow_exceptions = true)
24252 {
24253 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
24254 }
24255
24256 JSON_HEDLEY_WARN_UNUSED_RESULT
24257 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
24258 static basic_json from_ubjson(detail::span_input_adapter&& i,
24259 const bool strict = true,
24260 const bool allow_exceptions = true)
24261 {
24262 basic_json result;
24263 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24264 auto ia = i.get();
24265 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24266 return res ? result : basic_json(value_t::discarded);
24267 }
24268
24269
24330 template<typename InputType>
24331 JSON_HEDLEY_WARN_UNUSED_RESULT
24332 static basic_json from_bson(InputType&& i,
24333 const bool strict = true,
24334 const bool allow_exceptions = true)
24335 {
24336 basic_json result;
24337 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24338 auto ia = detail::input_adapter(std::forward<InputType>(i));
24339 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24340 return res ? result : basic_json(value_t::discarded);
24341 }
24342
24346 template<typename IteratorType>
24347 JSON_HEDLEY_WARN_UNUSED_RESULT
24348 static basic_json from_bson(IteratorType first, IteratorType last,
24349 const bool strict = true,
24350 const bool allow_exceptions = true)
24351 {
24352 basic_json result;
24353 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24354 auto ia = detail::input_adapter(std::move(first), std::move(last));
24355 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24356 return res ? result : basic_json(value_t::discarded);
24357 }
24358
24359 template<typename T>
24360 JSON_HEDLEY_WARN_UNUSED_RESULT
24361 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
24362 static basic_json from_bson(const T* ptr, std::size_t len,
24363 const bool strict = true,
24364 const bool allow_exceptions = true)
24365 {
24366 return from_bson(ptr, ptr + len, strict, allow_exceptions);
24367 }
24368
24369 JSON_HEDLEY_WARN_UNUSED_RESULT
24370 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
24371 static basic_json from_bson(detail::span_input_adapter&& i,
24372 const bool strict = true,
24373 const bool allow_exceptions = true)
24374 {
24375 basic_json result;
24376 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24377 auto ia = i.get();
24378 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24379 return res ? result : basic_json(value_t::discarded);
24380 }
24382
24384 // JSON Pointer support //
24386
24389
24423 reference operator[](const json_pointer& ptr)
24424 {
24425 return ptr.get_unchecked(this);
24426 }
24427
24451 const_reference operator[](const json_pointer& ptr) const
24452 {
24453 return ptr.get_unchecked(this);
24454 }
24455
24494 reference at(const json_pointer& ptr)
24495 {
24496 return ptr.get_checked(this);
24497 }
24498
24537 const_reference at(const json_pointer& ptr) const
24538 {
24539 return ptr.get_checked(this);
24540 }
24541
24564 basic_json flatten() const
24565 {
24566 basic_json result(value_t::object);
24567 json_pointer::flatten("", *this, result);
24568 return result;
24569 }
24570
24601 basic_json unflatten() const
24602 {
24603 return json_pointer::unflatten(*this);
24604 }
24605
24607
24609 // JSON Patch functions //
24611
24614
24662 basic_json patch(const basic_json& json_patch) const
24663 {
24664 // make a working copy to apply the patch to
24665 basic_json result = *this;
24666
24667 // the valid JSON Patch operations
24668 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
24669
24670 const auto get_op = [](const std::string & op)
24671 {
24672 if (op == "add")
24673 {
24674 return patch_operations::add;
24675 }
24676 if (op == "remove")
24677 {
24678 return patch_operations::remove;
24679 }
24680 if (op == "replace")
24681 {
24682 return patch_operations::replace;
24683 }
24684 if (op == "move")
24685 {
24686 return patch_operations::move;
24687 }
24688 if (op == "copy")
24689 {
24690 return patch_operations::copy;
24691 }
24692 if (op == "test")
24693 {
24694 return patch_operations::test;
24695 }
24696
24697 return patch_operations::invalid;
24698 };
24699
24700 // wrapper for "add" operation; add value at ptr
24701 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
24702 {
24703 // adding to the root of the target document means replacing it
24704 if (ptr.empty())
24705 {
24706 result = val;
24707 return;
24708 }
24709
24710 // make sure the top element of the pointer exists
24711 json_pointer top_pointer = ptr.top();
24712 if (top_pointer != ptr)
24713 {
24714 result.at(top_pointer);
24715 }
24716
24717 // get reference to parent of JSON pointer ptr
24718 const auto last_path = ptr.back();
24719 ptr.pop_back();
24720 basic_json& parent = result[ptr];
24721
24722 switch (parent.m_type)
24723 {
24724 case value_t::null:
24725 case value_t::object:
24726 {
24727 // use operator[] to add value
24728 parent[last_path] = val;
24729 break;
24730 }
24731
24732 case value_t::array:
24733 {
24734 if (last_path == "-")
24735 {
24736 // special case: append to back
24737 parent.push_back(val);
24738 }
24739 else
24740 {
24741 const auto idx = json_pointer::array_index(last_path);
24742 if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
24743 {
24744 // avoid undefined behavior
24745 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
24746 }
24747
24748 // default case: insert add offset
24749 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
24750 }
24751 break;
24752 }
24753
24754 // if there exists a parent it cannot be primitive
24755 default: // LCOV_EXCL_LINE
24756 JSON_ASSERT(false); // LCOV_EXCL_LINE
24757 }
24758 };
24759
24760 // wrapper for "remove" operation; remove value at ptr
24761 const auto operation_remove = [&result](json_pointer & ptr)
24762 {
24763 // get reference to parent of JSON pointer ptr
24764 const auto last_path = ptr.back();
24765 ptr.pop_back();
24766 basic_json& parent = result.at(ptr);
24767
24768 // remove child
24769 if (parent.is_object())
24770 {
24771 // perform range check
24772 auto it = parent.find(last_path);
24773 if (JSON_HEDLEY_LIKELY(it != parent.end()))
24774 {
24775 parent.erase(it);
24776 }
24777 else
24778 {
24779 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
24780 }
24781 }
24782 else if (parent.is_array())
24783 {
24784 // note erase performs range check
24785 parent.erase(json_pointer::array_index(last_path));
24786 }
24787 };
24788
24789 // type check: top level value must be an array
24790 if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
24791 {
24792 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24793 }
24794
24795 // iterate and apply the operations
24796 for (const auto& val : json_patch)
24797 {
24798 // wrapper to get a value for an operation
24799 const auto get_value = [&val](const std::string & op,
24800 const std::string & member,
24801 bool string_type) -> basic_json &
24802 {
24803 // find value
24804 auto it = val.m_value.object->find(member);
24805
24806 // context-sensitive error message
24807 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
24808
24809 // check if desired value is present
24810 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
24811 {
24812 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
24813 }
24814
24815 // check if result is of type string
24816 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
24817 {
24818 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
24819 }
24820
24821 // no error: return value
24822 return it->second;
24823 };
24824
24825 // type check: every element of the array must be an object
24826 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
24827 {
24828 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24829 }
24830
24831 // collect mandatory members
24832 const auto op = get_value("op", "op", true).template get<std::string>();
24833 const auto path = get_value(op, "path", true).template get<std::string>();
24834 json_pointer ptr(path);
24835
24836 switch (get_op(op))
24837 {
24838 case patch_operations::add:
24839 {
24840 operation_add(ptr, get_value("add", "value", false));
24841 break;
24842 }
24843
24844 case patch_operations::remove:
24845 {
24846 operation_remove(ptr);
24847 break;
24848 }
24849
24850 case patch_operations::replace:
24851 {
24852 // the "path" location must exist - use at()
24853 result.at(ptr) = get_value("replace", "value", false);
24854 break;
24855 }
24856
24857 case patch_operations::move:
24858 {
24859 const auto from_path = get_value("move", "from", true).template get<std::string>();
24860 json_pointer from_ptr(from_path);
24861
24862 // the "from" location must exist - use at()
24863 basic_json v = result.at(from_ptr);
24864
24865 // The move operation is functionally identical to a
24866 // "remove" operation on the "from" location, followed
24867 // immediately by an "add" operation at the target
24868 // location with the value that was just removed.
24869 operation_remove(from_ptr);
24870 operation_add(ptr, v);
24871 break;
24872 }
24873
24874 case patch_operations::copy:
24875 {
24876 const auto from_path = get_value("copy", "from", true).template get<std::string>();
24877 const json_pointer from_ptr(from_path);
24878
24879 // the "from" location must exist - use at()
24880 basic_json v = result.at(from_ptr);
24881
24882 // The copy is functionally identical to an "add"
24883 // operation at the target location using the value
24884 // specified in the "from" member.
24885 operation_add(ptr, v);
24886 break;
24887 }
24888
24889 case patch_operations::test:
24890 {
24891 bool success = false;
24892 JSON_TRY
24893 {
24894 // check if "value" matches the one at "path"
24895 // the "path" location must exist - use at()
24896 success = (result.at(ptr) == get_value("test", "value", false));
24897 }
24898 JSON_INTERNAL_CATCH (out_of_range&)
24899 {
24900 // ignore out of range errors: success remains false
24901 }
24902
24903 // throw an exception if test fails
24904 if (JSON_HEDLEY_UNLIKELY(!success))
24905 {
24906 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
24907 }
24908
24909 break;
24910 }
24911
24912 default:
24913 {
24914 // op must be "add", "remove", "replace", "move", "copy", or
24915 // "test"
24916 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
24917 }
24918 }
24919 }
24920
24921 return result;
24922 }
24923
24957 JSON_HEDLEY_WARN_UNUSED_RESULT
24958 static basic_json diff(const basic_json& source, const basic_json& target,
24959 const std::string& path = "")
24960 {
24961 // the patch
24962 basic_json result(value_t::array);
24963
24964 // if the values are the same, return empty patch
24965 if (source == target)
24966 {
24967 return result;
24968 }
24969
24970 if (source.type() != target.type())
24971 {
24972 // different types: replace value
24973 result.push_back(
24974 {
24975 {"op", "replace"}, {"path", path}, {"value", target}
24976 });
24977 return result;
24978 }
24979
24980 switch (source.type())
24981 {
24982 case value_t::array:
24983 {
24984 // first pass: traverse common elements
24985 std::size_t i = 0;
24986 while (i < source.size() && i < target.size())
24987 {
24988 // recursive call to compare array values at index i
24989 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
24990 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24991 ++i;
24992 }
24993
24994 // i now reached the end of at least one array
24995 // in a second pass, traverse the remaining elements
24996
24997 // remove my remaining elements
24998 const auto end_index = static_cast<difference_type>(result.size());
24999 while (i < source.size())
25000 {
25001 // add operations in reverse order to avoid invalid
25002 // indices
25003 result.insert(result.begin() + end_index, object(
25004 {
25005 {"op", "remove"},
25006 {"path", path + "/" + std::to_string(i)}
25007 }));
25008 ++i;
25009 }
25010
25011 // add other remaining elements
25012 while (i < target.size())
25013 {
25014 result.push_back(
25015 {
25016 {"op", "add"},
25017 {"path", path + "/-"},
25018 {"value", target[i]}
25019 });
25020 ++i;
25021 }
25022
25023 break;
25024 }
25025
25026 case value_t::object:
25027 {
25028 // first pass: traverse this object's elements
25029 for (auto it = source.cbegin(); it != source.cend(); ++it)
25030 {
25031 // escape the key name to be used in a JSON patch
25032 const auto key = json_pointer::escape(it.key());
25033
25034 if (target.find(it.key()) != target.end())
25035 {
25036 // recursive call to compare object values at key it
25037 auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
25038 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
25039 }
25040 else
25041 {
25042 // found a key that is not in o -> remove it
25043 result.push_back(object(
25044 {
25045 {"op", "remove"}, {"path", path + "/" + key}
25046 }));
25047 }
25048 }
25049
25050 // second pass: traverse other object's elements
25051 for (auto it = target.cbegin(); it != target.cend(); ++it)
25052 {
25053 if (source.find(it.key()) == source.end())
25054 {
25055 // found a key that is not in this -> add it
25056 const auto key = json_pointer::escape(it.key());
25057 result.push_back(
25058 {
25059 {"op", "add"}, {"path", path + "/" + key},
25060 {"value", it.value()}
25061 });
25062 }
25063 }
25064
25065 break;
25066 }
25067
25068 default:
25069 {
25070 // both primitive type: replace value
25071 result.push_back(
25072 {
25073 {"op", "replace"}, {"path", path}, {"value", target}
25074 });
25075 break;
25076 }
25077 }
25078
25079 return result;
25080 }
25081
25083
25085 // JSON Merge Patch functions //
25087
25090
25133 void merge_patch(const basic_json& apply_patch)
25134 {
25135 if (apply_patch.is_object())
25136 {
25137 if (!is_object())
25138 {
25139 *this = object();
25140 }
25141 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
25142 {
25143 if (it.value().is_null())
25144 {
25145 erase(it.key());
25146 }
25147 else
25148 {
25149 operator[](it.key()).merge_patch(it.value());
25150 }
25151 }
25152 }
25153 else
25154 {
25155 *this = apply_patch;
25156 }
25157 }
25158
25160};
25161
25171NLOHMANN_BASIC_JSON_TPL_DECLARATION
25172std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
25173{
25174 return j.dump();
25175}
25176} // namespace nlohmann
25177
25179// nonmember support //
25181
25182// specialization of std::swap, and std::hash
25183namespace std
25184{
25185
25187template<>
25188struct hash<nlohmann::json>
25189{
25195 std::size_t operator()(const nlohmann::json& j) const
25196 {
25197 return nlohmann::detail::hash(j);
25198 }
25199};
25200
25204template<>
25205struct less<::nlohmann::detail::value_t>
25206{
25211 bool operator()(nlohmann::detail::value_t lhs,
25212 nlohmann::detail::value_t rhs) const noexcept
25213 {
25214 return nlohmann::detail::operator<(lhs, rhs);
25215 }
25216};
25217
25218// C++20 prohibit function specialization in the std namespace.
25219#ifndef JSON_HAS_CPP_20
25220
25226template<>
25227inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
25228 is_nothrow_move_constructible<nlohmann::json>::value&&
25229 is_nothrow_move_assignable<nlohmann::json>::value
25230 )
25231{
25232 j1.swap(j2);
25233}
25234
25235#endif
25236
25237} // namespace std
25238
25252JSON_HEDLEY_NON_NULL(1)
25253inline nlohmann::json operator "" _json(const char* s, std::size_t n)
25254{
25255 return nlohmann::json::parse(s, s + n);
25256}
25257
25271JSON_HEDLEY_NON_NULL(1)
25272inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
25273{
25274 return nlohmann::json::json_pointer(std::string(s, n));
25275}
25276
25277// #include <nlohmann/detail/macro_unscope.hpp>
25278
25279
25280// restore GCC/clang diagnostic settings
25281#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
25282 #pragma GCC diagnostic pop
25283#endif
25284#if defined(__clang__)
25285 #pragma GCC diagnostic pop
25286#endif
25287
25288// clean up
25289#undef JSON_ASSERT
25290#undef JSON_INTERNAL_CATCH
25291#undef JSON_CATCH
25292#undef JSON_THROW
25293#undef JSON_TRY
25294#undef JSON_HAS_CPP_14
25295#undef JSON_HAS_CPP_17
25296#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
25297#undef NLOHMANN_BASIC_JSON_TPL
25298#undef JSON_EXPLICIT
25299
25300// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
25301#undef JSON_HEDLEY_ALWAYS_INLINE
25302#undef JSON_HEDLEY_ARM_VERSION
25303#undef JSON_HEDLEY_ARM_VERSION_CHECK
25304#undef JSON_HEDLEY_ARRAY_PARAM
25305#undef JSON_HEDLEY_ASSUME
25306#undef JSON_HEDLEY_BEGIN_C_DECLS
25307#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
25308#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
25309#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
25310#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
25311#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
25312#undef JSON_HEDLEY_CLANG_HAS_FEATURE
25313#undef JSON_HEDLEY_CLANG_HAS_WARNING
25314#undef JSON_HEDLEY_COMPCERT_VERSION
25315#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
25316#undef JSON_HEDLEY_CONCAT
25317#undef JSON_HEDLEY_CONCAT3
25318#undef JSON_HEDLEY_CONCAT3_EX
25319#undef JSON_HEDLEY_CONCAT_EX
25320#undef JSON_HEDLEY_CONST
25321#undef JSON_HEDLEY_CONSTEXPR
25322#undef JSON_HEDLEY_CONST_CAST
25323#undef JSON_HEDLEY_CPP_CAST
25324#undef JSON_HEDLEY_CRAY_VERSION
25325#undef JSON_HEDLEY_CRAY_VERSION_CHECK
25326#undef JSON_HEDLEY_C_DECL
25327#undef JSON_HEDLEY_DEPRECATED
25328#undef JSON_HEDLEY_DEPRECATED_FOR
25329#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
25330#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
25331#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
25332#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
25333#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
25334#undef JSON_HEDLEY_DIAGNOSTIC_POP
25335#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
25336#undef JSON_HEDLEY_DMC_VERSION
25337#undef JSON_HEDLEY_DMC_VERSION_CHECK
25338#undef JSON_HEDLEY_EMPTY_BASES
25339#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
25340#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
25341#undef JSON_HEDLEY_END_C_DECLS
25342#undef JSON_HEDLEY_FLAGS
25343#undef JSON_HEDLEY_FLAGS_CAST
25344#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
25345#undef JSON_HEDLEY_GCC_HAS_BUILTIN
25346#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
25347#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
25348#undef JSON_HEDLEY_GCC_HAS_EXTENSION
25349#undef JSON_HEDLEY_GCC_HAS_FEATURE
25350#undef JSON_HEDLEY_GCC_HAS_WARNING
25351#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
25352#undef JSON_HEDLEY_GCC_VERSION
25353#undef JSON_HEDLEY_GCC_VERSION_CHECK
25354#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
25355#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
25356#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
25357#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
25358#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
25359#undef JSON_HEDLEY_GNUC_HAS_FEATURE
25360#undef JSON_HEDLEY_GNUC_HAS_WARNING
25361#undef JSON_HEDLEY_GNUC_VERSION
25362#undef JSON_HEDLEY_GNUC_VERSION_CHECK
25363#undef JSON_HEDLEY_HAS_ATTRIBUTE
25364#undef JSON_HEDLEY_HAS_BUILTIN
25365#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
25366#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
25367#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
25368#undef JSON_HEDLEY_HAS_EXTENSION
25369#undef JSON_HEDLEY_HAS_FEATURE
25370#undef JSON_HEDLEY_HAS_WARNING
25371#undef JSON_HEDLEY_IAR_VERSION
25372#undef JSON_HEDLEY_IAR_VERSION_CHECK
25373#undef JSON_HEDLEY_IBM_VERSION
25374#undef JSON_HEDLEY_IBM_VERSION_CHECK
25375#undef JSON_HEDLEY_IMPORT
25376#undef JSON_HEDLEY_INLINE
25377#undef JSON_HEDLEY_INTEL_VERSION
25378#undef JSON_HEDLEY_INTEL_VERSION_CHECK
25379#undef JSON_HEDLEY_IS_CONSTANT
25380#undef JSON_HEDLEY_IS_CONSTEXPR_
25381#undef JSON_HEDLEY_LIKELY
25382#undef JSON_HEDLEY_MALLOC
25383#undef JSON_HEDLEY_MESSAGE
25384#undef JSON_HEDLEY_MSVC_VERSION
25385#undef JSON_HEDLEY_MSVC_VERSION_CHECK
25386#undef JSON_HEDLEY_NEVER_INLINE
25387#undef JSON_HEDLEY_NON_NULL
25388#undef JSON_HEDLEY_NO_ESCAPE
25389#undef JSON_HEDLEY_NO_RETURN
25390#undef JSON_HEDLEY_NO_THROW
25391#undef JSON_HEDLEY_NULL
25392#undef JSON_HEDLEY_PELLES_VERSION
25393#undef JSON_HEDLEY_PELLES_VERSION_CHECK
25394#undef JSON_HEDLEY_PGI_VERSION
25395#undef JSON_HEDLEY_PGI_VERSION_CHECK
25396#undef JSON_HEDLEY_PREDICT
25397#undef JSON_HEDLEY_PRINTF_FORMAT
25398#undef JSON_HEDLEY_PRIVATE
25399#undef JSON_HEDLEY_PUBLIC
25400#undef JSON_HEDLEY_PURE
25401#undef JSON_HEDLEY_REINTERPRET_CAST
25402#undef JSON_HEDLEY_REQUIRE
25403#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
25404#undef JSON_HEDLEY_REQUIRE_MSG
25405#undef JSON_HEDLEY_RESTRICT
25406#undef JSON_HEDLEY_RETURNS_NON_NULL
25407#undef JSON_HEDLEY_SENTINEL
25408#undef JSON_HEDLEY_STATIC_ASSERT
25409#undef JSON_HEDLEY_STATIC_CAST
25410#undef JSON_HEDLEY_STRINGIFY
25411#undef JSON_HEDLEY_STRINGIFY_EX
25412#undef JSON_HEDLEY_SUNPRO_VERSION
25413#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
25414#undef JSON_HEDLEY_TINYC_VERSION
25415#undef JSON_HEDLEY_TINYC_VERSION_CHECK
25416#undef JSON_HEDLEY_TI_ARMCL_VERSION
25417#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
25418#undef JSON_HEDLEY_TI_CL2000_VERSION
25419#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
25420#undef JSON_HEDLEY_TI_CL430_VERSION
25421#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
25422#undef JSON_HEDLEY_TI_CL6X_VERSION
25423#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
25424#undef JSON_HEDLEY_TI_CL7X_VERSION
25425#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
25426#undef JSON_HEDLEY_TI_CLPRU_VERSION
25427#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
25428#undef JSON_HEDLEY_TI_VERSION
25429#undef JSON_HEDLEY_TI_VERSION_CHECK
25430#undef JSON_HEDLEY_UNAVAILABLE
25431#undef JSON_HEDLEY_UNLIKELY
25432#undef JSON_HEDLEY_UNPREDICTABLE
25433#undef JSON_HEDLEY_UNREACHABLE
25434#undef JSON_HEDLEY_UNREACHABLE_RETURN
25435#undef JSON_HEDLEY_VERSION
25436#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
25437#undef JSON_HEDLEY_VERSION_DECODE_MINOR
25438#undef JSON_HEDLEY_VERSION_DECODE_REVISION
25439#undef JSON_HEDLEY_VERSION_ENCODE
25440#undef JSON_HEDLEY_WARNING
25441#undef JSON_HEDLEY_WARN_UNUSED_RESULT
25442#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
25443#undef JSON_HEDLEY_FALL_THROUGH
25444
25445
25446
25447#endif // INCLUDE_NLOHMANN_JSON_HPP_
namespace for Niels Lohmann
Definition json.hpp:82
basic_json<> json
default JSON class
Definition json.hpp:2933
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:25172
basic_json< nlohmann::ordered_map > ordered_json
ordered JSON class
Definition json.hpp:2945