A Discrete-Event Network Simulator
API
json.h
Go to the documentation of this file.
1 /*
2  __ _____ _____ _____
3  __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.9.1
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
6 
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10 
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
17 
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20 
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29 
30 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
31 #define INCLUDE_NLOHMANN_JSON_HPP_
32 
33 #define NLOHMANN_JSON_VERSION_MAJOR 3
34 #define NLOHMANN_JSON_VERSION_MINOR 9
35 #define NLOHMANN_JSON_VERSION_PATCH 1
36 
37 #include <algorithm> // all_of, find, for_each
38 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
39 #include <functional> // hash, less
40 #include <initializer_list> // initializer_list
41 #include <iosfwd> // istream, ostream
42 #include <iterator> // random_access_iterator_tag
43 #include <memory> // unique_ptr
44 #include <numeric> // accumulate
45 #include <string> // string, stoi, to_string
46 #include <utility> // declval, forward, move, pair, swap
47 #include <vector> // vector
48 
49 // #include <nlohmann/adl_serializer.hpp>
50 
51 
52 #include <utility>
53 
54 // #include <nlohmann/detail/conversions/from_json.hpp>
55 
56 
57 #include <algorithm> // transform
58 #include <array> // array
59 #include <forward_list> // forward_list
60 #include <iterator> // inserter, front_inserter, end
61 #include <map> // map
62 #include <string> // string
63 #include <tuple> // tuple, make_tuple
64 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
65 #include <unordered_map> // unordered_map
66 #include <utility> // pair, declval
67 #include <valarray> // valarray
68 
69 // #include <nlohmann/detail/exceptions.hpp>
70 
71 
72 #include <exception> // exception
73 #include <stdexcept> // runtime_error
74 #include <string> // to_string
75 
76 // #include <nlohmann/detail/input/position_t.hpp>
77 
78 
79 #include <cstddef> // size_t
80 
81 namespace nlohmann
82 {
83 namespace detail
84 {
86 struct position_t
87 {
89  std::size_t chars_read_total = 0;
91  std::size_t chars_read_current_line = 0;
93  std::size_t lines_read = 0;
94 
96  constexpr operator size_t() const
97  {
98  return chars_read_total;
99  }
100 };
101 
102 } // namespace detail
103 } // namespace nlohmann
104 
105 // #include <nlohmann/detail/macro_scope.hpp>
106 
107 
108 #include <utility> // pair
109 // #include <nlohmann/thirdparty/hedley/hedley.hpp>
110 /* Hedley - https://nemequ.github.io/hedley
111  * Created by Evan Nemerson <evan@nemerson.com>
112  *
113  * To the extent possible under law, the author(s) have dedicated all
114  * copyright and related and neighboring rights to this software to
115  * the public domain worldwide. This software is distributed without
116  * any warranty.
117  *
118  * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
119  * SPDX-License-Identifier: CC0-1.0
120  */
121 
122 #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 14)
123 #if defined(JSON_HEDLEY_VERSION)
124  #undef JSON_HEDLEY_VERSION
125 #endif
126 #define JSON_HEDLEY_VERSION 14
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) && !defined(__ICL)
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) && !defined(__ICL)
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) && !defined(__ICL)
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(JSON_HEDLEY_MSVC_VERSION)
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) && !defined(__ICL)
224  #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
225 #elif defined(__INTEL_COMPILER) && !defined(__ICL)
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_INTEL_CL_VERSION)
239  #undef JSON_HEDLEY_INTEL_CL_VERSION
240 #endif
241 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
242  #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
243 #endif
244 
245 #if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
246  #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
247 #endif
248 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
249  #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
250 #else
251  #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
252 #endif
253 
254 #if defined(JSON_HEDLEY_PGI_VERSION)
255  #undef JSON_HEDLEY_PGI_VERSION
256 #endif
257 #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
258  #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
259 #endif
260 
261 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
262  #undef JSON_HEDLEY_PGI_VERSION_CHECK
263 #endif
264 #if defined(JSON_HEDLEY_PGI_VERSION)
265  #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
266 #else
267  #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
268 #endif
269 
270 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
271  #undef JSON_HEDLEY_SUNPRO_VERSION
272 #endif
273 #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
274  #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)
275 #elif defined(__SUNPRO_C)
276  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
277 #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
278  #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)
279 #elif defined(__SUNPRO_CC)
280  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
281 #endif
282 
283 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
284  #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
285 #endif
286 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
287  #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
288 #else
289  #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
290 #endif
291 
292 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
293  #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
294 #endif
295 #if defined(__EMSCRIPTEN__)
296  #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
297 #endif
298 
299 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
300  #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
301 #endif
302 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
303  #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
304 #else
305  #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
306 #endif
307 
308 #if defined(JSON_HEDLEY_ARM_VERSION)
309  #undef JSON_HEDLEY_ARM_VERSION
310 #endif
311 #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
312  #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
313 #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
314  #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
315 #endif
316 
317 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
318  #undef JSON_HEDLEY_ARM_VERSION_CHECK
319 #endif
320 #if defined(JSON_HEDLEY_ARM_VERSION)
321  #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
322 #else
323  #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
324 #endif
325 
326 #if defined(JSON_HEDLEY_IBM_VERSION)
327  #undef JSON_HEDLEY_IBM_VERSION
328 #endif
329 #if defined(__ibmxl__)
330  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
331 #elif defined(__xlC__) && defined(__xlC_ver__)
332  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
333 #elif defined(__xlC__)
334  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
335 #endif
336 
337 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
338  #undef JSON_HEDLEY_IBM_VERSION_CHECK
339 #endif
340 #if defined(JSON_HEDLEY_IBM_VERSION)
341  #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
342 #else
343  #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
344 #endif
345 
346 #if defined(JSON_HEDLEY_TI_VERSION)
347  #undef JSON_HEDLEY_TI_VERSION
348 #endif
349 #if \
350  defined(__TI_COMPILER_VERSION__) && \
351  ( \
352  defined(__TMS470__) || defined(__TI_ARM__) || \
353  defined(__MSP430__) || \
354  defined(__TMS320C2000__) \
355  )
356 #if (__TI_COMPILER_VERSION__ >= 16000000)
357  #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
358 #endif
359 #endif
360 
361 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
362  #undef JSON_HEDLEY_TI_VERSION_CHECK
363 #endif
364 #if defined(JSON_HEDLEY_TI_VERSION)
365  #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
366 #else
367  #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
368 #endif
369 
370 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
371  #undef JSON_HEDLEY_TI_CL2000_VERSION
372 #endif
373 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
374  #define JSON_HEDLEY_TI_CL2000_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_CL2000_VERSION_CHECK)
378  #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
379 #endif
380 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
381  #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
382 #else
383  #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
384 #endif
385 
386 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
387  #undef JSON_HEDLEY_TI_CL430_VERSION
388 #endif
389 #if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
390  #define JSON_HEDLEY_TI_CL430_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_CL430_VERSION_CHECK)
394  #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
395 #endif
396 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
397  #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
398 #else
399  #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
400 #endif
401 
402 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
403  #undef JSON_HEDLEY_TI_ARMCL_VERSION
404 #endif
405 #if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
406  #define JSON_HEDLEY_TI_ARMCL_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_ARMCL_VERSION_CHECK)
410  #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
411 #endif
412 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
413  #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
414 #else
415  #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
416 #endif
417 
418 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
419  #undef JSON_HEDLEY_TI_CL6X_VERSION
420 #endif
421 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
422  #define JSON_HEDLEY_TI_CL6X_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_CL6X_VERSION_CHECK)
426  #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
427 #endif
428 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
429  #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
430 #else
431  #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
432 #endif
433 
434 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
435  #undef JSON_HEDLEY_TI_CL7X_VERSION
436 #endif
437 #if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
438  #define JSON_HEDLEY_TI_CL7X_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_CL7X_VERSION_CHECK)
442  #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
443 #endif
444 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
445  #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
446 #else
447  #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
448 #endif
449 
450 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
451  #undef JSON_HEDLEY_TI_CLPRU_VERSION
452 #endif
453 #if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
454  #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
455 #endif
456 
457 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
458  #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
459 #endif
460 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
461  #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
462 #else
463  #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
464 #endif
465 
466 #if defined(JSON_HEDLEY_CRAY_VERSION)
467  #undef JSON_HEDLEY_CRAY_VERSION
468 #endif
469 #if defined(_CRAYC)
470  #if defined(_RELEASE_PATCHLEVEL)
471  #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
472  #else
473  #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
474  #endif
475 #endif
476 
477 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
478  #undef JSON_HEDLEY_CRAY_VERSION_CHECK
479 #endif
480 #if defined(JSON_HEDLEY_CRAY_VERSION)
481  #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
482 #else
483  #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
484 #endif
485 
486 #if defined(JSON_HEDLEY_IAR_VERSION)
487  #undef JSON_HEDLEY_IAR_VERSION
488 #endif
489 #if defined(__IAR_SYSTEMS_ICC__)
490  #if __VER__ > 1000
491  #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
492  #else
493  #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(VER / 100, __VER__ % 100, 0)
494  #endif
495 #endif
496 
497 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
498  #undef JSON_HEDLEY_IAR_VERSION_CHECK
499 #endif
500 #if defined(JSON_HEDLEY_IAR_VERSION)
501  #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
502 #else
503  #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
504 #endif
505 
506 #if defined(JSON_HEDLEY_TINYC_VERSION)
507  #undef JSON_HEDLEY_TINYC_VERSION
508 #endif
509 #if defined(__TINYC__)
510  #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
511 #endif
512 
513 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
514  #undef JSON_HEDLEY_TINYC_VERSION_CHECK
515 #endif
516 #if defined(JSON_HEDLEY_TINYC_VERSION)
517  #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
518 #else
519  #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
520 #endif
521 
522 #if defined(JSON_HEDLEY_DMC_VERSION)
523  #undef JSON_HEDLEY_DMC_VERSION
524 #endif
525 #if defined(__DMC__)
526  #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
527 #endif
528 
529 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
530  #undef JSON_HEDLEY_DMC_VERSION_CHECK
531 #endif
532 #if defined(JSON_HEDLEY_DMC_VERSION)
533  #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
534 #else
535  #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
536 #endif
537 
538 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
539  #undef JSON_HEDLEY_COMPCERT_VERSION
540 #endif
541 #if defined(__COMPCERT_VERSION__)
542  #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
543 #endif
544 
545 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
546  #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
547 #endif
548 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
549  #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
550 #else
551  #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
552 #endif
553 
554 #if defined(JSON_HEDLEY_PELLES_VERSION)
555  #undef JSON_HEDLEY_PELLES_VERSION
556 #endif
557 #if defined(__POCC__)
558  #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
559 #endif
560 
561 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
562  #undef JSON_HEDLEY_PELLES_VERSION_CHECK
563 #endif
564 #if defined(JSON_HEDLEY_PELLES_VERSION)
565  #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
566 #else
567  #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
568 #endif
569 
570 #if defined(JSON_HEDLEY_GCC_VERSION)
571  #undef JSON_HEDLEY_GCC_VERSION
572 #endif
573 #if \
574  defined(JSON_HEDLEY_GNUC_VERSION) && \
575  !defined(__clang__) && \
576  !defined(JSON_HEDLEY_INTEL_VERSION) && \
577  !defined(JSON_HEDLEY_PGI_VERSION) && \
578  !defined(JSON_HEDLEY_ARM_VERSION) && \
579  !defined(JSON_HEDLEY_TI_VERSION) && \
580  !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
581  !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
582  !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
583  !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
584  !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
585  !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
586  !defined(__COMPCERT__)
587  #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
588 #endif
589 
590 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
591  #undef JSON_HEDLEY_GCC_VERSION_CHECK
592 #endif
593 #if defined(JSON_HEDLEY_GCC_VERSION)
594  #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
595 #else
596  #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
597 #endif
598 
599 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
600  #undef JSON_HEDLEY_HAS_ATTRIBUTE
601 #endif
602 #if defined(__has_attribute)
603  #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
604 #else
605  #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
606 #endif
607 
608 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
609  #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
610 #endif
611 #if defined(__has_attribute)
612  #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
613 #else
614  #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
615 #endif
616 
617 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
618  #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
619 #endif
620 #if defined(__has_attribute)
621  #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
622 #else
623  #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
624 #endif
625 
626 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
627  #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
628 #endif
629 #if \
630  defined(__has_cpp_attribute) && \
631  defined(__cplusplus) && \
632  (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
633  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
634 #else
635  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
636 #endif
637 
638 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
639  #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
640 #endif
641 #if !defined(__cplusplus) || !defined(__has_cpp_attribute)
642  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
643 #elif \
644  !defined(JSON_HEDLEY_PGI_VERSION) && \
645  !defined(JSON_HEDLEY_IAR_VERSION) && \
646  (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
647  (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
648  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
649 #else
650  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
651 #endif
652 
653 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
654  #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
655 #endif
656 #if defined(__has_cpp_attribute) && defined(__cplusplus)
657  #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
658 #else
659  #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
660 #endif
661 
662 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
663  #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
664 #endif
665 #if defined(__has_cpp_attribute) && defined(__cplusplus)
666  #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
667 #else
668  #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
669 #endif
670 
671 #if defined(JSON_HEDLEY_HAS_BUILTIN)
672  #undef JSON_HEDLEY_HAS_BUILTIN
673 #endif
674 #if defined(__has_builtin)
675  #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
676 #else
677  #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
678 #endif
679 
680 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
681  #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
682 #endif
683 #if defined(__has_builtin)
684  #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
685 #else
686  #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
687 #endif
688 
689 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
690  #undef JSON_HEDLEY_GCC_HAS_BUILTIN
691 #endif
692 #if defined(__has_builtin)
693  #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
694 #else
695  #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
696 #endif
697 
698 #if defined(JSON_HEDLEY_HAS_FEATURE)
699  #undef JSON_HEDLEY_HAS_FEATURE
700 #endif
701 #if defined(__has_feature)
702  #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
703 #else
704  #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
705 #endif
706 
707 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
708  #undef JSON_HEDLEY_GNUC_HAS_FEATURE
709 #endif
710 #if defined(__has_feature)
711  #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
712 #else
713  #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
714 #endif
715 
716 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
717  #undef JSON_HEDLEY_GCC_HAS_FEATURE
718 #endif
719 #if defined(__has_feature)
720  #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
721 #else
722  #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
723 #endif
724 
725 #if defined(JSON_HEDLEY_HAS_EXTENSION)
726  #undef JSON_HEDLEY_HAS_EXTENSION
727 #endif
728 #if defined(__has_extension)
729  #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
730 #else
731  #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
732 #endif
733 
734 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
735  #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
736 #endif
737 #if defined(__has_extension)
738  #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
739 #else
740  #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
741 #endif
742 
743 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
744  #undef JSON_HEDLEY_GCC_HAS_EXTENSION
745 #endif
746 #if defined(__has_extension)
747  #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
748 #else
749  #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
750 #endif
751 
752 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
753  #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
754 #endif
755 #if defined(__has_declspec_attribute)
756  #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
757 #else
758  #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
759 #endif
760 
761 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
762  #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
763 #endif
764 #if defined(__has_declspec_attribute)
765  #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
766 #else
767  #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
768 #endif
769 
770 #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
771  #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
772 #endif
773 #if defined(__has_declspec_attribute)
774  #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
775 #else
776  #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
777 #endif
778 
779 #if defined(JSON_HEDLEY_HAS_WARNING)
780  #undef JSON_HEDLEY_HAS_WARNING
781 #endif
782 #if defined(__has_warning)
783  #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
784 #else
785  #define JSON_HEDLEY_HAS_WARNING(warning) (0)
786 #endif
787 
788 #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
789  #undef JSON_HEDLEY_GNUC_HAS_WARNING
790 #endif
791 #if defined(__has_warning)
792  #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
793 #else
794  #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
795 #endif
796 
797 #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
798  #undef JSON_HEDLEY_GCC_HAS_WARNING
799 #endif
800 #if defined(__has_warning)
801  #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
802 #else
803  #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
804 #endif
805 
806 #if \
807  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
808  defined(__clang__) || \
809  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
810  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
811  JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
812  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
813  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
814  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
815  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
816  JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
817  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
818  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
819  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
820  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
821  JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
822  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
823  JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
824  (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
825  #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
826 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
827  #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
828 #else
829  #define JSON_HEDLEY_PRAGMA(value)
830 #endif
831 
832 #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
833  #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
834 #endif
835 #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
836  #undef JSON_HEDLEY_DIAGNOSTIC_POP
837 #endif
838 #if defined(__clang__)
839  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
840  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
841 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
842  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
843  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
844 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
845  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
846  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
847 #elif \
848  JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
849  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
850  #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
851  #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
852 #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
853  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
854  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
855 #elif \
856  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
857  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
858  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
859  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
860  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
861  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
862  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
863  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
864 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
865  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
866  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
867 #else
868  #define JSON_HEDLEY_DIAGNOSTIC_PUSH
869  #define JSON_HEDLEY_DIAGNOSTIC_POP
870 #endif
871 
872 /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
873  HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
874 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
875  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
876 #endif
877 #if defined(__cplusplus)
878 # if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
879 # if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
880 # if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
881 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
882  JSON_HEDLEY_DIAGNOSTIC_PUSH \
883  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
884  _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
885  _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
886  xpr \
887  JSON_HEDLEY_DIAGNOSTIC_POP
888 # else
889 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
890  JSON_HEDLEY_DIAGNOSTIC_PUSH \
891  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
892  _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
893  xpr \
894  JSON_HEDLEY_DIAGNOSTIC_POP
895 # endif
896 # else
897 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
898  JSON_HEDLEY_DIAGNOSTIC_PUSH \
899  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
900  xpr \
901  JSON_HEDLEY_DIAGNOSTIC_POP
902 # endif
903 # endif
904 #endif
905 #if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
906  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
907 #endif
908 
909 #if defined(JSON_HEDLEY_CONST_CAST)
910  #undef JSON_HEDLEY_CONST_CAST
911 #endif
912 #if defined(__cplusplus)
913 # define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
914 #elif \
915  JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
916  JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
917  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
918 # define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
919  JSON_HEDLEY_DIAGNOSTIC_PUSH \
920  JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
921  ((T) (expr)); \
922  JSON_HEDLEY_DIAGNOSTIC_POP \
923  }))
924 #else
925 # define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
926 #endif
927 
928 #if defined(JSON_HEDLEY_REINTERPRET_CAST)
929  #undef JSON_HEDLEY_REINTERPRET_CAST
930 #endif
931 #if defined(__cplusplus)
932  #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
933 #else
934  #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
935 #endif
936 
937 #if defined(JSON_HEDLEY_STATIC_CAST)
938  #undef JSON_HEDLEY_STATIC_CAST
939 #endif
940 #if defined(__cplusplus)
941  #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
942 #else
943  #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
944 #endif
945 
946 #if defined(JSON_HEDLEY_CPP_CAST)
947  #undef JSON_HEDLEY_CPP_CAST
948 #endif
949 #if defined(__cplusplus)
950 # if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
951 # define JSON_HEDLEY_CPP_CAST(T, expr) \
952  JSON_HEDLEY_DIAGNOSTIC_PUSH \
953  _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
954  ((T) (expr)) \
955  JSON_HEDLEY_DIAGNOSTIC_POP
956 # elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
957 # define JSON_HEDLEY_CPP_CAST(T, expr) \
958  JSON_HEDLEY_DIAGNOSTIC_PUSH \
959  _Pragma("diag_suppress=Pe137") \
960  JSON_HEDLEY_DIAGNOSTIC_POP
961 # else
962 # define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
963 # endif
964 #else
965 # define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
966 #endif
967 
968 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
969  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
970 #endif
971 #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
972  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
973 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
974  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
975 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
976  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
977 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
978  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
979 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
980  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
981 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
982  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
983 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
984  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
985 #elif \
986  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
987  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
988  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
989  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
990  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
991  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
992  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
993  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
994  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
995  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
996  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
997  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
998 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
999  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1000 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1001  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1002 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1003  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1004 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1005  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1006 #else
1007  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1008 #endif
1009 
1010 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1011  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1012 #endif
1013 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1014  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1015 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1016  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1017 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1018  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1019 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1020  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1021 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1022  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1023 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1024  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1025 #elif \
1026  JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1027  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1028  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1029  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1030  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1031 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1032  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1033 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1034  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1035 #else
1036  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1037 #endif
1038 
1039 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1040  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1041 #endif
1042 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1043  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1044 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1045  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1046 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1047  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1048 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1049  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1050 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1051  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1052 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1053  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1054 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1055  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1056 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1057  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1058 #elif \
1059  JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1060  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1061  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1062  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1063 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1064  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1065 #else
1066  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1067 #endif
1068 
1069 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1070  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1071 #endif
1072 #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1073  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1074 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1075  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1076 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1077  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1078 #else
1079  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1080 #endif
1081 
1082 #if defined(JSON_HEDLEY_DEPRECATED)
1083  #undef JSON_HEDLEY_DEPRECATED
1084 #endif
1085 #if defined(JSON_HEDLEY_DEPRECATED_FOR)
1086  #undef JSON_HEDLEY_DEPRECATED_FOR
1087 #endif
1088 #if \
1089  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1090  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1091  #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1092  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1093 #elif \
1094  JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) || \
1095  JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1096  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1097  JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1098  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1099  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1100  JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1101  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1102  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1103  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1104  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1105  #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1106  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1107 #elif defined(__cplusplus) && (__cplusplus >= 201402L)
1108  #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1109  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1110 #elif \
1111  JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1112  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1113  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1114  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1115  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1116  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1117  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1118  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1119  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1120  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1121  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1122  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1123  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1124  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1125  #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1126  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1127 #elif \
1128  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1129  JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1130  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1131  #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1132  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1133 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1134  #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1135  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1136 #else
1137  #define JSON_HEDLEY_DEPRECATED(since)
1138  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1139 #endif
1140 
1141 #if defined(JSON_HEDLEY_UNAVAILABLE)
1142  #undef JSON_HEDLEY_UNAVAILABLE
1143 #endif
1144 #if \
1145  JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1146  JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1147  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1148  #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1149 #else
1150  #define JSON_HEDLEY_UNAVAILABLE(available_since)
1151 #endif
1152 
1153 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1154  #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1155 #endif
1156 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1157  #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1158 #endif
1159 #if \
1160  JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1161  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1162  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1163  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1164  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1165  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1166  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1167  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1168  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1169  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1170  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1171  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1172  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1173  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1174  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1175  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1176  #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1177  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1178 #elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1179  #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1180  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1181 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1182  #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1183  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1184 #elif defined(_Check_return_) /* SAL */
1185  #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1186  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1187 #else
1188  #define JSON_HEDLEY_WARN_UNUSED_RESULT
1189  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1190 #endif
1191 
1192 #if defined(JSON_HEDLEY_SENTINEL)
1193  #undef JSON_HEDLEY_SENTINEL
1194 #endif
1195 #if \
1196  JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1197  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1198  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1199  JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0)
1200  #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1201 #else
1202  #define JSON_HEDLEY_SENTINEL(position)
1203 #endif
1204 
1205 #if defined(JSON_HEDLEY_NO_RETURN)
1206  #undef JSON_HEDLEY_NO_RETURN
1207 #endif
1208 #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1209  #define JSON_HEDLEY_NO_RETURN __noreturn
1210 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1211  #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1212 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1213  #define JSON_HEDLEY_NO_RETURN _Noreturn
1214 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
1215  #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1216 #elif \
1217  JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1218  JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1219  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1220  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1221  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1222  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1223  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1224  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1225  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1226  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1227  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1228  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1229  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1230  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1231  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1232  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1233  #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1234 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1235  #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1236 #elif \
1237  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1238  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1239  #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1240 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1241  #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1242 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1243  #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1244 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1245  #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1246 #else
1247  #define JSON_HEDLEY_NO_RETURN
1248 #endif
1249 
1250 #if defined(JSON_HEDLEY_NO_ESCAPE)
1251  #undef JSON_HEDLEY_NO_ESCAPE
1252 #endif
1253 #if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1254  #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1255 #else
1256  #define JSON_HEDLEY_NO_ESCAPE
1257 #endif
1258 
1259 #if defined(JSON_HEDLEY_UNREACHABLE)
1260  #undef JSON_HEDLEY_UNREACHABLE
1261 #endif
1262 #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1263  #undef JSON_HEDLEY_UNREACHABLE_RETURN
1264 #endif
1265 #if defined(JSON_HEDLEY_ASSUME)
1266  #undef JSON_HEDLEY_ASSUME
1267 #endif
1268 #if \
1269  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1270  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1271  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1272  #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1273 #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1274  #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1275 #elif \
1276  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1277  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1278  #if defined(__cplusplus)
1279  #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1280  #else
1281  #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1282  #endif
1283 #endif
1284 #if \
1285  (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1286  JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1287  JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1288  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1289  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5)
1290  #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1291 #elif defined(JSON_HEDLEY_ASSUME)
1292  #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1293 #endif
1294 #if !defined(JSON_HEDLEY_ASSUME)
1295  #if defined(JSON_HEDLEY_UNREACHABLE)
1296  #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1297  #else
1298  #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1299  #endif
1300 #endif
1301 #if defined(JSON_HEDLEY_UNREACHABLE)
1302  #if \
1303  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1304  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1305  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1306  #else
1307  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1308  #endif
1309 #else
1310  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1311 #endif
1312 #if !defined(JSON_HEDLEY_UNREACHABLE)
1313  #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1314 #endif
1315 
1317 #if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1318  #pragma clang diagnostic ignored "-Wpedantic"
1319 #endif
1320 #if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1321  #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1322 #endif
1323 #if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1324  #if defined(__clang__)
1325  #pragma clang diagnostic ignored "-Wvariadic-macros"
1326  #elif defined(JSON_HEDLEY_GCC_VERSION)
1327  #pragma GCC diagnostic ignored "-Wvariadic-macros"
1328  #endif
1329 #endif
1330 #if defined(JSON_HEDLEY_NON_NULL)
1331  #undef JSON_HEDLEY_NON_NULL
1332 #endif
1333 #if \
1334  JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1335  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1336  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1337  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1338  #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1339 #else
1340  #define JSON_HEDLEY_NON_NULL(...)
1341 #endif
1343 
1344 #if defined(JSON_HEDLEY_PRINTF_FORMAT)
1345  #undef JSON_HEDLEY_PRINTF_FORMAT
1346 #endif
1347 #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1348  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1349 #elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1350  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1351 #elif \
1352  JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1353  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1354  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1355  JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1356  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1357  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1358  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1359  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1360  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1361  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1362  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1363  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1364  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1365  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1366  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1367  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1368  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1369 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1370  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1371 #else
1372  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1373 #endif
1374 
1375 #if defined(JSON_HEDLEY_CONSTEXPR)
1376  #undef JSON_HEDLEY_CONSTEXPR
1377 #endif
1378 #if defined(__cplusplus)
1379  #if __cplusplus >= 201103L
1380  #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1381  #endif
1382 #endif
1383 #if !defined(JSON_HEDLEY_CONSTEXPR)
1384  #define JSON_HEDLEY_CONSTEXPR
1385 #endif
1386 
1387 #if defined(JSON_HEDLEY_PREDICT)
1388  #undef JSON_HEDLEY_PREDICT
1389 #endif
1390 #if defined(JSON_HEDLEY_LIKELY)
1391  #undef JSON_HEDLEY_LIKELY
1392 #endif
1393 #if defined(JSON_HEDLEY_UNLIKELY)
1394  #undef JSON_HEDLEY_UNLIKELY
1395 #endif
1396 #if defined(JSON_HEDLEY_UNPREDICTABLE)
1397  #undef JSON_HEDLEY_UNPREDICTABLE
1398 #endif
1399 #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1400  #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1401 #endif
1402 #if \
1403  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1404  JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0)
1405 # define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1406 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1407 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1408 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1409 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1410 #elif \
1411  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1412  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1413  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1414  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1415  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1416  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1417  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1418  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1419  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1420  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1421  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1422  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1423  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1424  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1425  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
1426 # define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1427  (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1428 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1429  (__extension__ ({ \
1430  double hedley_probability_ = (probability); \
1431  ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1432  }))
1433 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1434  (__extension__ ({ \
1435  double hedley_probability_ = (probability); \
1436  ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1437  }))
1438 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1439 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1440 #else
1441 # define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1442 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1443 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1444 # define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1445 # define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1446 #endif
1447 #if !defined(JSON_HEDLEY_UNPREDICTABLE)
1448  #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1449 #endif
1450 
1451 #if defined(JSON_HEDLEY_MALLOC)
1452  #undef JSON_HEDLEY_MALLOC
1453 #endif
1454 #if \
1455  JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1456  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1457  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1458  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1459  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1460  JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1461  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1462  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1463  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1464  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1465  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1466  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1467  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1468  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1469  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1470  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1471  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1472  #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1473 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1474  #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1475 #elif \
1476  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1477  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1478  #define JSON_HEDLEY_MALLOC __declspec(restrict)
1479 #else
1480  #define JSON_HEDLEY_MALLOC
1481 #endif
1482 
1483 #if defined(JSON_HEDLEY_PURE)
1484  #undef JSON_HEDLEY_PURE
1485 #endif
1486 #if \
1487  JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1488  JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1489  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1490  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1491  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1492  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1493  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1494  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1495  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1496  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1497  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1498  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1499  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1500  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1501  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1502  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1503  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1504  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1505 # define JSON_HEDLEY_PURE __attribute__((__pure__))
1506 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1507 # define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1508 #elif defined(__cplusplus) && \
1509  ( \
1510  JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1511  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1512  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1513  )
1514 # define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1515 #else
1516 # define JSON_HEDLEY_PURE
1517 #endif
1518 
1519 #if defined(JSON_HEDLEY_CONST)
1520  #undef JSON_HEDLEY_CONST
1521 #endif
1522 #if \
1523  JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1524  JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1525  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1526  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1527  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1528  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1529  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1530  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1531  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1532  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1533  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1534  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1535  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1536  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1537  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1538  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1539  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1540  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1541  #define JSON_HEDLEY_CONST __attribute__((__const__))
1542 #elif \
1543  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1544  #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1545 #else
1546  #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1547 #endif
1548 
1549 #if defined(JSON_HEDLEY_RESTRICT)
1550  #undef JSON_HEDLEY_RESTRICT
1551 #endif
1552 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1553  #define JSON_HEDLEY_RESTRICT restrict
1554 #elif \
1555  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1556  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1557  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1558  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1559  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1560  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1561  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1562  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1563  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1564  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1565  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1566  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1567  JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1568  defined(__clang__)
1569  #define JSON_HEDLEY_RESTRICT __restrict
1570 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1571  #define JSON_HEDLEY_RESTRICT _Restrict
1572 #else
1573  #define JSON_HEDLEY_RESTRICT
1574 #endif
1575 
1576 #if defined(JSON_HEDLEY_INLINE)
1577  #undef JSON_HEDLEY_INLINE
1578 #endif
1579 #if \
1580  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1581  (defined(__cplusplus) && (__cplusplus >= 199711L))
1582  #define JSON_HEDLEY_INLINE inline
1583 #elif \
1584  defined(JSON_HEDLEY_GCC_VERSION) || \
1585  JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1586  #define JSON_HEDLEY_INLINE __inline__
1587 #elif \
1588  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1589  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1590  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1591  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1592  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1593  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1594  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1595  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1596  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1597  #define JSON_HEDLEY_INLINE __inline
1598 #else
1599  #define JSON_HEDLEY_INLINE
1600 #endif
1601 
1602 #if defined(JSON_HEDLEY_ALWAYS_INLINE)
1603  #undef JSON_HEDLEY_ALWAYS_INLINE
1604 #endif
1605 #if \
1606  JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1607  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1608  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1609  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1610  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1611  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1612  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1613  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1614  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1615  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1616  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1617  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1618  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1619  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1620  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1621  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1622  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1623 # define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1624 #elif \
1625  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1626  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1627 # define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1628 #elif defined(__cplusplus) && \
1629  ( \
1630  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1631  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1632  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1633  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1634  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1635  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1636  )
1637 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1638 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1639 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1640 #else
1641 # define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1642 #endif
1643 
1644 #if defined(JSON_HEDLEY_NEVER_INLINE)
1645  #undef JSON_HEDLEY_NEVER_INLINE
1646 #endif
1647 #if \
1648  JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1649  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1650  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1651  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1652  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1653  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1654  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1655  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1656  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1657  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1658  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1659  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1660  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1661  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1662  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1663  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1664  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1665  #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1666 #elif \
1667  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1668  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1669  #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1670 #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1671  #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1672 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1673  #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1674 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1675  #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1676 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1677  #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1678 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1679  #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1680 #else
1681  #define JSON_HEDLEY_NEVER_INLINE
1682 #endif
1683 
1684 #if defined(JSON_HEDLEY_PRIVATE)
1685  #undef JSON_HEDLEY_PRIVATE
1686 #endif
1687 #if defined(JSON_HEDLEY_PUBLIC)
1688  #undef JSON_HEDLEY_PUBLIC
1689 #endif
1690 #if defined(JSON_HEDLEY_IMPORT)
1691  #undef JSON_HEDLEY_IMPORT
1692 #endif
1693 #if defined(_WIN32) || defined(__CYGWIN__)
1694 # define JSON_HEDLEY_PRIVATE
1695 # define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1696 # define JSON_HEDLEY_IMPORT __declspec(dllimport)
1697 #else
1698 # if \
1699  JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1700  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1701  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1702  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1703  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1704  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1705  ( \
1706  defined(__TI_EABI__) && \
1707  ( \
1708  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1709  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1710  ) \
1711  )
1712 # define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1713 # define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1714 # else
1715 # define JSON_HEDLEY_PRIVATE
1716 # define JSON_HEDLEY_PUBLIC
1717 # endif
1718 # define JSON_HEDLEY_IMPORT extern
1719 #endif
1720 
1721 #if defined(JSON_HEDLEY_NO_THROW)
1722  #undef JSON_HEDLEY_NO_THROW
1723 #endif
1724 #if \
1725  JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1726  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1727  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1728  #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1729 #elif \
1730  JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1731  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1732  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1733  #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1734 #else
1735  #define JSON_HEDLEY_NO_THROW
1736 #endif
1737 
1738 #if defined(JSON_HEDLEY_FALL_THROUGH)
1739  #undef JSON_HEDLEY_FALL_THROUGH
1740 #endif
1741 #if \
1742  JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1743  JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0)
1744  #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1745 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1746  #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1747 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1748  #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1749 #elif defined(__fallthrough) /* SAL */
1750  #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1751 #else
1752  #define JSON_HEDLEY_FALL_THROUGH
1753 #endif
1754 
1755 #if defined(JSON_HEDLEY_RETURNS_NON_NULL)
1756  #undef JSON_HEDLEY_RETURNS_NON_NULL
1757 #endif
1758 #if \
1759  JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1760  JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
1761  #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
1762 #elif defined(_Ret_notnull_) /* SAL */
1763  #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
1764 #else
1765  #define JSON_HEDLEY_RETURNS_NON_NULL
1766 #endif
1767 
1768 #if defined(JSON_HEDLEY_ARRAY_PARAM)
1769  #undef JSON_HEDLEY_ARRAY_PARAM
1770 #endif
1771 #if \
1772  defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1773  !defined(__STDC_NO_VLA__) && \
1774  !defined(__cplusplus) && \
1775  !defined(JSON_HEDLEY_PGI_VERSION) && \
1776  !defined(JSON_HEDLEY_TINYC_VERSION)
1777  #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1778 #else
1779  #define JSON_HEDLEY_ARRAY_PARAM(name)
1780 #endif
1781 
1782 #if defined(JSON_HEDLEY_IS_CONSTANT)
1783  #undef JSON_HEDLEY_IS_CONSTANT
1784 #endif
1785 #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1786  #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1787 #endif
1788 /* JSON_HEDLEY_IS_CONSTEXPR_ is for
1789  HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1790 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1791  #undef JSON_HEDLEY_IS_CONSTEXPR_
1792 #endif
1793 #if \
1794  JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1795  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1796  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1797  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1798  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1799  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1800  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1801  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1802  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
1803  #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1804 #endif
1805 #if !defined(__cplusplus)
1806 # if \
1807  JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1808  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1809  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1810  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1811  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1812  JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1813  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1814 #if defined(__INTPTR_TYPE__)
1815  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1816 #else
1817  #include <stdint.h>
1818  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1819 #endif
1820 # elif \
1821  ( \
1822  defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1823  !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1824  !defined(JSON_HEDLEY_PGI_VERSION) && \
1825  !defined(JSON_HEDLEY_IAR_VERSION)) || \
1826  JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) || \
1827  JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1828  JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1829  JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1830  JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1831 #if defined(__INTPTR_TYPE__)
1832  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1833 #else
1834  #include <stdint.h>
1835  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1836 #endif
1837 # elif \
1838  defined(JSON_HEDLEY_GCC_VERSION) || \
1839  defined(JSON_HEDLEY_INTEL_VERSION) || \
1840  defined(JSON_HEDLEY_TINYC_VERSION) || \
1841  defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1842  JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1843  defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1844  defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1845  defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1846  defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1847  defined(__clang__)
1848 # define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1849  sizeof(void) != \
1850  sizeof(*( \
1851  1 ? \
1852  ((void*) ((expr) * 0L) ) : \
1853 ((struct { char v[sizeof(void) * 2]; } *) 1) \
1854  ) \
1855  ) \
1856  )
1857 # endif
1858 #endif
1859 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1860  #if !defined(JSON_HEDLEY_IS_CONSTANT)
1861  #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1862  #endif
1863  #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
1864 #else
1865  #if !defined(JSON_HEDLEY_IS_CONSTANT)
1866  #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
1867  #endif
1868  #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
1869 #endif
1870 
1871 #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
1872  #undef JSON_HEDLEY_BEGIN_C_DECLS
1873 #endif
1874 #if defined(JSON_HEDLEY_END_C_DECLS)
1875  #undef JSON_HEDLEY_END_C_DECLS
1876 #endif
1877 #if defined(JSON_HEDLEY_C_DECL)
1878  #undef JSON_HEDLEY_C_DECL
1879 #endif
1880 #if defined(__cplusplus)
1881  #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
1882  #define JSON_HEDLEY_END_C_DECLS }
1883  #define JSON_HEDLEY_C_DECL extern "C"
1884 #else
1885  #define JSON_HEDLEY_BEGIN_C_DECLS
1886  #define JSON_HEDLEY_END_C_DECLS
1887  #define JSON_HEDLEY_C_DECL
1888 #endif
1889 
1890 #if defined(JSON_HEDLEY_STATIC_ASSERT)
1891  #undef JSON_HEDLEY_STATIC_ASSERT
1892 #endif
1893 #if \
1894  !defined(__cplusplus) && ( \
1895  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
1896  (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1897  JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
1898  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1899  defined(_Static_assert) \
1900  )
1901 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
1902 #elif \
1903  (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
1904  JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
1905  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1906 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
1907 #else
1908 # define JSON_HEDLEY_STATIC_ASSERT(expr, message)
1909 #endif
1910 
1911 #if defined(JSON_HEDLEY_NULL)
1912  #undef JSON_HEDLEY_NULL
1913 #endif
1914 #if defined(__cplusplus)
1915  #if __cplusplus >= 201103L
1916  #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
1917  #elif defined(NULL)
1918  #define JSON_HEDLEY_NULL NULL
1919  #else
1920  #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
1921  #endif
1922 #elif defined(NULL)
1923  #define JSON_HEDLEY_NULL NULL
1924 #else
1925  #define JSON_HEDLEY_NULL ((void*) 0)
1926 #endif
1927 
1928 #if defined(JSON_HEDLEY_MESSAGE)
1929  #undef JSON_HEDLEY_MESSAGE
1930 #endif
1931 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1932 # define JSON_HEDLEY_MESSAGE(msg) \
1933  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1934  JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1935  JSON_HEDLEY_PRAGMA(message msg) \
1936  JSON_HEDLEY_DIAGNOSTIC_POP
1937 #elif \
1938  JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
1939  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1940 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
1941 #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
1942 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
1943 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1944 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1945 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
1946 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1947 #else
1948 # define JSON_HEDLEY_MESSAGE(msg)
1949 #endif
1950 
1951 #if defined(JSON_HEDLEY_WARNING)
1952  #undef JSON_HEDLEY_WARNING
1953 #endif
1954 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1955 # define JSON_HEDLEY_WARNING(msg) \
1956  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1957  JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1958  JSON_HEDLEY_PRAGMA(clang warning msg) \
1959  JSON_HEDLEY_DIAGNOSTIC_POP
1960 #elif \
1961  JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
1962  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
1963  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1964 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
1965 #elif \
1966  JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
1967  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1968 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
1969 #else
1970 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
1971 #endif
1972 
1973 #if defined(JSON_HEDLEY_REQUIRE)
1974  #undef JSON_HEDLEY_REQUIRE
1975 #endif
1976 #if defined(JSON_HEDLEY_REQUIRE_MSG)
1977  #undef JSON_HEDLEY_REQUIRE_MSG
1978 #endif
1979 #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
1980 # if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
1981 # define JSON_HEDLEY_REQUIRE(expr) \
1982  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1983  _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1984  __attribute__((diagnose_if(!(expr), #expr, "error"))) \
1985  JSON_HEDLEY_DIAGNOSTIC_POP
1986 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
1987  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1988  _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1989  __attribute__((diagnose_if(!(expr), msg, "error"))) \
1990  JSON_HEDLEY_DIAGNOSTIC_POP
1991 # else
1992 # define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
1993 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
1994 # endif
1995 #else
1996 # define JSON_HEDLEY_REQUIRE(expr)
1997 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
1998 #endif
1999 
2000 #if defined(JSON_HEDLEY_FLAGS)
2001  #undef JSON_HEDLEY_FLAGS
2002 #endif
2003 #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum)
2004  #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2005 #else
2006  #define JSON_HEDLEY_FLAGS
2007 #endif
2008 
2009 #if defined(JSON_HEDLEY_FLAGS_CAST)
2010  #undef JSON_HEDLEY_FLAGS_CAST
2011 #endif
2012 #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2013 # define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2014  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2015  _Pragma("warning(disable:188)") \
2016  ((T) (expr)); \
2017  JSON_HEDLEY_DIAGNOSTIC_POP \
2018  }))
2019 #else
2020 # define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2021 #endif
2022 
2023 #if defined(JSON_HEDLEY_EMPTY_BASES)
2024  #undef JSON_HEDLEY_EMPTY_BASES
2025 #endif
2026 #if \
2027  (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2028  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2029  #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2030 #else
2031  #define JSON_HEDLEY_EMPTY_BASES
2032 #endif
2033 
2034 /* Remaining macros are deprecated. */
2035 
2036 #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2037  #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2038 #endif
2039 #if defined(__clang__)
2040  #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2041 #else
2042  #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2043 #endif
2044 
2045 #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2046  #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2047 #endif
2048 #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2049 
2050 #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2051  #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2052 #endif
2053 #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2054 
2055 #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2056  #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2057 #endif
2058 #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2059 
2060 #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2061  #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2062 #endif
2063 #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2064 
2065 #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2066  #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2067 #endif
2068 #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2069 
2070 #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2071  #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2072 #endif
2073 #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2074 
2075 #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2076  #undef JSON_HEDLEY_CLANG_HAS_WARNING
2077 #endif
2078 #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2079 
2080 #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2081 
2082 
2083 // This file contains all internal macro definitions
2084 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2085 
2086 // exclude unsupported compilers
2087 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2088  #if defined(__clang__)
2089  #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2090  #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2091  #endif
2092  #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2093  #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2094  #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2095  #endif
2096  #endif
2097 #endif
2098 
2099 // C++ language standard detection
2100 #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2101  #define JSON_HAS_CPP_20
2102  #define JSON_HAS_CPP_17
2103  #define JSON_HAS_CPP_14
2104 #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2105  #define JSON_HAS_CPP_17
2106  #define JSON_HAS_CPP_14
2107 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2108  #define JSON_HAS_CPP_14
2109 #endif
2110 
2111 // disable float-equal warnings on GCC/clang
2112 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
2113  #pragma GCC diagnostic push
2114  #pragma GCC diagnostic ignored "-Wfloat-equal"
2115 #endif
2116 
2117 // disable documentation warnings on clang
2118 #if defined(__clang__)
2119  #pragma GCC diagnostic push
2120  #pragma GCC diagnostic ignored "-Wdocumentation"
2121 #endif
2122 
2123 // allow to disable exceptions
2124 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2125  #define JSON_THROW(exception) throw exception
2126  #define JSON_TRY try
2127  #define JSON_CATCH(exception) catch(exception)
2128  #define JSON_INTERNAL_CATCH(exception) catch(exception)
2129 #else
2130  #include <cstdlib>
2131  #define JSON_THROW(exception) std::abort()
2132  #define JSON_TRY if(true)
2133  #define JSON_CATCH(exception) if(false)
2134  #define JSON_INTERNAL_CATCH(exception) if(false)
2135 #endif
2136 
2137 // override exception macros
2138 #if defined(JSON_THROW_USER)
2139  #undef JSON_THROW
2140  #define JSON_THROW JSON_THROW_USER
2141 #endif
2142 #if defined(JSON_TRY_USER)
2143  #undef JSON_TRY
2144  #define JSON_TRY JSON_TRY_USER
2145 #endif
2146 #if defined(JSON_CATCH_USER)
2147  #undef JSON_CATCH
2148  #define JSON_CATCH JSON_CATCH_USER
2149  #undef JSON_INTERNAL_CATCH
2150  #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2151 #endif
2152 #if defined(JSON_INTERNAL_CATCH_USER)
2153  #undef JSON_INTERNAL_CATCH
2154  #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2155 #endif
2156 
2157 // allow to override assert
2158 #if !defined(JSON_ASSERT)
2159  #include <cassert> // assert
2160  #define JSON_ASSERT(x) assert(x)
2161 #endif
2162 
2163 // allow to access some private functions (needed by the test suite)
2164 #if defined(JSON_TESTS_PRIVATE)
2165  #define JSON_PRIVATE_UNLESS_TESTED public
2166 #else
2167  #define JSON_PRIVATE_UNLESS_TESTED private
2168 #endif
2169 
2175 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2176  template<typename BasicJsonType> \
2177  inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2178  { \
2179  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2180  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2181  auto it = std::find_if(std::begin(m), std::end(m), \
2182  [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2183  { \
2184  return ej_pair.first == e; \
2185  }); \
2186  j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2187  } \
2188  template<typename BasicJsonType> \
2189  inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2190  { \
2191  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2192  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2193  auto it = std::find_if(std::begin(m), std::end(m), \
2194  [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2195  { \
2196  return ej_pair.second == j; \
2197  }); \
2198  e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2199  }
2200 
2201 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2202 // may be removed in the future once the class is split.
2203 
2204 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2205  template<template<typename, typename, typename...> class ObjectType, \
2206  template<typename, typename...> class ArrayType, \
2207  class StringType, class BooleanType, class NumberIntegerType, \
2208  class NumberUnsignedType, class NumberFloatType, \
2209  template<typename> class AllocatorType, \
2210  template<typename, typename = void> class JSONSerializer, \
2211  class BinaryType>
2212 
2213 #define NLOHMANN_BASIC_JSON_TPL \
2214  basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2215  NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2216  AllocatorType, JSONSerializer, BinaryType>
2217 
2218 // Macros to simplify conversion from/to types
2219 
2220 #define NLOHMANN_JSON_EXPAND( x ) x
2221 #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
2222 #define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2223  NLOHMANN_JSON_PASTE64, \
2224  NLOHMANN_JSON_PASTE63, \
2225  NLOHMANN_JSON_PASTE62, \
2226  NLOHMANN_JSON_PASTE61, \
2227  NLOHMANN_JSON_PASTE60, \
2228  NLOHMANN_JSON_PASTE59, \
2229  NLOHMANN_JSON_PASTE58, \
2230  NLOHMANN_JSON_PASTE57, \
2231  NLOHMANN_JSON_PASTE56, \
2232  NLOHMANN_JSON_PASTE55, \
2233  NLOHMANN_JSON_PASTE54, \
2234  NLOHMANN_JSON_PASTE53, \
2235  NLOHMANN_JSON_PASTE52, \
2236  NLOHMANN_JSON_PASTE51, \
2237  NLOHMANN_JSON_PASTE50, \
2238  NLOHMANN_JSON_PASTE49, \
2239  NLOHMANN_JSON_PASTE48, \
2240  NLOHMANN_JSON_PASTE47, \
2241  NLOHMANN_JSON_PASTE46, \
2242  NLOHMANN_JSON_PASTE45, \
2243  NLOHMANN_JSON_PASTE44, \
2244  NLOHMANN_JSON_PASTE43, \
2245  NLOHMANN_JSON_PASTE42, \
2246  NLOHMANN_JSON_PASTE41, \
2247  NLOHMANN_JSON_PASTE40, \
2248  NLOHMANN_JSON_PASTE39, \
2249  NLOHMANN_JSON_PASTE38, \
2250  NLOHMANN_JSON_PASTE37, \
2251  NLOHMANN_JSON_PASTE36, \
2252  NLOHMANN_JSON_PASTE35, \
2253  NLOHMANN_JSON_PASTE34, \
2254  NLOHMANN_JSON_PASTE33, \
2255  NLOHMANN_JSON_PASTE32, \
2256  NLOHMANN_JSON_PASTE31, \
2257  NLOHMANN_JSON_PASTE30, \
2258  NLOHMANN_JSON_PASTE29, \
2259  NLOHMANN_JSON_PASTE28, \
2260  NLOHMANN_JSON_PASTE27, \
2261  NLOHMANN_JSON_PASTE26, \
2262  NLOHMANN_JSON_PASTE25, \
2263  NLOHMANN_JSON_PASTE24, \
2264  NLOHMANN_JSON_PASTE23, \
2265  NLOHMANN_JSON_PASTE22, \
2266  NLOHMANN_JSON_PASTE21, \
2267  NLOHMANN_JSON_PASTE20, \
2268  NLOHMANN_JSON_PASTE19, \
2269  NLOHMANN_JSON_PASTE18, \
2270  NLOHMANN_JSON_PASTE17, \
2271  NLOHMANN_JSON_PASTE16, \
2272  NLOHMANN_JSON_PASTE15, \
2273  NLOHMANN_JSON_PASTE14, \
2274  NLOHMANN_JSON_PASTE13, \
2275  NLOHMANN_JSON_PASTE12, \
2276  NLOHMANN_JSON_PASTE11, \
2277  NLOHMANN_JSON_PASTE10, \
2278  NLOHMANN_JSON_PASTE9, \
2279  NLOHMANN_JSON_PASTE8, \
2280  NLOHMANN_JSON_PASTE7, \
2281  NLOHMANN_JSON_PASTE6, \
2282  NLOHMANN_JSON_PASTE5, \
2283  NLOHMANN_JSON_PASTE4, \
2284  NLOHMANN_JSON_PASTE3, \
2285  NLOHMANN_JSON_PASTE2, \
2286  NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2287 #define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2288 #define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2289 #define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2290 #define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2291 #define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2292 #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)
2293 #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)
2294 #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)
2295 #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)
2296 #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)
2297 #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)
2298 #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)
2299 #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)
2300 #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)
2301 #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)
2302 #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)
2303 #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)
2304 #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)
2305 #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)
2306 #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)
2307 #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)
2308 #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)
2309 #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)
2310 #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)
2311 #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)
2312 #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)
2313 #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)
2314 #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)
2315 #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)
2316 #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)
2317 #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)
2318 #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)
2319 #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)
2320 #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)
2321 #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)
2322 #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)
2323 #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)
2324 #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)
2325 #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)
2326 #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)
2327 #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)
2328 #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)
2329 #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)
2330 #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)
2331 #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)
2332 #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)
2333 #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)
2334 #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)
2335 #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)
2336 #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)
2337 #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)
2338 #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)
2339 #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)
2340 #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)
2341 #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)
2342 #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)
2343 #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)
2344 #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)
2345 #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)
2346 #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)
2347 #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)
2348 #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)
2349 #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)
2350 
2351 #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2352 #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2353 
2359 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2360  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__)) } \
2361  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__)) }
2362 
2368 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2369  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__)) } \
2370  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__)) }
2371 
2372 #ifndef JSON_USE_IMPLICIT_CONVERSIONS
2373  #define JSON_USE_IMPLICIT_CONVERSIONS 1
2374 #endif
2375 
2376 #if JSON_USE_IMPLICIT_CONVERSIONS
2377  #define JSON_EXPLICIT
2378 #else
2379  #define JSON_EXPLICIT explicit
2380 #endif
2381 
2382 
2383 namespace nlohmann
2384 {
2385 namespace detail
2386 {
2388 // exceptions //
2390 
2419 class exception : public std::exception
2420 {
2421  public:
2424  const char* what() const noexcept override
2425  {
2426  return m.what();
2427  }
2428 
2430  const int id;
2431 
2432  protected:
2434  exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
2435 
2436  static std::string name(const std::string& ename, int id_)
2437  {
2438  return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2439  }
2440 
2441  private:
2443  std::runtime_error m;
2444 };
2445 
2491 class parse_error : public exception
2492 {
2493  public:
2503  static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
2504  {
2505  std::string w = exception::name("parse_error", id_) + "parse error" +
2506  position_string(pos) + ": " + what_arg;
2507  return parse_error(id_, pos.chars_read_total, w.c_str());
2508  }
2509 
2510  static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
2511  {
2512  std::string w = exception::name("parse_error", id_) + "parse error" +
2513  (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2514  ": " + what_arg;
2515  return parse_error(id_, byte_, w.c_str());
2516  }
2517 
2527  const std::size_t byte;
2528 
2529  private:
2530  parse_error(int id_, std::size_t byte_, const char* what_arg)
2531  : exception(id_, what_arg), byte(byte_) {}
2532 
2533  static std::string position_string(const position_t& pos)
2534  {
2535  return " at line " + std::to_string(pos.lines_read + 1) +
2536  ", column " + std::to_string(pos.chars_read_current_line);
2537  }
2538 };
2539 
2578 {
2579  public:
2580  static invalid_iterator create(int id_, const std::string& what_arg)
2581  {
2582  std::string w = exception::name("invalid_iterator", id_) + what_arg;
2583  return invalid_iterator(id_, w.c_str());
2584  }
2585 
2586  private:
2588  invalid_iterator(int id_, const char* what_arg)
2589  : exception(id_, what_arg) {}
2590 };
2591 
2631 class type_error : public exception
2632 {
2633  public:
2634  static type_error create(int id_, const std::string& what_arg)
2635  {
2636  std::string w = exception::name("type_error", id_) + what_arg;
2637  return type_error(id_, w.c_str());
2638  }
2639 
2640  private:
2642  type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2643 };
2644 
2678 class out_of_range : public exception
2679 {
2680  public:
2681  static out_of_range create(int id_, const std::string& what_arg)
2682  {
2683  std::string w = exception::name("out_of_range", id_) + what_arg;
2684  return out_of_range(id_, w.c_str());
2685  }
2686 
2687  private:
2689  out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
2690 };
2691 
2716 class other_error : public exception
2717 {
2718  public:
2719  static other_error create(int id_, const std::string& what_arg)
2720  {
2721  std::string w = exception::name("other_error", id_) + what_arg;
2722  return other_error(id_, w.c_str());
2723  }
2724 
2725  private:
2727  other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2728 };
2729 } // namespace detail
2730 } // namespace nlohmann
2731 
2732 // #include <nlohmann/detail/macro_scope.hpp>
2733 
2734 // #include <nlohmann/detail/meta/cpp_future.hpp>
2735 
2736 
2737 #include <cstddef> // size_t
2738 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
2739 
2740 namespace nlohmann
2741 {
2742 namespace detail
2743 {
2744 // alias templates to reduce boilerplate
2745 template<bool B, typename T = void>
2746 using enable_if_t = typename std::enable_if<B, T>::type;
2747 
2748 template<typename T>
2749 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
2750 
2751 // implementation of C++14 index_sequence and affiliates
2752 // source: https://stackoverflow.com/a/32223343
2753 template<std::size_t... Ints>
2755 {
2757  using value_type = std::size_t;
2758  static constexpr std::size_t size() noexcept
2759  {
2760  return sizeof...(Ints);
2761  }
2762 };
2763 
2764 template<class Sequence1, class Sequence2>
2766 
2767 template<std::size_t... I1, std::size_t... I2>
2769  : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
2770 
2771 template<std::size_t N>
2773  : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
2774  typename make_index_sequence < N - N / 2 >::type > {};
2775 
2776 template<> struct make_index_sequence<0> : index_sequence<> {};
2777 template<> struct make_index_sequence<1> : index_sequence<0> {};
2778 
2779 template<typename... Ts>
2781 
2782 // dispatch utility (taken from ranges-v3)
2783 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
2784 template<> struct priority_tag<0> {};
2785 
2786 // taken from ranges-v3
2787 template<typename T>
2789 {
2790  static constexpr T value{};
2791 };
2792 
2793 template<typename T>
2794 constexpr T static_const<T>::value;
2795 } // namespace detail
2796 } // namespace nlohmann
2797 
2798 // #include <nlohmann/detail/meta/type_traits.hpp>
2799 
2800 
2801 #include <limits> // numeric_limits
2802 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
2803 #include <utility> // declval
2804 
2805 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
2806 
2807 
2808 #include <iterator> // random_access_iterator_tag
2809 
2810 // #include <nlohmann/detail/meta/void_t.hpp>
2811 
2812 
2813 namespace nlohmann
2814 {
2815 namespace detail
2816 {
2817 template<typename ...Ts> struct make_void
2818 {
2819  using type = void;
2820 };
2821 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
2822 } // namespace detail
2823 } // namespace nlohmann
2824 
2825 // #include <nlohmann/detail/meta/cpp_future.hpp>
2826 
2827 
2828 namespace nlohmann
2829 {
2830 namespace detail
2831 {
2832 template<typename It, typename = void>
2833 struct iterator_types {};
2834 
2835 template<typename It>
2837  It,
2838  void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
2839  typename It::reference, typename It::iterator_category >>
2840 {
2841  using difference_type = typename It::difference_type;
2842  using value_type = typename It::value_type;
2843  using pointer = typename It::pointer;
2844  using reference = typename It::reference;
2845  using iterator_category = typename It::iterator_category;
2846 };
2847 
2848 // This is required as some compilers implement std::iterator_traits in a way that
2849 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
2850 template<typename T, typename = void>
2852 {
2853 };
2854 
2855 template<typename T>
2856 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
2857  : iterator_types<T>
2858 {
2859 };
2860 
2861 template<typename T>
2863 {
2864  using iterator_category = std::random_access_iterator_tag;
2865  using value_type = T;
2866  using difference_type = ptrdiff_t;
2867  using pointer = T*;
2868  using reference = T&;
2869 };
2870 } // namespace detail
2871 } // namespace nlohmann
2872 
2873 // #include <nlohmann/detail/macro_scope.hpp>
2874 
2875 // #include <nlohmann/detail/meta/cpp_future.hpp>
2876 
2877 // #include <nlohmann/detail/meta/detected.hpp>
2878 
2879 
2880 #include <type_traits>
2881 
2882 // #include <nlohmann/detail/meta/void_t.hpp>
2883 
2884 
2885 // https://en.cppreference.com/w/cpp/experimental/is_detected
2886 namespace nlohmann
2887 {
2888 namespace detail
2889 {
2890 struct nonesuch
2891 {
2892  nonesuch() = delete;
2893  ~nonesuch() = delete;
2894  nonesuch(nonesuch const&) = delete;
2895  nonesuch(nonesuch const&&) = delete;
2896  void operator=(nonesuch const&) = delete;
2897  void operator=(nonesuch&&) = delete;
2898 };
2899 
2900 template<class Default,
2901  class AlwaysVoid,
2902  template<class...> class Op,
2903  class... Args>
2904 struct detector
2905 {
2906  using value_t = std::false_type;
2907  using type = Default;
2908 };
2909 
2910 template<class Default, template<class...> class Op, class... Args>
2911 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2912 {
2913  using value_t = std::true_type;
2914  using type = Op<Args...>;
2915 };
2916 
2917 template<template<class...> class Op, class... Args>
2918 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2919 
2920 template<template<class...> class Op, class... Args>
2921 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2922 
2923 template<class Default, template<class...> class Op, class... Args>
2924 using detected_or = detector<Default, void, Op, Args...>;
2925 
2926 template<class Default, template<class...> class Op, class... Args>
2927 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2928 
2929 template<class Expected, template<class...> class Op, class... Args>
2930 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2931 
2932 template<class To, template<class...> class Op, class... Args>
2934  std::is_convertible<detected_t<Op, Args...>, To>;
2935 } // namespace detail
2936 } // namespace nlohmann
2937 
2938 // #include <nlohmann/json_fwd.hpp>
2939 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
2940 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
2941 
2942 #include <cstdint> // int64_t, uint64_t
2943 #include <map> // map
2944 #include <memory> // allocator
2945 #include <string> // string
2946 #include <vector> // vector
2947 
2953 namespace nlohmann
2954 {
2962 template<typename T = void, typename SFINAE = void>
2963 struct adl_serializer;
2964 
2965 template<template<typename U, typename V, typename... Args> class ObjectType =
2966  std::map,
2967  template<typename U, typename... Args> class ArrayType = std::vector,
2968  class StringType = std::string, class BooleanType = bool,
2969  class NumberIntegerType = std::int64_t,
2970  class NumberUnsignedType = std::uint64_t,
2971  class NumberFloatType = double,
2972  template<typename U> class AllocatorType = std::allocator,
2973  template<typename T, typename SFINAE = void> class JSONSerializer =
2974  adl_serializer,
2975  class BinaryType = std::vector<std::uint8_t>>
2976 class basic_json;
2977 
2989 template<typename BasicJsonType>
2990 class json_pointer;
2991 
3001 
3002 template<class Key, class T, class IgnoredLess, class Allocator>
3003 struct ordered_map;
3004 
3013 
3014 } // namespace nlohmann
3015 
3016 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3017 
3018 
3019 namespace nlohmann
3020 {
3029 namespace detail
3030 {
3032 // helpers //
3034 
3035 // Note to maintainers:
3036 //
3037 // Every trait in this file expects a non CV-qualified type.
3038 // The only exceptions are in the 'aliases for detected' section
3039 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3040 //
3041 // In this case, T has to be properly CV-qualified to constraint the function arguments
3042 // (e.g. to_json(BasicJsonType&, const T&))
3043 
3044 template<typename> struct is_basic_json : std::false_type {};
3045 
3047 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3048 
3050 // json_ref helpers //
3052 
3053 template<typename>
3054 class json_ref;
3055 
3056 template<typename>
3057 struct is_json_ref : std::false_type {};
3058 
3059 template<typename T>
3060 struct is_json_ref<json_ref<T>> : std::true_type {};
3061 
3063 // aliases for detected //
3065 
3066 template<typename T>
3067 using mapped_type_t = typename T::mapped_type;
3068 
3069 template<typename T>
3070 using key_type_t = typename T::key_type;
3071 
3072 template<typename T>
3073 using value_type_t = typename T::value_type;
3074 
3075 template<typename T>
3076 using difference_type_t = typename T::difference_type;
3077 
3078 template<typename T>
3079 using pointer_t = typename T::pointer;
3080 
3081 template<typename T>
3082 using reference_t = typename T::reference;
3083 
3084 template<typename T>
3085 using iterator_category_t = typename T::iterator_category;
3086 
3087 template<typename T>
3088 using iterator_t = typename T::iterator;
3089 
3090 template<typename T, typename... Args>
3091 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3092 
3093 template<typename T, typename... Args>
3094 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3095 
3096 template<typename T, typename U>
3097 using get_template_function = decltype(std::declval<T>().template get<U>());
3098 
3099 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3100 template<typename BasicJsonType, typename T, typename = void>
3101 struct has_from_json : std::false_type {};
3102 
3103 // trait checking if j.get<T> is valid
3104 // use this trait instead of std::is_constructible or std::is_convertible,
3105 // both rely on, or make use of implicit conversions, and thus fail when T
3106 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3107 template <typename BasicJsonType, typename T>
3109 {
3111 };
3112 
3113 template<typename BasicJsonType, typename T>
3114 struct has_from_json < BasicJsonType, T,
3115  enable_if_t < !is_basic_json<T>::value >>
3116 {
3117  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3118 
3119  static constexpr bool value =
3121  const BasicJsonType&, T&>::value;
3122 };
3123 
3124 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3125 // this overload is used for non-default-constructible user-defined-types
3126 template<typename BasicJsonType, typename T, typename = void>
3127 struct has_non_default_from_json : std::false_type {};
3128 
3129 template<typename BasicJsonType, typename T>
3130 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3131 {
3132  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3133 
3134  static constexpr bool value =
3136  const BasicJsonType&>::value;
3137 };
3138 
3139 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3140 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3141 template<typename BasicJsonType, typename T, typename = void>
3142 struct has_to_json : std::false_type {};
3143 
3144 template<typename BasicJsonType, typename T>
3145 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3146 {
3147  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3148 
3149  static constexpr bool value =
3150  is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3151  T>::value;
3152 };
3153 
3154 
3156 // is_ functions //
3158 
3159 template<typename T, typename = void>
3160 struct is_iterator_traits : std::false_type {};
3161 
3162 template<typename T>
3164 {
3165  private:
3167 
3168  public:
3169  static constexpr auto value =
3175 };
3176 
3177 // source: https://stackoverflow.com/a/37193089/4116453
3178 
3179 template<typename T, typename = void>
3180 struct is_complete_type : std::false_type {};
3181 
3182 template<typename T>
3183 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3184 
3185 template<typename BasicJsonType, typename CompatibleObjectType,
3186  typename = void>
3187 struct is_compatible_object_type_impl : std::false_type {};
3188 
3189 template<typename BasicJsonType, typename CompatibleObjectType>
3191  BasicJsonType, CompatibleObjectType,
3192  enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3193  is_detected<key_type_t, CompatibleObjectType>::value >>
3194 {
3195 
3196  using object_t = typename BasicJsonType::object_t;
3197 
3198  // macOS's is_constructible does not play well with nonesuch...
3199  static constexpr bool value =
3200  std::is_constructible<typename object_t::key_type,
3201  typename CompatibleObjectType::key_type>::value &&
3202  std::is_constructible<typename object_t::mapped_type,
3203  typename CompatibleObjectType::mapped_type>::value;
3204 };
3205 
3206 template<typename BasicJsonType, typename CompatibleObjectType>
3208  : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3209 
3210 template<typename BasicJsonType, typename ConstructibleObjectType,
3211  typename = void>
3212 struct is_constructible_object_type_impl : std::false_type {};
3213 
3214 template<typename BasicJsonType, typename ConstructibleObjectType>
3216  BasicJsonType, ConstructibleObjectType,
3217  enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3218  is_detected<key_type_t, ConstructibleObjectType>::value >>
3219 {
3220  using object_t = typename BasicJsonType::object_t;
3221 
3222  static constexpr bool value =
3223  (std::is_default_constructible<ConstructibleObjectType>::value &&
3224  (std::is_move_assignable<ConstructibleObjectType>::value ||
3225  std::is_copy_assignable<ConstructibleObjectType>::value) &&
3226  (std::is_constructible<typename ConstructibleObjectType::key_type,
3227  typename object_t::key_type>::value &&
3228  std::is_same <
3229  typename object_t::mapped_type,
3230  typename ConstructibleObjectType::mapped_type >::value)) ||
3231  (has_from_json<BasicJsonType,
3232  typename ConstructibleObjectType::mapped_type>::value ||
3234  BasicJsonType,
3235  typename ConstructibleObjectType::mapped_type >::value);
3236 };
3237 
3238 template<typename BasicJsonType, typename ConstructibleObjectType>
3240  : is_constructible_object_type_impl<BasicJsonType,
3241  ConstructibleObjectType> {};
3242 
3243 template<typename BasicJsonType, typename CompatibleStringType,
3244  typename = void>
3245 struct is_compatible_string_type_impl : std::false_type {};
3246 
3247 template<typename BasicJsonType, typename CompatibleStringType>
3249  BasicJsonType, CompatibleStringType,
3250  enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3251  value_type_t, CompatibleStringType>::value >>
3252 {
3253  static constexpr auto value =
3254  std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
3255 };
3256 
3257 template<typename BasicJsonType, typename ConstructibleStringType>
3259  : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3260 
3261 template<typename BasicJsonType, typename ConstructibleStringType,
3262  typename = void>
3263 struct is_constructible_string_type_impl : std::false_type {};
3264 
3265 template<typename BasicJsonType, typename ConstructibleStringType>
3267  BasicJsonType, ConstructibleStringType,
3268  enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3269  value_type_t, ConstructibleStringType>::value >>
3270 {
3271  static constexpr auto value =
3272  std::is_constructible<ConstructibleStringType,
3273  typename BasicJsonType::string_t>::value;
3274 };
3275 
3276 template<typename BasicJsonType, typename ConstructibleStringType>
3278  : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3279 
3280 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3281 struct is_compatible_array_type_impl : std::false_type {};
3282 
3283 template<typename BasicJsonType, typename CompatibleArrayType>
3285  BasicJsonType, CompatibleArrayType,
3286  enable_if_t < is_detected<value_type_t, CompatibleArrayType>::value&&
3287  is_detected<iterator_t, CompatibleArrayType>::value&&
3288 // This is needed because json_reverse_iterator has a ::iterator type...
3289 // Therefore it is detected as a CompatibleArrayType.
3290 // The real fix would be to have an Iterable concept.
3292  iterator_traits<CompatibleArrayType >>::value >>
3293 {
3294  static constexpr bool value =
3295  std::is_constructible<BasicJsonType,
3296  typename CompatibleArrayType::value_type>::value;
3297 };
3298 
3299 template<typename BasicJsonType, typename CompatibleArrayType>
3301  : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3302 
3303 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3304 struct is_constructible_array_type_impl : std::false_type {};
3305 
3306 template<typename BasicJsonType, typename ConstructibleArrayType>
3308  BasicJsonType, ConstructibleArrayType,
3309  enable_if_t<std::is_same<ConstructibleArrayType,
3310  typename BasicJsonType::value_type>::value >>
3311  : std::true_type {};
3312 
3313 template<typename BasicJsonType, typename ConstructibleArrayType>
3315  BasicJsonType, ConstructibleArrayType,
3316  enable_if_t < !std::is_same<ConstructibleArrayType,
3317  typename BasicJsonType::value_type>::value&&
3318  std::is_default_constructible<ConstructibleArrayType>::value&&
3319 (std::is_move_assignable<ConstructibleArrayType>::value ||
3320  std::is_copy_assignable<ConstructibleArrayType>::value)&&
3321 is_detected<value_type_t, ConstructibleArrayType>::value&&
3322 is_detected<iterator_t, ConstructibleArrayType>::value&&
3324 detected_t<value_type_t, ConstructibleArrayType >>::value >>
3325 {
3326  static constexpr bool value =
3327  // This is needed because json_reverse_iterator has a ::iterator type,
3328  // furthermore, std::back_insert_iterator (and other iterators) have a
3329  // base class `iterator`... Therefore it is detected as a
3330  // ConstructibleArrayType. The real fix would be to have an Iterable
3331  // concept.
3333 
3334  (std::is_same<typename ConstructibleArrayType::value_type,
3335  typename BasicJsonType::array_t::value_type>::value ||
3336  has_from_json<BasicJsonType,
3337  typename ConstructibleArrayType::value_type>::value ||
3339  BasicJsonType, typename ConstructibleArrayType::value_type >::value);
3340 };
3341 
3342 template<typename BasicJsonType, typename ConstructibleArrayType>
3344  : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3345 
3346 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3347  typename = void>
3348 struct is_compatible_integer_type_impl : std::false_type {};
3349 
3350 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3352  RealIntegerType, CompatibleNumberIntegerType,
3353  enable_if_t < std::is_integral<RealIntegerType>::value&&
3354  std::is_integral<CompatibleNumberIntegerType>::value&&
3355  !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3356 {
3357  // is there an assert somewhere on overflows?
3358  using RealLimits = std::numeric_limits<RealIntegerType>;
3359  using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3360 
3361  static constexpr auto value =
3362  std::is_constructible<RealIntegerType,
3363  CompatibleNumberIntegerType>::value &&
3364  CompatibleLimits::is_integer &&
3365  RealLimits::is_signed == CompatibleLimits::is_signed;
3366 };
3367 
3368 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3370  : is_compatible_integer_type_impl<RealIntegerType,
3371  CompatibleNumberIntegerType> {};
3372 
3373 template<typename BasicJsonType, typename CompatibleType, typename = void>
3374 struct is_compatible_type_impl: std::false_type {};
3375 
3376 template<typename BasicJsonType, typename CompatibleType>
3378  BasicJsonType, CompatibleType,
3379  enable_if_t<is_complete_type<CompatibleType>::value >>
3380 {
3381  static constexpr bool value =
3383 };
3384 
3385 template<typename BasicJsonType, typename CompatibleType>
3387  : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3388 
3389 // https://en.cppreference.com/w/cpp/types/conjunction
3390 template<class...> struct conjunction : std::true_type { };
3391 template<class B1> struct conjunction<B1> : B1 { };
3392 template<class B1, class... Bn>
3393 struct conjunction<B1, Bn...>
3394 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3395 
3396 template<typename T1, typename T2>
3397 struct is_constructible_tuple : std::false_type {};
3398 
3399 template<typename T1, typename... Args>
3400 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<std::is_constructible<T1, Args>...> {};
3401 } // namespace detail
3402 } // namespace nlohmann
3403 
3404 // #include <nlohmann/detail/value_t.hpp>
3405 
3406 
3407 #include <array> // array
3408 #include <cstddef> // size_t
3409 #include <cstdint> // uint8_t
3410 #include <string> // string
3411 
3412 namespace nlohmann
3413 {
3414 namespace detail
3415 {
3417 // JSON type enumeration //
3419 
3444 enum class value_t : std::uint8_t
3445 {
3446  null,
3447  object,
3448  array,
3449  string,
3450  boolean,
3451  number_integer,
3452  number_unsigned,
3453  number_float,
3454  binary,
3455  discarded
3456 };
3457 
3471 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
3472 {
3473  static constexpr std::array<std::uint8_t, 9> order = {{
3474  0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
3475  1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
3476  6 /* binary */
3477  }
3478  };
3479 
3480  const auto l_index = static_cast<std::size_t>(lhs);
3481  const auto r_index = static_cast<std::size_t>(rhs);
3482  return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
3483 }
3484 } // namespace detail
3485 } // namespace nlohmann
3486 
3487 
3488 namespace nlohmann
3489 {
3490 namespace detail
3491 {
3492 template<typename BasicJsonType>
3493 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3494 {
3495  if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
3496  {
3497  JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
3498  }
3499  n = nullptr;
3500 }
3501 
3502 // overloads for basic_json template parameters
3503 template < typename BasicJsonType, typename ArithmeticType,
3504  enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
3505  !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3506  int > = 0 >
3507 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3508 {
3509  switch (static_cast<value_t>(j))
3510  {
3512  {
3513  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3514  break;
3515  }
3517  {
3518  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3519  break;
3520  }
3521  case value_t::number_float:
3522  {
3523  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3524  break;
3525  }
3526 
3527  default:
3528  JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
3529  }
3530 }
3531 
3532 template<typename BasicJsonType>
3533 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
3534 {
3535  if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
3536  {
3537  JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
3538  }
3539  b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
3540 }
3541 
3542 template<typename BasicJsonType>
3543 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
3544 {
3545  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3546  {
3547  JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
3548  }
3549  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3550 }
3551 
3552 template <
3553  typename BasicJsonType, typename ConstructibleStringType,
3554  enable_if_t <
3555  is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&
3556  !std::is_same<typename BasicJsonType::string_t,
3557  ConstructibleStringType>::value,
3558  int > = 0 >
3559 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
3560 {
3561  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3562  {
3563  JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
3564  }
3565 
3566  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3567 }
3568 
3569 template<typename BasicJsonType>
3570 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
3571 {
3572  get_arithmetic_value(j, val);
3573 }
3574 
3575 template<typename BasicJsonType>
3576 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
3577 {
3578  get_arithmetic_value(j, val);
3579 }
3580 
3581 template<typename BasicJsonType>
3582 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
3583 {
3584  get_arithmetic_value(j, val);
3585 }
3586 
3587 template<typename BasicJsonType, typename EnumType,
3588  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
3589 void from_json(const BasicJsonType& j, EnumType& e)
3590 {
3591  typename std::underlying_type<EnumType>::type val;
3592  get_arithmetic_value(j, val);
3593  e = static_cast<EnumType>(val);
3594 }
3595 
3596 // forward_list doesn't have an insert method
3597 template<typename BasicJsonType, typename T, typename Allocator,
3598  enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
3599 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
3600 {
3601  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3602  {
3603  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3604  }
3605  l.clear();
3606  std::transform(j.rbegin(), j.rend(),
3607  std::front_inserter(l), [](const BasicJsonType & i)
3608  {
3609  return i.template get<T>();
3610  });
3611 }
3612 
3613 // valarray doesn't have an insert method
3614 template<typename BasicJsonType, typename T,
3615  enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
3616 void from_json(const BasicJsonType& j, std::valarray<T>& l)
3617 {
3618  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3619  {
3620  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3621  }
3622  l.resize(j.size());
3623  std::transform(j.begin(), j.end(), std::begin(l),
3624  [](const BasicJsonType & elem)
3625  {
3626  return elem.template get<T>();
3627  });
3628 }
3629 
3630 template<typename BasicJsonType, typename T, std::size_t N>
3631 auto from_json(const BasicJsonType& j, T (&arr)[N])
3632 -> decltype(j.template get<T>(), void())
3633 {
3634  for (std::size_t i = 0; i < N; ++i)
3635  {
3636  arr[i] = j.at(i).template get<T>();
3637  }
3638 }
3639 
3640 template<typename BasicJsonType>
3641 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
3642 {
3643  arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
3644 }
3645 
3646 template<typename BasicJsonType, typename T, std::size_t N>
3647 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
3648  priority_tag<2> /*unused*/)
3649 -> decltype(j.template get<T>(), void())
3650 {
3651  for (std::size_t i = 0; i < N; ++i)
3652  {
3653  arr[i] = j.at(i).template get<T>();
3654  }
3655 }
3656 
3657 template<typename BasicJsonType, typename ConstructibleArrayType>
3658 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
3659 -> decltype(
3660  arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
3661  j.template get<typename ConstructibleArrayType::value_type>(),
3662  void())
3663 {
3664  using std::end;
3665 
3666  ConstructibleArrayType ret;
3667  ret.reserve(j.size());
3668  std::transform(j.begin(), j.end(),
3669  std::inserter(ret, end(ret)), [](const BasicJsonType & i)
3670  {
3671  // get<BasicJsonType>() returns *this, this won't call a from_json
3672  // method when value_type is BasicJsonType
3673  return i.template get<typename ConstructibleArrayType::value_type>();
3674  });
3675  arr = std::move(ret);
3676 }
3677 
3678 template<typename BasicJsonType, typename ConstructibleArrayType>
3679 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
3680  priority_tag<0> /*unused*/)
3681 {
3682  using std::end;
3683 
3684  ConstructibleArrayType ret;
3685  std::transform(
3686  j.begin(), j.end(), std::inserter(ret, end(ret)),
3687  [](const BasicJsonType & i)
3688  {
3689  // get<BasicJsonType>() returns *this, this won't call a from_json
3690  // method when value_type is BasicJsonType
3691  return i.template get<typename ConstructibleArrayType::value_type>();
3692  });
3693  arr = std::move(ret);
3694 }
3695 
3696 template < typename BasicJsonType, typename ConstructibleArrayType,
3697  enable_if_t <
3698  is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
3699  !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
3700  !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3701  !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
3702  !is_basic_json<ConstructibleArrayType>::value,
3703  int > = 0 >
3704 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
3705 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
3706 j.template get<typename ConstructibleArrayType::value_type>(),
3707 void())
3708 {
3709  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3710  {
3711  JSON_THROW(type_error::create(302, "type must be array, but is " +
3712  std::string(j.type_name())));
3713  }
3714 
3715  from_json_array_impl(j, arr, priority_tag<3> {});
3716 }
3717 
3718 template<typename BasicJsonType>
3719 void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
3720 {
3721  if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
3722  {
3723  JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name())));
3724  }
3725 
3726  bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
3727 }
3728 
3729 template<typename BasicJsonType, typename ConstructibleObjectType,
3730  enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
3731 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
3732 {
3733  if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
3734  {
3735  JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
3736  }
3737 
3738  ConstructibleObjectType ret;
3739  auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
3740  using value_type = typename ConstructibleObjectType::value_type;
3741  std::transform(
3742  inner_object->begin(), inner_object->end(),
3743  std::inserter(ret, ret.begin()),
3744  [](typename BasicJsonType::object_t::value_type const & p)
3745  {
3746  return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
3747  });
3748  obj = std::move(ret);
3749 }
3750 
3751 // overload for arithmetic types, not chosen for basic_json template arguments
3752 // (BooleanType, etc..); note: Is it really necessary to provide explicit
3753 // overloads for boolean_t etc. in case of a custom BooleanType which is not
3754 // an arithmetic type?
3755 template < typename BasicJsonType, typename ArithmeticType,
3756  enable_if_t <
3757  std::is_arithmetic<ArithmeticType>::value&&
3758  !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
3759  !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
3760  !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
3761  !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3762  int > = 0 >
3763 void from_json(const BasicJsonType& j, ArithmeticType& val)
3764 {
3765  switch (static_cast<value_t>(j))
3766  {
3768  {
3769  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3770  break;
3771  }
3773  {
3774  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3775  break;
3776  }
3777  case value_t::number_float:
3778  {
3779  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3780  break;
3781  }
3782  case value_t::boolean:
3783  {
3784  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
3785  break;
3786  }
3787 
3788  default:
3789  JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
3790  }
3791 }
3792 
3793 template<typename BasicJsonType, typename A1, typename A2>
3794 void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
3795 {
3796  p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
3797 }
3798 
3799 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
3800 void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
3801 {
3802  t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
3803 }
3804 
3805 template<typename BasicJsonType, typename... Args>
3806 void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
3807 {
3809 }
3810 
3811 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
3812  typename = enable_if_t < !std::is_constructible <
3813  typename BasicJsonType::string_t, Key >::value >>
3814 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
3815 {
3816  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3817  {
3818  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3819  }
3820  m.clear();
3821  for (const auto& p : j)
3822  {
3823  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
3824  {
3825  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3826  }
3827  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3828  }
3829 }
3830 
3831 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
3832  typename = enable_if_t < !std::is_constructible <
3833  typename BasicJsonType::string_t, Key >::value >>
3834 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
3835 {
3836  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3837  {
3838  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3839  }
3840  m.clear();
3841  for (const auto& p : j)
3842  {
3843  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
3844  {
3845  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3846  }
3847  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3848  }
3849 }
3850 
3852 {
3853  template<typename BasicJsonType, typename T>
3854  auto operator()(const BasicJsonType& j, T& val) const
3855  noexcept(noexcept(from_json(j, val)))
3856  -> decltype(from_json(j, val), void())
3857  {
3858  return from_json(j, val);
3859  }
3860 };
3861 } // namespace detail
3862 
3866 namespace
3867 {
3869 } // namespace
3870 } // namespace nlohmann
3871 
3872 // #include <nlohmann/detail/conversions/to_json.hpp>
3873 
3874 
3875 #include <algorithm> // copy
3876 #include <iterator> // begin, end
3877 #include <string> // string
3878 #include <tuple> // tuple, get
3879 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
3880 #include <utility> // move, forward, declval, pair
3881 #include <valarray> // valarray
3882 #include <vector> // vector
3883 
3884 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
3885 
3886 
3887 #include <cstddef> // size_t
3888 #include <iterator> // input_iterator_tag
3889 #include <string> // string, to_string
3890 #include <tuple> // tuple_size, get, tuple_element
3891 
3892 // #include <nlohmann/detail/meta/type_traits.hpp>
3893 
3894 // #include <nlohmann/detail/value_t.hpp>
3895 
3896 
3897 namespace nlohmann
3898 {
3899 namespace detail
3900 {
3901 template<typename string_type>
3902 void int_to_string( string_type& target, std::size_t value )
3903 {
3904  // For ADL
3905  using std::to_string;
3906  target = to_string(value);
3907 }
3908 template<typename IteratorType> class iteration_proxy_value
3909 {
3910  public:
3911  using difference_type = std::ptrdiff_t;
3913  using pointer = value_type * ;
3914  using reference = value_type & ;
3915  using iterator_category = std::input_iterator_tag;
3916  using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
3917 
3918  private:
3920  IteratorType anchor;
3922  std::size_t array_index = 0;
3924  mutable std::size_t array_index_last = 0;
3929 
3930  public:
3931  explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
3932 
3935  {
3936  return *this;
3937  }
3938 
3941  {
3942  ++anchor;
3943  ++array_index;
3944 
3945  return *this;
3946  }
3947 
3949  bool operator==(const iteration_proxy_value& o) const
3950  {
3951  return anchor == o.anchor;
3952  }
3953 
3955  bool operator!=(const iteration_proxy_value& o) const
3956  {
3957  return anchor != o.anchor;
3958  }
3959 
3961  const string_type& key() const
3962  {
3963  JSON_ASSERT(anchor.m_object != nullptr);
3964 
3965  switch (anchor.m_object->type())
3966  {
3967  // use integer array index as key
3968  case value_t::array:
3969  {
3971  {
3974  }
3975  return array_index_str;
3976  }
3977 
3978  // use key from the object
3979  case value_t::object:
3980  return anchor.key();
3981 
3982  // use an empty key for all primitive types
3983  default:
3984  return empty_str;
3985  }
3986  }
3987 
3990  {
3991  return anchor.value();
3992  }
3993 };
3994 
3996 template<typename IteratorType> class iteration_proxy
3997 {
3998  private:
4001 
4002  public:
4004  explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4005  : container(cont) {}
4006 
4009  {
4011  }
4012 
4015  {
4017  }
4018 };
4019 // Structured Bindings Support
4020 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4021 // And see https://github.com/nlohmann/json/pull/1391
4022 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
4024 {
4025  return i.key();
4026 }
4027 // Structured Bindings Support
4028 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4029 // And see https://github.com/nlohmann/json/pull/1391
4030 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
4031 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
4032 {
4033  return i.value();
4034 }
4035 } // namespace detail
4036 } // namespace nlohmann
4037 
4038 // The Addition to the STD Namespace is required to add
4039 // Structured Bindings Support to the iteration_proxy_value class
4040 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4041 // And see https://github.com/nlohmann/json/pull/1391
4042 namespace std
4043 {
4044 #if defined(__clang__)
4045  // Fix: https://github.com/nlohmann/json/issues/1401
4046  #pragma clang diagnostic push
4047  #pragma clang diagnostic ignored "-Wmismatched-tags"
4048 #endif
4049 template<typename IteratorType>
4050 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4051  : public std::integral_constant<std::size_t, 2> {};
4052 
4053 template<std::size_t N, typename IteratorType>
4054 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4055 {
4056  public:
4057  using type = decltype(
4058  get<N>(std::declval <
4060 };
4061 #if defined(__clang__)
4062  #pragma clang diagnostic pop
4063 #endif
4064 } // namespace std
4065 
4066 // #include <nlohmann/detail/meta/cpp_future.hpp>
4067 
4068 // #include <nlohmann/detail/meta/type_traits.hpp>
4069 
4070 // #include <nlohmann/detail/value_t.hpp>
4071 
4072 
4073 namespace nlohmann
4074 {
4075 namespace detail
4076 {
4078 // constructors //
4080 
4081 template<value_t> struct external_constructor;
4082 
4083 template<>
4085 {
4086  template<typename BasicJsonType>
4087  static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4088  {
4089  j.m_type = value_t::boolean;
4090  j.m_value = b;
4091  j.assert_invariant();
4092  }
4093 };
4094 
4095 template<>
4097 {
4098  template<typename BasicJsonType>
4099  static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4100  {
4101  j.m_type = value_t::string;
4102  j.m_value = s;
4103  j.assert_invariant();
4104  }
4105 
4106  template<typename BasicJsonType>
4107  static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4108  {
4109  j.m_type = value_t::string;
4110  j.m_value = std::move(s);
4111  j.assert_invariant();
4112  }
4113 
4114  template < typename BasicJsonType, typename CompatibleStringType,
4116  int > = 0 >
4117  static void construct(BasicJsonType& j, const CompatibleStringType& str)
4118  {
4119  j.m_type = value_t::string;
4120  j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4121  j.assert_invariant();
4122  }
4123 };
4124 
4125 template<>
4127 {
4128  template<typename BasicJsonType>
4129  static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4130  {
4131  j.m_type = value_t::binary;
4132  typename BasicJsonType::binary_t value{b};
4133  j.m_value = value;
4134  j.assert_invariant();
4135  }
4136 
4137  template<typename BasicJsonType>
4138  static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4139  {
4140  j.m_type = value_t::binary;
4141  typename BasicJsonType::binary_t value{std::move(b)};
4142  j.m_value = value;
4143  j.assert_invariant();
4144  }
4145 };
4146 
4147 template<>
4149 {
4150  template<typename BasicJsonType>
4151  static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4152  {
4153  j.m_type = value_t::number_float;
4154  j.m_value = val;
4155  j.assert_invariant();
4156  }
4157 };
4158 
4159 template<>
4161 {
4162  template<typename BasicJsonType>
4163  static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4164  {
4165  j.m_type = value_t::number_unsigned;
4166  j.m_value = val;
4167  j.assert_invariant();
4168  }
4169 };
4170 
4171 template<>
4173 {
4174  template<typename BasicJsonType>
4175  static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4176  {
4177  j.m_type = value_t::number_integer;
4178  j.m_value = val;
4179  j.assert_invariant();
4180  }
4181 };
4182 
4183 template<>
4185 {
4186  template<typename BasicJsonType>
4187  static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4188  {
4189  j.m_type = value_t::array;
4190  j.m_value = arr;
4191  j.assert_invariant();
4192  }
4193 
4194  template<typename BasicJsonType>
4195  static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4196  {
4197  j.m_type = value_t::array;
4198  j.m_value = std::move(arr);
4199  j.assert_invariant();
4200  }
4201 
4202  template < typename BasicJsonType, typename CompatibleArrayType,
4204  int > = 0 >
4205  static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4206  {
4207  using std::begin;
4208  using std::end;
4209  j.m_type = value_t::array;
4210  j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4211  j.assert_invariant();
4212  }
4213 
4214  template<typename BasicJsonType>
4215  static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4216  {
4217  j.m_type = value_t::array;
4218  j.m_value = value_t::array;
4219  j.m_value.array->reserve(arr.size());
4220  for (const bool x : arr)
4221  {
4222  j.m_value.array->push_back(x);
4223  }
4224  j.assert_invariant();
4225  }
4226 
4227  template<typename BasicJsonType, typename T,
4229  static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4230  {
4231  j.m_type = value_t::array;
4232  j.m_value = value_t::array;
4233  j.m_value.array->resize(arr.size());
4234  if (arr.size() > 0)
4235  {
4236  std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4237  }
4238  j.assert_invariant();
4239  }
4240 };
4241 
4242 template<>
4244 {
4245  template<typename BasicJsonType>
4246  static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
4247  {
4248  j.m_type = value_t::object;
4249  j.m_value = obj;
4250  j.assert_invariant();
4251  }
4252 
4253  template<typename BasicJsonType>
4254  static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4255  {
4256  j.m_type = value_t::object;
4257  j.m_value = std::move(obj);
4258  j.assert_invariant();
4259  }
4260 
4261  template < typename BasicJsonType, typename CompatibleObjectType,
4263  static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4264  {
4265  using std::begin;
4266  using std::end;
4267 
4268  j.m_type = value_t::object;
4269  j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4270  j.assert_invariant();
4271  }
4272 };
4273 
4275 // to_json //
4277 
4278 template<typename BasicJsonType, typename T,
4279  enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
4280 void to_json(BasicJsonType& j, T b) noexcept
4281 {
4283 }
4284 
4285 template<typename BasicJsonType, typename CompatibleString,
4286  enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
4287 void to_json(BasicJsonType& j, const CompatibleString& s)
4288 {
4290 }
4291 
4292 template<typename BasicJsonType>
4293 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4294 {
4296 }
4297 
4298 template<typename BasicJsonType, typename FloatType,
4299  enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
4300 void to_json(BasicJsonType& j, FloatType val) noexcept
4301 {
4302  external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4303 }
4304 
4305 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4306  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
4307 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4308 {
4309  external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4310 }
4311 
4312 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4313  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
4314 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4315 {
4316  external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4317 }
4318 
4319 template<typename BasicJsonType, typename EnumType,
4320  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4321 void to_json(BasicJsonType& j, EnumType e) noexcept
4322 {
4323  using underlying_type = typename std::underlying_type<EnumType>::type;
4324  external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4325 }
4326 
4327 template<typename BasicJsonType>
4328 void to_json(BasicJsonType& j, const std::vector<bool>& e)
4329 {
4331 }
4332 
4333 template < typename BasicJsonType, typename CompatibleArrayType,
4334  enable_if_t < is_compatible_array_type<BasicJsonType,
4335  CompatibleArrayType>::value&&
4336  !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
4337  !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
4338  !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
4339  !is_basic_json<CompatibleArrayType>::value,
4340  int > = 0 >
4341 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4342 {
4344 }
4345 
4346 template<typename BasicJsonType>
4347 void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4348 {
4350 }
4351 
4352 template<typename BasicJsonType, typename T,
4353  enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4354 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4355 {
4357 }
4358 
4359 template<typename BasicJsonType>
4360 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4361 {
4363 }
4364 
4365 template < typename BasicJsonType, typename CompatibleObjectType,
4366  enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
4367 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4368 {
4370 }
4371 
4372 template<typename BasicJsonType>
4373 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4374 {
4376 }
4377 
4378 template <
4379  typename BasicJsonType, typename T, std::size_t N,
4380  enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4381  const T(&)[N]>::value,
4382  int > = 0 >
4383 void to_json(BasicJsonType& j, const T(&arr)[N])
4384 {
4386 }
4387 
4388 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
4389 void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4390 {
4391  j = { p.first, p.second };
4392 }
4393 
4394 // for https://github.com/nlohmann/json/pull/1134
4395 template<typename BasicJsonType, typename T,
4396  enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
4397 void to_json(BasicJsonType& j, const T& b)
4398 {
4399  j = { {b.key(), b.value()} };
4400 }
4401 
4402 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
4403 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4404 {
4405  j = { std::get<Idx>(t)... };
4406 }
4407 
4408 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
4409 void to_json(BasicJsonType& j, const T& t)
4410 {
4411  to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
4412 }
4413 
4415 {
4416  template<typename BasicJsonType, typename T>
4417  auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
4418  -> decltype(to_json(j, std::forward<T>(val)), void())
4419  {
4420  return to_json(j, std::forward<T>(val));
4421  }
4422 };
4423 } // namespace detail
4424 
4426 namespace
4427 {
4429 } // namespace
4430 } // namespace nlohmann
4431 
4432 
4433 namespace nlohmann
4434 {
4435 
4436 template<typename, typename>
4438 {
4448  template<typename BasicJsonType, typename ValueType>
4449  static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
4450  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
4451  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
4452  {
4453  ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
4454  }
4455 
4465  template<typename BasicJsonType, typename ValueType>
4466  static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
4467  noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
4468  -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void())
4469  {
4470  ::nlohmann::to_json(j, std::forward<ValueType>(val));
4471  }
4472 };
4473 
4474 } // namespace nlohmann
4475 
4476 // #include <nlohmann/byte_container_with_subtype.hpp>
4477 
4478 
4479 #include <cstdint> // uint8_t
4480 #include <tuple> // tie
4481 #include <utility> // move
4482 
4483 namespace nlohmann
4484 {
4485 
4499 template<typename BinaryType>
4501 {
4502  public:
4505 
4507  : container_type()
4508  {}
4509 
4511  : container_type(b)
4512  {}
4513 
4514  byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
4515  : container_type(std::move(b))
4516  {}
4517 
4518  byte_container_with_subtype(const container_type& b, std::uint8_t subtype) noexcept(noexcept(container_type(b)))
4519  : container_type(b)
4520  , m_subtype(subtype)
4521  , m_has_subtype(true)
4522  {}
4523 
4524  byte_container_with_subtype(container_type&& b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b))))
4525  : container_type(std::move(b))
4526  , m_subtype(subtype)
4527  , m_has_subtype(true)
4528  {}
4529 
4531  {
4532  return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
4533  std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
4534  }
4535 
4537  {
4538  return !(rhs == *this);
4539  }
4540 
4559  void set_subtype(std::uint8_t subtype) noexcept
4560  {
4561  m_subtype = subtype;
4562  m_has_subtype = true;
4563  }
4564 
4586  constexpr std::uint8_t subtype() const noexcept
4587  {
4588  return m_subtype;
4589  }
4590 
4607  constexpr bool has_subtype() const noexcept
4608  {
4609  return m_has_subtype;
4610  }
4611 
4631  void clear_subtype() noexcept
4632  {
4633  m_subtype = 0;
4634  m_has_subtype = false;
4635  }
4636 
4637  private:
4638  std::uint8_t m_subtype = 0;
4639  bool m_has_subtype = false;
4640 };
4641 
4642 } // namespace nlohmann
4643 
4644 // #include <nlohmann/detail/conversions/from_json.hpp>
4645 
4646 // #include <nlohmann/detail/conversions/to_json.hpp>
4647 
4648 // #include <nlohmann/detail/exceptions.hpp>
4649 
4650 // #include <nlohmann/detail/hash.hpp>
4651 
4652 
4653 #include <cstddef> // size_t, uint8_t
4654 #include <functional> // hash
4655 
4656 namespace nlohmann
4657 {
4658 namespace detail
4659 {
4660 
4661 // boost::hash_combine
4662 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
4663 {
4664  seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
4665  return seed;
4666 }
4667 
4679 template<typename BasicJsonType>
4680 std::size_t hash(const BasicJsonType& j)
4681 {
4682  using string_t = typename BasicJsonType::string_t;
4683  using number_integer_t = typename BasicJsonType::number_integer_t;
4684  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4685  using number_float_t = typename BasicJsonType::number_float_t;
4686 
4687  const auto type = static_cast<std::size_t>(j.type());
4688  switch (j.type())
4689  {
4690  case BasicJsonType::value_t::null:
4691  case BasicJsonType::value_t::discarded:
4692  {
4693  return combine(type, 0);
4694  }
4695 
4696  case BasicJsonType::value_t::object:
4697  {
4698  auto seed = combine(type, j.size());
4699  for (const auto& element : j.items())
4700  {
4701  const auto h = std::hash<string_t> {}(element.key());
4702  seed = combine(seed, h);
4703  seed = combine(seed, hash(element.value()));
4704  }
4705  return seed;
4706  }
4707 
4708  case BasicJsonType::value_t::array:
4709  {
4710  auto seed = combine(type, j.size());
4711  for (const auto& element : j)
4712  {
4713  seed = combine(seed, hash(element));
4714  }
4715  return seed;
4716  }
4717 
4718  case BasicJsonType::value_t::string:
4719  {
4720  const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
4721  return combine(type, h);
4722  }
4723 
4724  case BasicJsonType::value_t::boolean:
4725  {
4726  const auto h = std::hash<bool> {}(j.template get<bool>());
4727  return combine(type, h);
4728  }
4729 
4730  case BasicJsonType::value_t::number_integer:
4731  {
4732  const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
4733  return combine(type, h);
4734  }
4735 
4736  case BasicJsonType::value_t::number_unsigned:
4737  {
4738  const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
4739  return combine(type, h);
4740  }
4741 
4742  case BasicJsonType::value_t::number_float:
4743  {
4744  const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
4745  return combine(type, h);
4746  }
4747 
4748  case BasicJsonType::value_t::binary:
4749  {
4750  auto seed = combine(type, j.get_binary().size());
4751  const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
4752  seed = combine(seed, h);
4753  seed = combine(seed, j.get_binary().subtype());
4754  for (const auto byte : j.get_binary())
4755  {
4756  seed = combine(seed, std::hash<std::uint8_t> {}(byte));
4757  }
4758  return seed;
4759  }
4760 
4761  default: // LCOV_EXCL_LINE
4762  JSON_ASSERT(false); // LCOV_EXCL_LINE
4763  return 0; // LCOV_EXCL_LINE
4764  }
4765 }
4766 
4767 } // namespace detail
4768 } // namespace nlohmann
4769 
4770 // #include <nlohmann/detail/input/binary_reader.hpp>
4771 
4772 
4773 #include <algorithm> // generate_n
4774 #include <array> // array
4775 #include <cmath> // ldexp
4776 #include <cstddef> // size_t
4777 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
4778 #include <cstdio> // snprintf
4779 #include <cstring> // memcpy
4780 #include <iterator> // back_inserter
4781 #include <limits> // numeric_limits
4782 #include <string> // char_traits, string
4783 #include <utility> // make_pair, move
4784 
4785 // #include <nlohmann/detail/exceptions.hpp>
4786 
4787 // #include <nlohmann/detail/input/input_adapters.hpp>
4788 
4789 
4790 #include <array> // array
4791 #include <cstddef> // size_t
4792 #include <cstdio> //FILE *
4793 #include <cstring> // strlen
4794 #include <istream> // istream
4795 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
4796 #include <memory> // shared_ptr, make_shared, addressof
4797 #include <numeric> // accumulate
4798 #include <string> // string, char_traits
4799 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
4800 #include <utility> // pair, declval
4801 
4802 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
4803 
4804 // #include <nlohmann/detail/macro_scope.hpp>
4805 
4806 
4807 namespace nlohmann
4808 {
4809 namespace detail
4810 {
4813 
4815 // input adapters //
4817 
4823 {
4824  public:
4825  using char_type = char;
4826 
4828  explicit file_input_adapter(std::FILE* f) noexcept
4829  : m_file(f)
4830  {}
4831 
4832  // make class move-only
4837 
4838  std::char_traits<char>::int_type get_character() noexcept
4839  {
4840  return std::fgetc(m_file);
4841  }
4842 
4843  private:
4845  std::FILE* m_file;
4846 };
4847 
4848 
4859 {
4860  public:
4861  using char_type = char;
4862 
4864  {
4865  // clear stream flags; we use underlying streambuf I/O, do not
4866  // maintain ifstream flags, except eof
4867  if (is != nullptr)
4868  {
4869  is->clear(is->rdstate() & std::ios::eofbit);
4870  }
4871  }
4872 
4873  explicit input_stream_adapter(std::istream& i)
4874  : is(&i), sb(i.rdbuf())
4875  {}
4876 
4877  // delete because of pointer members
4881 
4882  input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs.is), sb(rhs.sb)
4883  {
4884  rhs.is = nullptr;
4885  rhs.sb = nullptr;
4886  }
4887 
4888  // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
4889  // ensure that std::char_traits<char>::eof() and the character 0xFF do not
4890  // end up as the same value, eg. 0xFFFFFFFF.
4891  std::char_traits<char>::int_type get_character()
4892  {
4893  auto res = sb->sbumpc();
4894  // set eof manually, as we don't use the istream interface.
4895  if (JSON_HEDLEY_UNLIKELY(res == EOF))
4896  {
4897  is->clear(is->rdstate() | std::ios::eofbit);
4898  }
4899  return res;
4900  }
4901 
4902  private:
4904  std::istream* is = nullptr;
4905  std::streambuf* sb = nullptr;
4906 };
4907 
4908 // General-purpose iterator-based adapter. It might not be as fast as
4909 // theoretically possible for some containers, but it is extremely versatile.
4910 template<typename IteratorType>
4912 {
4913  public:
4914  using char_type = typename std::iterator_traits<IteratorType>::value_type;
4915 
4916  iterator_input_adapter(IteratorType first, IteratorType last)
4917  : current(std::move(first)), end(std::move(last)) {}
4918 
4919  typename std::char_traits<char_type>::int_type get_character()
4920  {
4921  if (JSON_HEDLEY_LIKELY(current != end))
4922  {
4923  auto result = std::char_traits<char_type>::to_int_type(*current);
4924  std::advance(current, 1);
4925  return result;
4926  }
4927  else
4928  {
4929  return std::char_traits<char_type>::eof();
4930  }
4931  }
4932 
4933  private:
4934  IteratorType current;
4935  IteratorType end;
4936 
4937  template<typename BaseInputAdapter, size_t T>
4939 
4940  bool empty() const
4941  {
4942  return current == end;
4943  }
4944 
4945 };
4946 
4947 
4948 template<typename BaseInputAdapter, size_t T>
4950 
4951 template<typename BaseInputAdapter>
4952 struct wide_string_input_helper<BaseInputAdapter, 4>
4953 {
4954  // UTF-32
4955  static void fill_buffer(BaseInputAdapter& input,
4956  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4957  size_t& utf8_bytes_index,
4958  size_t& utf8_bytes_filled)
4959  {
4960  utf8_bytes_index = 0;
4961 
4962  if (JSON_HEDLEY_UNLIKELY(input.empty()))
4963  {
4964  utf8_bytes[0] = std::char_traits<char>::eof();
4965  utf8_bytes_filled = 1;
4966  }
4967  else
4968  {
4969  // get the current character
4970  const auto wc = input.get_character();
4971 
4972  // UTF-32 to UTF-8 encoding
4973  if (wc < 0x80)
4974  {
4975  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4976  utf8_bytes_filled = 1;
4977  }
4978  else if (wc <= 0x7FF)
4979  {
4980  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
4981  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4982  utf8_bytes_filled = 2;
4983  }
4984  else if (wc <= 0xFFFF)
4985  {
4986  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
4987  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4988  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4989  utf8_bytes_filled = 3;
4990  }
4991  else if (wc <= 0x10FFFF)
4992  {
4993  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
4994  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
4995  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4996  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4997  utf8_bytes_filled = 4;
4998  }
4999  else
5000  {
5001  // unknown character
5002  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5003  utf8_bytes_filled = 1;
5004  }
5005  }
5006  }
5007 };
5008 
5009 template<typename BaseInputAdapter>
5010 struct wide_string_input_helper<BaseInputAdapter, 2>
5011 {
5012  // UTF-16
5013  static void fill_buffer(BaseInputAdapter& input,
5014  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5015  size_t& utf8_bytes_index,
5016  size_t& utf8_bytes_filled)
5017  {
5018  utf8_bytes_index = 0;
5019 
5020  if (JSON_HEDLEY_UNLIKELY(input.empty()))
5021  {
5022  utf8_bytes[0] = std::char_traits<char>::eof();
5023  utf8_bytes_filled = 1;
5024  }
5025  else
5026  {
5027  // get the current character
5028  const auto wc = input.get_character();
5029 
5030  // UTF-16 to UTF-8 encoding
5031  if (wc < 0x80)
5032  {
5033  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5034  utf8_bytes_filled = 1;
5035  }
5036  else if (wc <= 0x7FF)
5037  {
5038  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5039  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5040  utf8_bytes_filled = 2;
5041  }
5042  else if (0xD800 > wc || wc >= 0xE000)
5043  {
5044  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5045  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5046  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5047  utf8_bytes_filled = 3;
5048  }
5049  else
5050  {
5051  if (JSON_HEDLEY_UNLIKELY(!input.empty()))
5052  {
5053  const auto wc2 = static_cast<unsigned int>(input.get_character());
5054  const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
5055  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
5056  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
5057  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
5058  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
5059  utf8_bytes_filled = 4;
5060  }
5061  else
5062  {
5063  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5064  utf8_bytes_filled = 1;
5065  }
5066  }
5067  }
5068  }
5069 };
5070 
5071 // Wraps another input apdater to convert wide character types into individual bytes.
5072 template<typename BaseInputAdapter, typename WideCharType>
5074 {
5075  public:
5076  using char_type = char;
5077 
5078  wide_string_input_adapter(BaseInputAdapter base)
5079  : base_adapter(base) {}
5080 
5081  typename std::char_traits<char>::int_type get_character() noexcept
5082  {
5083  // check if buffer needs to be filled
5085  {
5086  fill_buffer<sizeof(WideCharType)>();
5087 
5090  }
5091 
5092  // use buffer
5095  return utf8_bytes[utf8_bytes_index++];
5096  }
5097 
5098  private:
5099  BaseInputAdapter base_adapter;
5100 
5101  template<size_t T>
5103  {
5105  }
5106 
5108  std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5109 
5111  std::size_t utf8_bytes_index = 0;
5113  std::size_t utf8_bytes_filled = 0;
5114 };
5115 
5116 
5117 template<typename IteratorType, typename Enable = void>
5119 {
5120  using iterator_type = IteratorType;
5121  using char_type = typename std::iterator_traits<iterator_type>::value_type;
5123 
5124  static adapter_type create(IteratorType first, IteratorType last)
5125  {
5126  return adapter_type(std::move(first), std::move(last));
5127  }
5128 };
5129 
5130 template<typename T>
5132 {
5133  using value_type = typename std::iterator_traits<T>::value_type;
5134  enum
5135  {
5136  value = sizeof(value_type) > 1
5137  };
5138 };
5139 
5140 template<typename IteratorType>
5142 {
5143  using iterator_type = IteratorType;
5144  using char_type = typename std::iterator_traits<iterator_type>::value_type;
5147 
5148  static adapter_type create(IteratorType first, IteratorType last)
5149  {
5150  return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5151  }
5152 };
5153 
5154 // General purpose iterator-based input
5155 template<typename IteratorType>
5157 {
5158  using factory_type = iterator_input_adapter_factory<IteratorType>;
5159  return factory_type::create(first, last);
5160 }
5161 
5162 // Convenience shorthand from container to iterator
5163 template<typename ContainerType>
5164 auto input_adapter(const ContainerType& container) -> decltype(input_adapter(begin(container), end(container)))
5165 {
5166  // Enable ADL
5167  using std::begin;
5168  using std::end;
5169 
5170  return input_adapter(begin(container), end(container));
5171 }
5172 
5173 // Special cases with fast paths
5175 {
5176  return file_input_adapter(file);
5177 }
5178 
5179 inline input_stream_adapter input_adapter(std::istream& stream)
5180 {
5181  return input_stream_adapter(stream);
5182 }
5183 
5184 inline input_stream_adapter input_adapter(std::istream&& stream)
5185 {
5186  return input_stream_adapter(stream);
5187 }
5188 
5189 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5190 
5191 // Null-delimited strings, and the like.
5192 template < typename CharT,
5193  typename std::enable_if <
5194  std::is_pointer<CharT>::value&&
5195  !std::is_array<CharT>::value&&
5196  std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5197  sizeof(typename std::remove_pointer<CharT>::type) == 1,
5198  int >::type = 0 >
5200 {
5201  auto length = std::strlen(reinterpret_cast<const char*>(b));
5202  const auto* ptr = reinterpret_cast<const char*>(b);
5203  return input_adapter(ptr, ptr + length);
5204 }
5205 
5206 template<typename T, std::size_t N>
5207 auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N))
5208 {
5209  return input_adapter(array, array + N);
5210 }
5211 
5212 // This class only handles inputs of input_buffer_adapter type.
5213 // It's required so that expressions like {ptr, len} can be implicitely casted
5214 // to the correct adapter.
5216 {
5217  public:
5218  template < typename CharT,
5219  typename std::enable_if <
5220  std::is_pointer<CharT>::value&&
5221  std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5222  sizeof(typename std::remove_pointer<CharT>::type) == 1,
5223  int >::type = 0 >
5224  span_input_adapter(CharT b, std::size_t l)
5225  : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5226 
5227  template<class IteratorType,
5228  typename std::enable_if<
5229  std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5230  int>::type = 0>
5231  span_input_adapter(IteratorType first, IteratorType last)
5232  : ia(input_adapter(first, last)) {}
5233 
5235  {
5236  return std::move(ia);
5237  }
5238 
5239  private:
5241 };
5242 } // namespace detail
5243 } // namespace nlohmann
5244 
5245 // #include <nlohmann/detail/input/json_sax.hpp>
5246 
5247 
5248 #include <cstddef>
5249 #include <string> // string
5250 #include <utility> // move
5251 #include <vector> // vector
5252 
5253 // #include <nlohmann/detail/exceptions.hpp>
5254 
5255 // #include <nlohmann/detail/macro_scope.hpp>
5256 
5257 
5258 namespace nlohmann
5259 {
5260 
5269 template<typename BasicJsonType>
5270 struct json_sax
5271 {
5272  using number_integer_t = typename BasicJsonType::number_integer_t;
5273  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5274  using number_float_t = typename BasicJsonType::number_float_t;
5275  using string_t = typename BasicJsonType::string_t;
5276  using binary_t = typename BasicJsonType::binary_t;
5277 
5282  virtual bool null() = 0;
5283 
5289  virtual bool boolean(bool val) = 0;
5290 
5296  virtual bool number_integer(number_integer_t val) = 0;
5297 
5303  virtual bool number_unsigned(number_unsigned_t val) = 0;
5304 
5311  virtual bool number_float(number_float_t val, const string_t& s) = 0;
5312 
5319  virtual bool string(string_t& val) = 0;
5320 
5327  virtual bool binary(binary_t& val) = 0;
5328 
5335  virtual bool start_object(std::size_t elements) = 0;
5336 
5343  virtual bool key(string_t& val) = 0;
5344 
5349  virtual bool end_object() = 0;
5350 
5357  virtual bool start_array(std::size_t elements) = 0;
5358 
5363  virtual bool end_array() = 0;
5364 
5372  virtual bool parse_error(std::size_t position,
5373  const std::string& last_token,
5374  const detail::exception& ex) = 0;
5375 
5376  virtual ~json_sax() = default;
5377 };
5378 
5379 
5380 namespace detail
5381 {
5395 template<typename BasicJsonType>
5397 {
5398  public:
5399  using number_integer_t = typename BasicJsonType::number_integer_t;
5400  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5401  using number_float_t = typename BasicJsonType::number_float_t;
5402  using string_t = typename BasicJsonType::string_t;
5403  using binary_t = typename BasicJsonType::binary_t;
5404 
5410  explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
5411  : root(r), allow_exceptions(allow_exceptions_)
5412  {}
5413 
5414  // make class move-only
5420 
5421  bool null()
5422  {
5423  handle_value(nullptr);
5424  return true;
5425  }
5426 
5427  bool boolean(bool val)
5428  {
5429  handle_value(val);
5430  return true;
5431  }
5432 
5434  {
5435  handle_value(val);
5436  return true;
5437  }
5438 
5440  {
5441  handle_value(val);
5442  return true;
5443  }
5444 
5445  bool number_float(number_float_t val, const string_t& /*unused*/)
5446  {
5447  handle_value(val);
5448  return true;
5449  }
5450 
5451  bool string(string_t& val)
5452  {
5453  handle_value(val);
5454  return true;
5455  }
5456 
5457  bool binary(binary_t& val)
5458  {
5459  handle_value(std::move(val));
5460  return true;
5461  }
5462 
5463  bool start_object(std::size_t len)
5464  {
5465  ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
5466 
5467  if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5468  {
5470  "excessive object size: " + std::to_string(len)));
5471  }
5472 
5473  return true;
5474  }
5475 
5476  bool key(string_t& val)
5477  {
5478  // add null at given key and store the reference for later
5479  object_element = &(ref_stack.back()->m_value.object->operator[](val));
5480  return true;
5481  }
5482 
5483  bool end_object()
5484  {
5485  ref_stack.pop_back();
5486  return true;
5487  }
5488 
5489  bool start_array(std::size_t len)
5490  {
5491  ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
5492 
5493  if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5494  {
5496  "excessive array size: " + std::to_string(len)));
5497  }
5498 
5499  return true;
5500  }
5501 
5502  bool end_array()
5503  {
5504  ref_stack.pop_back();
5505  return true;
5506  }
5507 
5508  template<class Exception>
5509  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5510  const Exception& ex)
5511  {
5512  errored = true;
5513  static_cast<void>(ex);
5514  if (allow_exceptions)
5515  {
5516  JSON_THROW(ex);
5517  }
5518  return false;
5519  }
5520 
5521  constexpr bool is_errored() const
5522  {
5523  return errored;
5524  }
5525 
5526  private:
5533  template<typename Value>
5535  BasicJsonType* handle_value(Value&& v)
5536  {
5537  if (ref_stack.empty())
5538  {
5539  root = BasicJsonType(std::forward<Value>(v));
5540  return &root;
5541  }
5542 
5543  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
5544 
5545  if (ref_stack.back()->is_array())
5546  {
5547  ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
5548  return &(ref_stack.back()->m_value.array->back());
5549  }
5550 
5551  JSON_ASSERT(ref_stack.back()->is_object());
5553  *object_element = BasicJsonType(std::forward<Value>(v));
5554  return object_element;
5555  }
5556 
5558  BasicJsonType& root;
5560  std::vector<BasicJsonType*> ref_stack {};
5562  BasicJsonType* object_element = nullptr;
5564  bool errored = false;
5566  const bool allow_exceptions = true;
5567 };
5568 
5569 template<typename BasicJsonType>
5571 {
5572  public:
5573  using number_integer_t = typename BasicJsonType::number_integer_t;
5574  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5575  using number_float_t = typename BasicJsonType::number_float_t;
5576  using string_t = typename BasicJsonType::string_t;
5577  using binary_t = typename BasicJsonType::binary_t;
5580 
5582  const parser_callback_t cb,
5583  const bool allow_exceptions_ = true)
5584  : root(r), callback(cb), allow_exceptions(allow_exceptions_)
5585  {
5586  keep_stack.push_back(true);
5587  }
5588 
5589  // make class move-only
5595 
5596  bool null()
5597  {
5598  handle_value(nullptr);
5599  return true;
5600  }
5601 
5602  bool boolean(bool val)
5603  {
5604  handle_value(val);
5605  return true;
5606  }
5607 
5609  {
5610  handle_value(val);
5611  return true;
5612  }
5613 
5615  {
5616  handle_value(val);
5617  return true;
5618  }
5619 
5620  bool number_float(number_float_t val, const string_t& /*unused*/)
5621  {
5622  handle_value(val);
5623  return true;
5624  }
5625 
5626  bool string(string_t& val)
5627  {
5628  handle_value(val);
5629  return true;
5630  }
5631 
5632  bool binary(binary_t& val)
5633  {
5634  handle_value(std::move(val));
5635  return true;
5636  }
5637 
5638  bool start_object(std::size_t len)
5639  {
5640  // check callback for object start
5641  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
5642  keep_stack.push_back(keep);
5643 
5644  auto val = handle_value(BasicJsonType::value_t::object, true);
5645  ref_stack.push_back(val.second);
5646 
5647  // check object limit
5648  if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5649  {
5650  JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
5651  }
5652 
5653  return true;
5654  }
5655 
5656  bool key(string_t& val)
5657  {
5658  BasicJsonType k = BasicJsonType(val);
5659 
5660  // check callback for key
5661  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
5662  key_keep_stack.push_back(keep);
5663 
5664  // add discarded value at given key and store the reference for later
5665  if (keep && ref_stack.back())
5666  {
5667  object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
5668  }
5669 
5670  return true;
5671  }
5672 
5673  bool end_object()
5674  {
5675  if (ref_stack.back() && !callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
5676  {
5677  // discard object
5678  *ref_stack.back() = discarded;
5679  }
5680 
5681  JSON_ASSERT(!ref_stack.empty());
5682  JSON_ASSERT(!keep_stack.empty());
5683  ref_stack.pop_back();
5684  keep_stack.pop_back();
5685 
5686  if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
5687  {
5688  // remove discarded value
5689  for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
5690  {
5691  if (it->is_discarded())
5692  {
5693  ref_stack.back()->erase(it);
5694  break;
5695  }
5696  }
5697  }
5698 
5699  return true;
5700  }
5701 
5702  bool start_array(std::size_t len)
5703  {
5704  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
5705  keep_stack.push_back(keep);
5706 
5707  auto val = handle_value(BasicJsonType::value_t::array, true);
5708  ref_stack.push_back(val.second);
5709 
5710  // check array limit
5711  if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5712  {
5713  JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
5714  }
5715 
5716  return true;
5717  }
5718 
5719  bool end_array()
5720  {
5721  bool keep = true;
5722 
5723  if (ref_stack.back())
5724  {
5725  keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
5726  if (!keep)
5727  {
5728  // discard array
5729  *ref_stack.back() = discarded;
5730  }
5731  }
5732 
5733  JSON_ASSERT(!ref_stack.empty());
5734  JSON_ASSERT(!keep_stack.empty());
5735  ref_stack.pop_back();
5736  keep_stack.pop_back();
5737 
5738  // remove discarded value
5739  if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
5740  {
5741  ref_stack.back()->m_value.array->pop_back();
5742  }
5743 
5744  return true;
5745  }
5746 
5747  template<class Exception>
5748  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5749  const Exception& ex)
5750  {
5751  errored = true;
5752  static_cast<void>(ex);
5753  if (allow_exceptions)
5754  {
5755  JSON_THROW(ex);
5756  }
5757  return false;
5758  }
5759 
5760  constexpr bool is_errored() const
5761  {
5762  return errored;
5763  }
5764 
5765  private:
5781  template<typename Value>
5782  std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
5783  {
5784  JSON_ASSERT(!keep_stack.empty());
5785 
5786  // do not handle this value if we know it would be added to a discarded
5787  // container
5788  if (!keep_stack.back())
5789  {
5790  return {false, nullptr};
5791  }
5792 
5793  // create value
5794  auto value = BasicJsonType(std::forward<Value>(v));
5795 
5796  // check callback
5797  const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
5798 
5799  // do not handle this value if we just learnt it shall be discarded
5800  if (!keep)
5801  {
5802  return {false, nullptr};
5803  }
5804 
5805  if (ref_stack.empty())
5806  {
5807  root = std::move(value);
5808  return {true, &root};
5809  }
5810 
5811  // skip this value if we already decided to skip the parent
5812  // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
5813  if (!ref_stack.back())
5814  {
5815  return {false, nullptr};
5816  }
5817 
5818  // we now only expect arrays and objects
5819  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
5820 
5821  // array
5822  if (ref_stack.back()->is_array())
5823  {
5824  ref_stack.back()->m_value.array->push_back(std::move(value));
5825  return {true, &(ref_stack.back()->m_value.array->back())};
5826  }
5827 
5828  // object
5829  JSON_ASSERT(ref_stack.back()->is_object());
5830  // check if we should store an element for the current key
5831  JSON_ASSERT(!key_keep_stack.empty());
5832  const bool store_element = key_keep_stack.back();
5833  key_keep_stack.pop_back();
5834 
5835  if (!store_element)
5836  {
5837  return {false, nullptr};
5838  }
5839 
5841  *object_element = std::move(value);
5842  return {true, object_element};
5843  }
5844 
5846  BasicJsonType& root;
5848  std::vector<BasicJsonType*> ref_stack {};
5850  std::vector<bool> keep_stack {};
5852  std::vector<bool> key_keep_stack {};
5854  BasicJsonType* object_element = nullptr;
5856  bool errored = false;
5858  const parser_callback_t callback = nullptr;
5860  const bool allow_exceptions = true;
5862  BasicJsonType discarded = BasicJsonType::value_t::discarded;
5863 };
5864 
5865 template<typename BasicJsonType>
5867 {
5868  public:
5869  using number_integer_t = typename BasicJsonType::number_integer_t;
5870  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5871  using number_float_t = typename BasicJsonType::number_float_t;
5872  using string_t = typename BasicJsonType::string_t;
5873  using binary_t = typename BasicJsonType::binary_t;
5874 
5875  bool null()
5876  {
5877  return true;
5878  }
5879 
5880  bool boolean(bool /*unused*/)
5881  {
5882  return true;
5883  }
5884 
5886  {
5887  return true;
5888  }
5889 
5891  {
5892  return true;
5893  }
5894 
5895  bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
5896  {
5897  return true;
5898  }
5899 
5900  bool string(string_t& /*unused*/)
5901  {
5902  return true;
5903  }
5904 
5905  bool binary(binary_t& /*unused*/)
5906  {
5907  return true;
5908  }
5909 
5910  bool start_object(std::size_t /*unused*/ = std::size_t(-1))
5911  {
5912  return true;
5913  }
5914 
5915  bool key(string_t& /*unused*/)
5916  {
5917  return true;
5918  }
5919 
5920  bool end_object()
5921  {
5922  return true;
5923  }
5924 
5925  bool start_array(std::size_t /*unused*/ = std::size_t(-1))
5926  {
5927  return true;
5928  }
5929 
5930  bool end_array()
5931  {
5932  return true;
5933  }
5934 
5935  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
5936  {
5937  return false;
5938  }
5939 };
5940 } // namespace detail
5941 
5942 } // namespace nlohmann
5943 
5944 // #include <nlohmann/detail/input/lexer.hpp>
5945 
5946 
5947 #include <array> // array
5948 #include <clocale> // localeconv
5949 #include <cstddef> // size_t
5950 #include <cstdio> // snprintf
5951 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
5952 #include <initializer_list> // initializer_list
5953 #include <string> // char_traits, string
5954 #include <utility> // move
5955 #include <vector> // vector
5956 
5957 // #include <nlohmann/detail/input/input_adapters.hpp>
5958 
5959 // #include <nlohmann/detail/input/position_t.hpp>
5960 
5961 // #include <nlohmann/detail/macro_scope.hpp>
5962 
5963 
5964 namespace nlohmann
5965 {
5966 namespace detail
5967 {
5969 // lexer //
5971 
5972 template<typename BasicJsonType>
5974 {
5975  public:
5977  enum class token_type
5978  {
5979  uninitialized,
5980  literal_true,
5981  literal_false,
5982  literal_null,
5983  value_string,
5984  value_unsigned,
5985  value_integer,
5986  value_float,
5987  begin_array,
5988  begin_object,
5989  end_array,
5990  end_object,
5991  name_separator,
5992  value_separator,
5993  parse_error,
5994  end_of_input,
5996  };
5997 
6001  static const char* token_type_name(const token_type t) noexcept
6002  {
6003  switch (t)
6004  {
6006  return "<uninitialized>";
6008  return "true literal";
6010  return "false literal";
6012  return "null literal";
6014  return "string literal";
6018  return "number literal";
6020  return "'['";
6022  return "'{'";
6023  case token_type::end_array:
6024  return "']'";
6026  return "'}'";
6028  return "':'";
6030  return "','";
6032  return "<parse error>";
6034  return "end of input";
6036  return "'[', '{', or a literal";
6037  // LCOV_EXCL_START
6038  default: // catch non-enum values
6039  return "unknown token";
6040  // LCOV_EXCL_STOP
6041  }
6042  }
6043 };
6049 template<typename BasicJsonType, typename InputAdapterType>
6050 class lexer : public lexer_base<BasicJsonType>
6051 {
6052  using number_integer_t = typename BasicJsonType::number_integer_t;
6053  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6054  using number_float_t = typename BasicJsonType::number_float_t;
6055  using string_t = typename BasicJsonType::string_t;
6056  using char_type = typename InputAdapterType::char_type;
6057  using char_int_type = typename std::char_traits<char_type>::int_type;
6058 
6059  public:
6061 
6062  explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false)
6063  : ia(std::move(adapter))
6064  , ignore_comments(ignore_comments_)
6066  {}
6067 
6068  // delete because of pointer members
6069  lexer(const lexer&) = delete;
6070  lexer(lexer&&) = default;
6071  lexer& operator=(lexer&) = delete;
6072  lexer& operator=(lexer&&) = default;
6073  ~lexer() = default;
6074 
6075  private:
6077  // locales
6079 
6082  static char get_decimal_point() noexcept
6083  {
6084  const auto* loc = localeconv();
6085  JSON_ASSERT(loc != nullptr);
6086  return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6087  }
6088 
6090  // scan functions
6092 
6109  {
6110  // this function only makes sense after reading `\u`
6111  JSON_ASSERT(current == 'u');
6112  int codepoint = 0;
6113 
6114  const auto factors = { 12u, 8u, 4u, 0u };
6115  for (const auto factor : factors)
6116  {
6117  get();
6118 
6119  if (current >= '0' && current <= '9')
6120  {
6121  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6122  }
6123  else if (current >= 'A' && current <= 'F')
6124  {
6125  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6126  }
6127  else if (current >= 'a' && current <= 'f')
6128  {
6129  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6130  }
6131  else
6132  {
6133  return -1;
6134  }
6135  }
6136 
6137  JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6138  return codepoint;
6139  }
6140 
6156  bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6157  {
6158  JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6159  add(current);
6160 
6161  for (auto range = ranges.begin(); range != ranges.end(); ++range)
6162  {
6163  get();
6164  if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6165  {
6166  add(current);
6167  }
6168  else
6169  {
6170  error_message = "invalid string: ill-formed UTF-8 byte";
6171  return false;
6172  }
6173  }
6174 
6175  return true;
6176  }
6177 
6194  {
6195  // reset token_buffer (ignore opening quote)
6196  reset();
6197 
6198  // we entered the function by reading an open quote
6199  JSON_ASSERT(current == '\"');
6200 
6201  while (true)
6202  {
6203  // get next character
6204  switch (get())
6205  {
6206  // end of file while parsing string
6207  case std::char_traits<char_type>::eof():
6208  {
6209  error_message = "invalid string: missing closing quote";
6210  return token_type::parse_error;
6211  }
6212 
6213  // closing quote
6214  case '\"':
6215  {
6216  return token_type::value_string;
6217  }
6218 
6219  // escapes
6220  case '\\':
6221  {
6222  switch (get())
6223  {
6224  // quotation mark
6225  case '\"':
6226  add('\"');
6227  break;
6228  // reverse solidus
6229  case '\\':
6230  add('\\');
6231  break;
6232  // solidus
6233  case '/':
6234  add('/');
6235  break;
6236  // backspace
6237  case 'b':
6238  add('\b');
6239  break;
6240  // form feed
6241  case 'f':
6242  add('\f');
6243  break;
6244  // line feed
6245  case 'n':
6246  add('\n');
6247  break;
6248  // carriage return
6249  case 'r':
6250  add('\r');
6251  break;
6252  // tab
6253  case 't':
6254  add('\t');
6255  break;
6256 
6257  // unicode escapes
6258  case 'u':
6259  {
6260  const int codepoint1 = get_codepoint();
6261  int codepoint = codepoint1; // start with codepoint1
6262 
6263  if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
6264  {
6265  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6266  return token_type::parse_error;
6267  }
6268 
6269  // check if code point is a high surrogate
6270  if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6271  {
6272  // expect next \uxxxx entry
6273  if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6274  {
6275  const int codepoint2 = get_codepoint();
6276 
6277  if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
6278  {
6279  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6280  return token_type::parse_error;
6281  }
6282 
6283  // check if codepoint2 is a low surrogate
6284  if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6285  {
6286  // overwrite codepoint
6287  codepoint = static_cast<int>(
6288  // high surrogate occupies the most significant 22 bits
6289  (static_cast<unsigned int>(codepoint1) << 10u)
6290  // low surrogate occupies the least significant 15 bits
6291  + static_cast<unsigned int>(codepoint2)
6292  // there is still the 0xD800, 0xDC00 and 0x10000 noise
6293  // in the result so we have to subtract with:
6294  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6295  - 0x35FDC00u);
6296  }
6297  else
6298  {
6299  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6300  return token_type::parse_error;
6301  }
6302  }
6303  else
6304  {
6305  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6306  return token_type::parse_error;
6307  }
6308  }
6309  else
6310  {
6311  if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6312  {
6313  error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6314  return token_type::parse_error;
6315  }
6316  }
6317 
6318  // result of the above calculation yields a proper codepoint
6319  JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
6320 
6321  // translate codepoint into bytes
6322  if (codepoint < 0x80)
6323  {
6324  // 1-byte characters: 0xxxxxxx (ASCII)
6325  add(static_cast<char_int_type>(codepoint));
6326  }
6327  else if (codepoint <= 0x7FF)
6328  {
6329  // 2-byte characters: 110xxxxx 10xxxxxx
6330  add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
6331  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6332  }
6333  else if (codepoint <= 0xFFFF)
6334  {
6335  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
6336  add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
6337  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6338  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6339  }
6340  else
6341  {
6342  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
6343  add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
6344  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
6345  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6346  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6347  }
6348 
6349  break;
6350  }
6351 
6352  // other characters after escape
6353  default:
6354  error_message = "invalid string: forbidden character after backslash";
6355  return token_type::parse_error;
6356  }
6357 
6358  break;
6359  }
6360 
6361  // invalid control characters
6362  case 0x00:
6363  {
6364  error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
6365  return token_type::parse_error;
6366  }
6367 
6368  case 0x01:
6369  {
6370  error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
6371  return token_type::parse_error;
6372  }
6373 
6374  case 0x02:
6375  {
6376  error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
6377  return token_type::parse_error;
6378  }
6379 
6380  case 0x03:
6381  {
6382  error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
6383  return token_type::parse_error;
6384  }
6385 
6386  case 0x04:
6387  {
6388  error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
6389  return token_type::parse_error;
6390  }
6391 
6392  case 0x05:
6393  {
6394  error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
6395  return token_type::parse_error;
6396  }
6397 
6398  case 0x06:
6399  {
6400  error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
6401  return token_type::parse_error;
6402  }
6403 
6404  case 0x07:
6405  {
6406  error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
6407  return token_type::parse_error;
6408  }
6409 
6410  case 0x08:
6411  {
6412  error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
6413  return token_type::parse_error;
6414  }
6415 
6416  case 0x09:
6417  {
6418  error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
6419  return token_type::parse_error;
6420  }
6421 
6422  case 0x0A:
6423  {
6424  error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
6425  return token_type::parse_error;
6426  }
6427 
6428  case 0x0B:
6429  {
6430  error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
6431  return token_type::parse_error;
6432  }
6433 
6434  case 0x0C:
6435  {
6436  error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
6437  return token_type::parse_error;
6438  }
6439 
6440  case 0x0D:
6441  {
6442  error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
6443  return token_type::parse_error;
6444  }
6445 
6446  case 0x0E:
6447  {
6448  error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
6449  return token_type::parse_error;
6450  }
6451 
6452  case 0x0F:
6453  {
6454  error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
6455  return token_type::parse_error;
6456  }
6457 
6458  case 0x10:
6459  {
6460  error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
6461  return token_type::parse_error;
6462  }
6463 
6464  case 0x11:
6465  {
6466  error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
6467  return token_type::parse_error;
6468  }
6469 
6470  case 0x12:
6471  {
6472  error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
6473  return token_type::parse_error;
6474  }
6475 
6476  case 0x13:
6477  {
6478  error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
6479  return token_type::parse_error;
6480  }
6481 
6482  case 0x14:
6483  {
6484  error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
6485  return token_type::parse_error;
6486  }
6487 
6488  case 0x15:
6489  {
6490  error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
6491  return token_type::parse_error;
6492  }
6493 
6494  case 0x16:
6495  {
6496  error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
6497  return token_type::parse_error;
6498  }
6499 
6500  case 0x17:
6501  {
6502  error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
6503  return token_type::parse_error;
6504  }
6505 
6506  case 0x18:
6507  {
6508  error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
6509  return token_type::parse_error;
6510  }
6511 
6512  case 0x19:
6513  {
6514  error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
6515  return token_type::parse_error;
6516  }
6517 
6518  case 0x1A:
6519  {
6520  error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
6521  return token_type::parse_error;
6522  }
6523 
6524  case 0x1B:
6525  {
6526  error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
6527  return token_type::parse_error;
6528  }
6529 
6530  case 0x1C:
6531  {
6532  error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
6533  return token_type::parse_error;
6534  }
6535 
6536  case 0x1D:
6537  {
6538  error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
6539  return token_type::parse_error;
6540  }
6541 
6542  case 0x1E:
6543  {
6544  error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
6545  return token_type::parse_error;
6546  }
6547 
6548  case 0x1F:
6549  {
6550  error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
6551  return token_type::parse_error;
6552  }
6553 
6554  // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
6555  case 0x20:
6556  case 0x21:
6557  case 0x23:
6558  case 0x24:
6559  case 0x25:
6560  case 0x26:
6561  case 0x27:
6562  case 0x28:
6563  case 0x29:
6564  case 0x2A:
6565  case 0x2B:
6566  case 0x2C:
6567  case 0x2D:
6568  case 0x2E:
6569  case 0x2F:
6570  case 0x30:
6571  case 0x31:
6572  case 0x32:
6573  case 0x33:
6574  case 0x34:
6575  case 0x35:
6576  case 0x36:
6577  case 0x37:
6578  case 0x38:
6579  case 0x39:
6580  case 0x3A:
6581  case 0x3B:
6582  case 0x3C:
6583  case 0x3D:
6584  case 0x3E:
6585  case 0x3F:
6586  case 0x40:
6587  case 0x41:
6588  case 0x42:
6589  case 0x43:
6590  case 0x44:
6591  case 0x45:
6592  case 0x46:
6593  case 0x47:
6594  case 0x48:
6595  case 0x49:
6596  case 0x4A:
6597  case 0x4B:
6598  case 0x4C:
6599  case 0x4D:
6600  case 0x4E:
6601  case 0x4F:
6602  case 0x50:
6603  case 0x51:
6604  case 0x52:
6605  case 0x53:
6606  case 0x54:
6607  case 0x55:
6608  case 0x56:
6609  case 0x57:
6610  case 0x58:
6611  case 0x59:
6612  case 0x5A:
6613  case 0x5B:
6614  case 0x5D:
6615  case 0x5E:
6616  case 0x5F:
6617  case 0x60:
6618  case 0x61:
6619  case 0x62:
6620  case 0x63:
6621  case 0x64:
6622  case 0x65:
6623  case 0x66:
6624  case 0x67:
6625  case 0x68:
6626  case 0x69:
6627  case 0x6A:
6628  case 0x6B:
6629  case 0x6C:
6630  case 0x6D:
6631  case 0x6E:
6632  case 0x6F:
6633  case 0x70:
6634  case 0x71:
6635  case 0x72:
6636  case 0x73:
6637  case 0x74:
6638  case 0x75:
6639  case 0x76:
6640  case 0x77:
6641  case 0x78:
6642  case 0x79:
6643  case 0x7A:
6644  case 0x7B:
6645  case 0x7C:
6646  case 0x7D:
6647  case 0x7E:
6648  case 0x7F:
6649  {
6650  add(current);
6651  break;
6652  }
6653 
6654  // U+0080..U+07FF: bytes C2..DF 80..BF
6655  case 0xC2:
6656  case 0xC3:
6657  case 0xC4:
6658  case 0xC5:
6659  case 0xC6:
6660  case 0xC7:
6661  case 0xC8:
6662  case 0xC9:
6663  case 0xCA:
6664  case 0xCB:
6665  case 0xCC:
6666  case 0xCD:
6667  case 0xCE:
6668  case 0xCF:
6669  case 0xD0:
6670  case 0xD1:
6671  case 0xD2:
6672  case 0xD3:
6673  case 0xD4:
6674  case 0xD5:
6675  case 0xD6:
6676  case 0xD7:
6677  case 0xD8:
6678  case 0xD9:
6679  case 0xDA:
6680  case 0xDB:
6681  case 0xDC:
6682  case 0xDD:
6683  case 0xDE:
6684  case 0xDF:
6685  {
6686  if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
6687  {
6688  return token_type::parse_error;
6689  }
6690  break;
6691  }
6692 
6693  // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
6694  case 0xE0:
6695  {
6696  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
6697  {
6698  return token_type::parse_error;
6699  }
6700  break;
6701  }
6702 
6703  // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
6704  // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
6705  case 0xE1:
6706  case 0xE2:
6707  case 0xE3:
6708  case 0xE4:
6709  case 0xE5:
6710  case 0xE6:
6711  case 0xE7:
6712  case 0xE8:
6713  case 0xE9:
6714  case 0xEA:
6715  case 0xEB:
6716  case 0xEC:
6717  case 0xEE:
6718  case 0xEF:
6719  {
6720  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
6721  {
6722  return token_type::parse_error;
6723  }
6724  break;
6725  }
6726 
6727  // U+D000..U+D7FF: bytes ED 80..9F 80..BF
6728  case 0xED:
6729  {
6730  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
6731  {
6732  return token_type::parse_error;
6733  }
6734  break;
6735  }
6736 
6737  // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
6738  case 0xF0:
6739  {
6740  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6741  {
6742  return token_type::parse_error;
6743  }
6744  break;
6745  }
6746 
6747  // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
6748  case 0xF1:
6749  case 0xF2:
6750  case 0xF3:
6751  {
6752  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6753  {
6754  return token_type::parse_error;
6755  }
6756  break;
6757  }
6758 
6759  // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
6760  case 0xF4:
6761  {
6762  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
6763  {
6764  return token_type::parse_error;
6765  }
6766  break;
6767  }
6768 
6769  // remaining bytes (80..C1 and F5..FF) are ill-formed
6770  default:
6771  {
6772  error_message = "invalid string: ill-formed UTF-8 byte";
6773  return token_type::parse_error;
6774  }
6775  }
6776  }
6777  }
6778 
6784  {
6785  switch (get())
6786  {
6787  // single-line comments skip input until a newline or EOF is read
6788  case '/':
6789  {
6790  while (true)
6791  {
6792  switch (get())
6793  {
6794  case '\n':
6795  case '\r':
6796  case std::char_traits<char_type>::eof():
6797  case '\0':
6798  return true;
6799 
6800  default:
6801  break;
6802  }
6803  }
6804  }
6805 
6806  // multi-line comments skip input until */ is read
6807  case '*':
6808  {
6809  while (true)
6810  {
6811  switch (get())
6812  {
6813  case std::char_traits<char_type>::eof():
6814  case '\0':
6815  {
6816  error_message = "invalid comment; missing closing '*/'";
6817  return false;
6818  }
6819 
6820  case '*':
6821  {
6822  switch (get())
6823  {
6824  case '/':
6825  return true;
6826 
6827  default:
6828  {
6829  unget();
6830  continue;
6831  }
6832  }
6833  }
6834 
6835  default:
6836  continue;
6837  }
6838  }
6839  }
6840 
6841  // unexpected character after reading '/'
6842  default:
6843  {
6844  error_message = "invalid comment; expecting '/' or '*' after '/'";
6845  return false;
6846  }
6847  }
6848  }
6849 
6851  static void strtof(float& f, const char* str, char** endptr) noexcept
6852  {
6853  f = std::strtof(str, endptr);
6854  }
6855 
6857  static void strtof(double& f, const char* str, char** endptr) noexcept
6858  {
6859  f = std::strtod(str, endptr);
6860  }
6861 
6863  static void strtof(long double& f, const char* str, char** endptr) noexcept
6864  {
6865  f = std::strtold(str, endptr);
6866  }
6867 
6908  token_type scan_number() // lgtm [cpp/use-of-goto]
6909  {
6910  // reset token_buffer to store the number's bytes
6911  reset();
6912 
6913  // the type of the parsed number; initially set to unsigned; will be
6914  // changed if minus sign, decimal point or exponent is read
6915  token_type number_type = token_type::value_unsigned;
6916 
6917  // state (init): we just found out we need to scan a number
6918  switch (current)
6919  {
6920  case '-':
6921  {
6922  add(current);
6923  goto scan_number_minus;
6924  }
6925 
6926  case '0':
6927  {
6928  add(current);
6929  goto scan_number_zero;
6930  }
6931 
6932  case '1':
6933  case '2':
6934  case '3':
6935  case '4':
6936  case '5':
6937  case '6':
6938  case '7':
6939  case '8':
6940  case '9':
6941  {
6942  add(current);
6943  goto scan_number_any1;
6944  }
6945 
6946  // all other characters are rejected outside scan_number()
6947  default: // LCOV_EXCL_LINE
6948  JSON_ASSERT(false); // LCOV_EXCL_LINE
6949  }
6950 
6951 scan_number_minus:
6952  // state: we just parsed a leading minus sign
6953  number_type = token_type::value_integer;
6954  switch (get())
6955  {
6956  case '0':
6957  {
6958  add(current);
6959  goto scan_number_zero;
6960  }
6961 
6962  case '1':
6963  case '2':
6964  case '3':
6965  case '4':
6966  case '5':
6967  case '6':
6968  case '7':
6969  case '8':
6970  case '9':
6971  {
6972  add(current);
6973  goto scan_number_any1;
6974  }
6975 
6976  default:
6977  {
6978  error_message = "invalid number; expected digit after '-'";
6979  return token_type::parse_error;
6980  }
6981  }
6982 
6983 scan_number_zero:
6984  // state: we just parse a zero (maybe with a leading minus sign)
6985  switch (get())
6986  {
6987  case '.':
6988  {
6990  goto scan_number_decimal1;
6991  }
6992 
6993  case 'e':
6994  case 'E':
6995  {
6996  add(current);
6997  goto scan_number_exponent;
6998  }
6999 
7000  default:
7001  goto scan_number_done;
7002  }
7003 
7004 scan_number_any1:
7005  // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7006  switch (get())
7007  {
7008  case '0':
7009  case '1':
7010  case '2':
7011  case '3':
7012  case '4':
7013  case '5':
7014  case '6':
7015  case '7':
7016  case '8':
7017  case '9':
7018  {
7019  add(current);
7020  goto scan_number_any1;
7021  }
7022 
7023  case '.':
7024  {
7026  goto scan_number_decimal1;
7027  }
7028 
7029  case 'e':
7030  case 'E':
7031  {
7032  add(current);
7033  goto scan_number_exponent;
7034  }
7035 
7036  default:
7037  goto scan_number_done;
7038  }
7039 
7040 scan_number_decimal1:
7041  // state: we just parsed a decimal point
7042  number_type = token_type::value_float;
7043  switch (get())
7044  {
7045  case '0':
7046  case '1':
7047  case '2':
7048  case '3':
7049  case '4':
7050  case '5':
7051  case '6':
7052  case '7':
7053  case '8':
7054  case '9':
7055  {
7056  add(current);
7057  goto scan_number_decimal2;
7058  }
7059 
7060  default:
7061  {
7062  error_message = "invalid number; expected digit after '.'";
7063  return token_type::parse_error;
7064  }
7065  }
7066 
7067 scan_number_decimal2:
7068  // we just parsed at least one number after a decimal point
7069  switch (get())
7070  {
7071  case '0':
7072  case '1':
7073  case '2':
7074  case '3':
7075  case '4':
7076  case '5':
7077  case '6':
7078  case '7':
7079  case '8':
7080  case '9':
7081  {
7082  add(current);
7083  goto scan_number_decimal2;
7084  }
7085 
7086  case 'e':
7087  case 'E':
7088  {
7089  add(current);
7090  goto scan_number_exponent;
7091  }
7092 
7093  default:
7094  goto scan_number_done;
7095  }
7096 
7097 scan_number_exponent:
7098  // we just parsed an exponent
7099  number_type = token_type::value_float;
7100  switch (get())
7101  {
7102  case '+':
7103  case '-':
7104  {
7105  add(current);
7106  goto scan_number_sign;
7107  }
7108 
7109  case '0':
7110  case '1':
7111  case '2':
7112  case '3':
7113  case '4':
7114  case '5':
7115  case '6':
7116  case '7':
7117  case '8':
7118  case '9':
7119  {
7120  add(current);
7121  goto scan_number_any2;
7122  }
7123 
7124  default:
7125  {
7126  error_message =
7127  "invalid number; expected '+', '-', or digit after exponent";
7128  return token_type::parse_error;
7129  }
7130  }
7131 
7132 scan_number_sign:
7133  // we just parsed an exponent sign
7134  switch (get())
7135  {
7136  case '0':
7137  case '1':
7138  case '2':
7139  case '3':
7140  case '4':
7141  case '5':
7142  case '6':
7143  case '7':
7144  case '8':
7145  case '9':
7146  {
7147  add(current);
7148  goto scan_number_any2;
7149  }
7150 
7151  default:
7152  {
7153  error_message = "invalid number; expected digit after exponent sign";
7154  return token_type::parse_error;
7155  }
7156  }
7157 
7158 scan_number_any2:
7159  // we just parsed a number after the exponent or exponent sign
7160  switch (get())
7161  {
7162  case '0':
7163  case '1':
7164  case '2':
7165  case '3':
7166  case '4':
7167  case '5':
7168  case '6':
7169  case '7':
7170  case '8':
7171  case '9':
7172  {
7173  add(current);
7174  goto scan_number_any2;
7175  }
7176 
7177  default:
7178  goto scan_number_done;
7179  }
7180 
7181 scan_number_done:
7182  // unget the character after the number (we only read it to know that
7183  // we are done scanning a number)
7184  unget();
7185 
7186  char* endptr = nullptr;
7187  errno = 0;
7188 
7189  // try to parse integers first and fall back to floats
7190  if (number_type == token_type::value_unsigned)
7191  {
7192  const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7193 
7194  // we checked the number format before
7195  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7196 
7197  if (errno == 0)
7198  {
7199  value_unsigned = static_cast<number_unsigned_t>(x);
7200  if (value_unsigned == x)
7201  {
7202  return token_type::value_unsigned;
7203  }
7204  }
7205  }
7206  else if (number_type == token_type::value_integer)
7207  {
7208  const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7209 
7210  // we checked the number format before
7211  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7212 
7213  if (errno == 0)
7214  {
7215  value_integer = static_cast<number_integer_t>(x);
7216  if (value_integer == x)
7217  {
7218  return token_type::value_integer;
7219  }
7220  }
7221  }
7222 
7223  // this code is reached if we parse a floating-point number or if an
7224  // integer conversion above failed
7225  strtof(value_float, token_buffer.data(), &endptr);
7226 
7227  // we checked the number format before
7228  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7229 
7230  return token_type::value_float;
7231  }
7232 
7239  token_type scan_literal(const char_type* literal_text, const std::size_t length,
7240  token_type return_type)
7241  {
7242  JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
7243  for (std::size_t i = 1; i < length; ++i)
7244  {
7245  if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
7246  {
7247  error_message = "invalid literal";
7248  return token_type::parse_error;
7249  }
7250  }
7251  return return_type;
7252  }
7253 
7255  // input management
7257 
7259  void reset() noexcept
7260  {
7261  token_buffer.clear();
7262  token_string.clear();
7263  token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7264  }
7265 
7266  /*
7267  @brief get next character from the input
7268 
7269  This function provides the interface to the used input adapter. It does
7270  not throw in case the input reached EOF, but returns a
7271  `std::char_traits<char>::eof()` in that case. Stores the scanned characters
7272  for use in error messages.
7273 
7274  @return character read from the input
7275  */
7277  {
7280 
7281  if (next_unget)
7282  {
7283  // just reset the next_unget variable and work with current
7284  next_unget = false;
7285  }
7286  else
7287  {
7288  current = ia.get_character();
7289  }
7290 
7291  if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7292  {
7293  token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7294  }
7295 
7296  if (current == '\n')
7297  {
7298  ++position.lines_read;
7300  }
7301 
7302  return current;
7303  }
7304 
7313  void unget()
7314  {
7315  next_unget = true;
7316 
7318 
7319  // in case we "unget" a newline, we have to also decrement the lines_read
7321  {
7322  if (position.lines_read > 0)
7323  {
7324  --position.lines_read;
7325  }
7326  }
7327  else
7328  {
7330  }
7331 
7332  if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7333  {
7334  JSON_ASSERT(!token_string.empty());
7335  token_string.pop_back();
7336  }
7337  }
7338 
7341  {
7342  token_buffer.push_back(static_cast<typename string_t::value_type>(c));
7343  }
7344 
7345  public:
7347  // value getters
7349 
7351  constexpr number_integer_t get_number_integer() const noexcept
7352  {
7353  return value_integer;
7354  }
7355 
7357  constexpr number_unsigned_t get_number_unsigned() const noexcept
7358  {
7359  return value_unsigned;
7360  }
7361 
7363  constexpr number_float_t get_number_float() const noexcept
7364  {
7365  return value_float;
7366  }
7367 
7370  {
7371  return token_buffer;
7372  }
7373 
7375  // diagnostics
7377 
7379  constexpr position_t get_position() const noexcept
7380  {
7381  return position;
7382  }
7383 
7387  std::string get_token_string() const
7388  {
7389  // escape control characters
7390  std::string result;
7391  for (const auto c : token_string)
7392  {
7393  if (static_cast<unsigned char>(c) <= '\x1F')
7394  {
7395  // escape control characters
7396  std::array<char, 9> cs{{}};
7397  (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c));
7398  result += cs.data();
7399  }
7400  else
7401  {
7402  // add character as is
7403  result.push_back(static_cast<std::string::value_type>(c));
7404  }
7405  }
7406 
7407  return result;
7408  }
7409 
7412  constexpr const char* get_error_message() const noexcept
7413  {
7414  return error_message;
7415  }
7416 
7418  // actual scanner
7420 
7425  bool skip_bom()
7426  {
7427  if (get() == 0xEF)
7428  {
7429  // check if we completely parse the BOM
7430  return get() == 0xBB && get() == 0xBF;
7431  }
7432 
7433  // the first character is not the beginning of the BOM; unget it to
7434  // process is later
7435  unget();
7436  return true;
7437  }
7438 
7440  {
7441  do
7442  {
7443  get();
7444  }
7445  while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
7446  }
7447 
7449  {
7450  // initially, skip the BOM
7451  if (position.chars_read_total == 0 && !skip_bom())
7452  {
7453  error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
7454  return token_type::parse_error;
7455  }
7456 
7457  // read next character and ignore whitespace
7458  skip_whitespace();
7459 
7460  // ignore comments
7461  while (ignore_comments && current == '/')
7462  {
7463  if (!scan_comment())
7464  {
7465  return token_type::parse_error;
7466  }
7467 
7468  // skip following whitespace
7469  skip_whitespace();
7470  }
7471 
7472  switch (current)
7473  {
7474  // structural characters
7475  case '[':
7476  return token_type::begin_array;
7477  case ']':
7478  return token_type::end_array;
7479  case '{':
7480  return token_type::begin_object;
7481  case '}':
7482  return token_type::end_object;
7483  case ':':
7484  return token_type::name_separator;
7485  case ',':
7486  return token_type::value_separator;
7487 
7488  // literals
7489  case 't':
7490  {
7491  std::array<char_type, 4> true_literal = {{'t', 'r', 'u', 'e'}};
7492  return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
7493  }
7494  case 'f':
7495  {
7496  std::array<char_type, 5> false_literal = {{'f', 'a', 'l', 's', 'e'}};
7497  return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
7498  }
7499  case 'n':
7500  {
7501  std::array<char_type, 4> null_literal = {{'n', 'u', 'l', 'l'}};
7502  return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
7503  }
7504 
7505  // string
7506  case '\"':
7507  return scan_string();
7508 
7509  // number
7510  case '-':
7511  case '0':
7512  case '1':
7513  case '2':
7514  case '3':
7515  case '4':
7516  case '5':
7517  case '6':
7518  case '7':
7519  case '8':
7520  case '9':
7521  return scan_number();
7522 
7523  // end of input (the null byte is needed when parsing from
7524  // string literals)
7525  case '\0':
7526  case std::char_traits<char_type>::eof():
7527  return token_type::end_of_input;
7528 
7529  // error
7530  default:
7531  error_message = "invalid literal";
7532  return token_type::parse_error;
7533  }
7534  }
7535 
7536  private:
7538  InputAdapterType ia;
7539 
7541  const bool ignore_comments = false;
7542 
7544  char_int_type current = std::char_traits<char_type>::eof();
7545 
7547  bool next_unget = false;
7548 
7551 
7553  std::vector<char_type> token_string {};
7554 
7557 
7559  const char* error_message = "";
7560 
7561  // number values
7565 
7568 };
7569 } // namespace detail
7570 } // namespace nlohmann
7571 
7572 // #include <nlohmann/detail/macro_scope.hpp>
7573 
7574 // #include <nlohmann/detail/meta/is_sax.hpp>
7575 
7576 
7577 #include <cstdint> // size_t
7578 #include <utility> // declval
7579 #include <string> // string
7580 
7581 // #include <nlohmann/detail/meta/detected.hpp>
7582 
7583 // #include <nlohmann/detail/meta/type_traits.hpp>
7584 
7585 
7586 namespace nlohmann
7587 {
7588 namespace detail
7589 {
7590 template<typename T>
7591 using null_function_t = decltype(std::declval<T&>().null());
7592 
7593 template<typename T>
7595  decltype(std::declval<T&>().boolean(std::declval<bool>()));
7596 
7597 template<typename T, typename Integer>
7599  decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
7600 
7601 template<typename T, typename Unsigned>
7603  decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
7604 
7605 template<typename T, typename Float, typename String>
7606 using number_float_function_t = decltype(std::declval<T&>().number_float(
7607  std::declval<Float>(), std::declval<const String&>()));
7608 
7609 template<typename T, typename String>
7611  decltype(std::declval<T&>().string(std::declval<String&>()));
7612 
7613 template<typename T, typename Binary>
7615  decltype(std::declval<T&>().binary(std::declval<Binary&>()));
7616 
7617 template<typename T>
7619  decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
7620 
7621 template<typename T, typename String>
7623  decltype(std::declval<T&>().key(std::declval<String&>()));
7624 
7625 template<typename T>
7626 using end_object_function_t = decltype(std::declval<T&>().end_object());
7627 
7628 template<typename T>
7630  decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
7631 
7632 template<typename T>
7633 using end_array_function_t = decltype(std::declval<T&>().end_array());
7634 
7635 template<typename T, typename Exception>
7636 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
7637  std::declval<std::size_t>(), std::declval<const std::string&>(),
7638  std::declval<const Exception&>()));
7639 
7640 template<typename SAX, typename BasicJsonType>
7641 struct is_sax
7642 {
7643  private:
7645  "BasicJsonType must be of type basic_json<...>");
7646 
7647  using number_integer_t = typename BasicJsonType::number_integer_t;
7648  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7649  using number_float_t = typename BasicJsonType::number_float_t;
7650  using string_t = typename BasicJsonType::string_t;
7651  using binary_t = typename BasicJsonType::binary_t;
7652  using exception_t = typename BasicJsonType::exception;
7653 
7654  public:
7655  static constexpr bool value =
7669 };
7670 
7671 template<typename SAX, typename BasicJsonType>
7673 {
7674  private:
7676  "BasicJsonType must be of type basic_json<...>");
7677 
7678  using number_integer_t = typename BasicJsonType::number_integer_t;
7679  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7680  using number_float_t = typename BasicJsonType::number_float_t;
7681  using string_t = typename BasicJsonType::string_t;
7682  using binary_t = typename BasicJsonType::binary_t;
7683  using exception_t = typename BasicJsonType::exception;
7684 
7685  public:
7687  "Missing/invalid function: bool null()");
7689  "Missing/invalid function: bool boolean(bool)");
7691  "Missing/invalid function: bool boolean(bool)");
7692  static_assert(
7694  number_integer_t>::value,
7695  "Missing/invalid function: bool number_integer(number_integer_t)");
7696  static_assert(
7698  number_unsigned_t>::value,
7699  "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
7700  static_assert(is_detected_exact<bool, number_float_function_t, SAX,
7701  number_float_t, string_t>::value,
7702  "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
7703  static_assert(
7705  "Missing/invalid function: bool string(string_t&)");
7706  static_assert(
7708  "Missing/invalid function: bool binary(binary_t&)");
7710  "Missing/invalid function: bool start_object(std::size_t)");
7712  "Missing/invalid function: bool key(string_t&)");
7714  "Missing/invalid function: bool end_object()");
7716  "Missing/invalid function: bool start_array(std::size_t)");
7718  "Missing/invalid function: bool end_array()");
7719  static_assert(
7721  "Missing/invalid function: bool parse_error(std::size_t, const "
7722  "std::string&, const exception&)");
7723 };
7724 } // namespace detail
7725 } // namespace nlohmann
7726 
7727 // #include <nlohmann/detail/value_t.hpp>
7728 
7729 
7730 namespace nlohmann
7731 {
7732 namespace detail
7733 {
7734 
7737 {
7738  error,
7739  ignore
7740 };
7741 
7749 static inline bool little_endianess(int num = 1) noexcept
7750 {
7751  return *reinterpret_cast<char*>(&num) == 1;
7752 }
7753 
7754 
7756 // binary reader //
7758 
7762 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
7764 {
7765  using number_integer_t = typename BasicJsonType::number_integer_t;
7766  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7767  using number_float_t = typename BasicJsonType::number_float_t;
7768  using string_t = typename BasicJsonType::string_t;
7769  using binary_t = typename BasicJsonType::binary_t;
7770  using json_sax_t = SAX;
7771  using char_type = typename InputAdapterType::char_type;
7772  using char_int_type = typename std::char_traits<char_type>::int_type;
7773 
7774  public:
7780  explicit binary_reader(InputAdapterType&& adapter) : ia(std::move(adapter))
7781  {
7783  }
7784 
7785  // make class move-only
7786  binary_reader(const binary_reader&) = delete;
7790  ~binary_reader() = default;
7791 
7801  bool sax_parse(const input_format_t format,
7802  json_sax_t* sax_,
7803  const bool strict = true,
7804  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
7805  {
7806  sax = sax_;
7807  bool result = false;
7808 
7809  switch (format)
7810  {
7811  case input_format_t::bson:
7813  break;
7814 
7815  case input_format_t::cbor:
7816  result = parse_cbor_internal(true, tag_handler);
7817  break;
7818 
7821  break;
7822 
7825  break;
7826 
7827  default: // LCOV_EXCL_LINE
7828  JSON_ASSERT(false); // LCOV_EXCL_LINE
7829  }
7830 
7831  // strict mode: next byte must be EOF
7832  if (result && strict)
7833  {
7834  if (format == input_format_t::ubjson)
7835  {
7836  get_ignore_noop();
7837  }
7838  else
7839  {
7840  get();
7841  }
7842 
7843  if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
7844  {
7845  return sax->parse_error(chars_read, get_token_string(),
7846  parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
7847  }
7848  }
7849 
7850  return result;
7851  }
7852 
7853  private:
7855  // BSON //
7857 
7863  {
7864  std::int32_t document_size{};
7865  get_number<std::int32_t, true>(input_format_t::bson, document_size);
7866 
7867  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
7868  {
7869  return false;
7870  }
7871 
7872  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
7873  {
7874  return false;
7875  }
7876 
7877  return sax->end_object();
7878  }
7879 
7888  {
7889  auto out = std::back_inserter(result);
7890  while (true)
7891  {
7892  get();
7894  {
7895  return false;
7896  }
7897  if (current == 0x00)
7898  {
7899  return true;
7900  }
7901  *out++ = static_cast<typename string_t::value_type>(current);
7902  }
7903  }
7904 
7916  template<typename NumberType>
7917  bool get_bson_string(const NumberType len, string_t& result)
7918  {
7919  if (JSON_HEDLEY_UNLIKELY(len < 1))
7920  {
7921  auto last_token = get_token_string();
7922  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")));
7923  }
7924 
7925  return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
7926  }
7927 
7937  template<typename NumberType>
7938  bool get_bson_binary(const NumberType len, binary_t& result)
7939  {
7940  if (JSON_HEDLEY_UNLIKELY(len < 0))
7941  {
7942  auto last_token = get_token_string();
7943  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")));
7944  }
7945 
7946  // All BSON binary values have a subtype
7947  std::uint8_t subtype{};
7948  get_number<std::uint8_t>(input_format_t::bson, subtype);
7949  result.set_subtype(subtype);
7950 
7951  return get_binary(input_format_t::bson, len, result);
7952  }
7953 
7965  const std::size_t element_type_parse_position)
7966  {
7967  switch (element_type)
7968  {
7969  case 0x01: // double
7970  {
7971  double number{};
7972  return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
7973  }
7974 
7975  case 0x02: // string
7976  {
7977  std::int32_t len{};
7978  string_t value;
7979  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
7980  }
7981 
7982  case 0x03: // object
7983  {
7984  return parse_bson_internal();
7985  }
7986 
7987  case 0x04: // array
7988  {
7989  return parse_bson_array();
7990  }
7991 
7992  case 0x05: // binary
7993  {
7994  std::int32_t len{};
7995  binary_t value;
7996  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
7997  }
7998 
7999  case 0x08: // boolean
8000  {
8001  return sax->boolean(get() != 0);
8002  }
8003 
8004  case 0x0A: // null
8005  {
8006  return sax->null();
8007  }
8008 
8009  case 0x10: // int32
8010  {
8011  std::int32_t value{};
8012  return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8013  }
8014 
8015  case 0x12: // int64
8016  {
8017  std::int64_t value{};
8018  return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8019  }
8020 
8021  default: // anything else not supported (yet)
8022  {
8023  std::array<char, 3> cr{{}};
8024  (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type));
8025  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())));
8026  }
8027  }
8028  }
8029 
8042  bool parse_bson_element_list(const bool is_array)
8043  {
8044  string_t key;
8045 
8046  while (auto element_type = get())
8047  {
8049  {
8050  return false;
8051  }
8052 
8053  const std::size_t element_type_parse_position = chars_read;
8055  {
8056  return false;
8057  }
8058 
8059  if (!is_array && !sax->key(key))
8060  {
8061  return false;
8062  }
8063 
8064  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
8065  {
8066  return false;
8067  }
8068 
8069  // get_bson_cstr only appends
8070  key.clear();
8071  }
8072 
8073  return true;
8074  }
8075 
8081  {
8082  std::int32_t document_size{};
8083  get_number<std::int32_t, true>(input_format_t::bson, document_size);
8084 
8085  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
8086  {
8087  return false;
8088  }
8089 
8090  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8091  {
8092  return false;
8093  }
8094 
8095  return sax->end_array();
8096  }
8097 
8099  // CBOR //
8101 
8110  bool parse_cbor_internal(const bool get_char,
8111  const cbor_tag_handler_t tag_handler)
8112  {
8113  switch (get_char ? get() : current)
8114  {
8115  // EOF
8116  case std::char_traits<char_type>::eof():
8117  return unexpect_eof(input_format_t::cbor, "value");
8118 
8119  // Integer 0x00..0x17 (0..23)
8120  case 0x00:
8121  case 0x01:
8122  case 0x02:
8123  case 0x03:
8124  case 0x04:
8125  case 0x05:
8126  case 0x06:
8127  case 0x07:
8128  case 0x08:
8129  case 0x09:
8130  case 0x0A:
8131  case 0x0B:
8132  case 0x0C:
8133  case 0x0D:
8134  case 0x0E:
8135  case 0x0F:
8136  case 0x10:
8137  case 0x11:
8138  case 0x12:
8139  case 0x13:
8140  case 0x14:
8141  case 0x15:
8142  case 0x16:
8143  case 0x17:
8144  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8145 
8146  case 0x18: // Unsigned integer (one-byte uint8_t follows)
8147  {
8148  std::uint8_t number{};
8149  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8150  }
8151 
8152  case 0x19: // Unsigned integer (two-byte uint16_t follows)
8153  {
8154  std::uint16_t number{};
8155  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8156  }
8157 
8158  case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8159  {
8160  std::uint32_t number{};
8161  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8162  }
8163 
8164  case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8165  {
8166  std::uint64_t number{};
8167  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8168  }
8169 
8170  // Negative integer -1-0x00..-1-0x17 (-1..-24)
8171  case 0x20:
8172  case 0x21:
8173  case 0x22:
8174  case 0x23:
8175  case 0x24:
8176  case 0x25:
8177  case 0x26:
8178  case 0x27:
8179  case 0x28:
8180  case 0x29:
8181  case 0x2A:
8182  case 0x2B:
8183  case 0x2C:
8184  case 0x2D:
8185  case 0x2E:
8186  case 0x2F:
8187  case 0x30:
8188  case 0x31:
8189  case 0x32:
8190  case 0x33:
8191  case 0x34:
8192  case 0x35:
8193  case 0x36:
8194  case 0x37:
8195  return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8196 
8197  case 0x38: // Negative integer (one-byte uint8_t follows)
8198  {
8199  std::uint8_t number{};
8200  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8201  }
8202 
8203  case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8204  {
8205  std::uint16_t number{};
8206  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8207  }
8208 
8209  case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8210  {
8211  std::uint32_t number{};
8212  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8213  }
8214 
8215  case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8216  {
8217  std::uint64_t number{};
8218  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8219  - static_cast<number_integer_t>(number));
8220  }
8221 
8222  // Binary data (0x00..0x17 bytes follow)
8223  case 0x40:
8224  case 0x41:
8225  case 0x42:
8226  case 0x43:
8227  case 0x44:
8228  case 0x45:
8229  case 0x46:
8230  case 0x47:
8231  case 0x48:
8232  case 0x49:
8233  case 0x4A:
8234  case 0x4B:
8235  case 0x4C:
8236  case 0x4D:
8237  case 0x4E:
8238  case 0x4F:
8239  case 0x50:
8240  case 0x51:
8241  case 0x52:
8242  case 0x53:
8243  case 0x54:
8244  case 0x55:
8245  case 0x56:
8246  case 0x57:
8247  case 0x58: // Binary data (one-byte uint8_t for n follows)
8248  case 0x59: // Binary data (two-byte uint16_t for n follow)
8249  case 0x5A: // Binary data (four-byte uint32_t for n follow)
8250  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8251  case 0x5F: // Binary data (indefinite length)
8252  {
8253  binary_t b;
8254  return get_cbor_binary(b) && sax->binary(b);
8255  }
8256 
8257  // UTF-8 string (0x00..0x17 bytes follow)
8258  case 0x60:
8259  case 0x61:
8260  case 0x62:
8261  case 0x63:
8262  case 0x64:
8263  case 0x65:
8264  case 0x66:
8265  case 0x67:
8266  case 0x68:
8267  case 0x69:
8268  case 0x6A:
8269  case 0x6B:
8270  case 0x6C:
8271  case 0x6D:
8272  case 0x6E:
8273  case 0x6F:
8274  case 0x70:
8275  case 0x71:
8276  case 0x72:
8277  case 0x73:
8278  case 0x74:
8279  case 0x75:
8280  case 0x76:
8281  case 0x77:
8282  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8283  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8284  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8285  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8286  case 0x7F: // UTF-8 string (indefinite length)
8287  {
8288  string_t s;
8289  return get_cbor_string(s) && sax->string(s);
8290  }
8291 
8292  // array (0x00..0x17 data items follow)
8293  case 0x80:
8294  case 0x81:
8295  case 0x82:
8296  case 0x83:
8297  case 0x84:
8298  case 0x85:
8299  case 0x86:
8300  case 0x87:
8301  case 0x88:
8302  case 0x89:
8303  case 0x8A:
8304  case 0x8B:
8305  case 0x8C:
8306  case 0x8D:
8307  case 0x8E:
8308  case 0x8F:
8309  case 0x90:
8310  case 0x91:
8311  case 0x92:
8312  case 0x93:
8313  case 0x94:
8314  case 0x95:
8315  case 0x96:
8316  case 0x97:
8317  return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8318 
8319  case 0x98: // array (one-byte uint8_t for n follows)
8320  {
8321  std::uint8_t len{};
8322  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8323  }
8324 
8325  case 0x99: // array (two-byte uint16_t for n follow)
8326  {
8327  std::uint16_t len{};
8328  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8329  }
8330 
8331  case 0x9A: // array (four-byte uint32_t for n follow)
8332  {
8333  std::uint32_t len{};
8334  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8335  }
8336 
8337  case 0x9B: // array (eight-byte uint64_t for n follow)
8338  {
8339  std::uint64_t len{};
8340  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8341  }
8342 
8343  case 0x9F: // array (indefinite length)
8344  return get_cbor_array(std::size_t(-1), tag_handler);
8345 
8346  // map (0x00..0x17 pairs of data items follow)
8347  case 0xA0:
8348  case 0xA1:
8349  case 0xA2:
8350  case 0xA3:
8351  case 0xA4:
8352  case 0xA5:
8353  case 0xA6:
8354  case 0xA7:
8355  case 0xA8:
8356  case 0xA9:
8357  case 0xAA:
8358  case 0xAB:
8359  case 0xAC:
8360  case 0xAD:
8361  case 0xAE:
8362  case 0xAF:
8363  case 0xB0:
8364  case 0xB1:
8365  case 0xB2:
8366  case 0xB3:
8367  case 0xB4:
8368  case 0xB5:
8369  case 0xB6:
8370  case 0xB7:
8371  return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8372 
8373  case 0xB8: // map (one-byte uint8_t for n follows)
8374  {
8375  std::uint8_t len{};
8376  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8377  }
8378 
8379  case 0xB9: // map (two-byte uint16_t for n follow)
8380  {
8381  std::uint16_t len{};
8382  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8383  }
8384 
8385  case 0xBA: // map (four-byte uint32_t for n follow)
8386  {
8387  std::uint32_t len{};
8388  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8389  }
8390 
8391  case 0xBB: // map (eight-byte uint64_t for n follow)
8392  {
8393  std::uint64_t len{};
8394  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8395  }
8396 
8397  case 0xBF: // map (indefinite length)
8398  return get_cbor_object(std::size_t(-1), tag_handler);
8399 
8400  case 0xC6: // tagged item
8401  case 0xC7:
8402  case 0xC8:
8403  case 0xC9:
8404  case 0xCA:
8405  case 0xCB:
8406  case 0xCC:
8407  case 0xCD:
8408  case 0xCE:
8409  case 0xCF:
8410  case 0xD0:
8411  case 0xD1:
8412  case 0xD2:
8413  case 0xD3:
8414  case 0xD4:
8415  case 0xD8: // tagged item (1 bytes follow)
8416  case 0xD9: // tagged item (2 bytes follow)
8417  case 0xDA: // tagged item (4 bytes follow)
8418  case 0xDB: // tagged item (8 bytes follow)
8419  {
8420  switch (tag_handler)
8421  {
8423  {
8424  auto last_token = get_token_string();
8425  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")));
8426  }
8427 
8429  {
8430  switch (current)
8431  {
8432  case 0xD8:
8433  {
8434  std::uint8_t len{};
8436  break;
8437  }
8438  case 0xD9:
8439  {
8440  std::uint16_t len{};
8442  break;
8443  }
8444  case 0xDA:
8445  {
8446  std::uint32_t len{};
8448  break;
8449  }
8450  case 0xDB:
8451  {
8452  std::uint64_t len{};
8454  break;
8455  }
8456  default:
8457  break;
8458  }
8459  return parse_cbor_internal(true, tag_handler);
8460  }
8461 
8462  default: // LCOV_EXCL_LINE
8463  JSON_ASSERT(false); // LCOV_EXCL_LINE
8464  return false; // LCOV_EXCL_LINE
8465  }
8466  }
8467 
8468  case 0xF4: // false
8469  return sax->boolean(false);
8470 
8471  case 0xF5: // true
8472  return sax->boolean(true);
8473 
8474  case 0xF6: // null
8475  return sax->null();
8476 
8477  case 0xF9: // Half-Precision Float (two-byte IEEE 754)
8478  {
8479  const auto byte1_raw = get();
8481  {
8482  return false;
8483  }
8484  const auto byte2_raw = get();
8486  {
8487  return false;
8488  }
8489 
8490  const auto byte1 = static_cast<unsigned char>(byte1_raw);
8491  const auto byte2 = static_cast<unsigned char>(byte2_raw);
8492 
8493  // code from RFC 7049, Appendix D, Figure 3:
8494  // As half-precision floating-point numbers were only added
8495  // to IEEE 754 in 2008, today's programming platforms often
8496  // still only have limited support for them. It is very
8497  // easy to include at least decoding support for them even
8498  // without such support. An example of a small decoder for
8499  // half-precision floating-point numbers in the C language
8500  // is shown in Fig. 3.
8501  const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
8502  const double val = [&half]
8503  {
8504  const int exp = (half >> 10u) & 0x1Fu;
8505  const unsigned int mant = half & 0x3FFu;
8506  JSON_ASSERT(0 <= exp&& exp <= 32);
8507  JSON_ASSERT(mant <= 1024);
8508  switch (exp)
8509  {
8510  case 0:
8511  return std::ldexp(mant, -24);
8512  case 31:
8513  return (mant == 0)
8514  ? std::numeric_limits<double>::infinity()
8515  : std::numeric_limits<double>::quiet_NaN();
8516  default:
8517  return std::ldexp(mant + 1024, exp - 25);
8518  }
8519  }();
8520  return sax->number_float((half & 0x8000u) != 0
8521  ? static_cast<number_float_t>(-val)
8522  : static_cast<number_float_t>(val), "");
8523  }
8524 
8525  case 0xFA: // Single-Precision Float (four-byte IEEE 754)
8526  {
8527  float number{};
8528  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
8529  }
8530 
8531  case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
8532  {
8533  double number{};
8534  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
8535  }
8536 
8537  default: // anything else (0xFF is handled inside the other types)
8538  {
8539  auto last_token = get_token_string();
8540  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")));
8541  }
8542  }
8543  }
8544 
8557  {
8559  {
8560  return false;
8561  }
8562 
8563  switch (current)
8564  {
8565  // UTF-8 string (0x00..0x17 bytes follow)
8566  case 0x60:
8567  case 0x61:
8568  case 0x62:
8569  case 0x63:
8570  case 0x64:
8571  case 0x65:
8572  case 0x66:
8573  case 0x67:
8574  case 0x68:
8575  case 0x69:
8576  case 0x6A:
8577  case 0x6B:
8578  case 0x6C:
8579  case 0x6D:
8580  case 0x6E:
8581  case 0x6F:
8582  case 0x70:
8583  case 0x71:
8584  case 0x72:
8585  case 0x73:
8586  case 0x74:
8587  case 0x75:
8588  case 0x76:
8589  case 0x77:
8590  {
8591  return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
8592  }
8593 
8594  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8595  {
8596  std::uint8_t len{};
8598  }
8599 
8600  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8601  {
8602  std::uint16_t len{};
8604  }
8605 
8606  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8607  {
8608  std::uint32_t len{};
8610  }
8611 
8612  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8613  {
8614  std::uint64_t len{};
8616  }
8617 
8618  case 0x7F: // UTF-8 string (indefinite length)
8619  {
8620  while (get() != 0xFF)
8621  {
8622  string_t chunk;
8623  if (!get_cbor_string(chunk))
8624  {
8625  return false;
8626  }
8627  result.append(chunk);
8628  }
8629  return true;
8630  }
8631 
8632  default:
8633  {
8634  auto last_token = get_token_string();
8635  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")));
8636  }
8637  }
8638  }
8639 
8652  {
8654  {
8655  return false;
8656  }
8657 
8658  switch (current)
8659  {
8660  // Binary data (0x00..0x17 bytes follow)
8661  case 0x40:
8662  case 0x41:
8663  case 0x42:
8664  case 0x43:
8665  case 0x44:
8666  case 0x45:
8667  case 0x46:
8668  case 0x47:
8669  case 0x48:
8670  case 0x49:
8671  case 0x4A:
8672  case 0x4B:
8673  case 0x4C:
8674  case 0x4D:
8675  case 0x4E:
8676  case 0x4F:
8677  case 0x50:
8678  case 0x51:
8679  case 0x52:
8680  case 0x53:
8681  case 0x54:
8682  case 0x55:
8683  case 0x56:
8684  case 0x57:
8685  {
8686  return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
8687  }
8688 
8689  case 0x58: // Binary data (one-byte uint8_t for n follows)
8690  {
8691  std::uint8_t len{};
8692  return get_number(input_format_t::cbor, len) &&
8694  }
8695 
8696  case 0x59: // Binary data (two-byte uint16_t for n follow)
8697  {
8698  std::uint16_t len{};
8699  return get_number(input_format_t::cbor, len) &&
8701  }
8702 
8703  case 0x5A: // Binary data (four-byte uint32_t for n follow)
8704  {
8705  std::uint32_t len{};
8706  return get_number(input_format_t::cbor, len) &&
8708  }
8709 
8710  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8711  {
8712  std::uint64_t len{};
8713  return get_number(input_format_t::cbor, len) &&
8715  }
8716 
8717  case 0x5F: // Binary data (indefinite length)
8718  {
8719  while (get() != 0xFF)
8720  {
8721  binary_t chunk;
8722  if (!get_cbor_binary(chunk))
8723  {
8724  return false;
8725  }
8726  result.insert(result.end(), chunk.begin(), chunk.end());
8727  }
8728  return true;
8729  }
8730 
8731  default:
8732  {
8733  auto last_token = get_token_string();
8734  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")));
8735  }
8736  }
8737  }
8738 
8745  bool get_cbor_array(const std::size_t len,
8746  const cbor_tag_handler_t tag_handler)
8747  {
8748  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
8749  {
8750  return false;
8751  }
8752 
8753  if (len != std::size_t(-1))
8754  {
8755  for (std::size_t i = 0; i < len; ++i)
8756  {
8757  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8758  {
8759  return false;
8760  }
8761  }
8762  }
8763  else
8764  {
8765  while (get() != 0xFF)
8766  {
8767  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
8768  {
8769  return false;
8770  }
8771  }
8772  }
8773 
8774  return sax->end_array();
8775  }
8776 
8783  bool get_cbor_object(const std::size_t len,
8784  const cbor_tag_handler_t tag_handler)
8785  {
8786  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
8787  {
8788  return false;
8789  }
8790 
8791  string_t key;
8792  if (len != std::size_t(-1))
8793  {
8794  for (std::size_t i = 0; i < len; ++i)
8795  {
8796  get();
8797  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
8798  {
8799  return false;
8800  }
8801 
8802  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8803  {
8804  return false;
8805  }
8806  key.clear();
8807  }
8808  }
8809  else
8810  {
8811  while (get() != 0xFF)
8812  {
8813  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
8814  {
8815  return false;
8816  }
8817 
8818  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8819  {
8820  return false;
8821  }
8822  key.clear();
8823  }
8824  }
8825 
8826  return sax->end_object();
8827  }
8828 
8830  // MsgPack //
8832 
8837  {
8838  switch (get())
8839  {
8840  // EOF
8841  case std::char_traits<char_type>::eof():
8842  return unexpect_eof(input_format_t::msgpack, "value");
8843 
8844  // positive fixint
8845  case 0x00:
8846  case 0x01:
8847  case 0x02:
8848  case 0x03:
8849  case 0x04:
8850  case 0x05:
8851  case 0x06:
8852  case 0x07:
8853  case 0x08:
8854  case 0x09:
8855  case 0x0A:
8856  case 0x0B:
8857  case 0x0C:
8858  case 0x0D:
8859  case 0x0E:
8860  case 0x0F:
8861  case 0x10:
8862  case 0x11:
8863  case 0x12:
8864  case 0x13:
8865  case 0x14:
8866  case 0x15:
8867  case 0x16:
8868  case 0x17:
8869  case 0x18:
8870  case 0x19:
8871  case 0x1A:
8872  case 0x1B:
8873  case 0x1C:
8874  case 0x1D:
8875  case 0x1E:
8876  case 0x1F:
8877  case 0x20:
8878  case 0x21:
8879  case 0x22:
8880  case 0x23:
8881  case 0x24:
8882  case 0x25:
8883  case 0x26:
8884  case 0x27:
8885  case 0x28:
8886  case 0x29:
8887  case 0x2A:
8888  case 0x2B:
8889  case 0x2C:
8890  case 0x2D:
8891  case 0x2E:
8892  case 0x2F:
8893  case 0x30:
8894  case 0x31:
8895  case 0x32:
8896  case 0x33:
8897  case 0x34:
8898  case 0x35:
8899  case 0x36:
8900  case 0x37:
8901  case 0x38:
8902  case 0x39:
8903  case 0x3A:
8904  case 0x3B:
8905  case 0x3C:
8906  case 0x3D:
8907  case 0x3E:
8908  case 0x3F:
8909  case 0x40:
8910  case 0x41:
8911  case 0x42:
8912  case 0x43:
8913  case 0x44:
8914  case 0x45:
8915  case 0x46:
8916  case 0x47:
8917  case 0x48:
8918  case 0x49:
8919  case 0x4A:
8920  case 0x4B:
8921  case 0x4C:
8922  case 0x4D:
8923  case 0x4E:
8924  case 0x4F:
8925  case 0x50:
8926  case 0x51:
8927  case 0x52:
8928  case 0x53:
8929  case 0x54:
8930  case 0x55:
8931  case 0x56:
8932  case 0x57:
8933  case 0x58:
8934  case 0x59:
8935  case 0x5A:
8936  case 0x5B:
8937  case 0x5C:
8938  case 0x5D:
8939  case 0x5E:
8940  case 0x5F:
8941  case 0x60:
8942  case 0x61:
8943  case 0x62:
8944  case 0x63:
8945  case 0x64:
8946  case 0x65:
8947  case 0x66:
8948  case 0x67:
8949  case 0x68:
8950  case 0x69:
8951  case 0x6A:
8952  case 0x6B:
8953  case 0x6C:
8954  case 0x6D:
8955  case 0x6E:
8956  case 0x6F:
8957  case 0x70:
8958  case 0x71:
8959  case 0x72:
8960  case 0x73:
8961  case 0x74:
8962  case 0x75:
8963  case 0x76:
8964  case 0x77:
8965  case 0x78:
8966  case 0x79:
8967  case 0x7A:
8968  case 0x7B:
8969  case 0x7C:
8970  case 0x7D:
8971  case 0x7E:
8972  case 0x7F:
8973  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8974 
8975  // fixmap
8976  case 0x80:
8977  case 0x81:
8978  case 0x82:
8979  case 0x83:
8980  case 0x84:
8981  case 0x85:
8982  case 0x86:
8983  case 0x87:
8984  case 0x88:
8985  case 0x89:
8986  case 0x8A:
8987  case 0x8B:
8988  case 0x8C:
8989  case 0x8D:
8990  case 0x8E:
8991  case 0x8F:
8992  return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
8993 
8994  // fixarray
8995  case 0x90:
8996  case 0x91:
8997  case 0x92:
8998  case 0x93:
8999  case 0x94:
9000  case 0x95:
9001  case 0x96:
9002  case 0x97:
9003  case 0x98:
9004  case 0x99:
9005  case 0x9A:
9006  case 0x9B:
9007  case 0x9C:
9008  case 0x9D:
9009  case 0x9E:
9010  case 0x9F:
9011  return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9012 
9013  // fixstr
9014  case 0xA0:
9015  case 0xA1:
9016  case 0xA2:
9017  case 0xA3:
9018  case 0xA4:
9019  case 0xA5:
9020  case 0xA6:
9021  case 0xA7:
9022  case 0xA8:
9023  case 0xA9:
9024  case 0xAA:
9025  case 0xAB:
9026  case 0xAC:
9027  case 0xAD:
9028  case 0xAE:
9029  case 0xAF:
9030  case 0xB0:
9031  case 0xB1:
9032  case 0xB2:
9033  case 0xB3:
9034  case 0xB4:
9035  case 0xB5:
9036  case 0xB6:
9037  case 0xB7:
9038  case 0xB8:
9039  case 0xB9:
9040  case 0xBA:
9041  case 0xBB:
9042  case 0xBC:
9043  case 0xBD:
9044  case 0xBE:
9045  case 0xBF:
9046  case 0xD9: // str 8
9047  case 0xDA: // str 16
9048  case 0xDB: // str 32
9049  {
9050  string_t s;
9051  return get_msgpack_string(s) && sax->string(s);
9052  }
9053 
9054  case 0xC0: // nil
9055  return sax->null();
9056 
9057  case 0xC2: // false
9058  return sax->boolean(false);
9059 
9060  case 0xC3: // true
9061  return sax->boolean(true);
9062 
9063  case 0xC4: // bin 8
9064  case 0xC5: // bin 16
9065  case 0xC6: // bin 32
9066  case 0xC7: // ext 8
9067  case 0xC8: // ext 16
9068  case 0xC9: // ext 32
9069  case 0xD4: // fixext 1
9070  case 0xD5: // fixext 2
9071  case 0xD6: // fixext 4
9072  case 0xD7: // fixext 8
9073  case 0xD8: // fixext 16
9074  {
9075  binary_t b;
9076  return get_msgpack_binary(b) && sax->binary(b);
9077  }
9078 
9079  case 0xCA: // float 32
9080  {
9081  float number{};
9082  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9083  }
9084 
9085  case 0xCB: // float 64
9086  {
9087  double number{};
9088  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9089  }
9090 
9091  case 0xCC: // uint 8
9092  {
9093  std::uint8_t number{};
9094  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9095  }
9096 
9097  case 0xCD: // uint 16
9098  {
9099  std::uint16_t number{};
9100  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9101  }
9102 
9103  case 0xCE: // uint 32
9104  {
9105  std::uint32_t number{};
9106  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9107  }
9108 
9109  case 0xCF: // uint 64
9110  {
9111  std::uint64_t number{};
9112  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9113  }
9114 
9115  case 0xD0: // int 8
9116  {
9117  std::int8_t number{};
9118  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9119  }
9120 
9121  case 0xD1: // int 16
9122  {
9123  std::int16_t number{};
9124  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9125  }
9126 
9127  case 0xD2: // int 32
9128  {
9129  std::int32_t number{};
9130  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9131  }
9132 
9133  case 0xD3: // int 64
9134  {
9135  std::int64_t number{};
9136  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9137  }
9138 
9139  case 0xDC: // array 16
9140  {
9141  std::uint16_t len{};
9142  return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9143  }
9144 
9145  case 0xDD: // array 32
9146  {
9147  std::uint32_t len{};
9148  return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9149  }
9150 
9151  case 0xDE: // map 16
9152  {
9153  std::uint16_t len{};
9154  return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9155  }
9156 
9157  case 0xDF: // map 32
9158  {
9159  std::uint32_t len{};
9160  return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9161  }
9162 
9163  // negative fixint
9164  case 0xE0:
9165  case 0xE1:
9166  case 0xE2:
9167  case 0xE3:
9168  case 0xE4:
9169  case 0xE5:
9170  case 0xE6:
9171  case 0xE7:
9172  case 0xE8:
9173  case 0xE9:
9174  case 0xEA:
9175  case 0xEB:
9176  case 0xEC:
9177  case 0xED:
9178  case 0xEE:
9179  case 0xEF:
9180  case 0xF0:
9181  case 0xF1:
9182  case 0xF2:
9183  case 0xF3:
9184  case 0xF4:
9185  case 0xF5:
9186  case 0xF6:
9187  case 0xF7:
9188  case 0xF8:
9189  case 0xF9:
9190  case 0xFA:
9191  case 0xFB:
9192  case 0xFC:
9193  case 0xFD:
9194  case 0xFE:
9195  case 0xFF:
9196  return sax->number_integer(static_cast<std::int8_t>(current));
9197 
9198  default: // anything else
9199  {
9200  auto last_token = get_token_string();
9201  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")));
9202  }
9203  }
9204  }
9205 
9217  {
9219  {
9220  return false;
9221  }
9222 
9223  switch (current)
9224  {
9225  // fixstr
9226  case 0xA0:
9227  case 0xA1:
9228  case 0xA2:
9229  case 0xA3:
9230  case 0xA4:
9231  case 0xA5:
9232  case 0xA6:
9233  case 0xA7:
9234  case 0xA8:
9235  case 0xA9:
9236  case 0xAA:
9237  case 0xAB:
9238  case 0xAC:
9239  case 0xAD:
9240  case 0xAE:
9241  case 0xAF:
9242  case 0xB0:
9243  case 0xB1:
9244  case 0xB2:
9245  case 0xB3:
9246  case 0xB4:
9247  case 0xB5:
9248  case 0xB6:
9249  case 0xB7:
9250  case 0xB8:
9251  case 0xB9:
9252  case 0xBA:
9253  case 0xBB:
9254  case 0xBC:
9255  case 0xBD:
9256  case 0xBE:
9257  case 0xBF:
9258  {
9259  return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
9260  }
9261 
9262  case 0xD9: // str 8
9263  {
9264  std::uint8_t len{};
9266  }
9267 
9268  case 0xDA: // str 16
9269  {
9270  std::uint16_t len{};
9272  }
9273 
9274  case 0xDB: // str 32
9275  {
9276  std::uint32_t len{};
9278  }
9279 
9280  default:
9281  {
9282  auto last_token = get_token_string();
9283  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")));
9284  }
9285  }
9286  }
9287 
9299  {
9300  // helper function to set the subtype
9301  auto assign_and_return_true = [&result](std::int8_t subtype)
9302  {
9303  result.set_subtype(static_cast<std::uint8_t>(subtype));
9304  return true;
9305  };
9306 
9307  switch (current)
9308  {
9309  case 0xC4: // bin 8
9310  {
9311  std::uint8_t len{};
9312  return get_number(input_format_t::msgpack, len) &&
9314  }
9315 
9316  case 0xC5: // bin 16
9317  {
9318  std::uint16_t len{};
9319  return get_number(input_format_t::msgpack, len) &&
9321  }
9322 
9323  case 0xC6: // bin 32
9324  {
9325  std::uint32_t len{};
9326  return get_number(input_format_t::msgpack, len) &&
9328  }
9329 
9330  case 0xC7: // ext 8
9331  {
9332  std::uint8_t len{};
9333  std::int8_t subtype{};
9334  return get_number(input_format_t::msgpack, len) &&
9335  get_number(input_format_t::msgpack, subtype) &&
9337  assign_and_return_true(subtype);
9338  }
9339 
9340  case 0xC8: // ext 16
9341  {
9342  std::uint16_t len{};
9343  std::int8_t subtype{};
9344  return get_number(input_format_t::msgpack, len) &&
9345  get_number(input_format_t::msgpack, subtype) &&
9347  assign_and_return_true(subtype);
9348  }
9349 
9350  case 0xC9: // ext 32
9351  {
9352  std::uint32_t len{};
9353  std::int8_t subtype{};
9354  return get_number(input_format_t::msgpack, len) &&
9355  get_number(input_format_t::msgpack, subtype) &&
9357  assign_and_return_true(subtype);
9358  }
9359 
9360  case 0xD4: // fixext 1
9361  {
9362  std::int8_t subtype{};
9363  return get_number(input_format_t::msgpack, subtype) &&
9365  assign_and_return_true(subtype);
9366  }
9367 
9368  case 0xD5: // fixext 2
9369  {
9370  std::int8_t subtype{};
9371  return get_number(input_format_t::msgpack, subtype) &&
9373  assign_and_return_true(subtype);
9374  }
9375 
9376  case 0xD6: // fixext 4
9377  {
9378  std::int8_t subtype{};
9379  return get_number(input_format_t::msgpack, subtype) &&
9381  assign_and_return_true(subtype);
9382  }
9383 
9384  case 0xD7: // fixext 8
9385  {
9386  std::int8_t subtype{};
9387  return get_number(input_format_t::msgpack, subtype) &&
9389  assign_and_return_true(subtype);
9390  }
9391 
9392  case 0xD8: // fixext 16
9393  {
9394  std::int8_t subtype{};
9395  return get_number(input_format_t::msgpack, subtype) &&
9397  assign_and_return_true(subtype);
9398  }
9399 
9400  default: // LCOV_EXCL_LINE
9401  return false; // LCOV_EXCL_LINE
9402  }
9403  }
9404 
9409  bool get_msgpack_array(const std::size_t len)
9410  {
9411  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9412  {
9413  return false;
9414  }
9415 
9416  for (std::size_t i = 0; i < len; ++i)
9417  {
9419  {
9420  return false;
9421  }
9422  }
9423 
9424  return sax->end_array();
9425  }
9426 
9431  bool get_msgpack_object(const std::size_t len)
9432  {
9433  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9434  {
9435  return false;
9436  }
9437 
9438  string_t key;
9439  for (std::size_t i = 0; i < len; ++i)
9440  {
9441  get();
9443  {
9444  return false;
9445  }
9446 
9448  {
9449  return false;
9450  }
9451  key.clear();
9452  }
9453 
9454  return sax->end_object();
9455  }
9456 
9458  // UBJSON //
9460 
9468  bool parse_ubjson_internal(const bool get_char = true)
9469  {
9470  return get_ubjson_value(get_char ? get_ignore_noop() : current);
9471  }
9472 
9487  bool get_ubjson_string(string_t& result, const bool get_char = true)
9488  {
9489  if (get_char)
9490  {
9491  get(); // TODO(niels): may we ignore N here?
9492  }
9493 
9495  {
9496  return false;
9497  }
9498 
9499  switch (current)
9500  {
9501  case 'U':
9502  {
9503  std::uint8_t len{};
9505  }
9506 
9507  case 'i':
9508  {
9509  std::int8_t len{};
9511  }
9512 
9513  case 'I':
9514  {
9515  std::int16_t len{};
9517  }
9518 
9519  case 'l':
9520  {
9521  std::int32_t len{};
9523  }
9524 
9525  case 'L':
9526  {
9527  std::int64_t len{};
9529  }
9530 
9531  default:
9532  auto last_token = get_token_string();
9533  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")));
9534  }
9535  }
9536 
9541  bool get_ubjson_size_value(std::size_t& result)
9542  {
9543  switch (get_ignore_noop())
9544  {
9545  case 'U':
9546  {
9547  std::uint8_t number{};
9549  {
9550  return false;
9551  }
9552  result = static_cast<std::size_t>(number);
9553  return true;
9554  }
9555 
9556  case 'i':
9557  {
9558  std::int8_t number{};
9560  {
9561  return false;
9562  }
9563  result = static_cast<std::size_t>(number);
9564  return true;
9565  }
9566 
9567  case 'I':
9568  {
9569  std::int16_t number{};
9571  {
9572  return false;
9573  }
9574  result = static_cast<std::size_t>(number);
9575  return true;
9576  }
9577 
9578  case 'l':
9579  {
9580  std::int32_t number{};
9582  {
9583  return false;
9584  }
9585  result = static_cast<std::size_t>(number);
9586  return true;
9587  }
9588 
9589  case 'L':
9590  {
9591  std::int64_t number{};
9593  {
9594  return false;
9595  }
9596  result = static_cast<std::size_t>(number);
9597  return true;
9598  }
9599 
9600  default:
9601  {
9602  auto last_token = get_token_string();
9603  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")));
9604  }
9605  }
9606  }
9607 
9618  bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
9619  {
9620  result.first = string_t::npos; // size
9621  result.second = 0; // type
9622 
9623  get_ignore_noop();
9624 
9625  if (current == '$')
9626  {
9627  result.second = get(); // must not ignore 'N', because 'N' maybe the type
9629  {
9630  return false;
9631  }
9632 
9633  get_ignore_noop();
9634  if (JSON_HEDLEY_UNLIKELY(current != '#'))
9635  {
9637  {
9638  return false;
9639  }
9640  auto last_token = get_token_string();
9641  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")));
9642  }
9643 
9644  return get_ubjson_size_value(result.first);
9645  }
9646 
9647  if (current == '#')
9648  {
9649  return get_ubjson_size_value(result.first);
9650  }
9651 
9652  return true;
9653  }
9654 
9659  bool get_ubjson_value(const char_int_type prefix)
9660  {
9661  switch (prefix)
9662  {
9663  case std::char_traits<char_type>::eof(): // EOF
9664  return unexpect_eof(input_format_t::ubjson, "value");
9665 
9666  case 'T': // true
9667  return sax->boolean(true);
9668  case 'F': // false
9669  return sax->boolean(false);
9670 
9671  case 'Z': // null
9672  return sax->null();
9673 
9674  case 'U':
9675  {
9676  std::uint8_t number{};
9677  return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
9678  }
9679 
9680  case 'i':
9681  {
9682  std::int8_t number{};
9683  return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9684  }
9685 
9686  case 'I':
9687  {
9688  std::int16_t number{};
9689  return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9690  }
9691 
9692  case 'l':
9693  {
9694  std::int32_t number{};
9695  return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9696  }
9697 
9698  case 'L':
9699  {
9700  std::int64_t number{};
9701  return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9702  }
9703 
9704  case 'd':
9705  {
9706  float number{};
9707  return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9708  }
9709 
9710  case 'D':
9711  {
9712  double number{};
9713  return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9714  }
9715 
9716  case 'H':
9717  {
9719  }
9720 
9721  case 'C': // char
9722  {
9723  get();
9725  {
9726  return false;
9727  }
9728  if (JSON_HEDLEY_UNLIKELY(current > 127))
9729  {
9730  auto last_token = get_token_string();
9731  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")));
9732  }
9733  string_t s(1, static_cast<typename string_t::value_type>(current));
9734  return sax->string(s);
9735  }
9736 
9737  case 'S': // string
9738  {
9739  string_t s;
9740  return get_ubjson_string(s) && sax->string(s);
9741  }
9742 
9743  case '[': // array
9744  return get_ubjson_array();
9745 
9746  case '{': // object
9747  return get_ubjson_object();
9748 
9749  default: // anything else
9750  {
9751  auto last_token = get_token_string();
9752  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")));
9753  }
9754  }
9755  }
9756 
9761  {
9762  std::pair<std::size_t, char_int_type> size_and_type;
9763  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
9764  {
9765  return false;
9766  }
9767 
9768  if (size_and_type.first != string_t::npos)
9769  {
9770  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
9771  {
9772  return false;
9773  }
9774 
9775  if (size_and_type.second != 0)
9776  {
9777  if (size_and_type.second != 'N')
9778  {
9779  for (std::size_t i = 0; i < size_and_type.first; ++i)
9780  {
9781  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
9782  {
9783  return false;
9784  }
9785  }
9786  }
9787  }
9788  else
9789  {
9790  for (std::size_t i = 0; i < size_and_type.first; ++i)
9791  {
9793  {
9794  return false;
9795  }
9796  }
9797  }
9798  }
9799  else
9800  {
9801  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
9802  {
9803  return false;
9804  }
9805 
9806  while (current != ']')
9807  {
9809  {
9810  return false;
9811  }
9812  get_ignore_noop();
9813  }
9814  }
9815 
9816  return sax->end_array();
9817  }
9818 
9823  {
9824  std::pair<std::size_t, char_int_type> size_and_type;
9825  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
9826  {
9827  return false;
9828  }
9829 
9830  string_t key;
9831  if (size_and_type.first != string_t::npos)
9832  {
9833  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
9834  {
9835  return false;
9836  }
9837 
9838  if (size_and_type.second != 0)
9839  {
9840  for (std::size_t i = 0; i < size_and_type.first; ++i)
9841  {
9843  {
9844  return false;
9845  }
9846  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
9847  {
9848  return false;
9849  }
9850  key.clear();
9851  }
9852  }
9853  else
9854  {
9855  for (std::size_t i = 0; i < size_and_type.first; ++i)
9856  {
9858  {
9859  return false;
9860  }
9862  {
9863  return false;
9864  }
9865  key.clear();
9866  }
9867  }
9868  }
9869  else
9870  {
9871  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
9872  {
9873  return false;
9874  }
9875 
9876  while (current != '}')
9877  {
9878  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
9879  {
9880  return false;
9881  }
9883  {
9884  return false;
9885  }
9886  get_ignore_noop();
9887  key.clear();
9888  }
9889  }
9890 
9891  return sax->end_object();
9892  }
9893 
9894  // Note, no reader for UBJSON binary types is implemented because they do
9895  // not exist
9896 
9898  {
9899  // get size of following number string
9900  std::size_t size{};
9901  auto res = get_ubjson_size_value(size);
9902  if (JSON_HEDLEY_UNLIKELY(!res))
9903  {
9904  return res;
9905  }
9906 
9907  // get number string
9908  std::vector<char> number_vector;
9909  for (std::size_t i = 0; i < size; ++i)
9910  {
9911  get();
9913  {
9914  return false;
9915  }
9916  number_vector.push_back(static_cast<char>(current));
9917  }
9918 
9919  // parse number string
9920  auto number_ia = detail::input_adapter(std::forward<decltype(number_vector)>(number_vector));
9921  auto number_lexer = detail::lexer<BasicJsonType, decltype(number_ia)>(std::move(number_ia), false);
9922  const auto result_number = number_lexer.scan();
9923  const auto number_string = number_lexer.get_token_string();
9924  const auto result_remainder = number_lexer.scan();
9925 
9926  using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
9927 
9928  if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
9929  {
9930  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")));
9931  }
9932 
9933  switch (result_number)
9934  {
9935  case token_type::value_integer:
9936  return sax->number_integer(number_lexer.get_number_integer());
9937  case token_type::value_unsigned:
9938  return sax->number_unsigned(number_lexer.get_number_unsigned());
9939  case token_type::value_float:
9940  return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
9941  default:
9942  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")));
9943  }
9944  }
9945 
9947  // Utility functions //
9949 
9960  {
9961  ++chars_read;
9962  return current = ia.get_character();
9963  }
9964 
9969  {
9970  do
9971  {
9972  get();
9973  }
9974  while (current == 'N');
9975 
9976  return current;
9977  }
9978 
9979  /*
9980  @brief read a number from the input
9981 
9982  @tparam NumberType the type of the number
9983  @param[in] format the current format (for diagnostics)
9984  @param[out] result number of type @a NumberType
9985 
9986  @return whether conversion completed
9987 
9988  @note This function needs to respect the system's endianess, because
9989  bytes in CBOR, MessagePack, and UBJSON are stored in network order
9990  (big endian) and therefore need reordering on little endian systems.
9991  */
9992  template<typename NumberType, bool InputIsLittleEndian = false>
9993  bool get_number(const input_format_t format, NumberType& result)
9994  {
9995  // step 1: read input into array with system's byte order
9996  std::array<std::uint8_t, sizeof(NumberType)> vec;
9997  for (std::size_t i = 0; i < sizeof(NumberType); ++i)
9998  {
9999  get();
10000  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
10001  {
10002  return false;
10003  }
10004 
10005  // reverse byte order prior to conversion if necessary
10006  if (is_little_endian != InputIsLittleEndian)
10007  {
10008  vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
10009  }
10010  else
10011  {
10012  vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
10013  }
10014  }
10015 
10016  // step 2: convert array into number of type T and return
10017  std::memcpy(&result, vec.data(), sizeof(NumberType));
10018  return true;
10019  }
10020 
10035  template<typename NumberType>
10036  bool get_string(const input_format_t format,
10037  const NumberType len,
10038  string_t& result)
10039  {
10040  bool success = true;
10041  for (NumberType i = 0; i < len; i++)
10042  {
10043  get();
10044  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
10045  {
10046  success = false;
10047  break;
10048  }
10049  result.push_back(static_cast<typename string_t::value_type>(current));
10050  };
10051  return success;
10052  }
10053 
10068  template<typename NumberType>
10069  bool get_binary(const input_format_t format,
10070  const NumberType len,
10071  binary_t& result)
10072  {
10073  bool success = true;
10074  for (NumberType i = 0; i < len; i++)
10075  {
10076  get();
10077  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10078  {
10079  success = false;
10080  break;
10081  }
10082  result.push_back(static_cast<std::uint8_t>(current));
10083  }
10084  return success;
10085  }
10086 
10093  bool unexpect_eof(const input_format_t format, const char* context) const
10094  {
10095  if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
10096  {
10097  return sax->parse_error(chars_read, "<end of file>",
10098  parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
10099  }
10100  return true;
10101  }
10102 
10106  std::string get_token_string() const
10107  {
10108  std::array<char, 3> cr{{}};
10109  (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current));
10110  return std::string{cr.data()};
10111  }
10112 
10119  std::string exception_message(const input_format_t format,
10120  const std::string& detail,
10121  const std::string& context) const
10122  {
10123  std::string error_msg = "syntax error while parsing ";
10124 
10125  switch (format)
10126  {
10127  case input_format_t::cbor:
10128  error_msg += "CBOR";
10129  break;
10130 
10132  error_msg += "MessagePack";
10133  break;
10134 
10136  error_msg += "UBJSON";
10137  break;
10138 
10139  case input_format_t::bson:
10140  error_msg += "BSON";
10141  break;
10142 
10143  default: // LCOV_EXCL_LINE
10144  JSON_ASSERT(false); // LCOV_EXCL_LINE
10145  }
10146 
10147  return error_msg + " " + context + ": " + detail;
10148  }
10149 
10150  private:
10152  InputAdapterType ia;
10153 
10155  char_int_type current = std::char_traits<char_type>::eof();
10156 
10158  std::size_t chars_read = 0;
10159 
10162 
10164  json_sax_t* sax = nullptr;
10165 };
10166 } // namespace detail
10167 } // namespace nlohmann
10168 
10169 // #include <nlohmann/detail/input/input_adapters.hpp>
10170 
10171 // #include <nlohmann/detail/input/lexer.hpp>
10172 
10173 // #include <nlohmann/detail/input/parser.hpp>
10174 
10175 
10176 #include <cmath> // isfinite
10177 #include <cstdint> // uint8_t
10178 #include <functional> // function
10179 #include <string> // string
10180 #include <utility> // move
10181 #include <vector> // vector
10182 
10183 // #include <nlohmann/detail/exceptions.hpp>
10184 
10185 // #include <nlohmann/detail/input/input_adapters.hpp>
10186 
10187 // #include <nlohmann/detail/input/json_sax.hpp>
10188 
10189 // #include <nlohmann/detail/input/lexer.hpp>
10190 
10191 // #include <nlohmann/detail/macro_scope.hpp>
10192 
10193 // #include <nlohmann/detail/meta/is_sax.hpp>
10194 
10195 // #include <nlohmann/detail/value_t.hpp>
10196 
10197 
10198 namespace nlohmann
10199 {
10200 namespace detail
10201 {
10203 // parser //
10205 
10206 enum class parse_event_t : uint8_t
10207 {
10209  object_start,
10211  object_end,
10213  array_start,
10215  array_end,
10217  key,
10219  value
10220 };
10221 
10222 template<typename BasicJsonType>
10224  std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
10225 
10231 template<typename BasicJsonType, typename InputAdapterType>
10232 class parser
10233 {
10234  using number_integer_t = typename BasicJsonType::number_integer_t;
10235  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10236  using number_float_t = typename BasicJsonType::number_float_t;
10237  using string_t = typename BasicJsonType::string_t;
10240 
10241  public:
10243  explicit parser(InputAdapterType&& adapter,
10244  const parser_callback_t<BasicJsonType> cb = nullptr,
10245  const bool allow_exceptions_ = true,
10246  const bool skip_comments = false)
10247  : callback(cb)
10248  , m_lexer(std::move(adapter), skip_comments)
10249  , allow_exceptions(allow_exceptions_)
10250  {
10251  // read first token
10252  get_token();
10253  }
10254 
10265  void parse(const bool strict, BasicJsonType& result)
10266  {
10267  if (callback)
10268  {
10270  sax_parse_internal(&sdp);
10271  result.assert_invariant();
10272 
10273  // in strict mode, input must be completely read
10274  if (strict && (get_token() != token_type::end_of_input))
10275  {
10276  sdp.parse_error(m_lexer.get_position(),
10277  m_lexer.get_token_string(),
10278  parse_error::create(101, m_lexer.get_position(),
10279  exception_message(token_type::end_of_input, "value")));
10280  }
10281 
10282  // in case of an error, return discarded value
10283  if (sdp.is_errored())
10284  {
10286  return;
10287  }
10288 
10289  // set top-level value to null if it was discarded by the callback
10290  // function
10291  if (result.is_discarded())
10292  {
10293  result = nullptr;
10294  }
10295  }
10296  else
10297  {
10299  sax_parse_internal(&sdp);
10300  result.assert_invariant();
10301 
10302  // in strict mode, input must be completely read
10303  if (strict && (get_token() != token_type::end_of_input))
10304  {
10305  sdp.parse_error(m_lexer.get_position(),
10306  m_lexer.get_token_string(),
10307  parse_error::create(101, m_lexer.get_position(),
10308  exception_message(token_type::end_of_input, "value")));
10309  }
10310 
10311  // in case of an error, return discarded value
10312  if (sdp.is_errored())
10313  {
10315  return;
10316  }
10317  }
10318  }
10319 
10326  bool accept(const bool strict = true)
10327  {
10328  json_sax_acceptor<BasicJsonType> sax_acceptor;
10329  return sax_parse(&sax_acceptor, strict);
10330  }
10331 
10332  template<typename SAX>
10334  bool sax_parse(SAX* sax, const bool strict = true)
10335  {
10337  const bool result = sax_parse_internal(sax);
10338 
10339  // strict mode: next byte must be EOF
10340  if (result && strict && (get_token() != token_type::end_of_input))
10341  {
10342  return sax->parse_error(m_lexer.get_position(),
10343  m_lexer.get_token_string(),
10344  parse_error::create(101, m_lexer.get_position(),
10345  exception_message(token_type::end_of_input, "value")));
10346  }
10347 
10348  return result;
10349  }
10350 
10351  private:
10352  template<typename SAX>
10354  bool sax_parse_internal(SAX* sax)
10355  {
10356  // stack to remember the hierarchy of structured values we are parsing
10357  // true = array; false = object
10358  std::vector<bool> states;
10359  // value to avoid a goto (see comment where set to true)
10360  bool skip_to_state_evaluation = false;
10361 
10362  while (true)
10363  {
10364  if (!skip_to_state_evaluation)
10365  {
10366  // invariant: get_token() was called before each iteration
10367  switch (last_token)
10368  {
10369  case token_type::begin_object:
10370  {
10371  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10372  {
10373  return false;
10374  }
10375 
10376  // closing } -> we are done
10377  if (get_token() == token_type::end_object)
10378  {
10379  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
10380  {
10381  return false;
10382  }
10383  break;
10384  }
10385 
10386  // parse key
10387  if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
10388  {
10389  return sax->parse_error(m_lexer.get_position(),
10390  m_lexer.get_token_string(),
10391  parse_error::create(101, m_lexer.get_position(),
10392  exception_message(token_type::value_string, "object key")));
10393  }
10394  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
10395  {
10396  return false;
10397  }
10398 
10399  // parse separator (:)
10400  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10401  {
10402  return sax->parse_error(m_lexer.get_position(),
10403  m_lexer.get_token_string(),
10404  parse_error::create(101, m_lexer.get_position(),
10405  exception_message(token_type::name_separator, "object separator")));
10406  }
10407 
10408  // remember we are now inside an object
10409  states.push_back(false);
10410 
10411  // parse values
10412  get_token();
10413  continue;
10414  }
10415 
10416  case token_type::begin_array:
10417  {
10418  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10419  {
10420  return false;
10421  }
10422 
10423  // closing ] -> we are done
10424  if (get_token() == token_type::end_array)
10425  {
10426  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
10427  {
10428  return false;
10429  }
10430  break;
10431  }
10432 
10433  // remember we are now inside an array
10434  states.push_back(true);
10435 
10436  // parse values (no need to call get_token)
10437  continue;
10438  }
10439 
10440  case token_type::value_float:
10441  {
10442  const auto res = m_lexer.get_number_float();
10443 
10444  if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
10445  {
10446  return sax->parse_error(m_lexer.get_position(),
10447  m_lexer.get_token_string(),
10448  out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
10449  }
10450 
10451  if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
10452  {
10453  return false;
10454  }
10455 
10456  break;
10457  }
10458 
10459  case token_type::literal_false:
10460  {
10461  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
10462  {
10463  return false;
10464  }
10465  break;
10466  }
10467 
10468  case token_type::literal_null:
10469  {
10470  if (JSON_HEDLEY_UNLIKELY(!sax->null()))
10471  {
10472  return false;
10473  }
10474  break;
10475  }
10476 
10477  case token_type::literal_true:
10478  {
10479  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
10480  {
10481  return false;
10482  }
10483  break;
10484  }
10485 
10486  case token_type::value_integer:
10487  {
10488  if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
10489  {
10490  return false;
10491  }
10492  break;
10493  }
10494 
10495  case token_type::value_string:
10496  {
10497  if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
10498  {
10499  return false;
10500  }
10501  break;
10502  }
10503 
10504  case token_type::value_unsigned:
10505  {
10506  if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
10507  {
10508  return false;
10509  }
10510  break;
10511  }
10512 
10513  case token_type::parse_error:
10514  {
10515  // using "uninitialized" to avoid "expected" message
10516  return sax->parse_error(m_lexer.get_position(),
10517  m_lexer.get_token_string(),
10518  parse_error::create(101, m_lexer.get_position(),
10519  exception_message(token_type::uninitialized, "value")));
10520  }
10521 
10522  default: // the last token was unexpected
10523  {
10524  return sax->parse_error(m_lexer.get_position(),
10525  m_lexer.get_token_string(),
10526  parse_error::create(101, m_lexer.get_position(),
10527  exception_message(token_type::literal_or_value, "value")));
10528  }
10529  }
10530  }
10531  else
10532  {
10533  skip_to_state_evaluation = false;
10534  }
10535 
10536  // we reached this line after we successfully parsed a value
10537  if (states.empty())
10538  {
10539  // empty stack: we reached the end of the hierarchy: done
10540  return true;
10541  }
10542 
10543  if (states.back()) // array
10544  {
10545  // comma -> next value
10546  if (get_token() == token_type::value_separator)
10547  {
10548  // parse a new value
10549  get_token();
10550  continue;
10551  }
10552 
10553  // closing ]
10554  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
10555  {
10556  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
10557  {
10558  return false;
10559  }
10560 
10561  // We are done with this array. Before we can parse a
10562  // new value, we need to evaluate the new state first.
10563  // By setting skip_to_state_evaluation to false, we
10564  // are effectively jumping to the beginning of this if.
10565  JSON_ASSERT(!states.empty());
10566  states.pop_back();
10567  skip_to_state_evaluation = true;
10568  continue;
10569  }
10570 
10571  return sax->parse_error(m_lexer.get_position(),
10572  m_lexer.get_token_string(),
10573  parse_error::create(101, m_lexer.get_position(),
10574  exception_message(token_type::end_array, "array")));
10575  }
10576  else // object
10577  {
10578  // comma -> next value
10579  if (get_token() == token_type::value_separator)
10580  {
10581  // parse key
10582  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
10583  {
10584  return sax->parse_error(m_lexer.get_position(),
10585  m_lexer.get_token_string(),
10586  parse_error::create(101, m_lexer.get_position(),
10587  exception_message(token_type::value_string, "object key")));
10588  }
10589 
10590  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
10591  {
10592  return false;
10593  }
10594 
10595  // parse separator (:)
10596  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10597  {
10598  return sax->parse_error(m_lexer.get_position(),
10599  m_lexer.get_token_string(),
10600  parse_error::create(101, m_lexer.get_position(),
10601  exception_message(token_type::name_separator, "object separator")));
10602  }
10603 
10604  // parse values
10605  get_token();
10606  continue;
10607  }
10608 
10609  // closing }
10610  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
10611  {
10612  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
10613  {
10614  return false;
10615  }
10616 
10617  // We are done with this object. Before we can parse a
10618  // new value, we need to evaluate the new state first.
10619  // By setting skip_to_state_evaluation to false, we
10620  // are effectively jumping to the beginning of this if.
10621  JSON_ASSERT(!states.empty());
10622  states.pop_back();
10623  skip_to_state_evaluation = true;
10624  continue;
10625  }
10626 
10627  return sax->parse_error(m_lexer.get_position(),
10628  m_lexer.get_token_string(),
10629  parse_error::create(101, m_lexer.get_position(),
10630  exception_message(token_type::end_object, "object")));
10631  }
10632  }
10633  }
10634 
10637  {
10638  return last_token = m_lexer.scan();
10639  }
10640 
10641  std::string exception_message(const token_type expected, const std::string& context)
10642  {
10643  std::string error_msg = "syntax error ";
10644 
10645  if (!context.empty())
10646  {
10647  error_msg += "while parsing " + context + " ";
10648  }
10649 
10650  error_msg += "- ";
10651 
10652  if (last_token == token_type::parse_error)
10653  {
10654  error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
10655  m_lexer.get_token_string() + "'";
10656  }
10657  else
10658  {
10659  error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
10660  }
10661 
10662  if (expected != token_type::uninitialized)
10663  {
10664  error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
10665  }
10666 
10667  return error_msg;
10668  }
10669 
10670  private:
10674  token_type last_token = token_type::uninitialized;
10678  const bool allow_exceptions = true;
10679 };
10680 } // namespace detail
10681 } // namespace nlohmann
10682 
10683 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
10684 
10685 
10686 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10687 
10688 
10689 #include <cstddef> // ptrdiff_t
10690 #include <limits> // numeric_limits
10691 
10692 namespace nlohmann
10693 {
10694 namespace detail
10695 {
10696 /*
10697 @brief an iterator for primitive JSON types
10698 
10699 This class models an iterator for primitive JSON types (boolean, number,
10700 string). It's only purpose is to allow the iterator/const_iterator classes
10701 to "iterate" over primitive values. Internally, the iterator is modeled by
10702 a `difference_type` variable. Value begin_value (`0`) models the begin,
10703 end_value (`1`) models past the end.
10704 */
10706 {
10707  private:
10708  using difference_type = std::ptrdiff_t;
10709  static constexpr difference_type begin_value = 0;
10710  static constexpr difference_type end_value = begin_value + 1;
10711 
10715 
10716  public:
10717  constexpr difference_type get_value() const noexcept
10718  {
10719  return m_it;
10720  }
10721 
10723  void set_begin() noexcept
10724  {
10725  m_it = begin_value;
10726  }
10727 
10729  void set_end() noexcept
10730  {
10731  m_it = end_value;
10732  }
10733 
10735  constexpr bool is_begin() const noexcept
10736  {
10737  return m_it == begin_value;
10738  }
10739 
10741  constexpr bool is_end() const noexcept
10742  {
10743  return m_it == end_value;
10744  }
10745 
10746  friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10747  {
10748  return lhs.m_it == rhs.m_it;
10749  }
10750 
10751  friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10752  {
10753  return lhs.m_it < rhs.m_it;
10754  }
10755 
10757  {
10758  auto result = *this;
10759  result += n;
10760  return result;
10761  }
10762 
10764  {
10765  return lhs.m_it - rhs.m_it;
10766  }
10767 
10769  {
10770  ++m_it;
10771  return *this;
10772  }
10773 
10774  primitive_iterator_t const operator++(int) noexcept
10775  {
10776  auto result = *this;
10777  ++m_it;
10778  return result;
10779  }
10780 
10782  {
10783  --m_it;
10784  return *this;
10785  }
10786 
10787  primitive_iterator_t const operator--(int) noexcept
10788  {
10789  auto result = *this;
10790  --m_it;
10791  return result;
10792  }
10793 
10795  {
10796  m_it += n;
10797  return *this;
10798  }
10799 
10801  {
10802  m_it -= n;
10803  return *this;
10804  }
10805 };
10806 } // namespace detail
10807 } // namespace nlohmann
10808 
10809 
10810 namespace nlohmann
10811 {
10812 namespace detail
10813 {
10820 template<typename BasicJsonType> struct internal_iterator
10821 {
10823  typename BasicJsonType::object_t::iterator object_iterator {};
10825  typename BasicJsonType::array_t::iterator array_iterator {};
10828 };
10829 } // namespace detail
10830 } // namespace nlohmann
10831 
10832 // #include <nlohmann/detail/iterators/iter_impl.hpp>
10833 
10834 
10835 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
10836 #include <type_traits> // conditional, is_const, remove_const
10837 
10838 // #include <nlohmann/detail/exceptions.hpp>
10839 
10840 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
10841 
10842 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10843 
10844 // #include <nlohmann/detail/macro_scope.hpp>
10845 
10846 // #include <nlohmann/detail/meta/cpp_future.hpp>
10847 
10848 // #include <nlohmann/detail/meta/type_traits.hpp>
10849 
10850 // #include <nlohmann/detail/value_t.hpp>
10851 
10852 
10853 namespace nlohmann
10854 {
10855 namespace detail
10856 {
10857 // forward declare, to be able to friend it later on
10858 template<typename IteratorType> class iteration_proxy;
10859 template<typename IteratorType> class iteration_proxy_value;
10860 
10877 template<typename BasicJsonType>
10879 {
10881  friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
10885 
10886  using object_t = typename BasicJsonType::object_t;
10887  using array_t = typename BasicJsonType::array_t;
10888  // make sure BasicJsonType is basic_json or const basic_json
10889  static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
10890  "iter_impl only accepts (const) basic_json");
10891 
10892  public:
10893 
10899  using iterator_category = std::bidirectional_iterator_tag;
10900 
10902  using value_type = typename BasicJsonType::value_type;
10904  using difference_type = typename BasicJsonType::difference_type;
10906  using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
10907  typename BasicJsonType::const_pointer,
10908  typename BasicJsonType::pointer>::type;
10910  using reference =
10911  typename std::conditional<std::is_const<BasicJsonType>::value,
10912  typename BasicJsonType::const_reference,
10913  typename BasicJsonType::reference>::type;
10914 
10916  iter_impl() = default;
10917 
10924  explicit iter_impl(pointer object) noexcept : m_object(object)
10925  {
10926  JSON_ASSERT(m_object != nullptr);
10927 
10928  switch (m_object->m_type)
10929  {
10930  case value_t::object:
10931  {
10932  m_it.object_iterator = typename object_t::iterator();
10933  break;
10934  }
10935 
10936  case value_t::array:
10937  {
10938  m_it.array_iterator = typename array_t::iterator();
10939  break;
10940  }
10941 
10942  default:
10943  {
10945  break;
10946  }
10947  }
10948  }
10949 
10967  : m_object(other.m_object), m_it(other.m_it)
10968  {}
10969 
10977  {
10978  m_object = other.m_object;
10979  m_it = other.m_it;
10980  return *this;
10981  }
10982 
10988  iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
10989  : m_object(other.m_object), m_it(other.m_it)
10990  {}
10991 
10998  iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
10999  {
11000  m_object = other.m_object;
11001  m_it = other.m_it;
11002  return *this;
11003  }
11004 
11010  void set_begin() noexcept
11011  {
11012  JSON_ASSERT(m_object != nullptr);
11013 
11014  switch (m_object->m_type)
11015  {
11016  case value_t::object:
11017  {
11018  m_it.object_iterator = m_object->m_value.object->begin();
11019  break;
11020  }
11021 
11022  case value_t::array:
11023  {
11024  m_it.array_iterator = m_object->m_value.array->begin();
11025  break;
11026  }
11027 
11028  case value_t::null:
11029  {
11030  // set to end so begin()==end() is true: null is empty
11032  break;
11033  }
11034 
11035  default:
11036  {
11038  break;
11039  }
11040  }
11041  }
11042 
11047  void set_end() noexcept
11048  {
11049  JSON_ASSERT(m_object != nullptr);
11050 
11051  switch (m_object->m_type)
11052  {
11053  case value_t::object:
11054  {
11055  m_it.object_iterator = m_object->m_value.object->end();
11056  break;
11057  }
11058 
11059  case value_t::array:
11060  {
11061  m_it.array_iterator = m_object->m_value.array->end();
11062  break;
11063  }
11064 
11065  default:
11066  {
11068  break;
11069  }
11070  }
11071  }
11072 
11073  public:
11079  {
11080  JSON_ASSERT(m_object != nullptr);
11081 
11082  switch (m_object->m_type)
11083  {
11084  case value_t::object:
11085  {
11086  JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11087  return m_it.object_iterator->second;
11088  }
11089 
11090  case value_t::array:
11091  {
11092  JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11093  return *m_it.array_iterator;
11094  }
11095 
11096  case value_t::null:
11097  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11098 
11099  default:
11100  {
11102  {
11103  return *m_object;
11104  }
11105 
11106  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11107  }
11108  }
11109  }
11110 
11116  {
11117  JSON_ASSERT(m_object != nullptr);
11118 
11119  switch (m_object->m_type)
11120  {
11121  case value_t::object:
11122  {
11123  JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11124  return &(m_it.object_iterator->second);
11125  }
11126 
11127  case value_t::array:
11128  {
11129  JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11130  return &*m_it.array_iterator;
11131  }
11132 
11133  default:
11134  {
11136  {
11137  return m_object;
11138  }
11139 
11140  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11141  }
11142  }
11143  }
11144 
11150  {
11151  auto result = *this;
11152  ++(*this);
11153  return result;
11154  }
11155 
11161  {
11162  JSON_ASSERT(m_object != nullptr);
11163 
11164  switch (m_object->m_type)
11165  {
11166  case value_t::object:
11167  {
11168  std::advance(m_it.object_iterator, 1);
11169  break;
11170  }
11171 
11172  case value_t::array:
11173  {
11174  std::advance(m_it.array_iterator, 1);
11175  break;
11176  }
11177 
11178  default:
11179  {
11181  break;
11182  }
11183  }
11184 
11185  return *this;
11186  }
11187 
11193  {
11194  auto result = *this;
11195  --(*this);
11196  return result;
11197  }
11198 
11204  {
11205  JSON_ASSERT(m_object != nullptr);
11206 
11207  switch (m_object->m_type)
11208  {
11209  case value_t::object:
11210  {
11211  std::advance(m_it.object_iterator, -1);
11212  break;
11213  }
11214 
11215  case value_t::array:
11216  {
11217  std::advance(m_it.array_iterator, -1);
11218  break;
11219  }
11220 
11221  default:
11222  {
11224  break;
11225  }
11226  }
11227 
11228  return *this;
11229  }
11230 
11235  bool operator==(const iter_impl& other) const
11236  {
11237  // if objects are not the same, the comparison is undefined
11238  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11239  {
11240  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
11241  }
11242 
11243  JSON_ASSERT(m_object != nullptr);
11244 
11245  switch (m_object->m_type)
11246  {
11247  case value_t::object:
11248  return (m_it.object_iterator == other.m_it.object_iterator);
11249 
11250  case value_t::array:
11251  return (m_it.array_iterator == other.m_it.array_iterator);
11252 
11253  default:
11254  return (m_it.primitive_iterator == other.m_it.primitive_iterator);
11255  }
11256  }
11257 
11262  bool operator!=(const iter_impl& other) const
11263  {
11264  return !operator==(other);
11265  }
11266 
11271  bool operator<(const iter_impl& other) const
11272  {
11273  // if objects are not the same, the comparison is undefined
11274  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11275  {
11276  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
11277  }
11278 
11279  JSON_ASSERT(m_object != nullptr);
11280 
11281  switch (m_object->m_type)
11282  {
11283  case value_t::object:
11284  JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
11285 
11286  case value_t::array:
11287  return (m_it.array_iterator < other.m_it.array_iterator);
11288 
11289  default:
11291  }
11292  }
11293 
11298  bool operator<=(const iter_impl& other) const
11299  {
11300  return !other.operator < (*this);
11301  }
11302 
11307  bool operator>(const iter_impl& other) const
11308  {
11309  return !operator<=(other);
11310  }
11311 
11316  bool operator>=(const iter_impl& other) const
11317  {
11318  return !operator<(other);
11319  }
11320 
11326  {
11327  JSON_ASSERT(m_object != nullptr);
11328 
11329  switch (m_object->m_type)
11330  {
11331  case value_t::object:
11332  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
11333 
11334  case value_t::array:
11335  {
11336  std::advance(m_it.array_iterator, i);
11337  break;
11338  }
11339 
11340  default:
11341  {
11342  m_it.primitive_iterator += i;
11343  break;
11344  }
11345  }
11346 
11347  return *this;
11348  }
11349 
11355  {
11356  return operator+=(-i);
11357  }
11358 
11364  {
11365  auto result = *this;
11366  result += i;
11367  return result;
11368  }
11369 
11375  {
11376  auto result = it;
11377  result += i;
11378  return result;
11379  }
11380 
11386  {
11387  auto result = *this;
11388  result -= i;
11389  return result;
11390  }
11391 
11397  {
11398  JSON_ASSERT(m_object != nullptr);
11399 
11400  switch (m_object->m_type)
11401  {
11402  case value_t::object:
11403  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
11404 
11405  case value_t::array:
11406  return m_it.array_iterator - other.m_it.array_iterator;
11407 
11408  default:
11410  }
11411  }
11412 
11418  {
11419  JSON_ASSERT(m_object != nullptr);
11420 
11421  switch (m_object->m_type)
11422  {
11423  case value_t::object:
11424  JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
11425 
11426  case value_t::array:
11427  return *std::next(m_it.array_iterator, n);
11428 
11429  case value_t::null:
11430  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11431 
11432  default:
11433  {
11435  {
11436  return *m_object;
11437  }
11438 
11439  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11440  }
11441  }
11442  }
11443 
11448  const typename object_t::key_type& key() const
11449  {
11450  JSON_ASSERT(m_object != nullptr);
11451 
11452  if (JSON_HEDLEY_LIKELY(m_object->is_object()))
11453  {
11454  return m_it.object_iterator->first;
11455  }
11456 
11457  JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
11458  }
11459 
11465  {
11466  return operator*();
11467  }
11468 
11471  pointer m_object = nullptr;
11474 };
11475 } // namespace detail
11476 } // namespace nlohmann
11477 
11478 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
11479 
11480 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
11481 
11482 
11483 #include <cstddef> // ptrdiff_t
11484 #include <iterator> // reverse_iterator
11485 #include <utility> // declval
11486 
11487 namespace nlohmann
11488 {
11489 namespace detail
11490 {
11492 // reverse_iterator //
11494 
11513 template<typename Base>
11514 class json_reverse_iterator : public std::reverse_iterator<Base>
11515 {
11516  public:
11517  using difference_type = std::ptrdiff_t;
11519  using base_iterator = std::reverse_iterator<Base>;
11521  using reference = typename Base::reference;
11522 
11524  explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
11525  : base_iterator(it) {}
11526 
11528  explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
11529 
11532  {
11533  return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
11534  }
11535 
11538  {
11539  return static_cast<json_reverse_iterator&>(base_iterator::operator++());
11540  }
11541 
11544  {
11545  return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
11546  }
11547 
11550  {
11551  return static_cast<json_reverse_iterator&>(base_iterator::operator--());
11552  }
11553 
11556  {
11557  return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
11558  }
11559 
11562  {
11563  return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
11564  }
11565 
11568  {
11569  return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
11570  }
11571 
11574  {
11575  return base_iterator(*this) - base_iterator(other);
11576  }
11577 
11580  {
11581  return *(this->operator+(n));
11582  }
11583 
11585  auto key() const -> decltype(std::declval<Base>().key())
11586  {
11587  auto it = --this->base();
11588  return it.key();
11589  }
11590 
11593  {
11594  auto it = --this->base();
11595  return it.operator * ();
11596  }
11597 };
11598 } // namespace detail
11599 } // namespace nlohmann
11600 
11601 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11602 
11603 // #include <nlohmann/detail/json_pointer.hpp>
11604 
11605 
11606 #include <algorithm> // all_of
11607 #include <cctype> // isdigit
11608 #include <limits> // max
11609 #include <numeric> // accumulate
11610 #include <string> // string
11611 #include <utility> // move
11612 #include <vector> // vector
11613 
11614 // #include <nlohmann/detail/exceptions.hpp>
11615 
11616 // #include <nlohmann/detail/macro_scope.hpp>
11617 
11618 // #include <nlohmann/detail/value_t.hpp>
11619 
11620 
11621 namespace nlohmann
11622 {
11623 template<typename BasicJsonType>
11625 {
11626  // allow basic_json to access private members
11628  friend class basic_json;
11629 
11630  public:
11652  explicit json_pointer(const std::string& s = "")
11654  {}
11655 
11670  std::string to_string() const
11671  {
11672  return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
11673  std::string{},
11674  [](const std::string & a, const std::string & b)
11675  {
11676  return a + "/" + escape(b);
11677  });
11678  }
11679 
11681  operator std::string() const
11682  {
11683  return to_string();
11684  }
11685 
11703  {
11704  reference_tokens.insert(reference_tokens.end(),
11705  ptr.reference_tokens.begin(),
11706  ptr.reference_tokens.end());
11707  return *this;
11708  }
11709 
11726  json_pointer& operator/=(std::string token)
11727  {
11728  push_back(std::move(token));
11729  return *this;
11730  }
11731 
11748  json_pointer& operator/=(std::size_t array_idx)
11749  {
11750  return *this /= std::to_string(array_idx);
11751  }
11752 
11769  const json_pointer& rhs)
11770  {
11771  return json_pointer(lhs) /= rhs;
11772  }
11773 
11789  friend json_pointer operator/(const json_pointer& ptr, std::string token)
11790  {
11791  return json_pointer(ptr) /= std::move(token);
11792  }
11793 
11809  friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
11810  {
11811  return json_pointer(ptr) /= array_idx;
11812  }
11813 
11828  {
11829  if (empty())
11830  {
11831  return *this;
11832  }
11833 
11834  json_pointer res = *this;
11835  res.pop_back();
11836  return res;
11837  }
11838 
11852  void pop_back()
11853  {
11854  if (JSON_HEDLEY_UNLIKELY(empty()))
11855  {
11856  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11857  }
11858 
11859  reference_tokens.pop_back();
11860  }
11861 
11876  const std::string& back() const
11877  {
11878  if (JSON_HEDLEY_UNLIKELY(empty()))
11879  {
11880  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11881  }
11882 
11883  return reference_tokens.back();
11884  }
11885 
11898  void push_back(const std::string& token)
11899  {
11900  reference_tokens.push_back(token);
11901  }
11902 
11904  void push_back(std::string&& token)
11905  {
11906  reference_tokens.push_back(std::move(token));
11907  }
11908 
11923  bool empty() const noexcept
11924  {
11925  return reference_tokens.empty();
11926  }
11927 
11928  private:
11939  static typename BasicJsonType::size_type array_index(const std::string& s)
11940  {
11941  using size_type = typename BasicJsonType::size_type;
11942 
11943  // error condition (cf. RFC 6901, Sect. 4)
11944  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
11945  {
11947  "array index '" + s +
11948  "' must not begin with '0'"));
11949  }
11950 
11951  // error condition (cf. RFC 6901, Sect. 4)
11952  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
11953  {
11954  JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number"));
11955  }
11956 
11957  std::size_t processed_chars = 0;
11958  unsigned long long res = 0;
11959  JSON_TRY
11960  {
11961  res = std::stoull(s, &processed_chars);
11962  }
11963  JSON_CATCH(std::out_of_range&)
11964  {
11965  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11966  }
11967 
11968  // check if the string was completely read
11969  if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
11970  {
11971  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11972  }
11973 
11974  // only triggered on special platforms (like 32bit), see also
11975  // https://github.com/nlohmann/json/pull/2203
11976  if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)()))
11977  {
11978  JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type")); // LCOV_EXCL_LINE
11979  }
11980 
11981  return static_cast<size_type>(res);
11982  }
11983 
11985  json_pointer top() const
11986  {
11987  if (JSON_HEDLEY_UNLIKELY(empty()))
11988  {
11989  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11990  }
11991 
11994  return result;
11995  }
11996 
11997  private:
12006  BasicJsonType& get_and_create(BasicJsonType& j) const
12007  {
12008  auto result = &j;
12009 
12010  // in case no reference tokens exist, return a reference to the JSON value
12011  // j which will be overwritten by a primitive value
12012  for (const auto& reference_token : reference_tokens)
12013  {
12014  switch (result->type())
12015  {
12016  case detail::value_t::null:
12017  {
12018  if (reference_token == "0")
12019  {
12020  // start a new array if reference token is 0
12021  result = &result->operator[](0);
12022  }
12023  else
12024  {
12025  // start a new object otherwise
12026  result = &result->operator[](reference_token);
12027  }
12028  break;
12029  }
12030 
12032  {
12033  // create an entry in the object
12034  result = &result->operator[](reference_token);
12035  break;
12036  }
12037 
12039  {
12040  // create an entry in the array
12041  result = &result->operator[](array_index(reference_token));
12042  break;
12043  }
12044 
12045  /*
12046  The following code is only reached if there exists a reference
12047  token _and_ the current value is primitive. In this case, we have
12048  an error situation, because primitive values may only occur as
12049  single value; that is, with an empty list of reference tokens.
12050  */
12051  default:
12052  JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
12053  }
12054  }
12055 
12056  return *result;
12057  }
12058 
12078  BasicJsonType& get_unchecked(BasicJsonType* ptr) const
12079  {
12080  for (const auto& reference_token : reference_tokens)
12081  {
12082  // convert null values to arrays or objects before continuing
12083  if (ptr->is_null())
12084  {
12085  // check if reference token is a number
12086  const bool nums =
12087  std::all_of(reference_token.begin(), reference_token.end(),
12088  [](const unsigned char x)
12089  {
12090  return std::isdigit(x);
12091  });
12092 
12093  // change value to array for numbers or "-" or to object otherwise
12094  *ptr = (nums || reference_token == "-")
12097  }
12098 
12099  switch (ptr->type())
12100  {
12102  {
12103  // use unchecked object access
12104  ptr = &ptr->operator[](reference_token);
12105  break;
12106  }
12107 
12109  {
12110  if (reference_token == "-")
12111  {
12112  // explicitly treat "-" as index beyond the end
12113  ptr = &ptr->operator[](ptr->m_value.array->size());
12114  }
12115  else
12116  {
12117  // convert array index to number; unchecked access
12118  ptr = &ptr->operator[](array_index(reference_token));
12119  }
12120  break;
12121  }
12122 
12123  default:
12124  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12125  }
12126  }
12127 
12128  return *ptr;
12129  }
12130 
12137  BasicJsonType& get_checked(BasicJsonType* ptr) const
12138  {
12139  for (const auto& reference_token : reference_tokens)
12140  {
12141  switch (ptr->type())
12142  {
12144  {
12145  // note: at performs range check
12146  ptr = &ptr->at(reference_token);
12147  break;
12148  }
12149 
12151  {
12152  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12153  {
12154  // "-" always fails the range check
12156  "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12157  ") is out of range"));
12158  }
12159 
12160  // note: at performs range check
12161  ptr = &ptr->at(array_index(reference_token));
12162  break;
12163  }
12164 
12165  default:
12166  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12167  }
12168  }
12169 
12170  return *ptr;
12171  }
12172 
12186  const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
12187  {
12188  for (const auto& reference_token : reference_tokens)
12189  {
12190  switch (ptr->type())
12191  {
12193  {
12194  // use unchecked object access
12195  ptr = &ptr->operator[](reference_token);
12196  break;
12197  }
12198 
12200  {
12201  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12202  {
12203  // "-" cannot be used for const access
12205  "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12206  ") is out of range"));
12207  }
12208 
12209  // use unchecked array access
12210  ptr = &ptr->operator[](array_index(reference_token));
12211  break;
12212  }
12213 
12214  default:
12215  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12216  }
12217  }
12218 
12219  return *ptr;
12220  }
12221 
12228  const BasicJsonType& get_checked(const BasicJsonType* ptr) const
12229  {
12230  for (const auto& reference_token : reference_tokens)
12231  {
12232  switch (ptr->type())
12233  {
12235  {
12236  // note: at performs range check
12237  ptr = &ptr->at(reference_token);
12238  break;
12239  }
12240 
12242  {
12243  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12244  {
12245  // "-" always fails the range check
12247  "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12248  ") is out of range"));
12249  }
12250 
12251  // note: at performs range check
12252  ptr = &ptr->at(array_index(reference_token));
12253  break;
12254  }
12255 
12256  default:
12257  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12258  }
12259  }
12260 
12261  return *ptr;
12262  }
12263 
12268  bool contains(const BasicJsonType* ptr) const
12269  {
12270  for (const auto& reference_token : reference_tokens)
12271  {
12272  switch (ptr->type())
12273  {
12275  {
12276  if (!ptr->contains(reference_token))
12277  {
12278  // we did not find the key in the object
12279  return false;
12280  }
12281 
12282  ptr = &ptr->operator[](reference_token);
12283  break;
12284  }
12285 
12287  {
12288  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12289  {
12290  // "-" always fails the range check
12291  return false;
12292  }
12293  if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
12294  {
12295  // invalid char
12296  return false;
12297  }
12298  if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
12299  {
12300  if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
12301  {
12302  // first char should be between '1' and '9'
12303  return false;
12304  }
12305  for (std::size_t i = 1; i < reference_token.size(); i++)
12306  {
12307  if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
12308  {
12309  // other char should be between '0' and '9'
12310  return false;
12311  }
12312  }
12313  }
12314 
12315  const auto idx = array_index(reference_token);
12316  if (idx >= ptr->size())
12317  {
12318  // index out of range
12319  return false;
12320  }
12321 
12322  ptr = &ptr->operator[](idx);
12323  break;
12324  }
12325 
12326  default:
12327  {
12328  // we do not expect primitive values if there is still a
12329  // reference token to process
12330  return false;
12331  }
12332  }
12333  }
12334 
12335  // no reference token left means we found a primitive value
12336  return true;
12337  }
12338 
12348  static std::vector<std::string> split(const std::string& reference_string)
12349  {
12350  std::vector<std::string> result;
12351 
12352  // special case: empty reference string -> no reference tokens
12353  if (reference_string.empty())
12354  {
12355  return result;
12356  }
12357 
12358  // check if nonempty reference string begins with slash
12359  if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
12360  {
12362  "JSON pointer must be empty or begin with '/' - was: '" +
12363  reference_string + "'"));
12364  }
12365 
12366  // extract the reference tokens:
12367  // - slash: position of the last read slash (or end of string)
12368  // - start: position after the previous slash
12369  for (
12370  // search for the first slash after the first character
12371  std::size_t slash = reference_string.find_first_of('/', 1),
12372  // set the beginning of the first reference token
12373  start = 1;
12374  // we can stop if start == 0 (if slash == std::string::npos)
12375  start != 0;
12376  // set the beginning of the next reference token
12377  // (will eventually be 0 if slash == std::string::npos)
12378  start = (slash == std::string::npos) ? 0 : slash + 1,
12379  // find next slash
12380  slash = reference_string.find_first_of('/', start))
12381  {
12382  // use the text between the beginning of the reference token
12383  // (start) and the last slash (slash).
12384  auto reference_token = reference_string.substr(start, slash - start);
12385 
12386  // check reference tokens are properly escaped
12387  for (std::size_t pos = reference_token.find_first_of('~');
12388  pos != std::string::npos;
12389  pos = reference_token.find_first_of('~', pos + 1))
12390  {
12391  JSON_ASSERT(reference_token[pos] == '~');
12392 
12393  // ~ must be followed by 0 or 1
12394  if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
12395  (reference_token[pos + 1] != '0' &&
12396  reference_token[pos + 1] != '1')))
12397  {
12398  JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
12399  }
12400  }
12401 
12402  // finally, store the reference token
12403  unescape(reference_token);
12404  result.push_back(reference_token);
12405  }
12406 
12407  return result;
12408  }
12409 
12423  static void replace_substring(std::string& s, const std::string& f,
12424  const std::string& t)
12425  {
12426  JSON_ASSERT(!f.empty());
12427  for (auto pos = s.find(f); // find first occurrence of f
12428  pos != std::string::npos; // make sure f was found
12429  s.replace(pos, f.size(), t), // replace with t, and
12430  pos = s.find(f, pos + t.size())) // find next occurrence of f
12431  {}
12432  }
12433 
12436  static std::string escape(std::string s)
12437  {
12438  replace_substring(s, "~", "~0");
12439  replace_substring(s, "/", "~1");
12440  return s;
12441  }
12442 
12444  static void unescape(std::string& s)
12445  {
12446  replace_substring(s, "~1", "/");
12447  replace_substring(s, "~0", "~");
12448  }
12449 
12450  private:
12458  static void flatten(const std::string& reference_string,
12459  const BasicJsonType& value,
12460  BasicJsonType& result)
12461  {
12462  switch (value.type())
12463  {
12465  {
12466  if (value.m_value.array->empty())
12467  {
12468  // flatten empty array as null
12469  result[reference_string] = nullptr;
12470  }
12471  else
12472  {
12473  // iterate array and use index as reference string
12474  for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
12475  {
12476  flatten(reference_string + "/" + std::to_string(i),
12477  value.m_value.array->operator[](i), result);
12478  }
12479  }
12480  break;
12481  }
12482 
12484  {
12485  if (value.m_value.object->empty())
12486  {
12487  // flatten empty object as null
12488  result[reference_string] = nullptr;
12489  }
12490  else
12491  {
12492  // iterate object and use keys as reference string
12493  for (const auto& element : *value.m_value.object)
12494  {
12495  flatten(reference_string + "/" + escape(element.first), element.second, result);
12496  }
12497  }
12498  break;
12499  }
12500 
12501  default:
12502  {
12503  // add primitive value with its reference string
12504  result[reference_string] = value;
12505  break;
12506  }
12507  }
12508  }
12509 
12520  static BasicJsonType
12521  unflatten(const BasicJsonType& value)
12522  {
12523  if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
12524  {
12525  JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
12526  }
12527 
12528  BasicJsonType result;
12529 
12530  // iterate the JSON object values
12531  for (const auto& element : *value.m_value.object)
12532  {
12533  if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
12534  {
12535  JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
12536  }
12537 
12538  // assign value to reference pointed to by JSON pointer; Note that if
12539  // the JSON pointer is "" (i.e., points to the whole value), function
12540  // get_and_create returns a reference to result itself. An assignment
12541  // will then create a primitive value.
12542  json_pointer(element.first).get_and_create(result) = element.second;
12543  }
12544 
12545  return result;
12546  }
12547 
12559  friend bool operator==(json_pointer const& lhs,
12560  json_pointer const& rhs) noexcept
12561  {
12562  return lhs.reference_tokens == rhs.reference_tokens;
12563  }
12564 
12576  friend bool operator!=(json_pointer const& lhs,
12577  json_pointer const& rhs) noexcept
12578  {
12579  return !(lhs == rhs);
12580  }
12581 
12583  std::vector<std::string> reference_tokens;
12584 };
12585 } // namespace nlohmann
12586 
12587 // #include <nlohmann/detail/json_ref.hpp>
12588 
12589 
12590 #include <initializer_list>
12591 #include <utility>
12592 
12593 // #include <nlohmann/detail/meta/type_traits.hpp>
12594 
12595 
12596 namespace nlohmann
12597 {
12598 namespace detail
12599 {
12600 template<typename BasicJsonType>
12602 {
12603  public:
12604  using value_type = BasicJsonType;
12605 
12607  : owned_value(std::move(value))
12609  , is_rvalue(true)
12610  {}
12611 
12612  json_ref(const value_type& value)
12613  : value_ref(const_cast<value_type*>(&value))
12614  , is_rvalue(false)
12615  {}
12616 
12617  json_ref(std::initializer_list<json_ref> init)
12618  : owned_value(init)
12620  , is_rvalue(true)
12621  {}
12622 
12623  template <
12624  class... Args,
12625  enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
12626  json_ref(Args && ... args)
12627  : owned_value(std::forward<Args>(args)...)
12629  , is_rvalue(true)
12630  {}
12631 
12632  // class should be movable only
12633  json_ref(json_ref&&) = default;
12634  json_ref(const json_ref&) = delete;
12635  json_ref& operator=(const json_ref&) = delete;
12637  ~json_ref() = default;
12638 
12640  {
12641  if (is_rvalue)
12642  {
12643  return std::move(*value_ref);
12644  }
12645  return *value_ref;
12646  }
12647 
12648  value_type const& operator*() const
12649  {
12650  return *static_cast<value_type const*>(value_ref);
12651  }
12652 
12653  value_type const* operator->() const
12654  {
12655  return static_cast<value_type const*>(value_ref);
12656  }
12657 
12658  private:
12659  mutable value_type owned_value = nullptr;
12660  value_type* value_ref = nullptr;
12661  const bool is_rvalue = true;
12662 };
12663 } // namespace detail
12664 } // namespace nlohmann
12665 
12666 // #include <nlohmann/detail/macro_scope.hpp>
12667 
12668 // #include <nlohmann/detail/meta/cpp_future.hpp>
12669 
12670 // #include <nlohmann/detail/meta/type_traits.hpp>
12671 
12672 // #include <nlohmann/detail/output/binary_writer.hpp>
12673 
12674 
12675 #include <algorithm> // reverse
12676 #include <array> // array
12677 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
12678 #include <cstring> // memcpy
12679 #include <limits> // numeric_limits
12680 #include <string> // string
12681 #include <cmath> // isnan, isinf
12682 
12683 // #include <nlohmann/detail/input/binary_reader.hpp>
12684 
12685 // #include <nlohmann/detail/macro_scope.hpp>
12686 
12687 // #include <nlohmann/detail/output/output_adapters.hpp>
12688 
12689 
12690 #include <algorithm> // copy
12691 #include <cstddef> // size_t
12692 #include <ios> // streamsize
12693 #include <iterator> // back_inserter
12694 #include <memory> // shared_ptr, make_shared
12695 #include <ostream> // basic_ostream
12696 #include <string> // basic_string
12697 #include <vector> // vector
12698 // #include <nlohmann/detail/macro_scope.hpp>
12699 
12700 
12701 namespace nlohmann
12702 {
12703 namespace detail
12704 {
12706 template<typename CharType> struct output_adapter_protocol
12707 {
12708  virtual void write_character(CharType c) = 0;
12709  virtual void write_characters(const CharType* s, std::size_t length) = 0;
12710  virtual ~output_adapter_protocol() = default;
12711 };
12712 
12714 template<typename CharType>
12715 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
12716 
12718 template<typename CharType>
12720 {
12721  public:
12722  explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
12723  : v(vec)
12724  {}
12725 
12726  void write_character(CharType c) override
12727  {
12728  v.push_back(c);
12729  }
12730 
12732  void write_characters(const CharType* s, std::size_t length) override
12733  {
12734  std::copy(s, s + length, std::back_inserter(v));
12735  }
12736 
12737  private:
12738  std::vector<CharType>& v;
12739 };
12740 
12742 template<typename CharType>
12744 {
12745  public:
12746  explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
12747  : stream(s)
12748  {}
12749 
12750  void write_character(CharType c) override
12751  {
12752  stream.put(c);
12753  }
12754 
12756  void write_characters(const CharType* s, std::size_t length) override
12757  {
12758  stream.write(s, static_cast<std::streamsize>(length));
12759  }
12760 
12761  private:
12762  std::basic_ostream<CharType>& stream;
12763 };
12764 
12766 template<typename CharType, typename StringType = std::basic_string<CharType>>
12768 {
12769  public:
12770  explicit output_string_adapter(StringType& s) noexcept
12771  : str(s)
12772  {}
12773 
12774  void write_character(CharType c) override
12775  {
12776  str.push_back(c);
12777  }
12778 
12780  void write_characters(const CharType* s, std::size_t length) override
12781  {
12782  str.append(s, length);
12783  }
12784 
12785  private:
12786  StringType& str;
12787 };
12788 
12789 template<typename CharType, typename StringType = std::basic_string<CharType>>
12791 {
12792  public:
12793  output_adapter(std::vector<CharType>& vec)
12794  : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
12795 
12796  output_adapter(std::basic_ostream<CharType>& s)
12797  : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
12798 
12799  output_adapter(StringType& s)
12800  : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
12801 
12803  {
12804  return oa;
12805  }
12806 
12807  private:
12809 };
12810 } // namespace detail
12811 } // namespace nlohmann
12812 
12813 
12814 namespace nlohmann
12815 {
12816 namespace detail
12817 {
12819 // binary writer //
12821 
12825 template<typename BasicJsonType, typename CharType>
12827 {
12828  using string_t = typename BasicJsonType::string_t;
12829  using binary_t = typename BasicJsonType::binary_t;
12830  using number_float_t = typename BasicJsonType::number_float_t;
12831 
12832  public:
12838  explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
12839  {
12840  JSON_ASSERT(oa);
12841  }
12842 
12847  void write_bson(const BasicJsonType& j)
12848  {
12849  switch (j.type())
12850  {
12851  case value_t::object:
12852  {
12853  write_bson_object(*j.m_value.object);
12854  break;
12855  }
12856 
12857  default:
12858  {
12859  JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
12860  }
12861  }
12862  }
12863 
12867  void write_cbor(const BasicJsonType& j)
12868  {
12869  switch (j.type())
12870  {
12871  case value_t::null:
12872  {
12873  oa->write_character(to_char_type(0xF6));
12874  break;
12875  }
12876 
12877  case value_t::boolean:
12878  {
12879  oa->write_character(j.m_value.boolean
12880  ? to_char_type(0xF5)
12881  : to_char_type(0xF4));
12882  break;
12883  }
12884 
12886  {
12887  if (j.m_value.number_integer >= 0)
12888  {
12889  // CBOR does not differentiate between positive signed
12890  // integers and unsigned integers. Therefore, we used the
12891  // code from the value_t::number_unsigned case here.
12892  if (j.m_value.number_integer <= 0x17)
12893  {
12894  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12895  }
12896  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
12897  {
12898  oa->write_character(to_char_type(0x18));
12899  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12900  }
12901  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
12902  {
12903  oa->write_character(to_char_type(0x19));
12904  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
12905  }
12906  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
12907  {
12908  oa->write_character(to_char_type(0x1A));
12909  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
12910  }
12911  else
12912  {
12913  oa->write_character(to_char_type(0x1B));
12914  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
12915  }
12916  }
12917  else
12918  {
12919  // The conversions below encode the sign in the first
12920  // byte, and the value is converted to a positive number.
12921  const auto positive_number = -1 - j.m_value.number_integer;
12922  if (j.m_value.number_integer >= -24)
12923  {
12924  write_number(static_cast<std::uint8_t>(0x20 + positive_number));
12925  }
12926  else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
12927  {
12928  oa->write_character(to_char_type(0x38));
12929  write_number(static_cast<std::uint8_t>(positive_number));
12930  }
12931  else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
12932  {
12933  oa->write_character(to_char_type(0x39));
12934  write_number(static_cast<std::uint16_t>(positive_number));
12935  }
12936  else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
12937  {
12938  oa->write_character(to_char_type(0x3A));
12939  write_number(static_cast<std::uint32_t>(positive_number));
12940  }
12941  else
12942  {
12943  oa->write_character(to_char_type(0x3B));
12944  write_number(static_cast<std::uint64_t>(positive_number));
12945  }
12946  }
12947  break;
12948  }
12949 
12951  {
12952  if (j.m_value.number_unsigned <= 0x17)
12953  {
12954  write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
12955  }
12956  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12957  {
12958  oa->write_character(to_char_type(0x18));
12959  write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
12960  }
12961  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12962  {
12963  oa->write_character(to_char_type(0x19));
12964  write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
12965  }
12966  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12967  {
12968  oa->write_character(to_char_type(0x1A));
12969  write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
12970  }
12971  else
12972  {
12973  oa->write_character(to_char_type(0x1B));
12974  write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
12975  }
12976  break;
12977  }
12978 
12979  case value_t::number_float:
12980  {
12981  if (std::isnan(j.m_value.number_float))
12982  {
12983  // NaN is 0xf97e00 in CBOR
12984  oa->write_character(to_char_type(0xF9));
12985  oa->write_character(to_char_type(0x7E));
12986  oa->write_character(to_char_type(0x00));
12987  }
12988  else if (std::isinf(j.m_value.number_float))
12989  {
12990  // Infinity is 0xf97c00, -Infinity is 0xf9fc00
12991  oa->write_character(to_char_type(0xf9));
12992  oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
12993  oa->write_character(to_char_type(0x00));
12994  }
12995  else
12996  {
12997  write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
12998  }
12999  break;
13000  }
13001 
13002  case value_t::string:
13003  {
13004  // step 1: write control byte and the string length
13005  const auto N = j.m_value.string->size();
13006  if (N <= 0x17)
13007  {
13008  write_number(static_cast<std::uint8_t>(0x60 + N));
13009  }
13010  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13011  {
13012  oa->write_character(to_char_type(0x78));
13013  write_number(static_cast<std::uint8_t>(N));
13014  }
13015  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13016  {
13017  oa->write_character(to_char_type(0x79));
13018  write_number(static_cast<std::uint16_t>(N));
13019  }
13020  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13021  {
13022  oa->write_character(to_char_type(0x7A));
13023  write_number(static_cast<std::uint32_t>(N));
13024  }
13025  // LCOV_EXCL_START
13026  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13027  {
13028  oa->write_character(to_char_type(0x7B));
13029  write_number(static_cast<std::uint64_t>(N));
13030  }
13031  // LCOV_EXCL_STOP
13032 
13033  // step 2: write the string
13034  oa->write_characters(
13035  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13036  j.m_value.string->size());
13037  break;
13038  }
13039 
13040  case value_t::array:
13041  {
13042  // step 1: write control byte and the array size
13043  const auto N = j.m_value.array->size();
13044  if (N <= 0x17)
13045  {
13046  write_number(static_cast<std::uint8_t>(0x80 + N));
13047  }
13048  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13049  {
13050  oa->write_character(to_char_type(0x98));
13051  write_number(static_cast<std::uint8_t>(N));
13052  }
13053  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13054  {
13055  oa->write_character(to_char_type(0x99));
13056  write_number(static_cast<std::uint16_t>(N));
13057  }
13058  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13059  {
13060  oa->write_character(to_char_type(0x9A));
13061  write_number(static_cast<std::uint32_t>(N));
13062  }
13063  // LCOV_EXCL_START
13064  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13065  {
13066  oa->write_character(to_char_type(0x9B));
13067  write_number(static_cast<std::uint64_t>(N));
13068  }
13069  // LCOV_EXCL_STOP
13070 
13071  // step 2: write each element
13072  for (const auto& el : *j.m_value.array)
13073  {
13074  write_cbor(el);
13075  }
13076  break;
13077  }
13078 
13079  case value_t::binary:
13080  {
13081  if (j.m_value.binary->has_subtype())
13082  {
13083  write_number(static_cast<std::uint8_t>(0xd8));
13084  write_number(j.m_value.binary->subtype());
13085  }
13086 
13087  // step 1: write control byte and the binary array size
13088  const auto N = j.m_value.binary->size();
13089  if (N <= 0x17)
13090  {
13091  write_number(static_cast<std::uint8_t>(0x40 + N));
13092  }
13093  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13094  {
13095  oa->write_character(to_char_type(0x58));
13096  write_number(static_cast<std::uint8_t>(N));
13097  }
13098  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13099  {
13100  oa->write_character(to_char_type(0x59));
13101  write_number(static_cast<std::uint16_t>(N));
13102  }
13103  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13104  {
13105  oa->write_character(to_char_type(0x5A));
13106  write_number(static_cast<std::uint32_t>(N));
13107  }
13108  // LCOV_EXCL_START
13109  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13110  {
13111  oa->write_character(to_char_type(0x5B));
13112  write_number(static_cast<std::uint64_t>(N));
13113  }
13114  // LCOV_EXCL_STOP
13115 
13116  // step 2: write each element
13117  oa->write_characters(
13118  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13119  N);
13120 
13121  break;
13122  }
13123 
13124  case value_t::object:
13125  {
13126  // step 1: write control byte and the object size
13127  const auto N = j.m_value.object->size();
13128  if (N <= 0x17)
13129  {
13130  write_number(static_cast<std::uint8_t>(0xA0 + N));
13131  }
13132  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13133  {
13134  oa->write_character(to_char_type(0xB8));
13135  write_number(static_cast<std::uint8_t>(N));
13136  }
13137  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13138  {
13139  oa->write_character(to_char_type(0xB9));
13140  write_number(static_cast<std::uint16_t>(N));
13141  }
13142  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13143  {
13144  oa->write_character(to_char_type(0xBA));
13145  write_number(static_cast<std::uint32_t>(N));
13146  }
13147  // LCOV_EXCL_START
13148  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13149  {
13150  oa->write_character(to_char_type(0xBB));
13151  write_number(static_cast<std::uint64_t>(N));
13152  }
13153  // LCOV_EXCL_STOP
13154 
13155  // step 2: write each element
13156  for (const auto& el : *j.m_value.object)
13157  {
13158  write_cbor(el.first);
13159  write_cbor(el.second);
13160  }
13161  break;
13162  }
13163 
13164  default:
13165  break;
13166  }
13167  }
13168 
13172  void write_msgpack(const BasicJsonType& j)
13173  {
13174  switch (j.type())
13175  {
13176  case value_t::null: // nil
13177  {
13178  oa->write_character(to_char_type(0xC0));
13179  break;
13180  }
13181 
13182  case value_t::boolean: // true and false
13183  {
13184  oa->write_character(j.m_value.boolean
13185  ? to_char_type(0xC3)
13186  : to_char_type(0xC2));
13187  break;
13188  }
13189 
13191  {
13192  if (j.m_value.number_integer >= 0)
13193  {
13194  // MessagePack does not differentiate between positive
13195  // signed integers and unsigned integers. Therefore, we used
13196  // the code from the value_t::number_unsigned case here.
13197  if (j.m_value.number_unsigned < 128)
13198  {
13199  // positive fixnum
13200  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13201  }
13202  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13203  {
13204  // uint 8
13205  oa->write_character(to_char_type(0xCC));
13206  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13207  }
13208  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13209  {
13210  // uint 16
13211  oa->write_character(to_char_type(0xCD));
13212  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13213  }
13214  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13215  {
13216  // uint 32
13217  oa->write_character(to_char_type(0xCE));
13218  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13219  }
13220  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
13221  {
13222  // uint 64
13223  oa->write_character(to_char_type(0xCF));
13224  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13225  }
13226  }
13227  else
13228  {
13229  if (j.m_value.number_integer >= -32)
13230  {
13231  // negative fixnum
13232  write_number(static_cast<std::int8_t>(j.m_value.number_integer));
13233  }
13234  else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
13235  j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
13236  {
13237  // int 8
13238  oa->write_character(to_char_type(0xD0));
13239  write_number(static_cast<std::int8_t>(j.m_value.number_integer));
13240  }
13241  else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
13242  j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
13243  {
13244  // int 16
13245  oa->write_character(to_char_type(0xD1));
13246  write_number(static_cast<std::int16_t>(j.m_value.number_integer));
13247  }
13248  else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
13249  j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
13250  {
13251  // int 32
13252  oa->write_character(to_char_type(0xD2));
13253  write_number(static_cast<std::int32_t>(j.m_value.number_integer));
13254  }
13255  else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
13256  j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
13257  {
13258  // int 64
13259  oa->write_character(to_char_type(0xD3));
13260  write_number(static_cast<std::int64_t>(j.m_value.number_integer));
13261  }
13262  }
13263  break;
13264  }
13265 
13267  {
13268  if (j.m_value.number_unsigned < 128)
13269  {
13270  // positive fixnum
13271  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13272  }
13273  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13274  {
13275  // uint 8
13276  oa->write_character(to_char_type(0xCC));
13277  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13278  }
13279  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13280  {
13281  // uint 16
13282  oa->write_character(to_char_type(0xCD));
13283  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13284  }
13285  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13286  {
13287  // uint 32
13288  oa->write_character(to_char_type(0xCE));
13289  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13290  }
13291  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
13292  {
13293  // uint 64
13294  oa->write_character(to_char_type(0xCF));
13295  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13296  }
13297  break;
13298  }
13299 
13300  case value_t::number_float:
13301  {
13302  write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
13303  break;
13304  }
13305 
13306  case value_t::string:
13307  {
13308  // step 1: write control byte and the string length
13309  const auto N = j.m_value.string->size();
13310  if (N <= 31)
13311  {
13312  // fixstr
13313  write_number(static_cast<std::uint8_t>(0xA0 | N));
13314  }
13315  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13316  {
13317  // str 8
13318  oa->write_character(to_char_type(0xD9));
13319  write_number(static_cast<std::uint8_t>(N));
13320  }
13321  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13322  {
13323  // str 16
13324  oa->write_character(to_char_type(0xDA));
13325  write_number(static_cast<std::uint16_t>(N));
13326  }
13327  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13328  {
13329  // str 32
13330  oa->write_character(to_char_type(0xDB));
13331  write_number(static_cast<std::uint32_t>(N));
13332  }
13333 
13334  // step 2: write the string
13335  oa->write_characters(
13336  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13337  j.m_value.string->size());
13338  break;
13339  }
13340 
13341  case value_t::array:
13342  {
13343  // step 1: write control byte and the array size
13344  const auto N = j.m_value.array->size();
13345  if (N <= 15)
13346  {
13347  // fixarray
13348  write_number(static_cast<std::uint8_t>(0x90 | N));
13349  }
13350  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13351  {
13352  // array 16
13353  oa->write_character(to_char_type(0xDC));
13354  write_number(static_cast<std::uint16_t>(N));
13355  }
13356  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13357  {
13358  // array 32
13359  oa->write_character(to_char_type(0xDD));
13360  write_number(static_cast<std::uint32_t>(N));
13361  }
13362 
13363  // step 2: write each element
13364  for (const auto& el : *j.m_value.array)
13365  {
13366  write_msgpack(el);
13367  }
13368  break;
13369  }
13370 
13371  case value_t::binary:
13372  {
13373  // step 0: determine if the binary type has a set subtype to
13374  // determine whether or not to use the ext or fixext types
13375  const bool use_ext = j.m_value.binary->has_subtype();
13376 
13377  // step 1: write control byte and the byte string length
13378  const auto N = j.m_value.binary->size();
13380  {
13381  std::uint8_t output_type{};
13382  bool fixed = true;
13383  if (use_ext)
13384  {
13385  switch (N)
13386  {
13387  case 1:
13388  output_type = 0xD4; // fixext 1
13389  break;
13390  case 2:
13391  output_type = 0xD5; // fixext 2
13392  break;
13393  case 4:
13394  output_type = 0xD6; // fixext 4
13395  break;
13396  case 8:
13397  output_type = 0xD7; // fixext 8
13398  break;
13399  case 16:
13400  output_type = 0xD8; // fixext 16
13401  break;
13402  default:
13403  output_type = 0xC7; // ext 8
13404  fixed = false;
13405  break;
13406  }
13407 
13408  }
13409  else
13410  {
13411  output_type = 0xC4; // bin 8
13412  fixed = false;
13413  }
13414 
13415  oa->write_character(to_char_type(output_type));
13416  if (!fixed)
13417  {
13418  write_number(static_cast<std::uint8_t>(N));
13419  }
13420  }
13421  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13422  {
13423  std::uint8_t output_type = use_ext
13424  ? 0xC8 // ext 16
13425  : 0xC5; // bin 16
13426 
13427  oa->write_character(to_char_type(output_type));
13428  write_number(static_cast<std::uint16_t>(N));
13429  }
13430  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13431  {
13432  std::uint8_t output_type = use_ext
13433  ? 0xC9 // ext 32
13434  : 0xC6; // bin 32
13435 
13436  oa->write_character(to_char_type(output_type));
13437  write_number(static_cast<std::uint32_t>(N));
13438  }
13439 
13440  // step 1.5: if this is an ext type, write the subtype
13441  if (use_ext)
13442  {
13443  write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
13444  }
13445 
13446  // step 2: write the byte string
13447  oa->write_characters(
13448  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13449  N);
13450 
13451  break;
13452  }
13453 
13454  case value_t::object:
13455  {
13456  // step 1: write control byte and the object size
13457  const auto N = j.m_value.object->size();
13458  if (N <= 15)
13459  {
13460  // fixmap
13461  write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
13462  }
13463  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13464  {
13465  // map 16
13466  oa->write_character(to_char_type(0xDE));
13467  write_number(static_cast<std::uint16_t>(N));
13468  }
13469  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13470  {
13471  // map 32
13472  oa->write_character(to_char_type(0xDF));
13473  write_number(static_cast<std::uint32_t>(N));
13474  }
13475 
13476  // step 2: write each element
13477  for (const auto& el : *j.m_value.object)
13478  {
13479  write_msgpack(el.first);
13480  write_msgpack(el.second);
13481  }
13482  break;
13483  }
13484 
13485  default:
13486  break;
13487  }
13488  }
13489 
13496  void write_ubjson(const BasicJsonType& j, const bool use_count,
13497  const bool use_type, const bool add_prefix = true)
13498  {
13499  switch (j.type())
13500  {
13501  case value_t::null:
13502  {
13503  if (add_prefix)
13504  {
13505  oa->write_character(to_char_type('Z'));
13506  }
13507  break;
13508  }
13509 
13510  case value_t::boolean:
13511  {
13512  if (add_prefix)
13513  {
13514  oa->write_character(j.m_value.boolean
13515  ? to_char_type('T')
13516  : to_char_type('F'));
13517  }
13518  break;
13519  }
13520 
13522  {
13523  write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
13524  break;
13525  }
13526 
13528  {
13529  write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
13530  break;
13531  }
13532 
13533  case value_t::number_float:
13534  {
13535  write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
13536  break;
13537  }
13538 
13539  case value_t::string:
13540  {
13541  if (add_prefix)
13542  {
13543  oa->write_character(to_char_type('S'));
13544  }
13545  write_number_with_ubjson_prefix(j.m_value.string->size(), true);
13546  oa->write_characters(
13547  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13548  j.m_value.string->size());
13549  break;
13550  }
13551 
13552  case value_t::array:
13553  {
13554  if (add_prefix)
13555  {
13556  oa->write_character(to_char_type('['));
13557  }
13558 
13559  bool prefix_required = true;
13560  if (use_type && !j.m_value.array->empty())
13561  {
13562  JSON_ASSERT(use_count);
13563  const CharType first_prefix = ubjson_prefix(j.front());
13564  const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
13565  [this, first_prefix](const BasicJsonType & v)
13566  {
13567  return ubjson_prefix(v) == first_prefix;
13568  });
13569 
13570  if (same_prefix)
13571  {
13572  prefix_required = false;
13573  oa->write_character(to_char_type('$'));
13574  oa->write_character(first_prefix);
13575  }
13576  }
13577 
13578  if (use_count)
13579  {
13580  oa->write_character(to_char_type('#'));
13581  write_number_with_ubjson_prefix(j.m_value.array->size(), true);
13582  }
13583 
13584  for (const auto& el : *j.m_value.array)
13585  {
13586  write_ubjson(el, use_count, use_type, prefix_required);
13587  }
13588 
13589  if (!use_count)
13590  {
13591  oa->write_character(to_char_type(']'));
13592  }
13593 
13594  break;
13595  }
13596 
13597  case value_t::binary:
13598  {
13599  if (add_prefix)
13600  {
13601  oa->write_character(to_char_type('['));
13602  }
13603 
13604  if (use_type && !j.m_value.binary->empty())
13605  {
13606  JSON_ASSERT(use_count);
13607  oa->write_character(to_char_type('$'));
13608  oa->write_character('U');
13609  }
13610 
13611  if (use_count)
13612  {
13613  oa->write_character(to_char_type('#'));
13614  write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
13615  }
13616 
13617  if (use_type)
13618  {
13619  oa->write_characters(
13620  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13621  j.m_value.binary->size());
13622  }
13623  else
13624  {
13625  for (size_t i = 0; i < j.m_value.binary->size(); ++i)
13626  {
13627  oa->write_character(to_char_type('U'));
13628  oa->write_character(j.m_value.binary->data()[i]);
13629  }
13630  }
13631 
13632  if (!use_count)
13633  {
13634  oa->write_character(to_char_type(']'));
13635  }
13636 
13637  break;
13638  }
13639 
13640  case value_t::object:
13641  {
13642  if (add_prefix)
13643  {
13644  oa->write_character(to_char_type('{'));
13645  }
13646 
13647  bool prefix_required = true;
13648  if (use_type && !j.m_value.object->empty())
13649  {
13650  JSON_ASSERT(use_count);
13651  const CharType first_prefix = ubjson_prefix(j.front());
13652  const bool same_prefix = std::all_of(j.begin(), j.end(),
13653  [this, first_prefix](const BasicJsonType & v)
13654  {
13655  return ubjson_prefix(v) == first_prefix;
13656  });
13657 
13658  if (same_prefix)
13659  {
13660  prefix_required = false;
13661  oa->write_character(to_char_type('$'));
13662  oa->write_character(first_prefix);
13663  }
13664  }
13665 
13666  if (use_count)
13667  {
13668  oa->write_character(to_char_type('#'));
13669  write_number_with_ubjson_prefix(j.m_value.object->size(), true);
13670  }
13671 
13672  for (const auto& el : *j.m_value.object)
13673  {
13674  write_number_with_ubjson_prefix(el.first.size(), true);
13675  oa->write_characters(
13676  reinterpret_cast<const CharType*>(el.first.c_str()),
13677  el.first.size());
13678  write_ubjson(el.second, use_count, use_type, prefix_required);
13679  }
13680 
13681  if (!use_count)
13682  {
13683  oa->write_character(to_char_type('}'));
13684  }
13685 
13686  break;
13687  }
13688 
13689  default:
13690  break;
13691  }
13692  }
13693 
13694  private:
13696  // BSON //
13698 
13703  static std::size_t calc_bson_entry_header_size(const string_t& name)
13704  {
13705  const auto it = name.find(static_cast<typename string_t::value_type>(0));
13706  if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
13707  {
13709  "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
13710  }
13711 
13712  return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
13713  }
13714 
13719  const std::uint8_t element_type)
13720  {
13721  oa->write_character(to_char_type(element_type)); // boolean
13722  oa->write_characters(
13723  reinterpret_cast<const CharType*>(name.c_str()),
13724  name.size() + 1u);
13725  }
13726 
13730  void write_bson_boolean(const string_t& name,
13731  const bool value)
13732  {
13733  write_bson_entry_header(name, 0x08);
13734  oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
13735  }
13736 
13740  void write_bson_double(const string_t& name,
13741  const double value)
13742  {
13743  write_bson_entry_header(name, 0x01);
13744  write_number<double, true>(value);
13745  }
13746 
13750  static std::size_t calc_bson_string_size(const string_t& value)
13751  {
13752  return sizeof(std::int32_t) + value.size() + 1ul;
13753  }
13754 
13758  void write_bson_string(const string_t& name,
13759  const string_t& value)
13760  {
13761  write_bson_entry_header(name, 0x02);
13762 
13763  write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
13764  oa->write_characters(
13765  reinterpret_cast<const CharType*>(value.c_str()),
13766  value.size() + 1);
13767  }
13768 
13772  void write_bson_null(const string_t& name)
13773  {
13774  write_bson_entry_header(name, 0x0A);
13775  }
13776 
13780  static std::size_t calc_bson_integer_size(const std::int64_t value)
13781  {
13783  ? sizeof(std::int32_t)
13784  : sizeof(std::int64_t);
13785  }
13786 
13790  void write_bson_integer(const string_t& name,
13791  const std::int64_t value)
13792  {
13794  {
13795  write_bson_entry_header(name, 0x10); // int32
13796  write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
13797  }
13798  else
13799  {
13800  write_bson_entry_header(name, 0x12); // int64
13801  write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
13802  }
13803  }
13804 
13808  static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
13809  {
13810  return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13811  ? sizeof(std::int32_t)
13812  : sizeof(std::int64_t);
13813  }
13814 
13818  void write_bson_unsigned(const string_t& name,
13819  const std::uint64_t value)
13820  {
13821  if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13822  {
13823  write_bson_entry_header(name, 0x10 /* int32 */);
13824  write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
13825  }
13826  else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
13827  {
13828  write_bson_entry_header(name, 0x12 /* int64 */);
13829  write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
13830  }
13831  else
13832  {
13833  JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
13834  }
13835  }
13836 
13841  const typename BasicJsonType::object_t& value)
13842  {
13843  write_bson_entry_header(name, 0x03); // object
13845  }
13846 
13850  static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
13851  {
13852  std::size_t array_index = 0ul;
13853 
13854  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)
13855  {
13856  return result + calc_bson_element_size(std::to_string(array_index++), el);
13857  });
13858 
13859  return sizeof(std::int32_t) + embedded_document_size + 1ul;
13860  }
13861 
13865  static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
13866  {
13867  return sizeof(std::int32_t) + value.size() + 1ul;
13868  }
13869 
13873  void write_bson_array(const string_t& name,
13874  const typename BasicJsonType::array_t& value)
13875  {
13876  write_bson_entry_header(name, 0x04); // array
13877  write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
13878 
13879  std::size_t array_index = 0ul;
13880 
13881  for (const auto& el : value)
13882  {
13883  write_bson_element(std::to_string(array_index++), el);
13884  }
13885 
13886  oa->write_character(to_char_type(0x00));
13887  }
13888 
13892  void write_bson_binary(const string_t& name,
13893  const binary_t& value)
13894  {
13895  write_bson_entry_header(name, 0x05);
13896 
13897  write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
13898  write_number(value.has_subtype() ? value.subtype() : std::uint8_t(0x00));
13899 
13900  oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
13901  }
13902 
13907  static std::size_t calc_bson_element_size(const string_t& name,
13908  const BasicJsonType& j)
13909  {
13910  const auto header_size = calc_bson_entry_header_size(name);
13911  switch (j.type())
13912  {
13913  case value_t::object:
13914  return header_size + calc_bson_object_size(*j.m_value.object);
13915 
13916  case value_t::array:
13917  return header_size + calc_bson_array_size(*j.m_value.array);
13918 
13919  case value_t::binary:
13920  return header_size + calc_bson_binary_size(*j.m_value.binary);
13921 
13922  case value_t::boolean:
13923  return header_size + 1ul;
13924 
13925  case value_t::number_float:
13926  return header_size + 8ul;
13927 
13929  return header_size + calc_bson_integer_size(j.m_value.number_integer);
13930 
13932  return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
13933 
13934  case value_t::string:
13935  return header_size + calc_bson_string_size(*j.m_value.string);
13936 
13937  case value_t::null:
13938  return header_size + 0ul;
13939 
13940  // LCOV_EXCL_START
13941  default:
13942  JSON_ASSERT(false);
13943  return 0ul;
13944  // LCOV_EXCL_STOP
13945  }
13946  }
13947 
13955  void write_bson_element(const string_t& name,
13956  const BasicJsonType& j)
13957  {
13958  switch (j.type())
13959  {
13960  case value_t::object:
13961  return write_bson_object_entry(name, *j.m_value.object);
13962 
13963  case value_t::array:
13964  return write_bson_array(name, *j.m_value.array);
13965 
13966  case value_t::binary:
13967  return write_bson_binary(name, *j.m_value.binary);
13968 
13969  case value_t::boolean:
13970  return write_bson_boolean(name, j.m_value.boolean);
13971 
13972  case value_t::number_float:
13973  return write_bson_double(name, j.m_value.number_float);
13974 
13976  return write_bson_integer(name, j.m_value.number_integer);
13977 
13979  return write_bson_unsigned(name, j.m_value.number_unsigned);
13980 
13981  case value_t::string:
13982  return write_bson_string(name, *j.m_value.string);
13983 
13984  case value_t::null:
13985  return write_bson_null(name);
13986 
13987  // LCOV_EXCL_START
13988  default:
13989  JSON_ASSERT(false);
13990  return;
13991  // LCOV_EXCL_STOP
13992  }
13993  }
13994 
14001  static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
14002  {
14003  std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
14004  [](size_t result, const typename BasicJsonType::object_t::value_type & el)
14005  {
14006  return result += calc_bson_element_size(el.first, el.second);
14007  });
14008 
14009  return sizeof(std::int32_t) + document_size + 1ul;
14010  }
14011 
14016  void write_bson_object(const typename BasicJsonType::object_t& value)
14017  {
14018  write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
14019 
14020  for (const auto& el : value)
14021  {
14022  write_bson_element(el.first, el.second);
14023  }
14024 
14025  oa->write_character(to_char_type(0x00));
14026  }
14027 
14029  // CBOR //
14031 
14032  static constexpr CharType get_cbor_float_prefix(float /*unused*/)
14033  {
14034  return to_char_type(0xFA); // Single-Precision Float
14035  }
14036 
14037  static constexpr CharType get_cbor_float_prefix(double /*unused*/)
14038  {
14039  return to_char_type(0xFB); // Double-Precision Float
14040  }
14041 
14043  // MsgPack //
14045 
14046  static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
14047  {
14048  return to_char_type(0xCA); // float 32
14049  }
14050 
14051  static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
14052  {
14053  return to_char_type(0xCB); // float 64
14054  }
14055 
14057  // UBJSON //
14059 
14060  // UBJSON: write number (floating point)
14061  template<typename NumberType, typename std::enable_if<
14062  std::is_floating_point<NumberType>::value, int>::type = 0>
14063  void write_number_with_ubjson_prefix(const NumberType n,
14064  const bool add_prefix)
14065  {
14066  if (add_prefix)
14067  {
14068  oa->write_character(get_ubjson_float_prefix(n));
14069  }
14070  write_number(n);
14071  }
14072 
14073  // UBJSON: write number (unsigned integer)
14074  template<typename NumberType, typename std::enable_if<
14075  std::is_unsigned<NumberType>::value, int>::type = 0>
14076  void write_number_with_ubjson_prefix(const NumberType n,
14077  const bool add_prefix)
14078  {
14079  if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14080  {
14081  if (add_prefix)
14082  {
14083  oa->write_character(to_char_type('i')); // int8
14084  }
14085  write_number(static_cast<std::uint8_t>(n));
14086  }
14087  else if (n <= (std::numeric_limits<std::uint8_t>::max)())
14088  {
14089  if (add_prefix)
14090  {
14091  oa->write_character(to_char_type('U')); // uint8
14092  }
14093  write_number(static_cast<std::uint8_t>(n));
14094  }
14095  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14096  {
14097  if (add_prefix)
14098  {
14099  oa->write_character(to_char_type('I')); // int16
14100  }
14101  write_number(static_cast<std::int16_t>(n));
14102  }
14103  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14104  {
14105  if (add_prefix)
14106  {
14107  oa->write_character(to_char_type('l')); // int32
14108  }
14109  write_number(static_cast<std::int32_t>(n));
14110  }
14111  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14112  {
14113  if (add_prefix)
14114  {
14115  oa->write_character(to_char_type('L')); // int64
14116  }
14117  write_number(static_cast<std::int64_t>(n));
14118  }
14119  else
14120  {
14121  if (add_prefix)
14122  {
14123  oa->write_character(to_char_type('H')); // high-precision number
14124  }
14125 
14126  const auto number = BasicJsonType(n).dump();
14127  write_number_with_ubjson_prefix(number.size(), true);
14128  for (std::size_t i = 0; i < number.size(); ++i)
14129  {
14130  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14131  }
14132  }
14133  }
14134 
14135  // UBJSON: write number (signed integer)
14136  template < typename NumberType, typename std::enable_if <
14137  std::is_signed<NumberType>::value&&
14138  !std::is_floating_point<NumberType>::value, int >::type = 0 >
14139  void write_number_with_ubjson_prefix(const NumberType n,
14140  const bool add_prefix)
14141  {
14143  {
14144  if (add_prefix)
14145  {
14146  oa->write_character(to_char_type('i')); // int8
14147  }
14148  write_number(static_cast<std::int8_t>(n));
14149  }
14150  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)()))
14151  {
14152  if (add_prefix)
14153  {
14154  oa->write_character(to_char_type('U')); // uint8
14155  }
14156  write_number(static_cast<std::uint8_t>(n));
14157  }
14159  {
14160  if (add_prefix)
14161  {
14162  oa->write_character(to_char_type('I')); // int16
14163  }
14164  write_number(static_cast<std::int16_t>(n));
14165  }
14167  {
14168  if (add_prefix)
14169  {
14170  oa->write_character(to_char_type('l')); // int32
14171  }
14172  write_number(static_cast<std::int32_t>(n));
14173  }
14175  {
14176  if (add_prefix)
14177  {
14178  oa->write_character(to_char_type('L')); // int64
14179  }
14180  write_number(static_cast<std::int64_t>(n));
14181  }
14182  // LCOV_EXCL_START
14183  else
14184  {
14185  if (add_prefix)
14186  {
14187  oa->write_character(to_char_type('H')); // high-precision number
14188  }
14189 
14190  const auto number = BasicJsonType(n).dump();
14191  write_number_with_ubjson_prefix(number.size(), true);
14192  for (std::size_t i = 0; i < number.size(); ++i)
14193  {
14194  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14195  }
14196  }
14197  // LCOV_EXCL_STOP
14198  }
14199 
14203  CharType ubjson_prefix(const BasicJsonType& j) const noexcept
14204  {
14205  switch (j.type())
14206  {
14207  case value_t::null:
14208  return 'Z';
14209 
14210  case value_t::boolean:
14211  return j.m_value.boolean ? 'T' : 'F';
14212 
14214  {
14215  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)())
14216  {
14217  return 'i';
14218  }
14219  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)())
14220  {
14221  return 'U';
14222  }
14223  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)())
14224  {
14225  return 'I';
14226  }
14227  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)())
14228  {
14229  return 'l';
14230  }
14231  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)())
14232  {
14233  return 'L';
14234  }
14235  // anything else is treated as high-precision number
14236  return 'H'; // LCOV_EXCL_LINE
14237  }
14238 
14240  {
14241  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14242  {
14243  return 'i';
14244  }
14245  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
14246  {
14247  return 'U';
14248  }
14249  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14250  {
14251  return 'I';
14252  }
14253  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14254  {
14255  return 'l';
14256  }
14257  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14258  {
14259  return 'L';
14260  }
14261  // anything else is treated as high-precision number
14262  return 'H'; // LCOV_EXCL_LINE
14263  }
14264 
14265  case value_t::number_float:
14266  return get_ubjson_float_prefix(j.m_value.number_float);
14267 
14268  case value_t::string:
14269  return 'S';
14270 
14271  case value_t::array: // fallthrough
14272  case value_t::binary:
14273  return '[';
14274 
14275  case value_t::object:
14276  return '{';
14277 
14278  default: // discarded values
14279  return 'N';
14280  }
14281  }
14282 
14283  static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
14284  {
14285  return 'd'; // float 32
14286  }
14287 
14288  static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
14289  {
14290  return 'D'; // float 64
14291  }
14292 
14294  // Utility functions //
14296 
14297  /*
14298  @brief write a number to output input
14299  @param[in] n number of type @a NumberType
14300  @tparam NumberType the type of the number
14301  @tparam OutputIsLittleEndian Set to true if output data is
14302  required to be little endian
14303 
14304  @note This function needs to respect the system's endianess, because bytes
14305  in CBOR, MessagePack, and UBJSON are stored in network order (big
14306  endian) and therefore need reordering on little endian systems.
14307  */
14308  template<typename NumberType, bool OutputIsLittleEndian = false>
14309  void write_number(const NumberType n)
14310  {
14311  // step 1: write number to array of length NumberType
14312  std::array<CharType, sizeof(NumberType)> vec;
14313  std::memcpy(vec.data(), &n, sizeof(NumberType));
14314 
14315  // step 2: write array to output (with possible reordering)
14316  if (is_little_endian != OutputIsLittleEndian)
14317  {
14318  // reverse byte order prior to conversion if necessary
14319  std::reverse(vec.begin(), vec.end());
14320  }
14321 
14322  oa->write_characters(vec.data(), sizeof(NumberType));
14323  }
14324 
14326  {
14327  if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
14328  static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
14329  static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
14330  {
14331  oa->write_character(format == detail::input_format_t::cbor
14332  ? get_cbor_float_prefix(static_cast<float>(n))
14333  : get_msgpack_float_prefix(static_cast<float>(n)));
14334  write_number(static_cast<float>(n));
14335  }
14336  else
14337  {
14338  oa->write_character(format == detail::input_format_t::cbor
14341  write_number(n);
14342  }
14343  }
14344 
14345  public:
14346  // The following to_char_type functions are implement the conversion
14347  // between uint8_t and CharType. In case CharType is not unsigned,
14348  // such a conversion is required to allow values greater than 128.
14349  // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
14350  template < typename C = CharType,
14351  enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
14352  static constexpr CharType to_char_type(std::uint8_t x) noexcept
14353  {
14354  return *reinterpret_cast<char*>(&x);
14355  }
14356 
14357  template < typename C = CharType,
14358  enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
14359  static CharType to_char_type(std::uint8_t x) noexcept
14360  {
14361  static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
14362  static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
14363  CharType result;
14364  std::memcpy(&result, &x, sizeof(x));
14365  return result;
14366  }
14367 
14368  template<typename C = CharType,
14370  static constexpr CharType to_char_type(std::uint8_t x) noexcept
14371  {
14372  return x;
14373  }
14374 
14375  template < typename InputCharType, typename C = CharType,
14376  enable_if_t <
14377  std::is_signed<C>::value &&
14378  std::is_signed<char>::value &&
14379  std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
14380  > * = nullptr >
14381  static constexpr CharType to_char_type(InputCharType x) noexcept
14382  {
14383  return x;
14384  }
14385 
14386  private:
14389 
14392 };
14393 } // namespace detail
14394 } // namespace nlohmann
14395 
14396 // #include <nlohmann/detail/output/output_adapters.hpp>
14397 
14398 // #include <nlohmann/detail/output/serializer.hpp>
14399 
14400 
14401 #include <algorithm> // reverse, remove, fill, find, none_of
14402 #include <array> // array
14403 #include <clocale> // localeconv, lconv
14404 #include <cmath> // labs, isfinite, isnan, signbit
14405 #include <cstddef> // size_t, ptrdiff_t
14406 #include <cstdint> // uint8_t
14407 #include <cstdio> // snprintf
14408 #include <limits> // numeric_limits
14409 #include <string> // string, char_traits
14410 #include <type_traits> // is_same
14411 #include <utility> // move
14412 
14413 // #include <nlohmann/detail/conversions/to_chars.hpp>
14414 
14415 
14416 #include <array> // array
14417 #include <cmath> // signbit, isfinite
14418 #include <cstdint> // intN_t, uintN_t
14419 #include <cstring> // memcpy, memmove
14420 #include <limits> // numeric_limits
14421 #include <type_traits> // conditional
14422 
14423 // #include <nlohmann/detail/macro_scope.hpp>
14424 
14425 
14426 namespace nlohmann
14427 {
14428 namespace detail
14429 {
14430 
14450 namespace dtoa_impl
14451 {
14452 
14453 template<typename Target, typename Source>
14454 Target reinterpret_bits(const Source source)
14455 {
14456  static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
14457 
14458  Target target;
14459  std::memcpy(&target, &source, sizeof(Source));
14460  return target;
14461 }
14462 
14463 struct diyfp // f * 2^e
14464 {
14465  static constexpr int kPrecision = 64; // = q
14466 
14467  std::uint64_t f = 0;
14468  int e = 0;
14469 
14470  constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
14471 
14476  static diyfp sub(const diyfp& x, const diyfp& y) noexcept
14477  {
14478  JSON_ASSERT(x.e == y.e);
14479  JSON_ASSERT(x.f >= y.f);
14480 
14481  return {x.f - y.f, x.e};
14482  }
14483 
14488  static diyfp mul(const diyfp& x, const diyfp& y) noexcept
14489  {
14490  static_assert(kPrecision == 64, "internal error");
14491 
14492  // Computes:
14493  // f = round((x.f * y.f) / 2^q)
14494  // e = x.e + y.e + q
14495 
14496  // Emulate the 64-bit * 64-bit multiplication:
14497  //
14498  // p = u * v
14499  // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
14500  // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
14501  // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
14502  // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
14503  // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
14504  // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
14505  // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
14506  //
14507  // (Since Q might be larger than 2^32 - 1)
14508  //
14509  // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
14510  //
14511  // (Q_hi + H does not overflow a 64-bit int)
14512  //
14513  // = p_lo + 2^64 p_hi
14514 
14515  const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
14516  const std::uint64_t u_hi = x.f >> 32u;
14517  const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
14518  const std::uint64_t v_hi = y.f >> 32u;
14519 
14520  const std::uint64_t p0 = u_lo * v_lo;
14521  const std::uint64_t p1 = u_lo * v_hi;
14522  const std::uint64_t p2 = u_hi * v_lo;
14523  const std::uint64_t p3 = u_hi * v_hi;
14524 
14525  const std::uint64_t p0_hi = p0 >> 32u;
14526  const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
14527  const std::uint64_t p1_hi = p1 >> 32u;
14528  const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
14529  const std::uint64_t p2_hi = p2 >> 32u;
14530 
14531  std::uint64_t Q = p0_hi + p1_lo + p2_lo;
14532 
14533  // The full product might now be computed as
14534  //
14535  // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
14536  // p_lo = p0_lo + (Q << 32)
14537  //
14538  // But in this particular case here, the full p_lo is not required.
14539  // Effectively we only need to add the highest bit in p_lo to p_hi (and
14540  // Q_hi + 1 does not overflow).
14541 
14542  Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
14543 
14544  const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
14545 
14546  return {h, x.e + y.e + 64};
14547  }
14548 
14553  static diyfp normalize(diyfp x) noexcept
14554  {
14555  JSON_ASSERT(x.f != 0);
14556 
14557  while ((x.f >> 63u) == 0)
14558  {
14559  x.f <<= 1u;
14560  x.e--;
14561  }
14562 
14563  return x;
14564  }
14565 
14570  static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
14571  {
14572  const int delta = x.e - target_exponent;
14573 
14574  JSON_ASSERT(delta >= 0);
14575  JSON_ASSERT(((x.f << delta) >> delta) == x.f);
14576 
14577  return {x.f << delta, target_exponent};
14578  }
14579 };
14580 
14582 {
14586 };
14587 
14594 template<typename FloatType>
14596 {
14597  JSON_ASSERT(std::isfinite(value));
14598  JSON_ASSERT(value > 0);
14599 
14600  // Convert the IEEE representation into a diyfp.
14601  //
14602  // If v is denormal:
14603  // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
14604  // If v is normalized:
14605  // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
14606 
14607  static_assert(std::numeric_limits<FloatType>::is_iec559,
14608  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
14609 
14610  constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
14611  constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
14612  constexpr int kMinExp = 1 - kBias;
14613  constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
14614 
14615  using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
14616 
14617  const std::uint64_t bits = reinterpret_bits<bits_type>(value);
14618  const std::uint64_t E = bits >> (kPrecision - 1);
14619  const std::uint64_t F = bits & (kHiddenBit - 1);
14620 
14621  const bool is_denormal = E == 0;
14622  const diyfp v = is_denormal
14623  ? diyfp(F, kMinExp)
14624  : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
14625 
14626  // Compute the boundaries m- and m+ of the floating-point value
14627  // v = f * 2^e.
14628  //
14629  // Determine v- and v+, the floating-point predecessor and successor if v,
14630  // respectively.
14631  //
14632  // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
14633  // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
14634  //
14635  // v+ = v + 2^e
14636  //
14637  // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
14638  // between m- and m+ round to v, regardless of how the input rounding
14639  // algorithm breaks ties.
14640  //
14641  // ---+-------------+-------------+-------------+-------------+--- (A)
14642  // v- m- v m+ v+
14643  //
14644  // -----------------+------+------+-------------+-------------+--- (B)
14645  // v- m- v m+ v+
14646 
14647  const bool lower_boundary_is_closer = F == 0 && E > 1;
14648  const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
14649  const diyfp m_minus = lower_boundary_is_closer
14650  ? diyfp(4 * v.f - 1, v.e - 2) // (B)
14651  : diyfp(2 * v.f - 1, v.e - 1); // (A)
14652 
14653  // Determine the normalized w+ = m+.
14654  const diyfp w_plus = diyfp::normalize(m_plus);
14655 
14656  // Determine w- = m- such that e_(w-) = e_(w+).
14657  const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
14658 
14659  return {diyfp::normalize(v), w_minus, w_plus};
14660 }
14661 
14662 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
14663 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
14664 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
14665 //
14666 // alpha <= e = e_c + e_w + q <= gamma
14667 //
14668 // or
14669 //
14670 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
14671 // <= f_c * f_w * 2^gamma
14672 //
14673 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
14674 //
14675 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
14676 //
14677 // or
14678 //
14679 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
14680 //
14681 // The choice of (alpha,gamma) determines the size of the table and the form of
14682 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
14683 // in practice:
14684 //
14685 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
14686 // processed independently: An integral part p1, and a fractional part p2:
14687 //
14688 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
14689 // = (f div 2^-e) + (f mod 2^-e) * 2^e
14690 // = p1 + p2 * 2^e
14691 //
14692 // The conversion of p1 into decimal form requires a series of divisions and
14693 // modulos by (a power of) 10. These operations are faster for 32-bit than for
14694 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
14695 // achieved by choosing
14696 //
14697 // -e >= 32 or e <= -32 := gamma
14698 //
14699 // In order to convert the fractional part
14700 //
14701 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
14702 //
14703 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
14704 // d[-i] are extracted in order:
14705 //
14706 // (10 * p2) div 2^-e = d[-1]
14707 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
14708 //
14709 // The multiplication by 10 must not overflow. It is sufficient to choose
14710 //
14711 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
14712 //
14713 // Since p2 = f mod 2^-e < 2^-e,
14714 //
14715 // -e <= 60 or e >= -60 := alpha
14716 
14717 constexpr int kAlpha = -60;
14718 constexpr int kGamma = -32;
14719 
14720 struct cached_power // c = f * 2^e ~= 10^k
14721 {
14722  std::uint64_t f;
14723  int e;
14724  int k;
14725 };
14726 
14735 {
14736  // Now
14737  //
14738  // alpha <= e_c + e + q <= gamma (1)
14739  // ==> f_c * 2^alpha <= c * 2^e * 2^q
14740  //
14741  // and since the c's are normalized, 2^(q-1) <= f_c,
14742  //
14743  // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
14744  // ==> 2^(alpha - e - 1) <= c
14745  //
14746  // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
14747  //
14748  // k = ceil( log_10( 2^(alpha - e - 1) ) )
14749  // = ceil( (alpha - e - 1) * log_10(2) )
14750  //
14751  // From the paper:
14752  // "In theory the result of the procedure could be wrong since c is rounded,
14753  // and the computation itself is approximated [...]. In practice, however,
14754  // this simple function is sufficient."
14755  //
14756  // For IEEE double precision floating-point numbers converted into
14757  // normalized diyfp's w = f * 2^e, with q = 64,
14758  //
14759  // e >= -1022 (min IEEE exponent)
14760  // -52 (p - 1)
14761  // -52 (p - 1, possibly normalize denormal IEEE numbers)
14762  // -11 (normalize the diyfp)
14763  // = -1137
14764  //
14765  // and
14766  //
14767  // e <= +1023 (max IEEE exponent)
14768  // -52 (p - 1)
14769  // -11 (normalize the diyfp)
14770  // = 960
14771  //
14772  // This binary exponent range [-1137,960] results in a decimal exponent
14773  // range [-307,324]. One does not need to store a cached power for each
14774  // k in this range. For each such k it suffices to find a cached power
14775  // such that the exponent of the product lies in [alpha,gamma].
14776  // This implies that the difference of the decimal exponents of adjacent
14777  // table entries must be less than or equal to
14778  //
14779  // floor( (gamma - alpha) * log_10(2) ) = 8.
14780  //
14781  // (A smaller distance gamma-alpha would require a larger table.)
14782 
14783  // NB:
14784  // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
14785 
14786  constexpr int kCachedPowersMinDecExp = -300;
14787  constexpr int kCachedPowersDecStep = 8;
14788 
14789  static constexpr std::array<cached_power, 79> kCachedPowers =
14790  {
14791  {
14792  { 0xAB70FE17C79AC6CA, -1060, -300 },
14793  { 0xFF77B1FCBEBCDC4F, -1034, -292 },
14794  { 0xBE5691EF416BD60C, -1007, -284 },
14795  { 0x8DD01FAD907FFC3C, -980, -276 },
14796  { 0xD3515C2831559A83, -954, -268 },
14797  { 0x9D71AC8FADA6C9B5, -927, -260 },
14798  { 0xEA9C227723EE8BCB, -901, -252 },
14799  { 0xAECC49914078536D, -874, -244 },
14800  { 0x823C12795DB6CE57, -847, -236 },
14801  { 0xC21094364DFB5637, -821, -228 },
14802  { 0x9096EA6F3848984F, -794, -220 },
14803  { 0xD77485CB25823AC7, -768, -212 },
14804  { 0xA086CFCD97BF97F4, -741, -204 },
14805  { 0xEF340A98172AACE5, -715, -196 },
14806  { 0xB23867FB2A35B28E, -688, -188 },
14807  { 0x84C8D4DFD2C63F3B, -661, -180 },
14808  { 0xC5DD44271AD3CDBA, -635, -172 },
14809  { 0x936B9FCEBB25C996, -608, -164 },
14810  { 0xDBAC6C247D62A584, -582, -156 },
14811  { 0xA3AB66580D5FDAF6, -555, -148 },
14812  { 0xF3E2F893DEC3F126, -529, -140 },
14813  { 0xB5B5ADA8AAFF80B8, -502, -132 },
14814  { 0x87625F056C7C4A8B, -475, -124 },
14815  { 0xC9BCFF6034C13053, -449, -116 },
14816  { 0x964E858C91BA2655, -422, -108 },
14817  { 0xDFF9772470297EBD, -396, -100 },
14818  { 0xA6DFBD9FB8E5B88F, -369, -92 },
14819  { 0xF8A95FCF88747D94, -343, -84 },
14820  { 0xB94470938FA89BCF, -316, -76 },
14821  { 0x8A08F0F8BF0F156B, -289, -68 },
14822  { 0xCDB02555653131B6, -263, -60 },
14823  { 0x993FE2C6D07B7FAC, -236, -52 },
14824  { 0xE45C10C42A2B3B06, -210, -44 },
14825  { 0xAA242499697392D3, -183, -36 },
14826  { 0xFD87B5F28300CA0E, -157, -28 },
14827  { 0xBCE5086492111AEB, -130, -20 },
14828  { 0x8CBCCC096F5088CC, -103, -12 },
14829  { 0xD1B71758E219652C, -77, -4 },
14830  { 0x9C40000000000000, -50, 4 },
14831  { 0xE8D4A51000000000, -24, 12 },
14832  { 0xAD78EBC5AC620000, 3, 20 },
14833  { 0x813F3978F8940984, 30, 28 },
14834  { 0xC097CE7BC90715B3, 56, 36 },
14835  { 0x8F7E32CE7BEA5C70, 83, 44 },
14836  { 0xD5D238A4ABE98068, 109, 52 },
14837  { 0x9F4F2726179A2245, 136, 60 },
14838  { 0xED63A231D4C4FB27, 162, 68 },
14839  { 0xB0DE65388CC8ADA8, 189, 76 },
14840  { 0x83C7088E1AAB65DB, 216, 84 },
14841  { 0xC45D1DF942711D9A, 242, 92 },
14842  { 0x924D692CA61BE758, 269, 100 },
14843  { 0xDA01EE641A708DEA, 295, 108 },
14844  { 0xA26DA3999AEF774A, 322, 116 },
14845  { 0xF209787BB47D6B85, 348, 124 },
14846  { 0xB454E4A179DD1877, 375, 132 },
14847  { 0x865B86925B9BC5C2, 402, 140 },
14848  { 0xC83553C5C8965D3D, 428, 148 },
14849  { 0x952AB45CFA97A0B3, 455, 156 },
14850  { 0xDE469FBD99A05FE3, 481, 164 },
14851  { 0xA59BC234DB398C25, 508, 172 },
14852  { 0xF6C69A72A3989F5C, 534, 180 },
14853  { 0xB7DCBF5354E9BECE, 561, 188 },
14854  { 0x88FCF317F22241E2, 588, 196 },
14855  { 0xCC20CE9BD35C78A5, 614, 204 },
14856  { 0x98165AF37B2153DF, 641, 212 },
14857  { 0xE2A0B5DC971F303A, 667, 220 },
14858  { 0xA8D9D1535CE3B396, 694, 228 },
14859  { 0xFB9B7CD9A4A7443C, 720, 236 },
14860  { 0xBB764C4CA7A44410, 747, 244 },
14861  { 0x8BAB8EEFB6409C1A, 774, 252 },
14862  { 0xD01FEF10A657842C, 800, 260 },
14863  { 0x9B10A4E5E9913129, 827, 268 },
14864  { 0xE7109BFBA19C0C9D, 853, 276 },
14865  { 0xAC2820D9623BF429, 880, 284 },
14866  { 0x80444B5E7AA7CF85, 907, 292 },
14867  { 0xBF21E44003ACDD2D, 933, 300 },
14868  { 0x8E679C2F5E44FF8F, 960, 308 },
14869  { 0xD433179D9C8CB841, 986, 316 },
14870  { 0x9E19DB92B4E31BA9, 1013, 324 },
14871  }
14872  };
14873 
14874  // This computation gives exactly the same results for k as
14875  // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
14876  // for |e| <= 1500, but doesn't require floating-point operations.
14877  // NB: log_10(2) ~= 78913 / 2^18
14878  JSON_ASSERT(e >= -1500);
14879  JSON_ASSERT(e <= 1500);
14880  const int f = kAlpha - e - 1;
14881  const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
14882 
14883  const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
14884  JSON_ASSERT(index >= 0);
14885  JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
14886 
14887  const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
14888  JSON_ASSERT(kAlpha <= cached.e + e + 64);
14889  JSON_ASSERT(kGamma >= cached.e + e + 64);
14890 
14891  return cached;
14892 }
14893 
14898 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
14899 {
14900  // LCOV_EXCL_START
14901  if (n >= 1000000000)
14902  {
14903  pow10 = 1000000000;
14904  return 10;
14905  }
14906  // LCOV_EXCL_STOP
14907  else if (n >= 100000000)
14908  {
14909  pow10 = 100000000;
14910  return 9;
14911  }
14912  else if (n >= 10000000)
14913  {
14914  pow10 = 10000000;
14915  return 8;
14916  }
14917  else if (n >= 1000000)
14918  {
14919  pow10 = 1000000;
14920  return 7;
14921  }
14922  else if (n >= 100000)
14923  {
14924  pow10 = 100000;
14925  return 6;
14926  }
14927  else if (n >= 10000)
14928  {
14929  pow10 = 10000;
14930  return 5;
14931  }
14932  else if (n >= 1000)
14933  {
14934  pow10 = 1000;
14935  return 4;
14936  }
14937  else if (n >= 100)
14938  {
14939  pow10 = 100;
14940  return 3;
14941  }
14942  else if (n >= 10)
14943  {
14944  pow10 = 10;
14945  return 2;
14946  }
14947  else
14948  {
14949  pow10 = 1;
14950  return 1;
14951  }
14952 }
14953 
14954 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
14955  std::uint64_t rest, std::uint64_t ten_k)
14956 {
14957  JSON_ASSERT(len >= 1);
14958  JSON_ASSERT(dist <= delta);
14959  JSON_ASSERT(rest <= delta);
14960  JSON_ASSERT(ten_k > 0);
14961 
14962  // <--------------------------- delta ---->
14963  // <---- dist --------->
14964  // --------------[------------------+-------------------]--------------
14965  // M- w M+
14966  //
14967  // ten_k
14968  // <------>
14969  // <---- rest ---->
14970  // --------------[------------------+----+--------------]--------------
14971  // w V
14972  // = buf * 10^k
14973  //
14974  // ten_k represents a unit-in-the-last-place in the decimal representation
14975  // stored in buf.
14976  // Decrement buf by ten_k while this takes buf closer to w.
14977 
14978  // The tests are written in this order to avoid overflow in unsigned
14979  // integer arithmetic.
14980 
14981  while (rest < dist
14982  && delta - rest >= ten_k
14983  && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
14984  {
14985  JSON_ASSERT(buf[len - 1] != '0');
14986  buf[len - 1]--;
14987  rest += ten_k;
14988  }
14989 }
14990 
14995 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
14996  diyfp M_minus, diyfp w, diyfp M_plus)
14997 {
14998  static_assert(kAlpha >= -60, "internal error");
14999  static_assert(kGamma <= -32, "internal error");
15000 
15001  // Generates the digits (and the exponent) of a decimal floating-point
15002  // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
15003  // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
15004  //
15005  // <--------------------------- delta ---->
15006  // <---- dist --------->
15007  // --------------[------------------+-------------------]--------------
15008  // M- w M+
15009  //
15010  // Grisu2 generates the digits of M+ from left to right and stops as soon as
15011  // V is in [M-,M+].
15012 
15013  JSON_ASSERT(M_plus.e >= kAlpha);
15014  JSON_ASSERT(M_plus.e <= kGamma);
15015 
15016  std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
15017  std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
15018 
15019  // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
15020  //
15021  // M+ = f * 2^e
15022  // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
15023  // = ((p1 ) * 2^-e + (p2 )) * 2^e
15024  // = p1 + p2 * 2^e
15025 
15026  const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
15027 
15028  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.)
15029  std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
15030 
15031  // 1)
15032  //
15033  // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
15034 
15035  JSON_ASSERT(p1 > 0);
15036 
15037  std::uint32_t pow10;
15038  const int k = find_largest_pow10(p1, pow10);
15039 
15040  // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
15041  //
15042  // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
15043  // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
15044  //
15045  // M+ = p1 + p2 * 2^e
15046  // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
15047  // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
15048  // = d[k-1] * 10^(k-1) + ( rest) * 2^e
15049  //
15050  // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
15051  //
15052  // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
15053  //
15054  // but stop as soon as
15055  //
15056  // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
15057 
15058  int n = k;
15059  while (n > 0)
15060  {
15061  // Invariants:
15062  // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
15063  // pow10 = 10^(n-1) <= p1 < 10^n
15064  //
15065  const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
15066  const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
15067  //
15068  // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
15069  // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
15070  //
15071  JSON_ASSERT(d <= 9);
15072  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15073  //
15074  // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
15075  //
15076  p1 = r;
15077  n--;
15078  //
15079  // M+ = buffer * 10^n + (p1 + p2 * 2^e)
15080  // pow10 = 10^n
15081  //
15082 
15083  // Now check if enough digits have been generated.
15084  // Compute
15085  //
15086  // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
15087  //
15088  // Note:
15089  // Since rest and delta share the same exponent e, it suffices to
15090  // compare the significands.
15091  const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
15092  if (rest <= delta)
15093  {
15094  // V = buffer * 10^n, with M- <= V <= M+.
15095 
15096  decimal_exponent += n;
15097 
15098  // We may now just stop. But instead look if the buffer could be
15099  // decremented to bring V closer to w.
15100  //
15101  // pow10 = 10^n is now 1 ulp in the decimal representation V.
15102  // The rounding procedure works with diyfp's with an implicit
15103  // exponent of e.
15104  //
15105  // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
15106  //
15107  const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
15108  grisu2_round(buffer, length, dist, delta, rest, ten_n);
15109 
15110  return;
15111  }
15112 
15113  pow10 /= 10;
15114  //
15115  // pow10 = 10^(n-1) <= p1 < 10^n
15116  // Invariants restored.
15117  }
15118 
15119  // 2)
15120  //
15121  // The digits of the integral part have been generated:
15122  //
15123  // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
15124  // = buffer + p2 * 2^e
15125  //
15126  // Now generate the digits of the fractional part p2 * 2^e.
15127  //
15128  // Note:
15129  // No decimal point is generated: the exponent is adjusted instead.
15130  //
15131  // p2 actually represents the fraction
15132  //
15133  // p2 * 2^e
15134  // = p2 / 2^-e
15135  // = d[-1] / 10^1 + d[-2] / 10^2 + ...
15136  //
15137  // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
15138  //
15139  // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
15140  // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
15141  //
15142  // using
15143  //
15144  // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
15145  // = ( d) * 2^-e + ( r)
15146  //
15147  // or
15148  // 10^m * p2 * 2^e = d + r * 2^e
15149  //
15150  // i.e.
15151  //
15152  // M+ = buffer + p2 * 2^e
15153  // = buffer + 10^-m * (d + r * 2^e)
15154  // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
15155  //
15156  // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
15157 
15158  JSON_ASSERT(p2 > delta);
15159 
15160  int m = 0;
15161  for (;;)
15162  {
15163  // Invariant:
15164  // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
15165  // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
15166  // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
15167  // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
15168  //
15170  p2 *= 10;
15171  const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
15172  const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
15173  //
15174  // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
15175  // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
15176  // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
15177  //
15178  JSON_ASSERT(d <= 9);
15179  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15180  //
15181  // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
15182  //
15183  p2 = r;
15184  m++;
15185  //
15186  // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
15187  // Invariant restored.
15188 
15189  // Check if enough digits have been generated.
15190  //
15191  // 10^-m * p2 * 2^e <= delta * 2^e
15192  // p2 * 2^e <= 10^m * delta * 2^e
15193  // p2 <= 10^m * delta
15194  delta *= 10;
15195  dist *= 10;
15196  if (p2 <= delta)
15197  {
15198  break;
15199  }
15200  }
15201 
15202  // V = buffer * 10^-m, with M- <= V <= M+.
15203 
15204  decimal_exponent -= m;
15205 
15206  // 1 ulp in the decimal representation is now 10^-m.
15207  // Since delta and dist are now scaled by 10^m, we need to do the
15208  // same with ulp in order to keep the units in sync.
15209  //
15210  // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
15211  //
15212  const std::uint64_t ten_m = one.f;
15213  grisu2_round(buffer, length, dist, delta, p2, ten_m);
15214 
15215  // By construction this algorithm generates the shortest possible decimal
15216  // number (Loitsch, Theorem 6.2) which rounds back to w.
15217  // For an input number of precision p, at least
15218  //
15219  // N = 1 + ceil(p * log_10(2))
15220  //
15221  // decimal digits are sufficient to identify all binary floating-point
15222  // numbers (Matula, "In-and-Out conversions").
15223  // This implies that the algorithm does not produce more than N decimal
15224  // digits.
15225  //
15226  // N = 17 for p = 53 (IEEE double precision)
15227  // N = 9 for p = 24 (IEEE single precision)
15228 }
15229 
15236 inline void grisu2(char* buf, int& len, int& decimal_exponent,
15237  diyfp m_minus, diyfp v, diyfp m_plus)
15238 {
15239  JSON_ASSERT(m_plus.e == m_minus.e);
15240  JSON_ASSERT(m_plus.e == v.e);
15241 
15242  // --------(-----------------------+-----------------------)-------- (A)
15243  // m- v m+
15244  //
15245  // --------------------(-----------+-----------------------)-------- (B)
15246  // m- v m+
15247  //
15248  // First scale v (and m- and m+) such that the exponent is in the range
15249  // [alpha, gamma].
15250 
15251  const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
15252 
15253  const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
15254 
15255  // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
15256  const diyfp w = diyfp::mul(v, c_minus_k);
15257  const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
15258  const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
15259 
15260  // ----(---+---)---------------(---+---)---------------(---+---)----
15261  // w- w w+
15262  // = c*m- = c*v = c*m+
15263  //
15264  // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
15265  // w+ are now off by a small amount.
15266  // In fact:
15267  //
15268  // w - v * 10^k < 1 ulp
15269  //
15270  // To account for this inaccuracy, add resp. subtract 1 ulp.
15271  //
15272  // --------+---[---------------(---+---)---------------]---+--------
15273  // w- M- w M+ w+
15274  //
15275  // Now any number in [M-, M+] (bounds included) will round to w when input,
15276  // regardless of how the input rounding algorithm breaks ties.
15277  //
15278  // And digit_gen generates the shortest possible such number in [M-, M+].
15279  // Note that this does not mean that Grisu2 always generates the shortest
15280  // possible number in the interval (m-, m+).
15281  const diyfp M_minus(w_minus.f + 1, w_minus.e);
15282  const diyfp M_plus (w_plus.f - 1, w_plus.e );
15283 
15284  decimal_exponent = -cached.k; // = -(-k) = k
15285 
15286  grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
15287 }
15288 
15294 template<typename FloatType>
15296 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
15297 {
15298  static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
15299  "internal error: not enough precision");
15300 
15301  JSON_ASSERT(std::isfinite(value));
15302  JSON_ASSERT(value > 0);
15303 
15304  // If the neighbors (and boundaries) of 'value' are always computed for double-precision
15305  // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
15306  // decimal representations are not exactly "short".
15307  //
15308  // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
15309  // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
15310  // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
15311  // does.
15312  // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
15313  // representation using the corresponding std::from_chars function recovers value exactly". That
15314  // indicates that single precision floating-point numbers should be recovered using
15315  // 'std::strtof'.
15316  //
15317  // NB: If the neighbors are computed for single-precision numbers, there is a single float
15318  // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
15319  // value is off by 1 ulp.
15320 #if 0
15321  const boundaries w = compute_boundaries(static_cast<double>(value));
15322 #else
15323  const boundaries w = compute_boundaries(value);
15324 #endif
15325 
15326  grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
15327 }
15328 
15336 inline char* append_exponent(char* buf, int e)
15337 {
15338  JSON_ASSERT(e > -1000);
15339  JSON_ASSERT(e < 1000);
15340 
15341  if (e < 0)
15342  {
15343  e = -e;
15344  *buf++ = '-';
15345  }
15346  else
15347  {
15348  *buf++ = '+';
15349  }
15350 
15351  auto k = static_cast<std::uint32_t>(e);
15352  if (k < 10)
15353  {
15354  // Always print at least two digits in the exponent.
15355  // This is for compatibility with printf("%g").
15356  *buf++ = '0';
15357  *buf++ = static_cast<char>('0' + k);
15358  }
15359  else if (k < 100)
15360  {
15361  *buf++ = static_cast<char>('0' + k / 10);
15362  k %= 10;
15363  *buf++ = static_cast<char>('0' + k);
15364  }
15365  else
15366  {
15367  *buf++ = static_cast<char>('0' + k / 100);
15368  k %= 100;
15369  *buf++ = static_cast<char>('0' + k / 10);
15370  k %= 10;
15371  *buf++ = static_cast<char>('0' + k);
15372  }
15373 
15374  return buf;
15375 }
15376 
15388 inline char* format_buffer(char* buf, int len, int decimal_exponent,
15389  int min_exp, int max_exp)
15390 {
15391  JSON_ASSERT(min_exp < 0);
15392  JSON_ASSERT(max_exp > 0);
15393 
15394  const int k = len;
15395  const int n = len + decimal_exponent;
15396 
15397  // v = buf * 10^(n-k)
15398  // k is the length of the buffer (number of decimal digits)
15399  // n is the position of the decimal point relative to the start of the buffer.
15400 
15401  if (k <= n && n <= max_exp)
15402  {
15403  // digits[000]
15404  // len <= max_exp + 2
15405 
15406  std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
15407  // Make it look like a floating-point number (#362, #378)
15408  buf[n + 0] = '.';
15409  buf[n + 1] = '0';
15410  return buf + (static_cast<size_t>(n) + 2);
15411  }
15412 
15413  if (0 < n && n <= max_exp)
15414  {
15415  // dig.its
15416  // len <= max_digits10 + 1
15417 
15418  JSON_ASSERT(k > n);
15419 
15420  std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
15421  buf[n] = '.';
15422  return buf + (static_cast<size_t>(k) + 1U);
15423  }
15424 
15425  if (min_exp < n && n <= 0)
15426  {
15427  // 0.[000]digits
15428  // len <= 2 + (-min_exp - 1) + max_digits10
15429 
15430  std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
15431  buf[0] = '0';
15432  buf[1] = '.';
15433  std::memset(buf + 2, '0', static_cast<size_t>(-n));
15434  return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
15435  }
15436 
15437  if (k == 1)
15438  {
15439  // dE+123
15440  // len <= 1 + 5
15441 
15442  buf += 1;
15443  }
15444  else
15445  {
15446  // d.igitsE+123
15447  // len <= max_digits10 + 1 + 5
15448 
15449  std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
15450  buf[1] = '.';
15451  buf += 1 + static_cast<size_t>(k);
15452  }
15453 
15454  *buf++ = 'e';
15455  return append_exponent(buf, n - 1);
15456 }
15457 
15458 } // namespace dtoa_impl
15459 
15470 template<typename FloatType>
15473 char* to_chars(char* first, const char* last, FloatType value)
15474 {
15475  static_cast<void>(last); // maybe unused - fix warning
15476  JSON_ASSERT(std::isfinite(value));
15477 
15478  // Use signbit(value) instead of (value < 0) since signbit works for -0.
15479  if (std::signbit(value))
15480  {
15481  value = -value;
15482  *first++ = '-';
15483  }
15484 
15485  if (value == 0) // +-0
15486  {
15487  *first++ = '0';
15488  // Make it look like a floating-point number (#362, #378)
15489  *first++ = '.';
15490  *first++ = '0';
15491  return first;
15492  }
15493 
15494  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
15495 
15496  // Compute v = buffer * 10^decimal_exponent.
15497  // The decimal digits are stored in the buffer, which needs to be interpreted
15498  // as an unsigned decimal integer.
15499  // len is the length of the buffer, i.e. the number of decimal digits.
15500  int len = 0;
15501  int decimal_exponent = 0;
15502  dtoa_impl::grisu2(first, len, decimal_exponent, value);
15503 
15504  JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
15505 
15506  // Format the buffer like printf("%.*g", prec, value)
15507  constexpr int kMinExp = -4;
15508  // Use digits10 here to increase compatibility with version 2.
15509  constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
15510 
15511  JSON_ASSERT(last - first >= kMaxExp + 2);
15512  JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
15513  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
15514 
15515  return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
15516 }
15517 
15518 } // namespace detail
15519 } // namespace nlohmann
15520 
15521 // #include <nlohmann/detail/exceptions.hpp>
15522 
15523 // #include <nlohmann/detail/macro_scope.hpp>
15524 
15525 // #include <nlohmann/detail/meta/cpp_future.hpp>
15526 
15527 // #include <nlohmann/detail/output/binary_writer.hpp>
15528 
15529 // #include <nlohmann/detail/output/output_adapters.hpp>
15530 
15531 // #include <nlohmann/detail/value_t.hpp>
15532 
15533 
15534 namespace nlohmann
15535 {
15536 namespace detail
15537 {
15539 // serialization //
15541 
15544 {
15545  strict,
15546  replace,
15547  ignore
15548 };
15549 
15550 template<typename BasicJsonType>
15552 {
15553  using string_t = typename BasicJsonType::string_t;
15554  using number_float_t = typename BasicJsonType::number_float_t;
15555  using number_integer_t = typename BasicJsonType::number_integer_t;
15556  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
15557  using binary_char_t = typename BasicJsonType::binary_t::value_type;
15558  static constexpr std::uint8_t UTF8_ACCEPT = 0;
15559  static constexpr std::uint8_t UTF8_REJECT = 1;
15560 
15561  public:
15567  serializer(output_adapter_t<char> s, const char ichar,
15568  error_handler_t error_handler_ = error_handler_t::strict)
15569  : o(std::move(s))
15570  , loc(std::localeconv())
15571  , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
15572  , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
15573  , indent_char(ichar)
15574  , indent_string(512, indent_char)
15575  , error_handler(error_handler_)
15576  {}
15577 
15578  // delete because of pointer members
15579  serializer(const serializer&) = delete;
15580  serializer& operator=(const serializer&) = delete;
15581  serializer(serializer&&) = delete;
15583  ~serializer() = default;
15584 
15607  void dump(const BasicJsonType& val,
15608  const bool pretty_print,
15609  const bool ensure_ascii,
15610  const unsigned int indent_step,
15611  const unsigned int current_indent = 0)
15612  {
15613  switch (val.m_type)
15614  {
15615  case value_t::object:
15616  {
15617  if (val.m_value.object->empty())
15618  {
15619  o->write_characters("{}", 2);
15620  return;
15621  }
15622 
15623  if (pretty_print)
15624  {
15625  o->write_characters("{\n", 2);
15626 
15627  // variable to hold indentation for recursive calls
15628  const auto new_indent = current_indent + indent_step;
15629  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15630  {
15631  indent_string.resize(indent_string.size() * 2, ' ');
15632  }
15633 
15634  // first n-1 elements
15635  auto i = val.m_value.object->cbegin();
15636  for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15637  {
15638  o->write_characters(indent_string.c_str(), new_indent);
15639  o->write_character('\"');
15640  dump_escaped(i->first, ensure_ascii);
15641  o->write_characters("\": ", 3);
15642  dump(i->second, true, ensure_ascii, indent_step, new_indent);
15643  o->write_characters(",\n", 2);
15644  }
15645 
15646  // last element
15647  JSON_ASSERT(i != val.m_value.object->cend());
15648  JSON_ASSERT(std::next(i) == val.m_value.object->cend());
15649  o->write_characters(indent_string.c_str(), new_indent);
15650  o->write_character('\"');
15651  dump_escaped(i->first, ensure_ascii);
15652  o->write_characters("\": ", 3);
15653  dump(i->second, true, ensure_ascii, indent_step, new_indent);
15654 
15655  o->write_character('\n');
15656  o->write_characters(indent_string.c_str(), current_indent);
15657  o->write_character('}');
15658  }
15659  else
15660  {
15661  o->write_character('{');
15662 
15663  // first n-1 elements
15664  auto i = val.m_value.object->cbegin();
15665  for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15666  {
15667  o->write_character('\"');
15668  dump_escaped(i->first, ensure_ascii);
15669  o->write_characters("\":", 2);
15670  dump(i->second, false, ensure_ascii, indent_step, current_indent);
15671  o->write_character(',');
15672  }
15673 
15674  // last element
15675  JSON_ASSERT(i != val.m_value.object->cend());
15676  JSON_ASSERT(std::next(i) == val.m_value.object->cend());
15677  o->write_character('\"');
15678  dump_escaped(i->first, ensure_ascii);
15679  o->write_characters("\":", 2);
15680  dump(i->second, false, ensure_ascii, indent_step, current_indent);
15681 
15682  o->write_character('}');
15683  }
15684 
15685  return;
15686  }
15687 
15688  case value_t::array:
15689  {
15690  if (val.m_value.array->empty())
15691  {
15692  o->write_characters("[]", 2);
15693  return;
15694  }
15695 
15696  if (pretty_print)
15697  {
15698  o->write_characters("[\n", 2);
15699 
15700  // variable to hold indentation for recursive calls
15701  const auto new_indent = current_indent + indent_step;
15702  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15703  {
15704  indent_string.resize(indent_string.size() * 2, ' ');
15705  }
15706 
15707  // first n-1 elements
15708  for (auto i = val.m_value.array->cbegin();
15709  i != val.m_value.array->cend() - 1; ++i)
15710  {
15711  o->write_characters(indent_string.c_str(), new_indent);
15712  dump(*i, true, ensure_ascii, indent_step, new_indent);
15713  o->write_characters(",\n", 2);
15714  }
15715 
15716  // last element
15717  JSON_ASSERT(!val.m_value.array->empty());
15718  o->write_characters(indent_string.c_str(), new_indent);
15719  dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
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_character('[');
15728 
15729  // first n-1 elements
15730  for (auto i = val.m_value.array->cbegin();
15731  i != val.m_value.array->cend() - 1; ++i)
15732  {
15733  dump(*i, false, ensure_ascii, indent_step, current_indent);
15734  o->write_character(',');
15735  }
15736 
15737  // last element
15738  JSON_ASSERT(!val.m_value.array->empty());
15739  dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
15740 
15741  o->write_character(']');
15742  }
15743 
15744  return;
15745  }
15746 
15747  case value_t::string:
15748  {
15749  o->write_character('\"');
15750  dump_escaped(*val.m_value.string, ensure_ascii);
15751  o->write_character('\"');
15752  return;
15753  }
15754 
15755  case value_t::binary:
15756  {
15757  if (pretty_print)
15758  {
15759  o->write_characters("{\n", 2);
15760 
15761  // variable to hold indentation for recursive calls
15762  const auto new_indent = current_indent + indent_step;
15763  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15764  {
15765  indent_string.resize(indent_string.size() * 2, ' ');
15766  }
15767 
15768  o->write_characters(indent_string.c_str(), new_indent);
15769 
15770  o->write_characters("\"bytes\": [", 10);
15771 
15772  if (!val.m_value.binary->empty())
15773  {
15774  for (auto i = val.m_value.binary->cbegin();
15775  i != val.m_value.binary->cend() - 1; ++i)
15776  {
15777  dump_integer(*i);
15778  o->write_characters(", ", 2);
15779  }
15780  dump_integer(val.m_value.binary->back());
15781  }
15782 
15783  o->write_characters("],\n", 3);
15784  o->write_characters(indent_string.c_str(), new_indent);
15785 
15786  o->write_characters("\"subtype\": ", 11);
15787  if (val.m_value.binary->has_subtype())
15788  {
15789  dump_integer(val.m_value.binary->subtype());
15790  }
15791  else
15792  {
15793  o->write_characters("null", 4);
15794  }
15795  o->write_character('\n');
15796  o->write_characters(indent_string.c_str(), current_indent);
15797  o->write_character('}');
15798  }
15799  else
15800  {
15801  o->write_characters("{\"bytes\":[", 10);
15802 
15803  if (!val.m_value.binary->empty())
15804  {
15805  for (auto i = val.m_value.binary->cbegin();
15806  i != val.m_value.binary->cend() - 1; ++i)
15807  {
15808  dump_integer(*i);
15809  o->write_character(',');
15810  }
15811  dump_integer(val.m_value.binary->back());
15812  }
15813 
15814  o->write_characters("],\"subtype\":", 12);
15815  if (val.m_value.binary->has_subtype())
15816  {
15817  dump_integer(val.m_value.binary->subtype());
15818  o->write_character('}');
15819  }
15820  else
15821  {
15822  o->write_characters("null}", 5);
15823  }
15824  }
15825  return;
15826  }
15827 
15828  case value_t::boolean:
15829  {
15830  if (val.m_value.boolean)
15831  {
15832  o->write_characters("true", 4);
15833  }
15834  else
15835  {
15836  o->write_characters("false", 5);
15837  }
15838  return;
15839  }
15840 
15842  {
15843  dump_integer(val.m_value.number_integer);
15844  return;
15845  }
15846 
15848  {
15849  dump_integer(val.m_value.number_unsigned);
15850  return;
15851  }
15852 
15853  case value_t::number_float:
15854  {
15855  dump_float(val.m_value.number_float);
15856  return;
15857  }
15858 
15859  case value_t::discarded:
15860  {
15861  o->write_characters("<discarded>", 11);
15862  return;
15863  }
15864 
15865  case value_t::null:
15866  {
15867  o->write_characters("null", 4);
15868  return;
15869  }
15870 
15871  default: // LCOV_EXCL_LINE
15872  JSON_ASSERT(false); // LCOV_EXCL_LINE
15873  }
15874  }
15875 
15891  void dump_escaped(const string_t& s, const bool ensure_ascii)
15892  {
15893  std::uint32_t codepoint;
15894  std::uint8_t state = UTF8_ACCEPT;
15895  std::size_t bytes = 0; // number of bytes written to string_buffer
15896 
15897  // number of bytes written at the point of the last valid byte
15898  std::size_t bytes_after_last_accept = 0;
15899  std::size_t undumped_chars = 0;
15900 
15901  for (std::size_t i = 0; i < s.size(); ++i)
15902  {
15903  const auto byte = static_cast<uint8_t>(s[i]);
15904 
15905  switch (decode(state, codepoint, byte))
15906  {
15907  case UTF8_ACCEPT: // decode found a new code point
15908  {
15909  switch (codepoint)
15910  {
15911  case 0x08: // backspace
15912  {
15913  string_buffer[bytes++] = '\\';
15914  string_buffer[bytes++] = 'b';
15915  break;
15916  }
15917 
15918  case 0x09: // horizontal tab
15919  {
15920  string_buffer[bytes++] = '\\';
15921  string_buffer[bytes++] = 't';
15922  break;
15923  }
15924 
15925  case 0x0A: // newline
15926  {
15927  string_buffer[bytes++] = '\\';
15928  string_buffer[bytes++] = 'n';
15929  break;
15930  }
15931 
15932  case 0x0C: // formfeed
15933  {
15934  string_buffer[bytes++] = '\\';
15935  string_buffer[bytes++] = 'f';
15936  break;
15937  }
15938 
15939  case 0x0D: // carriage return
15940  {
15941  string_buffer[bytes++] = '\\';
15942  string_buffer[bytes++] = 'r';
15943  break;
15944  }
15945 
15946  case 0x22: // quotation mark
15947  {
15948  string_buffer[bytes++] = '\\';
15949  string_buffer[bytes++] = '\"';
15950  break;
15951  }
15952 
15953  case 0x5C: // reverse solidus
15954  {
15955  string_buffer[bytes++] = '\\';
15956  string_buffer[bytes++] = '\\';
15957  break;
15958  }
15959 
15960  default:
15961  {
15962  // escape control characters (0x00..0x1F) or, if
15963  // ensure_ascii parameter is used, non-ASCII characters
15964  if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
15965  {
15966  if (codepoint <= 0xFFFF)
15967  {
15968  (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
15969  static_cast<std::uint16_t>(codepoint));
15970  bytes += 6;
15971  }
15972  else
15973  {
15974  (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
15975  static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
15976  static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
15977  bytes += 12;
15978  }
15979  }
15980  else
15981  {
15982  // copy byte to buffer (all previous bytes
15983  // been copied have in default case above)
15984  string_buffer[bytes++] = s[i];
15985  }
15986  break;
15987  }
15988  }
15989 
15990  // write buffer and reset index; there must be 13 bytes
15991  // left, as this is the maximal number of bytes to be
15992  // written ("\uxxxx\uxxxx\0") for one code point
15993  if (string_buffer.size() - bytes < 13)
15994  {
15995  o->write_characters(string_buffer.data(), bytes);
15996  bytes = 0;
15997  }
15998 
15999  // remember the byte position of this accept
16001  undumped_chars = 0;
16002  break;
16003  }
16004 
16005  case UTF8_REJECT: // decode found invalid UTF-8 byte
16006  {
16007  switch (error_handler)
16008  {
16010  {
16011  std::string sn(3, '\0');
16012  (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
16013  JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
16014  }
16015 
16018  {
16019  // in case we saw this character the first time, we
16020  // would like to read it again, because the byte
16021  // may be OK for itself, but just not OK for the
16022  // previous sequence
16023  if (undumped_chars > 0)
16024  {
16025  --i;
16026  }
16027 
16028  // reset length buffer to the last accepted index;
16029  // thus removing/ignoring the invalid characters
16031 
16033  {
16034  // add a replacement character
16035  if (ensure_ascii)
16036  {
16037  string_buffer[bytes++] = '\\';
16038  string_buffer[bytes++] = 'u';
16039  string_buffer[bytes++] = 'f';
16040  string_buffer[bytes++] = 'f';
16041  string_buffer[bytes++] = 'f';
16042  string_buffer[bytes++] = 'd';
16043  }
16044  else
16045  {
16049  }
16050 
16051  // write buffer and reset index; there must be 13 bytes
16052  // left, as this is the maximal number of bytes to be
16053  // written ("\uxxxx\uxxxx\0") for one code point
16054  if (string_buffer.size() - bytes < 13)
16055  {
16056  o->write_characters(string_buffer.data(), bytes);
16057  bytes = 0;
16058  }
16059 
16061  }
16062 
16063  undumped_chars = 0;
16064 
16065  // continue processing the string
16066  state = UTF8_ACCEPT;
16067  break;
16068  }
16069 
16070  default: // LCOV_EXCL_LINE
16071  JSON_ASSERT(false); // LCOV_EXCL_LINE
16072  }
16073  break;
16074  }
16075 
16076  default: // decode found yet incomplete multi-byte code point
16077  {
16078  if (!ensure_ascii)
16079  {
16080  // code point will not be escaped - copy byte to buffer
16081  string_buffer[bytes++] = s[i];
16082  }
16083  ++undumped_chars;
16084  break;
16085  }
16086  }
16087  }
16088 
16089  // we finished processing the string
16091  {
16092  // write buffer
16093  if (bytes > 0)
16094  {
16095  o->write_characters(string_buffer.data(), bytes);
16096  }
16097  }
16098  else
16099  {
16100  // we finish reading, but do not accept: string was incomplete
16101  switch (error_handler)
16102  {
16104  {
16105  std::string sn(3, '\0');
16106  (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
16107  JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
16108  }
16109 
16111  {
16112  // write all accepted bytes
16113  o->write_characters(string_buffer.data(), bytes_after_last_accept);
16114  break;
16115  }
16116 
16118  {
16119  // write all accepted bytes
16120  o->write_characters(string_buffer.data(), bytes_after_last_accept);
16121  // add a replacement character
16122  if (ensure_ascii)
16123  {
16124  o->write_characters("\\ufffd", 6);
16125  }
16126  else
16127  {
16128  o->write_characters("\xEF\xBF\xBD", 3);
16129  }
16130  break;
16131  }
16132 
16133  default: // LCOV_EXCL_LINE
16134  JSON_ASSERT(false); // LCOV_EXCL_LINE
16135  }
16136  }
16137  }
16138 
16139  private:
16148  inline unsigned int count_digits(number_unsigned_t x) noexcept
16149  {
16150  unsigned int n_digits = 1;
16151  for (;;)
16152  {
16153  if (x < 10)
16154  {
16155  return n_digits;
16156  }
16157  if (x < 100)
16158  {
16159  return n_digits + 1;
16160  }
16161  if (x < 1000)
16162  {
16163  return n_digits + 2;
16164  }
16165  if (x < 10000)
16166  {
16167  return n_digits + 3;
16168  }
16169  x = x / 10000u;
16170  n_digits += 4;
16171  }
16172  }
16173 
16183  template < typename NumberType, detail::enable_if_t <
16184  std::is_same<NumberType, number_unsigned_t>::value ||
16185  std::is_same<NumberType, number_integer_t>::value ||
16186  std::is_same<NumberType, binary_char_t>::value,
16187  int > = 0 >
16188  void dump_integer(NumberType x)
16189  {
16190  static constexpr std::array<std::array<char, 2>, 100> digits_to_99
16191  {
16192  {
16193  {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
16194  {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
16195  {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
16196  {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
16197  {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
16198  {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
16199  {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
16200  {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
16201  {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
16202  {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
16203  }
16204  };
16205 
16206  // special case for "0"
16207  if (x == 0)
16208  {
16209  o->write_character('0');
16210  return;
16211  }
16212 
16213  // use a pointer to fill the buffer
16214  auto buffer_ptr = number_buffer.begin();
16215 
16216  const bool is_negative = std::is_same<NumberType, number_integer_t>::value && !(x >= 0); // see issue #755
16217  number_unsigned_t abs_value;
16218 
16219  unsigned int n_chars;
16220 
16221  if (is_negative)
16222  {
16223  *buffer_ptr = '-';
16224  abs_value = remove_sign(static_cast<number_integer_t>(x));
16225 
16226  // account one more byte for the minus sign
16227  n_chars = 1 + count_digits(abs_value);
16228  }
16229  else
16230  {
16231  abs_value = static_cast<number_unsigned_t>(x);
16232  n_chars = count_digits(abs_value);
16233  }
16234 
16235  // spare 1 byte for '\0'
16236  JSON_ASSERT(n_chars < number_buffer.size() - 1);
16237 
16238  // jump to the end to generate the string from backward
16239  // so we later avoid reversing the result
16240  buffer_ptr += n_chars;
16241 
16242  // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
16243  // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
16244  while (abs_value >= 100)
16245  {
16246  const auto digits_index = static_cast<unsigned>((abs_value % 100));
16247  abs_value /= 100;
16248  *(--buffer_ptr) = digits_to_99[digits_index][1];
16249  *(--buffer_ptr) = digits_to_99[digits_index][0];
16250  }
16251 
16252  if (abs_value >= 10)
16253  {
16254  const auto digits_index = static_cast<unsigned>(abs_value);
16255  *(--buffer_ptr) = digits_to_99[digits_index][1];
16256  *(--buffer_ptr) = digits_to_99[digits_index][0];
16257  }
16258  else
16259  {
16260  *(--buffer_ptr) = static_cast<char>('0' + abs_value);
16261  }
16262 
16263  o->write_characters(number_buffer.data(), n_chars);
16264  }
16265 
16274  void dump_float(number_float_t x)
16275  {
16276  // NaN / inf
16277  if (!std::isfinite(x))
16278  {
16279  o->write_characters("null", 4);
16280  return;
16281  }
16282 
16283  // If number_float_t is an IEEE-754 single or double precision number,
16284  // use the Grisu2 algorithm to produce short numbers which are
16285  // guaranteed to round-trip, using strtof and strtod, resp.
16286  //
16287  // NB: The test below works if <long double> == <double>.
16288  static constexpr bool is_ieee_single_or_double
16289  = (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) ||
16290  (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);
16291 
16292  dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
16293  }
16294 
16295  void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
16296  {
16297  char* begin = number_buffer.data();
16298  char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
16299 
16300  o->write_characters(begin, static_cast<size_t>(end - begin));
16301  }
16302 
16303  void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
16304  {
16305  // get number of digits for a float -> text -> float round-trip
16306  static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
16307 
16308  // the actual conversion
16309  std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
16310 
16311  // negative value indicates an error
16312  JSON_ASSERT(len > 0);
16313  // check if buffer was large enough
16314  JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
16315 
16316  // erase thousands separator
16317  if (thousands_sep != '\0')
16318  {
16319  const auto end = std::remove(number_buffer.begin(),
16320  number_buffer.begin() + len, thousands_sep);
16321  std::fill(end, number_buffer.end(), '\0');
16322  JSON_ASSERT((end - number_buffer.begin()) <= len);
16323  len = (end - number_buffer.begin());
16324  }
16325 
16326  // convert decimal point to '.'
16327  if (decimal_point != '\0' && decimal_point != '.')
16328  {
16329  const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
16330  if (dec_pos != number_buffer.end())
16331  {
16332  *dec_pos = '.';
16333  }
16334  }
16335 
16336  o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
16337 
16338  // determine if need to append ".0"
16339  const bool value_is_int_like =
16340  std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
16341  [](char c)
16342  {
16343  return c == '.' || c == 'e';
16344  });
16345 
16346  if (value_is_int_like)
16347  {
16348  o->write_characters(".0", 2);
16349  }
16350  }
16351 
16373  static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
16374  {
16375  static const std::array<std::uint8_t, 400> utf8d =
16376  {
16377  {
16378  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
16379  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
16380  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
16381  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
16382  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
16383  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
16384  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
16385  0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
16386  0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
16387  0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
16388  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
16389  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
16390  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
16391  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
16392  }
16393  };
16394 
16395  const std::uint8_t type = utf8d[byte];
16396 
16397  codep = (state != UTF8_ACCEPT)
16398  ? (byte & 0x3fu) | (codep << 6u)
16399  : (0xFFu >> type) & (byte);
16400 
16401  std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
16402  JSON_ASSERT(index < 400);
16403  state = utf8d[index];
16404  return state;
16405  }
16406 
16407  /*
16408  * Overload to make the compiler happy while it is instantiating
16409  * dump_integer for number_unsigned_t.
16410  * Must never be called.
16411  */
16413  {
16414  JSON_ASSERT(false); // LCOV_EXCL_LINE
16415  return x; // LCOV_EXCL_LINE
16416  }
16417 
16418  /*
16419  * Helper function for dump_integer
16420  *
16421  * This function takes a negative signed integer and returns its absolute
16422  * value as unsigned integer. The plus/minus shuffling is necessary as we can
16423  * not directly remove the sign of an arbitrary signed integer as the
16424  * absolute values of INT_MIN and INT_MAX are usually not the same. See
16425  * #1708 for details.
16426  */
16427  inline number_unsigned_t remove_sign(number_integer_t x) noexcept
16428  {
16430  return static_cast<number_unsigned_t>(-(x + 1)) + 1;
16431  }
16432 
16433  private:
16435  output_adapter_t<char> o = nullptr;
16436 
16438  std::array<char, 64> number_buffer{{}};
16439 
16441  const std::lconv* loc = nullptr;
16443  const char thousands_sep = '\0';
16445  const char decimal_point = '\0';
16446 
16448  std::array<char, 512> string_buffer{{}};
16449 
16451  const char indent_char;
16454 
16457 };
16458 } // namespace detail
16459 } // namespace nlohmann
16460 
16461 // #include <nlohmann/detail/value_t.hpp>
16462 
16463 // #include <nlohmann/json_fwd.hpp>
16464 
16465 // #include <nlohmann/ordered_map.hpp>
16466 
16467 
16468 #include <functional> // less
16469 #include <memory> // allocator
16470 #include <utility> // pair
16471 #include <vector> // vector
16472 
16473 // #include <nlohmann/detail/macro_scope.hpp>
16474 
16475 
16476 namespace nlohmann
16477 {
16478 
16481 template <class Key, class T, class IgnoredLess = std::less<Key>,
16482  class Allocator = std::allocator<std::pair<const Key, T>>>
16483  struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
16484 {
16485  using key_type = Key;
16486  using mapped_type = T;
16487  using Container = std::vector<std::pair<const Key, T>, Allocator>;
16488  using typename Container::iterator;
16489  using typename Container::const_iterator;
16490  using typename Container::size_type;
16491  using typename Container::value_type;
16492 
16493  // Explicit constructors instead of `using Container::Container`
16494  // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
16495  ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
16496  template <class It>
16497  ordered_map(It first, It last, const Allocator& alloc = Allocator())
16498  : Container{first, last, alloc} {}
16499  ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
16500  : Container{init, alloc} {}
16501 
16502  std::pair<iterator, bool> emplace(const key_type& key, T&& t)
16503  {
16504  for (auto it = this->begin(); it != this->end(); ++it)
16505  {
16506  if (it->first == key)
16507  {
16508  return {it, false};
16509  }
16510  }
16511  Container::emplace_back(key, t);
16512  return {--this->end(), true};
16513  }
16514 
16515  T& operator[](const Key& key)
16516  {
16517  return emplace(key, T{}).first->second;
16518  }
16519 
16520  const T& operator[](const Key& key) const
16521  {
16522  return at(key);
16523  }
16524 
16525  T& at(const Key& key)
16526  {
16527  for (auto it = this->begin(); it != this->end(); ++it)
16528  {
16529  if (it->first == key)
16530  {
16531  return it->second;
16532  }
16533  }
16534 
16535  JSON_THROW(std::out_of_range("key not found"));
16536  }
16537 
16538  const T& at(const Key& key) const
16539  {
16540  for (auto it = this->begin(); it != this->end(); ++it)
16541  {
16542  if (it->first == key)
16543  {
16544  return it->second;
16545  }
16546  }
16547 
16548  JSON_THROW(std::out_of_range("key not found"));
16549  }
16550 
16551  size_type erase(const Key& key)
16552  {
16553  for (auto it = this->begin(); it != this->end(); ++it)
16554  {
16555  if (it->first == key)
16556  {
16557  // Since we cannot move const Keys, re-construct them in place
16558  for (auto next = it; ++next != this->end(); ++it)
16559  {
16560  it->~value_type(); // Destroy but keep allocation
16561  new (&*it) value_type{std::move(*next)};
16562  }
16563  Container::pop_back();
16564  return 1;
16565  }
16566  }
16567  return 0;
16568  }
16569 
16570  iterator erase(iterator pos)
16571  {
16572  auto it = pos;
16573 
16574  // Since we cannot move const Keys, re-construct them in place
16575  for (auto next = it; ++next != this->end(); ++it)
16576  {
16577  it->~value_type(); // Destroy but keep allocation
16578  new (&*it) value_type{std::move(*next)};
16579  }
16580  Container::pop_back();
16581  return pos;
16582  }
16583 
16584  size_type count(const Key& key) const
16585  {
16586  for (auto it = this->begin(); it != this->end(); ++it)
16587  {
16588  if (it->first == key)
16589  {
16590  return 1;
16591  }
16592  }
16593  return 0;
16594  }
16595 
16596  iterator find(const Key& key)
16597  {
16598  for (auto it = this->begin(); it != this->end(); ++it)
16599  {
16600  if (it->first == key)
16601  {
16602  return it;
16603  }
16604  }
16605  return Container::end();
16606  }
16607 
16608  const_iterator find(const Key& key) const
16609  {
16610  for (auto it = this->begin(); it != this->end(); ++it)
16611  {
16612  if (it->first == key)
16613  {
16614  return it;
16615  }
16616  }
16617  return Container::end();
16618  }
16619 
16620  std::pair<iterator, bool> insert( value_type&& value )
16621  {
16622  return emplace(value.first, std::move(value.second));
16623  }
16624 
16625  std::pair<iterator, bool> insert( const value_type& value )
16626  {
16627  for (auto it = this->begin(); it != this->end(); ++it)
16628  {
16629  if (it->first == value.first)
16630  {
16631  return {it, false};
16632  }
16633  }
16634  Container::push_back(value);
16635  return {--this->end(), true};
16636  }
16637 };
16638 
16639 } // namespace nlohmann
16640 
16641 
16647 namespace nlohmann
16648 {
16649 
16736 {
16737  private:
16738  template<detail::value_t> friend struct detail::external_constructor;
16739  friend ::nlohmann::json_pointer<basic_json>;
16740 
16741  template<typename BasicJsonType, typename InputType>
16742  friend class ::nlohmann::detail::parser;
16743  friend ::nlohmann::detail::serializer<basic_json>;
16744  template<typename BasicJsonType>
16745  friend class ::nlohmann::detail::iter_impl;
16746  template<typename BasicJsonType, typename CharType>
16747  friend class ::nlohmann::detail::binary_writer;
16748  template<typename BasicJsonType, typename InputType, typename SAX>
16749  friend class ::nlohmann::detail::binary_reader;
16750  template<typename BasicJsonType>
16751  friend class ::nlohmann::detail::json_sax_dom_parser;
16752  template<typename BasicJsonType>
16753  friend class ::nlohmann::detail::json_sax_dom_callback_parser;
16754 
16757 
16759  // convenience aliases for types residing in namespace detail;
16761 
16762  template<typename InputAdapterType>
16763  static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
16764  InputAdapterType adapter,
16766  const bool allow_exceptions = true,
16767  const bool ignore_comments = false
16768  )
16769  {
16770  return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
16771  std::move(cb), allow_exceptions, ignore_comments);
16772  }
16773 
16774  private:
16776  template<typename BasicJsonType>
16778  template<typename BasicJsonType>
16780  template<typename Iterator>
16783 
16784  template<typename CharType>
16786 
16787  template<typename InputType>
16790 
16792  using serializer = ::nlohmann::detail::serializer<basic_json>;
16793 
16794  public:
16798  template<typename T, typename SFINAE>
16799  using json_serializer = JSONSerializer<T, SFINAE>;
16805  using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
16806 
16810 
16812  // exceptions //
16814 
16818 
16831 
16833 
16834 
16836  // container types //
16838 
16843 
16846 
16850  using const_reference = const value_type&;
16851 
16853  using difference_type = std::ptrdiff_t;
16855  using size_type = std::size_t;
16856 
16858  using allocator_type = AllocatorType<basic_json>;
16859 
16861  using pointer = typename std::allocator_traits<allocator_type>::pointer;
16863  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
16864 
16873 
16875 
16876 
16881  {
16882  return allocator_type();
16883  }
16884 
16912  static basic_json meta()
16913  {
16915 
16916  result["copyright"] = "(C) 2013-2020 Niels Lohmann";
16917  result["name"] = "JSON for Modern C++";
16918  result["url"] = "https://github.com/nlohmann/json";
16919  result["version"]["string"] =
16923  result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
16924  result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
16925  result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
16926 
16927 #ifdef _WIN32
16928  result["platform"] = "win32";
16929 #elif defined __linux__
16930  result["platform"] = "linux";
16931 #elif defined __APPLE__
16932  result["platform"] = "apple";
16933 #elif defined __unix__
16934  result["platform"] = "unix";
16935 #else
16936  result["platform"] = "unknown";
16937 #endif
16938 
16939 #if defined(__ICC) || defined(__INTEL_COMPILER)
16940  result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
16941 #elif defined(__clang__)
16942  result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
16943 #elif defined(__GNUC__) || defined(__GNUG__)
16944  result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
16945 #elif defined(__HP_cc) || defined(__HP_aCC)
16946  result["compiler"] = "hp"
16947 #elif defined(__IBMCPP__)
16948  result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
16949 #elif defined(_MSC_VER)
16950  result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
16951 #elif defined(__PGI)
16952  result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
16953 #elif defined(__SUNPRO_CC)
16954  result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
16955 #else
16956  result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
16957 #endif
16958 
16959 #ifdef __cplusplus
16960  result["compiler"]["c++"] = std::to_string(__cplusplus);
16961 #else
16962  result["compiler"]["c++"] = "unknown";
16963 #endif
16964  return result;
16965  }
16966 
16967 
16969  // JSON value data types //
16971 
16976 
16977 #if defined(JSON_HAS_CPP_14)
16978  // Use transparent comparator if possible, combined with perfect forwarding
16979  // on find() and count() calls prevents unnecessary string construction.
16980  using object_comparator_t = std::less<>;
16981 #else
16982  using object_comparator_t = std::less<StringType>;
16983 #endif
16984 
17068  using object_t = ObjectType<StringType,
17069  basic_json,
17071  AllocatorType<std::pair<const StringType,
17072  basic_json>>>;
17073 
17118  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
17119 
17171  using string_t = StringType;
17172 
17197  using boolean_t = BooleanType;
17198 
17269  using number_integer_t = NumberIntegerType;
17270 
17340  using number_unsigned_t = NumberUnsignedType;
17341 
17408  using number_float_t = NumberFloatType;
17409 
17481 
17482  private:
17483 
17485  template<typename T, typename... Args>
17487  static T* create(Args&& ... args)
17488  {
17489  AllocatorType<T> alloc;
17490  using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
17491 
17492  auto deleter = [&](T * object)
17493  {
17494  AllocatorTraits::deallocate(alloc, object, 1);
17495  };
17496  std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
17497  AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
17498  JSON_ASSERT(object != nullptr);
17499  return object.release();
17500  }
17501 
17503  // JSON value storage //
17505 
17532  union json_value
17533  {
17535  object_t* object;
17550 
17552  json_value() = default;
17554  json_value(boolean_t v) noexcept : boolean(v) {}
17563  {
17564  switch (t)
17565  {
17566  case value_t::object:
17567  {
17568  object = create<object_t>();
17569  break;
17570  }
17571 
17572  case value_t::array:
17573  {
17574  array = create<array_t>();
17575  break;
17576  }
17577 
17578  case value_t::string:
17579  {
17580  string = create<string_t>("");
17581  break;
17582  }
17583 
17584  case value_t::binary:
17585  {
17586  binary = create<binary_t>();
17587  break;
17588  }
17589 
17590  case value_t::boolean:
17591  {
17592  boolean = boolean_t(false);
17593  break;
17594  }
17595 
17597  {
17599  break;
17600  }
17601 
17603  {
17605  break;
17606  }
17607 
17608  case value_t::number_float:
17609  {
17611  break;
17612  }
17613 
17614  case value_t::null:
17615  {
17616  object = nullptr; // silence warning, see #821
17617  break;
17618  }
17619 
17620  default:
17621  {
17622  object = nullptr; // silence warning, see #821
17624  {
17625  JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.9.1")); // LCOV_EXCL_LINE
17626  }
17627  break;
17628  }
17629  }
17630  }
17631 
17634  {
17635  string = create<string_t>(value);
17636  }
17637 
17640  {
17641  string = create<string_t>(std::move(value));
17642  }
17643 
17646  {
17647  object = create<object_t>(value);
17648  }
17649 
17652  {
17653  object = create<object_t>(std::move(value));
17654  }
17655 
17658  {
17659  array = create<array_t>(value);
17660  }
17661 
17664  {
17665  array = create<array_t>(std::move(value));
17666  }
17667 
17670  {
17671  binary = create<binary_t>(value);
17672  }
17673 
17676  {
17677  binary = create<binary_t>(std::move(value));
17678  }
17679 
17682  {
17683  binary = create<binary_t>(value);
17684  }
17685 
17688  {
17689  binary = create<binary_t>(std::move(value));
17690  }
17691 
17692  void destroy(value_t t) noexcept
17693  {
17694  // flatten the current json_value to a heap-allocated stack
17695  std::vector<basic_json> stack;
17696 
17697  // move the top-level items to stack
17698  if (t == value_t::array)
17699  {
17700  stack.reserve(array->size());
17701  std::move(array->begin(), array->end(), std::back_inserter(stack));
17702  }
17703  else if (t == value_t::object)
17704  {
17705  stack.reserve(object->size());
17706  for (auto&& it : *object)
17707  {
17708  stack.push_back(std::move(it.second));
17709  }
17710  }
17711 
17712  while (!stack.empty())
17713  {
17714  // move the last item to local variable to be processed
17715  basic_json current_item(std::move(stack.back()));
17716  stack.pop_back();
17717 
17718  // if current_item is array/object, move
17719  // its children to the stack to be processed later
17720  if (current_item.is_array())
17721  {
17722  std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
17723  std::back_inserter(stack));
17724 
17725  current_item.m_value.array->clear();
17726  }
17727  else if (current_item.is_object())
17728  {
17729  for (auto&& it : *current_item.m_value.object)
17730  {
17731  stack.push_back(std::move(it.second));
17732  }
17733 
17734  current_item.m_value.object->clear();
17735  }
17736 
17737  // it's now safe that current_item get destructed
17738  // since it doesn't have any children
17739  }
17740 
17741  switch (t)
17742  {
17743  case value_t::object:
17744  {
17745  AllocatorType<object_t> alloc;
17746  std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
17747  std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
17748  break;
17749  }
17750 
17751  case value_t::array:
17752  {
17753  AllocatorType<array_t> alloc;
17754  std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
17755  std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
17756  break;
17757  }
17758 
17759  case value_t::string:
17760  {
17761  AllocatorType<string_t> alloc;
17762  std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
17763  std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
17764  break;
17765  }
17766 
17767  case value_t::binary:
17768  {
17769  AllocatorType<binary_t> alloc;
17770  std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
17771  std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
17772  break;
17773  }
17774 
17775  default:
17776  {
17777  break;
17778  }
17779  }
17780  }
17781  };
17782 
17783  private:
17793  void assert_invariant() const noexcept
17794  {
17795  JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
17796  JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
17797  JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
17798  JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
17799  }
17800 
17801  public:
17803  // JSON parser callback //
17805 
17822 
17873 
17875  // constructors //
17877 
17882 
17914  : m_type(v), m_value(v)
17915  {
17916  assert_invariant();
17917  }
17918 
17937  basic_json(std::nullptr_t = nullptr) noexcept
17938  : basic_json(value_t::null)
17939  {
17940  assert_invariant();
17941  }
17942 
18006  template < typename CompatibleType,
18007  typename U = detail::uncvref_t<CompatibleType>,
18010  basic_json(CompatibleType && val) noexcept(noexcept(
18011  JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
18012  std::forward<CompatibleType>(val))))
18013  {
18014  JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
18015  assert_invariant();
18016  }
18017 
18044  template < typename BasicJsonType,
18046  detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
18047  basic_json(const BasicJsonType& val)
18048  {
18049  using other_boolean_t = typename BasicJsonType::boolean_t;
18050  using other_number_float_t = typename BasicJsonType::number_float_t;
18051  using other_number_integer_t = typename BasicJsonType::number_integer_t;
18052  using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
18053  using other_string_t = typename BasicJsonType::string_t;
18054  using other_object_t = typename BasicJsonType::object_t;
18055  using other_array_t = typename BasicJsonType::array_t;
18056  using other_binary_t = typename BasicJsonType::binary_t;
18057 
18058  switch (val.type())
18059  {
18060  case value_t::boolean:
18061  JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
18062  break;
18063  case value_t::number_float:
18064  JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
18065  break;
18067  JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
18068  break;
18070  JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
18071  break;
18072  case value_t::string:
18073  JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
18074  break;
18075  case value_t::object:
18076  JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
18077  break;
18078  case value_t::array:
18079  JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
18080  break;
18081  case value_t::binary:
18082  JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
18083  break;
18084  case value_t::null:
18085  *this = nullptr;
18086  break;
18087  case value_t::discarded:
18088  m_type = value_t::discarded;
18089  break;
18090  default: // LCOV_EXCL_LINE
18091  JSON_ASSERT(false); // LCOV_EXCL_LINE
18092  }
18093  assert_invariant();
18094  }
18095 
18171  bool type_deduction = true,
18172  value_t manual_type = value_t::array)
18173  {
18174  // check if each element is an array with two elements whose first
18175  // element is a string
18176  bool is_an_object = std::all_of(init.begin(), init.end(),
18177  [](const detail::json_ref<basic_json>& element_ref)
18178  {
18179  return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
18180  });
18181 
18182  // adjust type if type deduction is not wanted
18183  if (!type_deduction)
18184  {
18185  // if array is wanted, do not create an object though possible
18186  if (manual_type == value_t::array)
18187  {
18188  is_an_object = false;
18189  }
18190 
18191  // if object is wanted but impossible, throw an exception
18192  if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
18193  {
18194  JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
18195  }
18196  }
18197 
18198  if (is_an_object)
18199  {
18200  // the initializer list is a list of pairs -> create object
18201  m_type = value_t::object;
18203 
18204  std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
18205  {
18206  auto element = element_ref.moved_or_copied();
18207  m_value.object->emplace(
18208  std::move(*((*element.m_value.array)[0].m_value.string)),
18209  std::move((*element.m_value.array)[1]));
18210  });
18211  }
18212  else
18213  {
18214  // the initializer list describes an array -> create array
18215  m_type = value_t::array;
18216  m_value.array = create<array_t>(init.begin(), init.end());
18217  }
18218 
18219  assert_invariant();
18220  }
18221 
18250  static basic_json binary(const typename binary_t::container_type& init)
18251  {
18252  auto res = basic_json();
18253  res.m_type = value_t::binary;
18254  res.m_value = init;
18255  return res;
18256  }
18257 
18287  static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype)
18288  {
18289  auto res = basic_json();
18290  res.m_type = value_t::binary;
18291  res.m_value = binary_t(init, subtype);
18292  return res;
18293  }
18294 
18298  {
18299  auto res = basic_json();
18300  res.m_type = value_t::binary;
18301  res.m_value = std::move(init);
18302  return res;
18303  }
18304 
18307  static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype)
18308  {
18309  auto res = basic_json();
18310  res.m_type = value_t::binary;
18311  res.m_value = binary_t(std::move(init), subtype);
18312  return res;
18313  }
18314 
18354  {
18355  return basic_json(init, false, value_t::array);
18356  }
18357 
18398  {
18399  return basic_json(init, false, value_t::object);
18400  }
18401 
18425  : m_type(value_t::array)
18426  {
18427  m_value.array = create<array_t>(cnt, val);
18428  assert_invariant();
18429  }
18430 
18486  template < class InputIT, typename std::enable_if <
18487  std::is_same<InputIT, typename basic_json_t::iterator>::value ||
18488  std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
18489  basic_json(InputIT first, InputIT last)
18490  {
18491  JSON_ASSERT(first.m_object != nullptr);
18492  JSON_ASSERT(last.m_object != nullptr);
18493 
18494  // make sure iterator fits the current value
18495  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
18496  {
18497  JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
18498  }
18499 
18500  // copy type from first iterator
18501  m_type = first.m_object->m_type;
18502 
18503  // check if iterator range is complete for primitive values
18504  switch (m_type)
18505  {
18506  case value_t::boolean:
18507  case value_t::number_float:
18510  case value_t::string:
18511  {
18512  if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
18513  || !last.m_it.primitive_iterator.is_end()))
18514  {
18515  JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
18516  }
18517  break;
18518  }
18519 
18520  default:
18521  break;
18522  }
18523 
18524  switch (m_type)
18525  {
18527  {
18528  m_value.number_integer = first.m_object->m_value.number_integer;
18529  break;
18530  }
18531 
18533  {
18534  m_value.number_unsigned = first.m_object->m_value.number_unsigned;
18535  break;
18536  }
18537 
18538  case value_t::number_float:
18539  {
18540  m_value.number_float = first.m_object->m_value.number_float;
18541  break;
18542  }
18543 
18544  case value_t::boolean:
18545  {
18546  m_value.boolean = first.m_object->m_value.boolean;
18547  break;
18548  }
18549 
18550  case value_t::string:
18551  {
18552  m_value = *first.m_object->m_value.string;
18553  break;
18554  }
18555 
18556  case value_t::object:
18557  {
18558  m_value.object = create<object_t>(first.m_it.object_iterator,
18559  last.m_it.object_iterator);
18560  break;
18561  }
18562 
18563  case value_t::array:
18564  {
18565  m_value.array = create<array_t>(first.m_it.array_iterator,
18566  last.m_it.array_iterator);
18567  break;
18568  }
18569 
18570  case value_t::binary:
18571  {
18572  m_value = *first.m_object->m_value.binary;
18573  break;
18574  }
18575 
18576  default:
18577  JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
18578  std::string(first.m_object->type_name())));
18579  }
18580 
18581  assert_invariant();
18582  }
18583 
18584 
18586  // other constructors and destructor //
18588 
18589  template<typename JsonRef,
18591  std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
18592  basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
18593 
18619  basic_json(const basic_json& other)
18620  : m_type(other.m_type)
18621  {
18622  // check of passed value is valid
18623  other.assert_invariant();
18624 
18625  switch (m_type)
18626  {
18627  case value_t::object:
18628  {
18629  m_value = *other.m_value.object;
18630  break;
18631  }
18632 
18633  case value_t::array:
18634  {
18635  m_value = *other.m_value.array;
18636  break;
18637  }
18638 
18639  case value_t::string:
18640  {
18641  m_value = *other.m_value.string;
18642  break;
18643  }
18644 
18645  case value_t::boolean:
18646  {
18647  m_value = other.m_value.boolean;
18648  break;
18649  }
18650 
18652  {
18653  m_value = other.m_value.number_integer;
18654  break;
18655  }
18656 
18658  {
18659  m_value = other.m_value.number_unsigned;
18660  break;
18661  }
18662 
18663  case value_t::number_float:
18664  {
18665  m_value = other.m_value.number_float;
18666  break;
18667  }
18668 
18669  case value_t::binary:
18670  {
18671  m_value = *other.m_value.binary;
18672  break;
18673  }
18674 
18675  default:
18676  break;
18677  }
18678 
18679  assert_invariant();
18680  }
18681 
18708  basic_json(basic_json&& other) noexcept
18709  : m_type(std::move(other.m_type)),
18710  m_value(std::move(other.m_value))
18711  {
18712  // check that passed value is valid
18713  other.assert_invariant();
18714 
18715  // invalidate payload
18716  other.m_type = value_t::null;
18717  other.m_value = {};
18718 
18719  assert_invariant();
18720  }
18721 
18745  basic_json& operator=(basic_json other) noexcept (
18746  std::is_nothrow_move_constructible<value_t>::value&&
18747  std::is_nothrow_move_assignable<value_t>::value&&
18748  std::is_nothrow_move_constructible<json_value>::value&&
18749  std::is_nothrow_move_assignable<json_value>::value
18750  )
18751  {
18752  // check that passed value is valid
18753  other.assert_invariant();
18754 
18755  using std::swap;
18756  swap(m_type, other.m_type);
18757  swap(m_value, other.m_value);
18758 
18759  assert_invariant();
18760  return *this;
18761  }
18762 
18778  ~basic_json() noexcept
18779  {
18780  assert_invariant();
18781  m_value.destroy(m_type);
18782  }
18783 
18785 
18786  public:
18788  // object inspection //
18790 
18794 
18842  string_t dump(const int indent = -1,
18843  const char indent_char = ' ',
18844  const bool ensure_ascii = false,
18845  const error_handler_t error_handler = error_handler_t::strict) const
18846  {
18847  string_t result;
18848  serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
18849 
18850  if (indent >= 0)
18851  {
18852  s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
18853  }
18854  else
18855  {
18856  s.dump(*this, false, ensure_ascii, 0);
18857  }
18858 
18859  return result;
18860  }
18861 
18895  constexpr value_t type() const noexcept
18896  {
18897  return m_type;
18898  }
18899 
18926  constexpr bool is_primitive() const noexcept
18927  {
18928  return is_null() || is_string() || is_boolean() || is_number() || is_binary();
18929  }
18930 
18953  constexpr bool is_structured() const noexcept
18954  {
18955  return is_array() || is_object();
18956  }
18957 
18975  constexpr bool is_null() const noexcept
18976  {
18977  return m_type == value_t::null;
18978  }
18979 
18997  constexpr bool is_boolean() const noexcept
18998  {
18999  return m_type == value_t::boolean;
19000  }
19001 
19027  constexpr bool is_number() const noexcept
19028  {
19029  return is_number_integer() || is_number_float();
19030  }
19031 
19056  constexpr bool is_number_integer() const noexcept
19057  {
19058  return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
19059  }
19060 
19084  constexpr bool is_number_unsigned() const noexcept
19085  {
19086  return m_type == value_t::number_unsigned;
19087  }
19088 
19112  constexpr bool is_number_float() const noexcept
19113  {
19114  return m_type == value_t::number_float;
19115  }
19116 
19134  constexpr bool is_object() const noexcept
19135  {
19136  return m_type == value_t::object;
19137  }
19138 
19156  constexpr bool is_array() const noexcept
19157  {
19158  return m_type == value_t::array;
19159  }
19160 
19178  constexpr bool is_string() const noexcept
19179  {
19180  return m_type == value_t::string;
19181  }
19182 
19200  constexpr bool is_binary() const noexcept
19201  {
19202  return m_type == value_t::binary;
19203  }
19204 
19227  constexpr bool is_discarded() const noexcept
19228  {
19229  return m_type == value_t::discarded;
19230  }
19231 
19253  constexpr operator value_t() const noexcept
19254  {
19255  return m_type;
19256  }
19257 
19259 
19260  private:
19262  // value access //
19264 
19266  boolean_t get_impl(boolean_t* /*unused*/) const
19267  {
19269  {
19270  return m_value.boolean;
19271  }
19272 
19273  JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
19274  }
19275 
19277  object_t* get_impl_ptr(object_t* /*unused*/) noexcept
19278  {
19279  return is_object() ? m_value.object : nullptr;
19280  }
19281 
19283  constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
19284  {
19285  return is_object() ? m_value.object : nullptr;
19286  }
19287 
19289  array_t* get_impl_ptr(array_t* /*unused*/) noexcept
19290  {
19291  return is_array() ? m_value.array : nullptr;
19292  }
19293 
19295  constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
19296  {
19297  return is_array() ? m_value.array : nullptr;
19298  }
19299 
19301  string_t* get_impl_ptr(string_t* /*unused*/) noexcept
19302  {
19303  return is_string() ? m_value.string : nullptr;
19304  }
19305 
19307  constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
19308  {
19309  return is_string() ? m_value.string : nullptr;
19310  }
19311 
19313  boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
19314  {
19315  return is_boolean() ? &m_value.boolean : nullptr;
19316  }
19317 
19319  constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
19320  {
19321  return is_boolean() ? &m_value.boolean : nullptr;
19322  }
19323 
19326  {
19327  return is_number_integer() ? &m_value.number_integer : nullptr;
19328  }
19329 
19331  constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
19332  {
19333  return is_number_integer() ? &m_value.number_integer : nullptr;
19334  }
19335 
19338  {
19339  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19340  }
19341 
19343  constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
19344  {
19345  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19346  }
19347 
19350  {
19351  return is_number_float() ? &m_value.number_float : nullptr;
19352  }
19353 
19355  constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
19356  {
19357  return is_number_float() ? &m_value.number_float : nullptr;
19358  }
19359 
19361  binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
19362  {
19363  return is_binary() ? m_value.binary : nullptr;
19364  }
19365 
19367  constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
19368  {
19369  return is_binary() ? m_value.binary : nullptr;
19370  }
19371 
19383  template<typename ReferenceType, typename ThisType>
19384  static ReferenceType get_ref_impl(ThisType& obj)
19385  {
19386  // delegate the call to get_ptr<>()
19387  auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
19388 
19389  if (JSON_HEDLEY_LIKELY(ptr != nullptr))
19390  {
19391  return *ptr;
19392  }
19393 
19394  JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
19395  }
19396 
19397  public:
19401 
19416  template<typename BasicJsonType, detail::enable_if_t<
19417  std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
19418  int> = 0>
19419  basic_json get() const
19420  {
19421  return *this;
19422  }
19423 
19439  template < typename BasicJsonType, detail::enable_if_t <
19440  !std::is_same<BasicJsonType, basic_json>::value&&
19442  BasicJsonType get() const
19443  {
19444  return *this;
19445  }
19446 
19486  template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
19487  detail::enable_if_t <
19488  !detail::is_basic_json<ValueType>::value &&
19489  detail::has_from_json<basic_json_t, ValueType>::value &&
19490  !detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19491  int > = 0 >
19492  ValueType get() const noexcept(noexcept(
19493  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
19494  {
19495  // we cannot static_assert on ValueTypeCV being non-const, because
19496  // there is support for get<const basic_json_t>(), which is why we
19497  // still need the uncvref
19498  static_assert(!std::is_reference<ValueTypeCV>::value,
19499  "get() cannot be used with reference types, you might want to use get_ref()");
19500  static_assert(std::is_default_constructible<ValueType>::value,
19501  "types must be DefaultConstructible when used with get()");
19502 
19503  ValueType ret;
19505  return ret;
19506  }
19507 
19539  template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
19540  detail::enable_if_t < !std::is_same<basic_json_t, ValueType>::value &&
19541  detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19542  int > = 0 >
19543  ValueType get() const noexcept(noexcept(
19544  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
19545  {
19546  static_assert(!std::is_reference<ValueTypeCV>::value,
19547  "get() cannot be used with reference types, you might want to use get_ref()");
19549  }
19550 
19584  template < typename ValueType,
19588  int > = 0 >
19589  ValueType & get_to(ValueType& v) const noexcept(noexcept(
19590  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
19591  {
19593  return v;
19594  }
19595 
19596  // specialization to allow to call get_to with a basic_json value
19597  // see https://github.com/nlohmann/json/issues/2175
19598  template<typename ValueType,
19601  int> = 0>
19602  ValueType & get_to(ValueType& v) const
19603  {
19604  v = *this;
19605  return v;
19606  }
19607 
19608  template <
19609  typename T, std::size_t N,
19610  typename Array = T (&)[N],
19613  Array get_to(T (&v)[N]) const
19614  noexcept(noexcept(JSONSerializer<Array>::from_json(
19615  std::declval<const basic_json_t&>(), v)))
19616  {
19618  return v;
19619  }
19620 
19621 
19648  template<typename PointerType, typename std::enable_if<
19649  std::is_pointer<PointerType>::value, int>::type = 0>
19650  auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19651  {
19652  // delegate the call to get_impl_ptr<>()
19653  return get_impl_ptr(static_cast<PointerType>(nullptr));
19654  }
19655 
19660  template < typename PointerType, typename std::enable_if <
19661  std::is_pointer<PointerType>::value&&
19662  std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
19663  constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19664  {
19665  // delegate the call to get_impl_ptr<>() const
19666  return get_impl_ptr(static_cast<PointerType>(nullptr));
19667  }
19668 
19696  template<typename PointerType, typename std::enable_if<
19697  std::is_pointer<PointerType>::value, int>::type = 0>
19698  auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
19699  {
19700  // delegate the call to get_ptr
19701  return get_ptr<PointerType>();
19702  }
19703 
19708  template<typename PointerType, typename std::enable_if<
19709  std::is_pointer<PointerType>::value, int>::type = 0>
19710  constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
19711  {
19712  // delegate the call to get_ptr
19713  return get_ptr<PointerType>();
19714  }
19715 
19742  template<typename ReferenceType, typename std::enable_if<
19743  std::is_reference<ReferenceType>::value, int>::type = 0>
19744  ReferenceType get_ref()
19745  {
19746  // delegate call to get_ref_impl
19747  return get_ref_impl<ReferenceType>(*this);
19748  }
19749 
19754  template < typename ReferenceType, typename std::enable_if <
19755  std::is_reference<ReferenceType>::value&&
19756  std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
19757  ReferenceType get_ref() const
19758  {
19759  // delegate call to get_ref_impl
19760  return get_ref_impl<ReferenceType>(*this);
19761  }
19762 
19792  template < typename ValueType, typename std::enable_if <
19793  !std::is_pointer<ValueType>::value&&
19794  !std::is_same<ValueType, detail::json_ref<basic_json>>::value&&
19795  !std::is_same<ValueType, typename string_t::value_type>::value&&
19797  && !std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
19798 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
19799  && !std::is_same<ValueType, typename std::string_view>::value
19800 #endif
19802  , int >::type = 0 >
19803  JSON_EXPLICIT operator ValueType() const
19804  {
19805  // delegate the call to get<>() const
19806  return get<ValueType>();
19807  }
19808 
19819  {
19820  if (!is_binary())
19821  {
19822  JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19823  }
19824 
19825  return *get_ptr<binary_t*>();
19826  }
19827 
19829  const binary_t& get_binary() const
19830  {
19831  if (!is_binary())
19832  {
19833  JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19834  }
19835 
19836  return *get_ptr<const binary_t*>();
19837  }
19838 
19840 
19841 
19843  // element access //
19845 
19849 
19877  {
19878  // at only works for arrays
19880  {
19881  JSON_TRY
19882  {
19883  return m_value.array->at(idx);
19884  }
19885  JSON_CATCH (std::out_of_range&)
19886  {
19887  // create better exception explanation
19888  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19889  }
19890  }
19891  else
19892  {
19893  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19894  }
19895  }
19896 
19924  {
19925  // at only works for arrays
19927  {
19928  JSON_TRY
19929  {
19930  return m_value.array->at(idx);
19931  }
19932  JSON_CATCH (std::out_of_range&)
19933  {
19934  // create better exception explanation
19935  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19936  }
19937  }
19938  else
19939  {
19940  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19941  }
19942  }
19943 
19974  reference at(const typename object_t::key_type& key)
19975  {
19976  // at only works for objects
19978  {
19979  JSON_TRY
19980  {
19981  return m_value.object->at(key);
19982  }
19983  JSON_CATCH (std::out_of_range&)
19984  {
19985  // create better exception explanation
19986  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19987  }
19988  }
19989  else
19990  {
19991  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19992  }
19993  }
19994 
20025  const_reference at(const typename object_t::key_type& key) const
20026  {
20027  // at only works for objects
20029  {
20030  JSON_TRY
20031  {
20032  return m_value.object->at(key);
20033  }
20034  JSON_CATCH (std::out_of_range&)
20035  {
20036  // create better exception explanation
20037  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
20038  }
20039  }
20040  else
20041  {
20042  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
20043  }
20044  }
20045 
20072  {
20073  // implicitly convert null value to an empty array
20074  if (is_null())
20075  {
20076  m_type = value_t::array;
20077  m_value.array = create<array_t>();
20078  assert_invariant();
20079  }
20080 
20081  // operator[] only works for arrays
20083  {
20084  // fill up array with null values if given idx is outside range
20085  if (idx >= m_value.array->size())
20086  {
20087  m_value.array->insert(m_value.array->end(),
20088  idx - m_value.array->size() + 1,
20089  basic_json());
20090  }
20091 
20092  return m_value.array->operator[](idx);
20093  }
20094 
20095  JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
20096  }
20097 
20118  {
20119  // const operator[] only works for arrays
20121  {
20122  return m_value.array->operator[](idx);
20123  }
20124 
20125  JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
20126  }
20127 
20155  reference operator[](const typename object_t::key_type& key)
20156  {
20157  // implicitly convert null value to an empty object
20158  if (is_null())
20159  {
20160  m_type = value_t::object;
20161  m_value.object = create<object_t>();
20162  assert_invariant();
20163  }
20164 
20165  // operator[] only works for objects
20167  {
20168  return m_value.object->operator[](key);
20169  }
20170 
20171  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20172  }
20173 
20204  const_reference operator[](const typename object_t::key_type& key) const
20205  {
20206  // const operator[] only works for objects
20208  {
20209  JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20210  return m_value.object->find(key)->second;
20211  }
20212 
20213  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20214  }
20215 
20243  template<typename T>
20245  reference operator[](T* key)
20246  {
20247  // implicitly convert null to object
20248  if (is_null())
20249  {
20250  m_type = value_t::object;
20252  assert_invariant();
20253  }
20254 
20255  // at only works for objects
20257  {
20258  return m_value.object->operator[](key);
20259  }
20260 
20261  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20262  }
20263 
20294  template<typename T>
20296  const_reference operator[](T* key) const
20297  {
20298  // at only works for objects
20300  {
20301  JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20302  return m_value.object->find(key)->second;
20303  }
20304 
20305  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20306  }
20307 
20358  // using std::is_convertible in a std::enable_if will fail when using explicit conversions
20359  template < class ValueType, typename std::enable_if <
20361  && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
20362  ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
20363  {
20364  // at only works for objects
20366  {
20367  // if key is found, return value and given default value otherwise
20368  const auto it = find(key);
20369  if (it != end())
20370  {
20371  return it->template get<ValueType>();
20372  }
20373 
20374  return default_value;
20375  }
20376 
20377  JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
20378  }
20379 
20384  string_t value(const typename object_t::key_type& key, const char* default_value) const
20385  {
20386  return value(key, string_t(default_value));
20387  }
20388 
20432  template<class ValueType, typename std::enable_if<
20434  ValueType value(const json_pointer& ptr, const ValueType& default_value) const
20435  {
20436  // at only works for objects
20438  {
20439  // if pointer resolves a value, return it or use default value
20440  JSON_TRY
20441  {
20442  return ptr.get_checked(this).template get<ValueType>();
20443  }
20445  {
20446  return default_value;
20447  }
20448  }
20449 
20450  JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
20451  }
20452 
20458  string_t value(const json_pointer& ptr, const char* default_value) const
20459  {
20460  return value(ptr, string_t(default_value));
20461  }
20462 
20489  {
20490  return *begin();
20491  }
20492 
20497  {
20498  return *cbegin();
20499  }
20500 
20533  {
20534  auto tmp = end();
20535  --tmp;
20536  return *tmp;
20537  }
20538 
20543  {
20544  auto tmp = cend();
20545  --tmp;
20546  return *tmp;
20547  }
20548 
20595  template < class IteratorType, typename std::enable_if <
20596  std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20597  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
20598  = 0 >
20599  IteratorType erase(IteratorType pos)
20600  {
20601  // make sure iterator fits the current value
20602  if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
20603  {
20604  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
20605  }
20606 
20607  IteratorType result = end();
20608 
20609  switch (m_type)
20610  {
20611  case value_t::boolean:
20612  case value_t::number_float:
20615  case value_t::string:
20616  case value_t::binary:
20617  {
20618  if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
20619  {
20620  JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
20621  }
20622 
20623  if (is_string())
20624  {
20625  AllocatorType<string_t> alloc;
20626  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20627  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20628  m_value.string = nullptr;
20629  }
20630  else if (is_binary())
20631  {
20632  AllocatorType<binary_t> alloc;
20633  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20634  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20635  m_value.binary = nullptr;
20636  }
20637 
20638  m_type = value_t::null;
20639  assert_invariant();
20640  break;
20641  }
20642 
20643  case value_t::object:
20644  {
20645  result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
20646  break;
20647  }
20648 
20649  case value_t::array:
20650  {
20651  result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
20652  break;
20653  }
20654 
20655  default:
20656  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20657  }
20658 
20659  return result;
20660  }
20661 
20708  template < class IteratorType, typename std::enable_if <
20709  std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20710  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
20711  = 0 >
20712  IteratorType erase(IteratorType first, IteratorType last)
20713  {
20714  // make sure iterator fits the current value
20715  if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
20716  {
20717  JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
20718  }
20719 
20720  IteratorType result = end();
20721 
20722  switch (m_type)
20723  {
20724  case value_t::boolean:
20725  case value_t::number_float:
20728  case value_t::string:
20729  case value_t::binary:
20730  {
20731  if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
20732  || !last.m_it.primitive_iterator.is_end()))
20733  {
20734  JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
20735  }
20736 
20737  if (is_string())
20738  {
20739  AllocatorType<string_t> alloc;
20740  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20741  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20742  m_value.string = nullptr;
20743  }
20744  else if (is_binary())
20745  {
20746  AllocatorType<binary_t> alloc;
20747  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20748  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20749  m_value.binary = nullptr;
20750  }
20751 
20752  m_type = value_t::null;
20753  assert_invariant();
20754  break;
20755  }
20756 
20757  case value_t::object:
20758  {
20759  result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
20760  last.m_it.object_iterator);
20761  break;
20762  }
20763 
20764  case value_t::array:
20765  {
20766  result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
20767  last.m_it.array_iterator);
20768  break;
20769  }
20770 
20771  default:
20772  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20773  }
20774 
20775  return result;
20776  }
20777 
20807  size_type erase(const typename object_t::key_type& key)
20808  {
20809  // this erase only works for objects
20811  {
20812  return m_value.object->erase(key);
20813  }
20814 
20815  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20816  }
20817 
20842  void erase(const size_type idx)
20843  {
20844  // this erase only works for arrays
20846  {
20847  if (JSON_HEDLEY_UNLIKELY(idx >= size()))
20848  {
20849  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
20850  }
20851 
20852  m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
20853  }
20854  else
20855  {
20856  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20857  }
20858  }
20859 
20861 
20862 
20864  // lookup //
20866 
20869 
20894  template<typename KeyT>
20895  iterator find(KeyT&& key)
20896  {
20897  auto result = end();
20898 
20899  if (is_object())
20900  {
20901  result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20902  }
20903 
20904  return result;
20905  }
20906 
20911  template<typename KeyT>
20912  const_iterator find(KeyT&& key) const
20913  {
20914  auto result = cend();
20915 
20916  if (is_object())
20917  {
20918  result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20919  }
20920 
20921  return result;
20922  }
20923 
20945  template<typename KeyT>
20946  size_type count(KeyT&& key) const
20947  {
20948  // return 0 for all nonobject types
20949  return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
20950  }
20951 
20977  template < typename KeyT, typename std::enable_if <
20978  !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
20979  bool contains(KeyT && key) const
20980  {
20981  return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
20982  }
20983 
21010  bool contains(const json_pointer& ptr) const
21011  {
21012  return ptr.contains(this);
21013  }
21014 
21016 
21017 
21019  // iterators //
21021 
21024 
21049  iterator begin() noexcept
21050  {
21051  iterator result(this);
21052  result.set_begin();
21053  return result;
21054  }
21055 
21059  const_iterator begin() const noexcept
21060  {
21061  return cbegin();
21062  }
21063 
21089  const_iterator cbegin() const noexcept
21090  {
21091  const_iterator result(this);
21092  result.set_begin();
21093  return result;
21094  }
21095 
21120  iterator end() noexcept
21121  {
21122  iterator result(this);
21123  result.set_end();
21124  return result;
21125  }
21126 
21130  const_iterator end() const noexcept
21131  {
21132  return cend();
21133  }
21134 
21160  const_iterator cend() const noexcept
21161  {
21162  const_iterator result(this);
21163  result.set_end();
21164  return result;
21165  }
21166 
21191  {
21192  return reverse_iterator(end());
21193  }
21194 
21199  {
21200  return crbegin();
21201  }
21202 
21228  {
21229  return reverse_iterator(begin());
21230  }
21231 
21235  const_reverse_iterator rend() const noexcept
21236  {
21237  return crend();
21238  }
21239 
21265  {
21266  return const_reverse_iterator(cend());
21267  }
21268 
21294  {
21295  return const_reverse_iterator(cbegin());
21296  }
21297 
21298  public:
21358  {
21359  return ref.items();
21360  }
21361 
21367  {
21368  return ref.items();
21369  }
21370 
21440  {
21441  return iteration_proxy<iterator>(*this);
21442  }
21443 
21448  {
21449  return iteration_proxy<const_iterator>(*this);
21450  }
21451 
21453 
21454 
21456  // capacity //
21458 
21461 
21504  bool empty() const noexcept
21505  {
21506  switch (m_type)
21507  {
21508  case value_t::null:
21509  {
21510  // null values are empty
21511  return true;
21512  }
21513 
21514  case value_t::array:
21515  {
21516  // delegate call to array_t::empty()
21517  return m_value.array->empty();
21518  }
21519 
21520  case value_t::object:
21521  {
21522  // delegate call to object_t::empty()
21523  return m_value.object->empty();
21524  }
21525 
21526  default:
21527  {
21528  // all other types are nonempty
21529  return false;
21530  }
21531  }
21532  }
21533 
21577  size_type size() const noexcept
21578  {
21579  switch (m_type)
21580  {
21581  case value_t::null:
21582  {
21583  // null values are empty
21584  return 0;
21585  }
21586 
21587  case value_t::array:
21588  {
21589  // delegate call to array_t::size()
21590  return m_value.array->size();
21591  }
21592 
21593  case value_t::object:
21594  {
21595  // delegate call to object_t::size()
21596  return m_value.object->size();
21597  }
21598 
21599  default:
21600  {
21601  // all other types have size 1
21602  return 1;
21603  }
21604  }
21605  }
21606 
21648  size_type max_size() const noexcept
21649  {
21650  switch (m_type)
21651  {
21652  case value_t::array:
21653  {
21654  // delegate call to array_t::max_size()
21655  return m_value.array->max_size();
21656  }
21657 
21658  case value_t::object:
21659  {
21660  // delegate call to object_t::max_size()
21661  return m_value.object->max_size();
21662  }
21663 
21664  default:
21665  {
21666  // all other types have max_size() == size()
21667  return size();
21668  }
21669  }
21670  }
21671 
21673 
21674 
21676  // modifiers //
21678 
21681 
21719  void clear() noexcept
21720  {
21721  switch (m_type)
21722  {
21724  {
21725  m_value.number_integer = 0;
21726  break;
21727  }
21728 
21730  {
21731  m_value.number_unsigned = 0;
21732  break;
21733  }
21734 
21735  case value_t::number_float:
21736  {
21737  m_value.number_float = 0.0;
21738  break;
21739  }
21740 
21741  case value_t::boolean:
21742  {
21743  m_value.boolean = false;
21744  break;
21745  }
21746 
21747  case value_t::string:
21748  {
21749  m_value.string->clear();
21750  break;
21751  }
21752 
21753  case value_t::binary:
21754  {
21755  m_value.binary->clear();
21756  break;
21757  }
21758 
21759  case value_t::array:
21760  {
21761  m_value.array->clear();
21762  break;
21763  }
21764 
21765  case value_t::object:
21766  {
21767  m_value.object->clear();
21768  break;
21769  }
21770 
21771  default:
21772  break;
21773  }
21774  }
21775 
21796  void push_back(basic_json&& val)
21797  {
21798  // push_back only works for null objects or arrays
21799  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21800  {
21801  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21802  }
21803 
21804  // transform null object into an array
21805  if (is_null())
21806  {
21807  m_type = value_t::array;
21809  assert_invariant();
21810  }
21811 
21812  // add element to array (move semantics)
21813  m_value.array->push_back(std::move(val));
21814  // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
21815  }
21816 
21822  {
21823  push_back(std::move(val));
21824  return *this;
21825  }
21826 
21831  void push_back(const basic_json& val)
21832  {
21833  // push_back only works for null objects or arrays
21834  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21835  {
21836  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21837  }
21838 
21839  // transform null object into an array
21840  if (is_null())
21841  {
21842  m_type = value_t::array;
21844  assert_invariant();
21845  }
21846 
21847  // add element to array
21848  m_value.array->push_back(val);
21849  }
21850 
21856  {
21857  push_back(val);
21858  return *this;
21859  }
21860 
21881  void push_back(const typename object_t::value_type& val)
21882  {
21883  // push_back only works for null objects or objects
21884  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21885  {
21886  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21887  }
21888 
21889  // transform null object into an object
21890  if (is_null())
21891  {
21892  m_type = value_t::object;
21894  assert_invariant();
21895  }
21896 
21897  // add element to array
21898  m_value.object->insert(val);
21899  }
21900 
21905  reference operator+=(const typename object_t::value_type& val)
21906  {
21907  push_back(val);
21908  return *this;
21909  }
21910 
21937  {
21938  if (is_object() && init.size() == 2 && (*init.begin())->is_string())
21939  {
21940  basic_json&& key = init.begin()->moved_or_copied();
21941  push_back(typename object_t::value_type(
21942  std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
21943  }
21944  else
21945  {
21946  push_back(basic_json(init));
21947  }
21948  }
21949 
21955  {
21956  push_back(init);
21957  return *this;
21958  }
21959 
21983  template<class... Args>
21984  reference emplace_back(Args&& ... args)
21985  {
21986  // emplace_back only works for null objects or arrays
21987  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21988  {
21989  JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
21990  }
21991 
21992  // transform null object into an array
21993  if (is_null())
21994  {
21995  m_type = value_t::array;
21997  assert_invariant();
21998  }
21999 
22000  // add element to array (perfect forwarding)
22001 #ifdef JSON_HAS_CPP_17
22002  return m_value.array->emplace_back(std::forward<Args>(args)...);
22003 #else
22004  m_value.array->emplace_back(std::forward<Args>(args)...);
22005  return m_value.array->back();
22006 #endif
22007  }
22008 
22036  template<class... Args>
22037  std::pair<iterator, bool> emplace(Args&& ... args)
22038  {
22039  // emplace only works for null objects or arrays
22040  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22041  {
22042  JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
22043  }
22044 
22045  // transform null object into an object
22046  if (is_null())
22047  {
22048  m_type = value_t::object;
22050  assert_invariant();
22051  }
22052 
22053  // add element to array (perfect forwarding)
22054  auto res = m_value.object->emplace(std::forward<Args>(args)...);
22055  // create result iterator and set iterator to the result of emplace
22056  auto it = begin();
22057  it.m_it.object_iterator = res.first;
22058 
22059  // return pair of iterator and boolean
22060  return {it, res.second};
22061  }
22062 
22066  template<typename... Args>
22068  {
22069  iterator result(this);
22070  JSON_ASSERT(m_value.array != nullptr);
22071 
22072  auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
22073  m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
22074  result.m_it.array_iterator = m_value.array->begin() + insert_pos;
22075 
22076  // This could have been written as:
22077  // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
22078  // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
22079 
22080  return result;
22081  }
22082 
22106  {
22107  // insert only works for arrays
22109  {
22110  // check if iterator pos fits to this JSON value
22111  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22112  {
22113  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22114  }
22115 
22116  // insert to array and return iterator
22117  return insert_iterator(pos, val);
22118  }
22119 
22120  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22121  }
22122 
22128  {
22129  return insert(pos, val);
22130  }
22131 
22157  {
22158  // insert only works for arrays
22160  {
22161  // check if iterator pos fits to this JSON value
22162  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22163  {
22164  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22165  }
22166 
22167  // insert to array and return iterator
22168  return insert_iterator(pos, cnt, val);
22169  }
22170 
22171  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22172  }
22173 
22205  {
22206  // insert only works for arrays
22208  {
22209  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22210  }
22211 
22212  // check if iterator pos fits to this JSON value
22213  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22214  {
22215  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22216  }
22217 
22218  // check if range iterators belong to the same JSON object
22219  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22220  {
22221  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22222  }
22223 
22224  if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
22225  {
22226  JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
22227  }
22228 
22229  // insert to array and return iterator
22230  return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
22231  }
22232 
22258  {
22259  // insert only works for arrays
22261  {
22262  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22263  }
22264 
22265  // check if iterator pos fits to this JSON value
22266  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22267  {
22268  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22269  }
22270 
22271  // insert to array and return iterator
22272  return insert_iterator(pos, ilist.begin(), ilist.end());
22273  }
22274 
22299  {
22300  // insert only works for objects
22302  {
22303  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22304  }
22305 
22306  // check if range iterators belong to the same JSON object
22307  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22308  {
22309  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22310  }
22311 
22312  // passed iterators must belong to objects
22313  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22314  {
22315  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
22316  }
22317 
22318  m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
22319  }
22320 
22341  {
22342  // implicitly convert null value to an empty object
22343  if (is_null())
22344  {
22345  m_type = value_t::object;
22346  m_value.object = create<object_t>();
22347  assert_invariant();
22348  }
22349 
22351  {
22352  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
22353  }
22354  if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
22355  {
22356  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
22357  }
22358 
22359  for (auto it = j.cbegin(); it != j.cend(); ++it)
22360  {
22361  m_value.object->operator[](it.key()) = it.value();
22362  }
22363  }
22364 
22392  {
22393  // implicitly convert null value to an empty object
22394  if (is_null())
22395  {
22396  m_type = value_t::object;
22397  m_value.object = create<object_t>();
22398  assert_invariant();
22399  }
22400 
22402  {
22403  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
22404  }
22405 
22406  // check if range iterators belong to the same JSON object
22407  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22408  {
22409  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22410  }
22411 
22412  // passed iterators must belong to objects
22413  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
22414  || !last.m_object->is_object()))
22415  {
22416  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
22417  }
22418 
22419  for (auto it = first; it != last; ++it)
22420  {
22421  m_value.object->operator[](it.key()) = it.value();
22422  }
22423  }
22424 
22442  void swap(reference other) noexcept (
22443  std::is_nothrow_move_constructible<value_t>::value&&
22444  std::is_nothrow_move_assignable<value_t>::value&&
22445  std::is_nothrow_move_constructible<json_value>::value&&
22446  std::is_nothrow_move_assignable<json_value>::value
22447  )
22448  {
22449  std::swap(m_type, other.m_type);
22450  std::swap(m_value, other.m_value);
22451  assert_invariant();
22452  }
22453 
22472  friend void swap(reference left, reference right) noexcept (
22473  std::is_nothrow_move_constructible<value_t>::value&&
22474  std::is_nothrow_move_assignable<value_t>::value&&
22475  std::is_nothrow_move_constructible<json_value>::value&&
22476  std::is_nothrow_move_assignable<json_value>::value
22477  )
22478  {
22479  left.swap(right);
22480  }
22481 
22502  void swap(array_t& other)
22503  {
22504  // swap only works for arrays
22506  {
22507  std::swap(*(m_value.array), other);
22508  }
22509  else
22510  {
22511  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22512  }
22513  }
22514 
22535  void swap(object_t& other)
22536  {
22537  // swap only works for objects
22539  {
22540  std::swap(*(m_value.object), other);
22541  }
22542  else
22543  {
22544  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22545  }
22546  }
22547 
22568  void swap(string_t& other)
22569  {
22570  // swap only works for strings
22572  {
22573  std::swap(*(m_value.string), other);
22574  }
22575  else
22576  {
22577  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22578  }
22579  }
22580 
22601  void swap(binary_t& other)
22602  {
22603  // swap only works for strings
22605  {
22606  std::swap(*(m_value.binary), other);
22607  }
22608  else
22609  {
22610  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22611  }
22612  }
22613 
22615  void swap(typename binary_t::container_type& other)
22616  {
22617  // swap only works for strings
22619  {
22620  std::swap(*(m_value.binary), other);
22621  }
22622  else
22623  {
22624  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22625  }
22626  }
22627 
22629 
22630  public:
22632  // lexicographical comparison operators //
22634 
22637 
22693  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
22694  {
22695  const auto lhs_type = lhs.type();
22696  const auto rhs_type = rhs.type();
22697 
22698  if (lhs_type == rhs_type)
22699  {
22700  switch (lhs_type)
22701  {
22702  case value_t::array:
22703  return *lhs.m_value.array == *rhs.m_value.array;
22704 
22705  case value_t::object:
22706  return *lhs.m_value.object == *rhs.m_value.object;
22707 
22708  case value_t::null:
22709  return true;
22710 
22711  case value_t::string:
22712  return *lhs.m_value.string == *rhs.m_value.string;
22713 
22714  case value_t::boolean:
22715  return lhs.m_value.boolean == rhs.m_value.boolean;
22716 
22718  return lhs.m_value.number_integer == rhs.m_value.number_integer;
22719 
22721  return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
22722 
22723  case value_t::number_float:
22724  return lhs.m_value.number_float == rhs.m_value.number_float;
22725 
22726  case value_t::binary:
22727  return *lhs.m_value.binary == *rhs.m_value.binary;
22728 
22729  default:
22730  return false;
22731  }
22732  }
22733  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
22734  {
22735  return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
22736  }
22737  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
22738  {
22739  return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
22740  }
22741  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
22742  {
22743  return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
22744  }
22745  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
22746  {
22747  return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
22748  }
22749  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
22750  {
22751  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
22752  }
22753  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
22754  {
22755  return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22756  }
22757 
22758  return false;
22759  }
22760 
22765  template<typename ScalarType, typename std::enable_if<
22766  std::is_scalar<ScalarType>::value, int>::type = 0>
22767  friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
22768  {
22769  return lhs == basic_json(rhs);
22770  }
22771 
22776  template<typename ScalarType, typename std::enable_if<
22777  std::is_scalar<ScalarType>::value, int>::type = 0>
22778  friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
22779  {
22780  return basic_json(lhs) == rhs;
22781  }
22782 
22801  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
22802  {
22803  return !(lhs == rhs);
22804  }
22805 
22810  template<typename ScalarType, typename std::enable_if<
22811  std::is_scalar<ScalarType>::value, int>::type = 0>
22812  friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
22813  {
22814  return lhs != basic_json(rhs);
22815  }
22816 
22821  template<typename ScalarType, typename std::enable_if<
22822  std::is_scalar<ScalarType>::value, int>::type = 0>
22823  friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
22824  {
22825  return basic_json(lhs) != rhs;
22826  }
22827 
22854  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
22855  {
22856  const auto lhs_type = lhs.type();
22857  const auto rhs_type = rhs.type();
22858 
22859  if (lhs_type == rhs_type)
22860  {
22861  switch (lhs_type)
22862  {
22863  case value_t::array:
22864  // note parentheses are necessary, see
22865  // https://github.com/nlohmann/json/issues/1530
22866  return (*lhs.m_value.array) < (*rhs.m_value.array);
22867 
22868  case value_t::object:
22869  return (*lhs.m_value.object) < (*rhs.m_value.object);
22870 
22871  case value_t::null:
22872  return false;
22873 
22874  case value_t::string:
22875  return (*lhs.m_value.string) < (*rhs.m_value.string);
22876 
22877  case value_t::boolean:
22878  return (lhs.m_value.boolean) < (rhs.m_value.boolean);
22879 
22881  return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
22882 
22884  return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
22885 
22886  case value_t::number_float:
22887  return (lhs.m_value.number_float) < (rhs.m_value.number_float);
22888 
22889  case value_t::binary:
22890  return (*lhs.m_value.binary) < (*rhs.m_value.binary);
22891 
22892  default:
22893  return false;
22894  }
22895  }
22896  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
22897  {
22898  return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
22899  }
22900  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
22901  {
22902  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
22903  }
22904  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
22905  {
22906  return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
22907  }
22908  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
22909  {
22910  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
22911  }
22912  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
22913  {
22914  return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22915  }
22916  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
22917  {
22918  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
22919  }
22920 
22921  // We only reach this line if we cannot compare values. In that case,
22922  // we compare types. Note we have to call the operator explicitly,
22923  // because MSVC has problems otherwise.
22924  return operator<(lhs_type, rhs_type);
22925  }
22926 
22931  template<typename ScalarType, typename std::enable_if<
22932  std::is_scalar<ScalarType>::value, int>::type = 0>
22933  friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
22934  {
22935  return lhs < basic_json(rhs);
22936  }
22937 
22942  template<typename ScalarType, typename std::enable_if<
22943  std::is_scalar<ScalarType>::value, int>::type = 0>
22944  friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
22945  {
22946  return basic_json(lhs) < rhs;
22947  }
22948 
22968  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
22969  {
22970  return !(rhs < lhs);
22971  }
22972 
22977  template<typename ScalarType, typename std::enable_if<
22978  std::is_scalar<ScalarType>::value, int>::type = 0>
22979  friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
22980  {
22981  return lhs <= basic_json(rhs);
22982  }
22983 
22988  template<typename ScalarType, typename std::enable_if<
22989  std::is_scalar<ScalarType>::value, int>::type = 0>
22990  friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
22991  {
22992  return basic_json(lhs) <= rhs;
22993  }
22994 
23014  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
23015  {
23016  return !(lhs <= rhs);
23017  }
23018 
23023  template<typename ScalarType, typename std::enable_if<
23024  std::is_scalar<ScalarType>::value, int>::type = 0>
23025  friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
23026  {
23027  return lhs > basic_json(rhs);
23028  }
23029 
23034  template<typename ScalarType, typename std::enable_if<
23035  std::is_scalar<ScalarType>::value, int>::type = 0>
23036  friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
23037  {
23038  return basic_json(lhs) > rhs;
23039  }
23040 
23060  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
23061  {
23062  return !(lhs < rhs);
23063  }
23064 
23069  template<typename ScalarType, typename std::enable_if<
23070  std::is_scalar<ScalarType>::value, int>::type = 0>
23071  friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
23072  {
23073  return lhs >= basic_json(rhs);
23074  }
23075 
23080  template<typename ScalarType, typename std::enable_if<
23081  std::is_scalar<ScalarType>::value, int>::type = 0>
23082  friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
23083  {
23084  return basic_json(lhs) >= rhs;
23085  }
23086 
23088 
23090  // serialization //
23092 
23095 
23127  friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
23128  {
23129  // read width member and use it as indentation parameter if nonzero
23130  const bool pretty_print = o.width() > 0;
23131  const auto indentation = pretty_print ? o.width() : 0;
23132 
23133  // reset width to 0 for subsequent calls to this stream
23134  o.width(0);
23135 
23136  // do the actual serialization
23137  serializer s(detail::output_adapter<char>(o), o.fill());
23138  s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
23139  return o;
23140  }
23141 
23150  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
23151  friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
23152  {
23153  return o << j;
23154  }
23155 
23157 
23158 
23160  // deserialization //
23162 
23165 
23217  template<typename InputType>
23219  static basic_json parse(InputType&& i,
23220  const parser_callback_t cb = nullptr,
23221  const bool allow_exceptions = true,
23222  const bool ignore_comments = false)
23223  {
23225  parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
23226  return result;
23227  }
23228 
23255  template<typename IteratorType>
23257  static basic_json parse(IteratorType first,
23258  IteratorType last,
23259  const parser_callback_t cb = nullptr,
23260  const bool allow_exceptions = true,
23261  const bool ignore_comments = false)
23262  {
23264  parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
23265  return result;
23266  }
23267 
23269  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
23270  static basic_json parse(detail::span_input_adapter&& i,
23271  const parser_callback_t cb = nullptr,
23272  const bool allow_exceptions = true,
23273  const bool ignore_comments = false)
23274  {
23276  parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
23277  return result;
23278  }
23279 
23310  template<typename InputType>
23311  static bool accept(InputType&& i,
23312  const bool ignore_comments = false)
23313  {
23314  return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
23315  }
23316 
23317  template<typename IteratorType>
23318  static bool accept(IteratorType first, IteratorType last,
23319  const bool ignore_comments = false)
23320  {
23321  return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
23322  }
23323 
23325  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
23326  static bool accept(detail::span_input_adapter&& i,
23327  const bool ignore_comments = false)
23328  {
23329  return parser(i.get(), nullptr, false, ignore_comments).accept(true);
23330  }
23331 
23372  template <typename InputType, typename SAX>
23374  static bool sax_parse(InputType&& i, SAX* sax,
23376  const bool strict = true,
23377  const bool ignore_comments = false)
23378  {
23379  auto ia = detail::input_adapter(std::forward<InputType>(i));
23380  return format == input_format_t::json
23381  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23382  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23383  }
23384 
23385  template<class IteratorType, class SAX>
23387  static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
23389  const bool strict = true,
23390  const bool ignore_comments = false)
23391  {
23392  auto ia = detail::input_adapter(std::move(first), std::move(last));
23393  return format == input_format_t::json
23394  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23395  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23396  }
23397 
23398  template <typename SAX>
23399  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
23401  static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
23403  const bool strict = true,
23404  const bool ignore_comments = false)
23405  {
23406  auto ia = i.get();
23407  return format == input_format_t::json
23408  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23409  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23410  }
23411 
23420  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
23421  friend std::istream& operator<<(basic_json& j, std::istream& i)
23422  {
23423  return operator>>(i, j);
23424  }
23425 
23451  friend std::istream& operator>>(std::istream& i, basic_json& j)
23452  {
23453  parser(detail::input_adapter(i)).parse(false, j);
23454  return i;
23455  }
23456 
23458 
23460  // convenience functions //
23462 
23495  const char* type_name() const noexcept
23496  {
23497  {
23498  switch (m_type)
23499  {
23500  case value_t::null:
23501  return "null";
23502  case value_t::object:
23503  return "object";
23504  case value_t::array:
23505  return "array";
23506  case value_t::string:
23507  return "string";
23508  case value_t::boolean:
23509  return "boolean";
23510  case value_t::binary:
23511  return "binary";
23512  case value_t::discarded:
23513  return "discarded";
23514  default:
23515  return "number";
23516  }
23517  }
23518  }
23519 
23520 
23523  // member variables //
23525 
23527  value_t m_type = value_t::null;
23528 
23531 
23533  // binary serialization/deserialization //
23535 
23538 
23539  public:
23634  static std::vector<uint8_t> to_cbor(const basic_json& j)
23635  {
23636  std::vector<uint8_t> result;
23637  to_cbor(j, result);
23638  return result;
23639  }
23640 
23642  {
23644  }
23645 
23647  {
23649  }
23650 
23729  static std::vector<uint8_t> to_msgpack(const basic_json& j)
23730  {
23731  std::vector<uint8_t> result;
23732  to_msgpack(j, result);
23733  return result;
23734  }
23735 
23737  {
23739  }
23740 
23742  {
23744  }
23745 
23832  static std::vector<uint8_t> to_ubjson(const basic_json& j,
23833  const bool use_size = false,
23834  const bool use_type = false)
23835  {
23836  std::vector<uint8_t> result;
23837  to_ubjson(j, result, use_size, use_type);
23838  return result;
23839  }
23840 
23842  const bool use_size = false, const bool use_type = false)
23843  {
23844  binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
23845  }
23846 
23848  const bool use_size = false, const bool use_type = false)
23849  {
23850  binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23851  }
23852 
23853 
23910  static std::vector<uint8_t> to_bson(const basic_json& j)
23911  {
23912  std::vector<uint8_t> result;
23913  to_bson(j, result);
23914  return result;
23915  }
23916 
23926  {
23928  }
23929 
23934  {
23936  }
23937 
23938 
24041  template<typename InputType>
24043  static basic_json from_cbor(InputType&& i,
24044  const bool strict = true,
24045  const bool allow_exceptions = true,
24046  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24047  {
24049  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24050  auto ia = detail::input_adapter(std::forward<InputType>(i));
24051  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24052  return res ? result : basic_json(value_t::discarded);
24053  }
24054 
24058  template<typename IteratorType>
24060  static basic_json from_cbor(IteratorType first, IteratorType last,
24061  const bool strict = true,
24062  const bool allow_exceptions = true,
24063  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24064  {
24066  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24067  auto ia = detail::input_adapter(std::move(first), std::move(last));
24068  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24069  return res ? result : basic_json(value_t::discarded);
24070  }
24071 
24072  template<typename T>
24074  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
24075  static basic_json from_cbor(const T* ptr, std::size_t len,
24076  const bool strict = true,
24077  const bool allow_exceptions = true,
24078  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24079  {
24080  return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
24081  }
24082 
24083 
24085  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
24086  static basic_json from_cbor(detail::span_input_adapter&& i,
24087  const bool strict = true,
24088  const bool allow_exceptions = true,
24089  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24090  {
24092  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24093  auto ia = i.get();
24094  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24095  return res ? result : basic_json(value_t::discarded);
24096  }
24097 
24184  template<typename InputType>
24186  static basic_json from_msgpack(InputType&& i,
24187  const bool strict = true,
24188  const bool allow_exceptions = true)
24189  {
24191  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24192  auto ia = detail::input_adapter(std::forward<InputType>(i));
24193  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24194  return res ? result : basic_json(value_t::discarded);
24195  }
24196 
24200  template<typename IteratorType>
24202  static basic_json from_msgpack(IteratorType first, IteratorType last,
24203  const bool strict = true,
24204  const bool allow_exceptions = true)
24205  {
24207  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24208  auto ia = detail::input_adapter(std::move(first), std::move(last));
24209  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24210  return res ? result : basic_json(value_t::discarded);
24211  }
24212 
24213 
24214  template<typename T>
24216  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
24217  static basic_json from_msgpack(const T* ptr, std::size_t len,
24218  const bool strict = true,
24219  const bool allow_exceptions = true)
24220  {
24221  return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
24222  }
24223 
24225  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
24226  static basic_json from_msgpack(detail::span_input_adapter&& i,
24227  const bool strict = true,
24228  const bool allow_exceptions = true)
24229  {
24231  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24232  auto ia = i.get();
24233  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24234  return res ? result : basic_json(value_t::discarded);
24235  }
24236 
24237 
24300  template<typename InputType>
24302  static basic_json from_ubjson(InputType&& i,
24303  const bool strict = true,
24304  const bool allow_exceptions = true)
24305  {
24307  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24308  auto ia = detail::input_adapter(std::forward<InputType>(i));
24309  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24310  return res ? result : basic_json(value_t::discarded);
24311  }
24312 
24316  template<typename IteratorType>
24318  static basic_json from_ubjson(IteratorType first, IteratorType last,
24319  const bool strict = true,
24320  const bool allow_exceptions = true)
24321  {
24323  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24324  auto ia = detail::input_adapter(std::move(first), std::move(last));
24325  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24326  return res ? result : basic_json(value_t::discarded);
24327  }
24328 
24329  template<typename T>
24331  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
24332  static basic_json from_ubjson(const T* ptr, std::size_t len,
24333  const bool strict = true,
24334  const bool allow_exceptions = true)
24335  {
24336  return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
24337  }
24338 
24340  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
24341  static basic_json from_ubjson(detail::span_input_adapter&& i,
24342  const bool strict = true,
24343  const bool allow_exceptions = true)
24344  {
24346  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24347  auto ia = i.get();
24348  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24349  return res ? result : basic_json(value_t::discarded);
24350  }
24351 
24352 
24413  template<typename InputType>
24415  static basic_json from_bson(InputType&& i,
24416  const bool strict = true,
24417  const bool allow_exceptions = true)
24418  {
24420  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24421  auto ia = detail::input_adapter(std::forward<InputType>(i));
24422  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24423  return res ? result : basic_json(value_t::discarded);
24424  }
24425 
24429  template<typename IteratorType>
24431  static basic_json from_bson(IteratorType first, IteratorType last,
24432  const bool strict = true,
24433  const bool allow_exceptions = true)
24434  {
24436  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24437  auto ia = detail::input_adapter(std::move(first), std::move(last));
24438  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24439  return res ? result : basic_json(value_t::discarded);
24440  }
24441 
24442  template<typename T>
24444  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
24445  static basic_json from_bson(const T* ptr, std::size_t len,
24446  const bool strict = true,
24447  const bool allow_exceptions = true)
24448  {
24449  return from_bson(ptr, ptr + len, strict, allow_exceptions);
24450  }
24451 
24453  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
24454  static basic_json from_bson(detail::span_input_adapter&& i,
24455  const bool strict = true,
24456  const bool allow_exceptions = true)
24457  {
24459  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24460  auto ia = i.get();
24461  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24462  return res ? result : basic_json(value_t::discarded);
24463  }
24465 
24467  // JSON Pointer support //
24469 
24472 
24507  {
24508  return ptr.get_unchecked(this);
24509  }
24510 
24535  {
24536  return ptr.get_unchecked(this);
24537  }
24538 
24578  {
24579  return ptr.get_checked(this);
24580  }
24581 
24620  const_reference at(const json_pointer& ptr) const
24621  {
24622  return ptr.get_checked(this);
24623  }
24624 
24648  {
24650  json_pointer::flatten("", *this, result);
24651  return result;
24652  }
24653 
24685  {
24686  return json_pointer::unflatten(*this);
24687  }
24688 
24690 
24692  // JSON Patch functions //
24694 
24697 
24745  basic_json patch(const basic_json& json_patch) const
24746  {
24747  // make a working copy to apply the patch to
24748  basic_json result = *this;
24749 
24750  // the valid JSON Patch operations
24751  enum class patch_operations {add, remove, replace, move, copy, test, invalid};
24752 
24753  const auto get_op = [](const std::string & op)
24754  {
24755  if (op == "add")
24756  {
24757  return patch_operations::add;
24758  }
24759  if (op == "remove")
24760  {
24761  return patch_operations::remove;
24762  }
24763  if (op == "replace")
24764  {
24765  return patch_operations::replace;
24766  }
24767  if (op == "move")
24768  {
24769  return patch_operations::move;
24770  }
24771  if (op == "copy")
24772  {
24773  return patch_operations::copy;
24774  }
24775  if (op == "test")
24776  {
24777  return patch_operations::test;
24778  }
24779 
24780  return patch_operations::invalid;
24781  };
24782 
24783  // wrapper for "add" operation; add value at ptr
24784  const auto operation_add = [&result](json_pointer & ptr, basic_json val)
24785  {
24786  // adding to the root of the target document means replacing it
24787  if (ptr.empty())
24788  {
24789  result = val;
24790  return;
24791  }
24792 
24793  // make sure the top element of the pointer exists
24794  json_pointer top_pointer = ptr.top();
24795  if (top_pointer != ptr)
24796  {
24797  result.at(top_pointer);
24798  }
24799 
24800  // get reference to parent of JSON pointer ptr
24801  const auto last_path = ptr.back();
24802  ptr.pop_back();
24803  basic_json& parent = result[ptr];
24804 
24805  switch (parent.m_type)
24806  {
24807  case value_t::null:
24808  case value_t::object:
24809  {
24810  // use operator[] to add value
24811  parent[last_path] = val;
24812  break;
24813  }
24814 
24815  case value_t::array:
24816  {
24817  if (last_path == "-")
24818  {
24819  // special case: append to back
24820  parent.push_back(val);
24821  }
24822  else
24823  {
24824  const auto idx = json_pointer::array_index(last_path);
24825  if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
24826  {
24827  // avoid undefined behavior
24828  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
24829  }
24830 
24831  // default case: insert add offset
24832  parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
24833  }
24834  break;
24835  }
24836 
24837  // if there exists a parent it cannot be primitive
24838  default: // LCOV_EXCL_LINE
24839  JSON_ASSERT(false); // LCOV_EXCL_LINE
24840  }
24841  };
24842 
24843  // wrapper for "remove" operation; remove value at ptr
24844  const auto operation_remove = [&result](json_pointer & ptr)
24845  {
24846  // get reference to parent of JSON pointer ptr
24847  const auto last_path = ptr.back();
24848  ptr.pop_back();
24849  basic_json& parent = result.at(ptr);
24850 
24851  // remove child
24852  if (parent.is_object())
24853  {
24854  // perform range check
24855  auto it = parent.find(last_path);
24856  if (JSON_HEDLEY_LIKELY(it != parent.end()))
24857  {
24858  parent.erase(it);
24859  }
24860  else
24861  {
24862  JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
24863  }
24864  }
24865  else if (parent.is_array())
24866  {
24867  // note erase performs range check
24868  parent.erase(json_pointer::array_index(last_path));
24869  }
24870  };
24871 
24872  // type check: top level value must be an array
24873  if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
24874  {
24875  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24876  }
24877 
24878  // iterate and apply the operations
24879  for (const auto& val : json_patch)
24880  {
24881  // wrapper to get a value for an operation
24882  const auto get_value = [&val](const std::string & op,
24883  const std::string & member,
24884  bool string_type) -> basic_json &
24885  {
24886  // find value
24887  auto it = val.m_value.object->find(member);
24888 
24889  // context-sensitive error message
24890  const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
24891 
24892  // check if desired value is present
24893  if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
24894  {
24895  JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
24896  }
24897 
24898  // check if result is of type string
24899  if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
24900  {
24901  JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
24902  }
24903 
24904  // no error: return value
24905  return it->second;
24906  };
24907 
24908  // type check: every element of the array must be an object
24909  if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
24910  {
24911  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24912  }
24913 
24914  // collect mandatory members
24915  const auto op = get_value("op", "op", true).template get<std::string>();
24916  const auto path = get_value(op, "path", true).template get<std::string>();
24917  json_pointer ptr(path);
24918 
24919  switch (get_op(op))
24920  {
24921  case patch_operations::add:
24922  {
24923  operation_add(ptr, get_value("add", "value", false));
24924  break;
24925  }
24926 
24927  case patch_operations::remove:
24928  {
24929  operation_remove(ptr);
24930  break;
24931  }
24932 
24933  case patch_operations::replace:
24934  {
24935  // the "path" location must exist - use at()
24936  result.at(ptr) = get_value("replace", "value", false);
24937  break;
24938  }
24939 
24940  case patch_operations::move:
24941  {
24942  const auto from_path = get_value("move", "from", true).template get<std::string>();
24943  json_pointer from_ptr(from_path);
24944 
24945  // the "from" location must exist - use at()
24946  basic_json v = result.at(from_ptr);
24947 
24948  // The move operation is functionally identical to a
24949  // "remove" operation on the "from" location, followed
24950  // immediately by an "add" operation at the target
24951  // location with the value that was just removed.
24952  operation_remove(from_ptr);
24953  operation_add(ptr, v);
24954  break;
24955  }
24956 
24957  case patch_operations::copy:
24958  {
24959  const auto from_path = get_value("copy", "from", true).template get<std::string>();
24960  const json_pointer from_ptr(from_path);
24961 
24962  // the "from" location must exist - use at()
24963  basic_json v = result.at(from_ptr);
24964 
24965  // The copy is functionally identical to an "add"
24966  // operation at the target location using the value
24967  // specified in the "from" member.
24968  operation_add(ptr, v);
24969  break;
24970  }
24971 
24972  case patch_operations::test:
24973  {
24974  bool success = false;
24975  JSON_TRY
24976  {
24977  // check if "value" matches the one at "path"
24978  // the "path" location must exist - use at()
24979  success = (result.at(ptr) == get_value("test", "value", false));
24980  }
24982  {
24983  // ignore out of range errors: success remains false
24984  }
24985 
24986  // throw an exception if test fails
24987  if (JSON_HEDLEY_UNLIKELY(!success))
24988  {
24989  JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
24990  }
24991 
24992  break;
24993  }
24994 
24995  default:
24996  {
24997  // op must be "add", "remove", "replace", "move", "copy", or
24998  // "test"
24999  JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
25000  }
25001  }
25002  }
25003 
25004  return result;
25005  }
25006 
25041  static basic_json diff(const basic_json& source, const basic_json& target,
25042  const std::string& path = "")
25043  {
25044  // the patch
25046 
25047  // if the values are the same, return empty patch
25048  if (source == target)
25049  {
25050  return result;
25051  }
25052 
25053  if (source.type() != target.type())
25054  {
25055  // different types: replace value
25056  result.push_back(
25057  {
25058  {"op", "replace"}, {"path", path}, {"value", target}
25059  });
25060  return result;
25061  }
25062 
25063  switch (source.type())
25064  {
25065  case value_t::array:
25066  {
25067  // first pass: traverse common elements
25068  std::size_t i = 0;
25069  while (i < source.size() && i < target.size())
25070  {
25071  // recursive call to compare array values at index i
25072  auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
25073  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
25074  ++i;
25075  }
25076 
25077  // i now reached the end of at least one array
25078  // in a second pass, traverse the remaining elements
25079 
25080  // remove my remaining elements
25081  const auto end_index = static_cast<difference_type>(result.size());
25082  while (i < source.size())
25083  {
25084  // add operations in reverse order to avoid invalid
25085  // indices
25086  result.insert(result.begin() + end_index, object(
25087  {
25088  {"op", "remove"},
25089  {"path", path + "/" + std::to_string(i)}
25090  }));
25091  ++i;
25092  }
25093 
25094  // add other remaining elements
25095  while (i < target.size())
25096  {
25097  result.push_back(
25098  {
25099  {"op", "add"},
25100  {"path", path + "/-"},
25101  {"value", target[i]}
25102  });
25103  ++i;
25104  }
25105 
25106  break;
25107  }
25108 
25109  case value_t::object:
25110  {
25111  // first pass: traverse this object's elements
25112  for (auto it = source.cbegin(); it != source.cend(); ++it)
25113  {
25114  // escape the key name to be used in a JSON patch
25115  const auto key = json_pointer::escape(it.key());
25116 
25117  if (target.find(it.key()) != target.end())
25118  {
25119  // recursive call to compare object values at key it
25120  auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
25121  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
25122  }
25123  else
25124  {
25125  // found a key that is not in o -> remove it
25126  result.push_back(object(
25127  {
25128  {"op", "remove"}, {"path", path + "/" + key}
25129  }));
25130  }
25131  }
25132 
25133  // second pass: traverse other object's elements
25134  for (auto it = target.cbegin(); it != target.cend(); ++it)
25135  {
25136  if (source.find(it.key()) == source.end())
25137  {
25138  // found a key that is not in this -> add it
25139  const auto key = json_pointer::escape(it.key());
25140  result.push_back(
25141  {
25142  {"op", "add"}, {"path", path + "/" + key},
25143  {"value", it.value()}
25144  });
25145  }
25146  }
25147 
25148  break;
25149  }
25150 
25151  default:
25152  {
25153  // both primitive type: replace value
25154  result.push_back(
25155  {
25156  {"op", "replace"}, {"path", path}, {"value", target}
25157  });
25158  break;
25159  }
25160  }
25161 
25162  return result;
25163  }
25164 
25166 
25168  // JSON Merge Patch functions //
25170 
25173 
25216  void merge_patch(const basic_json& apply_patch)
25217  {
25218  if (apply_patch.is_object())
25219  {
25220  if (!is_object())
25221  {
25222  *this = object();
25223  }
25224  for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
25225  {
25226  if (it.value().is_null())
25227  {
25228  erase(it.key());
25229  }
25230  else
25231  {
25232  operator[](it.key()).merge_patch(it.value());
25233  }
25234  }
25235  }
25236  else
25237  {
25238  *this = apply_patch;
25239  }
25240  }
25241 
25243 };
25244 
25255 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
25256 {
25257  return j.dump();
25258 }
25259 } // namespace nlohmann
25260 
25262 // nonmember support //
25264 
25265 // specialization of std::swap, and std::hash
25266 namespace std
25267 {
25268 
25270 template<>
25272 {
25278  std::size_t operator()(const nlohmann::json& j) const
25279  {
25280  return nlohmann::detail::hash(j);
25281  }
25282 };
25283 
25287 template<>
25289 {
25295  nlohmann::detail::value_t rhs) const noexcept
25296  {
25297  return nlohmann::detail::operator<(lhs, rhs);
25298  }
25299 };
25300 
25301 // C++20 prohibit function specialization in the std namespace.
25302 #ifndef JSON_HAS_CPP_20
25303 
25309 template<>
25310 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
25311  is_nothrow_move_constructible<nlohmann::json>::value&&
25312  is_nothrow_move_assignable<nlohmann::json>::value
25313  )
25314 {
25315  j1.swap(j2);
25316 }
25317 
25318 #endif
25319 
25320 } // namespace std
25321 
25336 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
25337 {
25338  return nlohmann::json::parse(s, s + n);
25339 }
25340 
25355 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
25356 {
25357  return nlohmann::json::json_pointer(std::string(s, n));
25358 }
25359 
25360 // #include <nlohmann/detail/macro_unscope.hpp>
25361 
25362 
25363 // restore GCC/clang diagnostic settings
25364 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
25365  #pragma GCC diagnostic pop
25366 #endif
25367 #if defined(__clang__)
25368  #pragma GCC diagnostic pop
25369 #endif
25370 
25371 // clean up
25372 #undef JSON_ASSERT
25373 #undef JSON_INTERNAL_CATCH
25374 #undef JSON_CATCH
25375 #undef JSON_THROW
25376 #undef JSON_TRY
25377 #undef JSON_PRIVATE_UNLESS_TESTED
25378 #undef JSON_HAS_CPP_14
25379 #undef JSON_HAS_CPP_17
25380 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
25381 #undef NLOHMANN_BASIC_JSON_TPL
25382 #undef JSON_EXPLICIT
25383 
25384 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
25385 #undef JSON_HEDLEY_ALWAYS_INLINE
25386 #undef JSON_HEDLEY_ARM_VERSION
25387 #undef JSON_HEDLEY_ARM_VERSION_CHECK
25388 #undef JSON_HEDLEY_ARRAY_PARAM
25389 #undef JSON_HEDLEY_ASSUME
25390 #undef JSON_HEDLEY_BEGIN_C_DECLS
25391 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
25392 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
25393 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
25394 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
25395 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
25396 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
25397 #undef JSON_HEDLEY_CLANG_HAS_WARNING
25398 #undef JSON_HEDLEY_COMPCERT_VERSION
25399 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
25400 #undef JSON_HEDLEY_CONCAT
25401 #undef JSON_HEDLEY_CONCAT3
25402 #undef JSON_HEDLEY_CONCAT3_EX
25403 #undef JSON_HEDLEY_CONCAT_EX
25404 #undef JSON_HEDLEY_CONST
25405 #undef JSON_HEDLEY_CONSTEXPR
25406 #undef JSON_HEDLEY_CONST_CAST
25407 #undef JSON_HEDLEY_CPP_CAST
25408 #undef JSON_HEDLEY_CRAY_VERSION
25409 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
25410 #undef JSON_HEDLEY_C_DECL
25411 #undef JSON_HEDLEY_DEPRECATED
25412 #undef JSON_HEDLEY_DEPRECATED_FOR
25413 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
25414 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
25415 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
25416 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
25417 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
25418 #undef JSON_HEDLEY_DIAGNOSTIC_POP
25419 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
25420 #undef JSON_HEDLEY_DMC_VERSION
25421 #undef JSON_HEDLEY_DMC_VERSION_CHECK
25422 #undef JSON_HEDLEY_EMPTY_BASES
25423 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
25424 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
25425 #undef JSON_HEDLEY_END_C_DECLS
25426 #undef JSON_HEDLEY_FLAGS
25427 #undef JSON_HEDLEY_FLAGS_CAST
25428 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
25429 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
25430 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
25431 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
25432 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
25433 #undef JSON_HEDLEY_GCC_HAS_FEATURE
25434 #undef JSON_HEDLEY_GCC_HAS_WARNING
25435 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
25436 #undef JSON_HEDLEY_GCC_VERSION
25437 #undef JSON_HEDLEY_GCC_VERSION_CHECK
25438 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
25439 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
25440 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
25441 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
25442 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
25443 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
25444 #undef JSON_HEDLEY_GNUC_HAS_WARNING
25445 #undef JSON_HEDLEY_GNUC_VERSION
25446 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
25447 #undef JSON_HEDLEY_HAS_ATTRIBUTE
25448 #undef JSON_HEDLEY_HAS_BUILTIN
25449 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
25450 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
25451 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
25452 #undef JSON_HEDLEY_HAS_EXTENSION
25453 #undef JSON_HEDLEY_HAS_FEATURE
25454 #undef JSON_HEDLEY_HAS_WARNING
25455 #undef JSON_HEDLEY_IAR_VERSION
25456 #undef JSON_HEDLEY_IAR_VERSION_CHECK
25457 #undef JSON_HEDLEY_IBM_VERSION
25458 #undef JSON_HEDLEY_IBM_VERSION_CHECK
25459 #undef JSON_HEDLEY_IMPORT
25460 #undef JSON_HEDLEY_INLINE
25461 #undef JSON_HEDLEY_INTEL_CL_VERSION
25462 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
25463 #undef JSON_HEDLEY_INTEL_VERSION
25464 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
25465 #undef JSON_HEDLEY_IS_CONSTANT
25466 #undef JSON_HEDLEY_IS_CONSTEXPR_
25467 #undef JSON_HEDLEY_LIKELY
25468 #undef JSON_HEDLEY_MALLOC
25469 #undef JSON_HEDLEY_MESSAGE
25470 #undef JSON_HEDLEY_MSVC_VERSION
25471 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
25472 #undef JSON_HEDLEY_NEVER_INLINE
25473 #undef JSON_HEDLEY_NON_NULL
25474 #undef JSON_HEDLEY_NO_ESCAPE
25475 #undef JSON_HEDLEY_NO_RETURN
25476 #undef JSON_HEDLEY_NO_THROW
25477 #undef JSON_HEDLEY_NULL
25478 #undef JSON_HEDLEY_PELLES_VERSION
25479 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
25480 #undef JSON_HEDLEY_PGI_VERSION
25481 #undef JSON_HEDLEY_PGI_VERSION_CHECK
25482 #undef JSON_HEDLEY_PREDICT
25483 #undef JSON_HEDLEY_PRINTF_FORMAT
25484 #undef JSON_HEDLEY_PRIVATE
25485 #undef JSON_HEDLEY_PUBLIC
25486 #undef JSON_HEDLEY_PURE
25487 #undef JSON_HEDLEY_REINTERPRET_CAST
25488 #undef JSON_HEDLEY_REQUIRE
25489 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
25490 #undef JSON_HEDLEY_REQUIRE_MSG
25491 #undef JSON_HEDLEY_RESTRICT
25492 #undef JSON_HEDLEY_RETURNS_NON_NULL
25493 #undef JSON_HEDLEY_SENTINEL
25494 #undef JSON_HEDLEY_STATIC_ASSERT
25495 #undef JSON_HEDLEY_STATIC_CAST
25496 #undef JSON_HEDLEY_STRINGIFY
25497 #undef JSON_HEDLEY_STRINGIFY_EX
25498 #undef JSON_HEDLEY_SUNPRO_VERSION
25499 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
25500 #undef JSON_HEDLEY_TINYC_VERSION
25501 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
25502 #undef JSON_HEDLEY_TI_ARMCL_VERSION
25503 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
25504 #undef JSON_HEDLEY_TI_CL2000_VERSION
25505 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
25506 #undef JSON_HEDLEY_TI_CL430_VERSION
25507 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
25508 #undef JSON_HEDLEY_TI_CL6X_VERSION
25509 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
25510 #undef JSON_HEDLEY_TI_CL7X_VERSION
25511 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
25512 #undef JSON_HEDLEY_TI_CLPRU_VERSION
25513 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
25514 #undef JSON_HEDLEY_TI_VERSION
25515 #undef JSON_HEDLEY_TI_VERSION_CHECK
25516 #undef JSON_HEDLEY_UNAVAILABLE
25517 #undef JSON_HEDLEY_UNLIKELY
25518 #undef JSON_HEDLEY_UNPREDICTABLE
25519 #undef JSON_HEDLEY_UNREACHABLE
25520 #undef JSON_HEDLEY_UNREACHABLE_RETURN
25521 #undef JSON_HEDLEY_VERSION
25522 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
25523 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
25524 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
25525 #undef JSON_HEDLEY_VERSION_ENCODE
25526 #undef JSON_HEDLEY_WARNING
25527 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
25528 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
25529 #undef JSON_HEDLEY_FALL_THROUGH
25530 
25531 
25532 
25533 #endif // INCLUDE_NLOHMANN_JSON_HPP_
#define min(a, b)
Definition: 80211b.c:42
double f(double x, void *params)
Definition: 80211b.c:70
#define max(a, b)
Definition: 80211b.c:43
a class to store JSON values
Definition: json.h:16736
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init, std::uint8_t subtype)
explicitly create a binary array (with subtype)
Definition: json.h:18307
constexpr auto get() const noexcept -> decltype(std::declval< const basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.h:19710
void insert(const_iterator first, const_iterator last)
inserts elements
Definition: json.h:22298
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.h:17872
bool contains(KeyT &&key) const
check the existence of an element in a JSON object
Definition: json.h:20979
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.h:21264
number_unsigned_t number_unsigned
number (unsigned integer)
Definition: json.h:17547
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.h:24534
basic_json get() const
get special-case overload
Definition: json.h:19419
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.h:24506
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.h:20362
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.h:19112
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.h:17269
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.h:22693
friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.h:23036
NLOHMANN_BASIC_JSON_TPL basic_json_t
workaround type for MSVC
Definition: json.h:16756
static bool sax_parse(InputType &&i, SAX *sax, input_format_t format=input_format_t::json, const bool strict=true, const bool ignore_comments=false)
generate SAX events
Definition: json.h:23374
constexpr const number_integer_t * get_impl_ptr(const number_integer_t *) const noexcept
get a pointer to the value (integer number)
Definition: json.h:19331
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.h:19744
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(InputType &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a compatible input
Definition: json.h:23219
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.h:21984
const_iterator find(KeyT &&key) const
find an element in a JSON object
Definition: json.h:20912
basic_json(const value_t v)
create an empty value with a given type
Definition: json.h:17913
static void to_ubjson(const basic_json &j, detail::output_adapter< uint8_t > o, const bool use_size=false, const bool use_type=false)
create a CBOR serialization of a given JSON value
Definition: json.h:23841
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.h:18745
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.h:21648
basic_json(CompatibleType &&val) noexcept(noexcept(JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value
Definition: json.h:18010
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition: json.h:25041
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.h:20842
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.h:21293
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.h:20025
static iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition: json.h:21357
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.h:19974
iterator begin() noexcept
returns an iterator to the first element
Definition: json.h:21049
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.h:18489
static std::vector< uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.h:23832
json_value(object_t &&value)
constructor for rvalue objects
Definition: json.h:17651
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
Definition: json.h:19313
basic_json(const JsonRef &ref)
explicitly create a binary array (without subtype)
Definition: json.h:18592
static void to_cbor(const basic_json &j, detail::output_adapter< uint8_t > o)
create a CBOR serialization of a given JSON value
Definition: json.h:23641
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
Definition: json.h:19301
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.h:18353
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
Definition: json.h:17560
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.h:21235
json_value(string_t &&value)
constructor for rvalue strings
Definition: json.h:17639
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.h:21160
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
Definition: json.h:17556
reference back()
access the last element
Definition: json.h:20532
static bool accept(InputType &&i, const bool ignore_comments=false)
check if the input is valid JSON
Definition: json.h:23311
StringType string_t
a type for a string
Definition: json.h:17171
size_type size() const noexcept
returns the number of elements
Definition: json.h:21577
void push_back(const basic_json &val)
add an object to an array
Definition: json.h:21831
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.h:23151
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition: json.h:16912
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.h:20434
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
Definition: json.h:22340
constexpr const binary_t * get_impl_ptr(const binary_t *) const noexcept
get a pointer to the value (binary)
Definition: json.h:19367
std::size_t size_type
a type to represent container sizes
Definition: json.h:16855
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
Definition: json.h:19289
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.h:16853
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition: json.h:18250
reference operator[](const typename object_t::key_type &key)
access specified object element
Definition: json.h:20155
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
Definition: json.h:19349
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
Definition: json.h:17558
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.h:21821
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.h:18047
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.h:16863
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
Definition: json.h:24431
friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than
Definition: json.h:23025
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.h:16861
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.h:24043
BooleanType boolean_t
a type for a boolean
Definition: json.h:17197
void push_back(initializer_list_t init)
add an object to an object
Definition: json.h:21936
JSON_HEDLEY_RETURNS_NON_NULL const char * type_name() const noexcept
return the type as string
Definition: json.h:23495
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
Definition: json.h:19266
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition: json.h:18842
static bool accept(IteratorType first, IteratorType last, const bool ignore_comments=false)
deserialize from stream
Definition: json.h:23318
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.h:20599
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
Definition: json.h:24415
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.h:18953
const_iterator begin() const noexcept
returns a const iterator to the first element
Definition: json.h:21059
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
Definition: json.h:21447
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.h:19876
reference front()
access the first element
Definition: json.h:20488
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.h:18926
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.h:19084
static void to_cbor(const basic_json &j, detail::output_adapter< char > o)
create a CBOR serialization of a given JSON value
Definition: json.h:23646
void swap(object_t &other)
exchanges the values
Definition: json.h:22535
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.h:19134
const_reference front() const
access the first element
Definition: json.h:20496
binary_t * get_impl_ptr(binary_t *) noexcept
get a pointer to the value (binary)
Definition: json.h:19361
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.h:18895
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.h:17408
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.h:16870
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.h:22968
bool empty() const noexcept
checks whether the container is empty.
Definition: json.h:21504
constexpr const number_unsigned_t * get_impl_ptr(const number_unsigned_t *) const noexcept
get a pointer to the value (unsigned number)
Definition: json.h:19343
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.h:23127
friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.h:23082
json_value(value_t t)
constructor for empty values of a given type
Definition: json.h:17562
basic_json(const basic_json &other)
copy constructor
Definition: json.h:18619
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
Definition: json.h:19319
~basic_json() noexcept
destructor
Definition: json.h:18778
BasicJsonType get() const
get special-case overload
Definition: json.h:19442
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.h:18708
static void to_bson(const basic_json &j, detail::output_adapter< uint8_t > o)
Serializes the given JSON object j to BSON and forwards the corresponding BSON-representation to the ...
Definition: json.h:23925
friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than or equal
Definition: json.h:23071
static void to_ubjson(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
create a CBOR serialization of a given JSON value
Definition: json.h:23847
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.h:22801
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
Definition: json.h:22156
json_value m_value
the value of the current element
Definition: json.h:23530
boolean_t boolean
boolean
Definition: json.h:17543
void swap(typename binary_t::container_type &other)
Definition: json.h:22615
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.h:23060
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
Definition: json.h:19283
void swap(array_t &other)
exchanges the values
Definition: json.h:22502
friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than
Definition: json.h:22933
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.h:21227
friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than or equal
Definition: json.h:22979
json_value(const string_t &value)
constructor for strings
Definition: json.h:17633
json_value(const binary_t &value)
constructor for binary arrays (internal type)
Definition: json.h:17681
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.h:19757
json_value(const array_t &value)
constructor for arrays
Definition: json.h:17657
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
Definition: json.h:22204
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.h:19698
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.h:24620
const_iterator end() const noexcept
returns a const iterator to one past the last element
Definition: json.h:21130
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.h:25216
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.h:19650
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements
Definition: json.h:22257
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.h:17118
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
get special-case overload
Definition: json.h:19613
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.h:23014
json_value(const object_t &value)
constructor for objects
Definition: json.h:17645
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.h:20712
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
Definition: json.h:19277
json_value(typename binary_t::container_type &&value)
constructor for rvalue binary arrays
Definition: json.h:17675
json_value(boolean_t v) noexcept
constructor for booleans
Definition: json.h:17554
ValueType get() const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), std::declval< ValueType & >())))
get a value (explicit)
Definition: json.h:19492
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.h:18997
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.h:21439
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.h:21120
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.h:22442
void clear() noexcept
clears the contents
Definition: json.h:21719
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
Definition: json.h:24202
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.h:19200
static std::vector< uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.h:23729
binary_t * binary
binary (stored with pointer to save storage)
Definition: json.h:17541
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.h:18397
constexpr const number_float_t * get_impl_ptr(const number_float_t *) const noexcept
get a pointer to the value (floating-point number)
Definition: json.h:19355
iterator insert(const_iterator pos, basic_json &&val)
inserts element
Definition: json.h:22127
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
Definition: json.h:24318
reference operator[](size_type idx)
access specified array element
Definition: json.h:20071
static void to_bson(const basic_json &j, detail::output_adapter< char > o)
Serializes the given JSON object j to BSON and forwards the corresponding BSON-representation to the ...
Definition: json.h:23933
void update(const_iterator first, const_iterator last)
updates a JSON object from another object, overwriting existing keys
Definition: json.h:22391
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.h:24577
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
Definition: json.h:19589
void swap(binary_t &other)
exchanges the values
Definition: json.h:22601
static std::vector< uint8_t > to_bson(const basic_json &j)
Serializes the given JSON object j to BSON and returns a vector containing the corresponding BSON-rep...
Definition: json.h:23910
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.h:16872
void assert_invariant() const noexcept
checks the class invariants
Definition: json.h:17793
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.h:24302
static void to_msgpack(const basic_json &j, detail::output_adapter< uint8_t > o)
create a CBOR serialization of a given JSON value
Definition: json.h:23736
static ::nlohmann::detail::parser< basic_json, InputAdapterType > parser(InputAdapterType adapter, detail::parser_callback_t< basic_json >cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
Definition: json.h:16763
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
Definition: json.h:19337
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.h:21198
binary_t & get_binary()
Definition: json.h:19818
void swap(string_t &other)
exchanges the values
Definition: json.h:22568
const_reference back() const
access the last element
Definition: json.h:20542
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.h:22854
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.h:23451
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array (without subtype)
Definition: json.h:18297
friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.h:22823
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.h:19178
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
Definition: json.h:19325
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.h:19156
iterator insert_iterator(const_iterator pos, Args &&... args)
Helper for insertion of an iterator.
Definition: json.h:22067
basic_json flatten() const
return flattened JSON value
Definition: json.h:24647
void push_back(basic_json &&val)
add an object to an array
Definition: json.h:21796
friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
comparison: equal
Definition: json.h:22767
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition: json.h:24060
size_type count(KeyT &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.h:20946
json_value(const typename binary_t::container_type &value)
constructor for binary arrays
Definition: json.h:17669
const binary_t & get_binary() const
Definition: json.h:19829
json_value()=default
default constructor (for null values)
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.h:19027
number_float_t number_float
number (floating-point)
Definition: json.h:17549
friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.h:22944
std::less< StringType > object_comparator_t
a type for an object
Definition: json.h:16982
string_t * string
string (stored with pointer to save storage)
Definition: json.h:17539
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.h:22037
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.h:21954
::nlohmann::detail::output_adapter_t< CharType > output_adapter_t
Definition: json.h:16785
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.h:19056
static JSON_HEDLEY_RETURNS_NON_NULL T * create(Args &&... args)
helper for exception-safe object creation
Definition: json.h:17487
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.h:16805
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
Definition: json.h:19295
detail::value_t value_t
Definition: json.h:16795
ValueType & get_to(ValueType &v) const
get special-case overload
Definition: json.h:19602
json_value(binary_t &&value)
constructor for rvalue binary arrays (internal type)
Definition: json.h:17687
static void to_msgpack(const basic_json &j, detail::output_adapter< char > o)
create a CBOR serialization of a given JSON value
Definition: json.h:23741
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
Definition: json.h:20204
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init, std::uint8_t subtype)
explicitly create a binary array (with subtype)
Definition: json.h:18287
iterator find(KeyT &&key)
find an element in a JSON object
Definition: json.h:20895
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.h:17937
const_reference operator[](size_type idx) const
access specified array element
Definition: json.h:20117
array_t * array
array (stored with pointer to save storage)
Definition: json.h:17537
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.h:16858
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.h:17479
JSONSerializer< T, SFINAE > json_serializer
Definition: json.h:16799
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.h:21881
friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.h:22990
ValueType get() const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >())))
get a value (explicit); special case
Definition: json.h:19543
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a pair of character iterators
Definition: json.h:23257
number_integer_t number_integer
number (integer)
Definition: json.h:17545
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
Definition: json.h:19307
static std::vector< uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.h:23634
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition: json.h:21010
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.h:24186
void destroy(value_t t) noexcept
Definition: json.h:17692
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.h:24745
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
Definition: json.h:20384
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.h:24684
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.h:17340
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.h:21905
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.h:21089
json_value(array_t &&value)
constructor for rvalue arrays
Definition: json.h:17663
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.h:18170
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.h:19923
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.h:22105
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.h:19227
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.h:18975
friend void swap(reference left, reference right) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.h:22472
friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.h:22778
ObjectType< StringType, basic_json, object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > >> object_t
a type for an object
Definition: json.h:17072
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.h:21855
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.h:20807
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
Definition: json.h:19384
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.h:18424
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.h:16880
constexpr auto get_ptr() const noexcept -> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.h:19663
friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
comparison: not equal
Definition: json.h:22812
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.h:21190
an internal type for a backed binary type
Definition: json.h:4501
BinaryType container_type
the type of the underlying container
Definition: json.h:4504
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition: json.h:4510
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition: json.h:4514
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.h:4536
void clear_subtype() noexcept
clears the binary subtype
Definition: json.h:4631
byte_container_with_subtype(container_type &&b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b))))
Definition: json.h:4524
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.h:4506
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.h:4607
void set_subtype(std::uint8_t subtype) noexcept
sets the binary subtype
Definition: json.h:4559
byte_container_with_subtype(const container_type &b, std::uint8_t subtype) noexcept(noexcept(container_type(b)))
Definition: json.h:4518
constexpr std::uint8_t subtype() const noexcept
return the binary subtype
Definition: json.h:4586
bool operator==(const byte_container_with_subtype &rhs) const
Definition: json.h:4530
deserialization of CBOR, MessagePack, and UBJSON values
Definition: json.h:7764
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.h:7766
bool get_msgpack_array(const std::size_t len)
Definition: json.h:9409
bool get_bson_string(const NumberType len, string_t &result)
Parses a zero-terminated string of length len from the BSON input.
Definition: json.h:7917
bool parse_bson_element_internal(const char_int_type element_type, const std::size_t element_type_parse_position)
Read a BSON document element of the given element_type.
Definition: json.h:7964
bool parse_bson_array()
Reads an array from the BSON input and passes it to the SAX-parser.
Definition: json.h:8080
char_int_type get_ignore_noop()
Definition: json.h:9968
bool get_ubjson_high_precision_number()
Definition: json.h:9897
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.h:7765
bool get_bson_cstr(string_t &result)
Parses a C-style string from the BSON input.
Definition: json.h:7887
binary_reader & operator=(const binary_reader &)=delete
bool get_cbor_array(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition: json.h:8745
bool get_msgpack_binary(binary_t &result)
reads a MessagePack byte array
Definition: json.h:9298
bool get_cbor_object(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition: json.h:8783
bool get_ubjson_string(string_t &result, const bool get_char=true)
reads a UBJSON string
Definition: json.h:9487
bool parse_bson_element_list(const bool is_array)
Read a BSON element list (as specified in the BSON-spec)
Definition: json.h:8042
bool parse_cbor_internal(const bool get_char, const cbor_tag_handler_t tag_handler)
Definition: json.h:8110
bool get_string(const input_format_t format, const NumberType len, string_t &result)
create a string by reading characters from the input
Definition: json.h:10036
bool get_cbor_string(string_t &result)
reads a CBOR string
Definition: json.h:8556
InputAdapterType ia
input adapter
Definition: json.h:10152
bool get_binary(const input_format_t format, const NumberType len, binary_t &result)
create a byte array by reading bytes from the input
Definition: json.h:10069
bool parse_ubjson_internal(const bool get_char=true)
Definition: json.h:9468
bool unexpect_eof(const input_format_t format, const char *context) const
Definition: json.h:10093
bool get_ubjson_size_type(std::pair< std::size_t, char_int_type > &result)
determine the type and size for a container
Definition: json.h:9618
std::string get_token_string() const
Definition: json.h:10106
bool get_ubjson_value(const char_int_type prefix)
Definition: json.h:9659
typename BasicJsonType::string_t string_t
Definition: json.h:7768
bool get_msgpack_object(const std::size_t len)
Definition: json.h:9431
bool get_bson_binary(const NumberType len, binary_t &result)
Parses a byte array input of length len from the BSON input.
Definition: json.h:7938
std::string exception_message(const input_format_t format, const std::string &detail, const std::string &context) const
Definition: json.h:10119
std::size_t chars_read
the number of characters read
Definition: json.h:10158
typename std::char_traits< char_type >::int_type char_int_type
Definition: json.h:7772
binary_reader(const binary_reader &)=delete
char_int_type current
the current character
Definition: json.h:10155
bool sax_parse(const input_format_t format, json_sax_t *sax_, const bool strict=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition: json.h:7801
json_sax_t * sax
the SAX parser
Definition: json.h:10164
bool get_ubjson_size_value(std::size_t &result)
Definition: json.h:9541
typename InputAdapterType::char_type char_type
Definition: json.h:7771
bool parse_bson_internal()
Reads in a BSON-object and passes it to the SAX-parser.
Definition: json.h:7862
bool get_number(const input_format_t format, NumberType &result)
Definition: json.h:9993
bool get_cbor_binary(binary_t &result)
reads a CBOR byte array
Definition: json.h:8651
binary_reader(binary_reader &&)=default
typename BasicJsonType::binary_t binary_t
Definition: json.h:7769
char_int_type get()
get next character from the input
Definition: json.h:9959
binary_reader & operator=(binary_reader &&)=default
const bool is_little_endian
whether we can assume little endianess
Definition: json.h:10161
binary_reader(InputAdapterType &&adapter)
create a binary reader
Definition: json.h:7780
bool get_msgpack_string(string_t &result)
reads a MessagePack string
Definition: json.h:9216
typename BasicJsonType::number_float_t number_float_t
Definition: json.h:7767
serialization to CBOR and MessagePack values
Definition: json.h:12827
void write_bson_array(const string_t &name, const typename BasicJsonType::array_t &value)
Writes a BSON element with key name and array value.
Definition: json.h:13873
const bool is_little_endian
whether we can assume little endianess
Definition: json.h:14388
void write_number_with_ubjson_prefix(const NumberType n, const bool add_prefix)
Definition: json.h:14063
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true)
Definition: json.h:13496
static constexpr CharType get_ubjson_float_prefix(double)
Definition: json.h:14288
void write_bson_entry_header(const string_t &name, const std::uint8_t element_type)
Writes the given element_type and name to the output adapter.
Definition: json.h:13718
static std::size_t calc_bson_element_size(const string_t &name, const BasicJsonType &j)
Calculates the size necessary to serialize the JSON value j with its name.
Definition: json.h:13907
void write_bson_double(const string_t &name, const double value)
Writes a BSON element with key name and double value value.
Definition: json.h:13740
void write_bson_object(const typename BasicJsonType::object_t &value)
Definition: json.h:14016
typename BasicJsonType::string_t string_t
Definition: json.h:12828
static constexpr CharType get_cbor_float_prefix(float)
Definition: json.h:14032
static constexpr CharType to_char_type(InputCharType x) noexcept
Definition: json.h:14381
typename BasicJsonType::binary_t binary_t
Definition: json.h:12829
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.h:12838
static constexpr CharType get_msgpack_float_prefix(double)
Definition: json.h:14051
CharType ubjson_prefix(const BasicJsonType &j) const noexcept
determine the type prefix of container values
Definition: json.h:14203
void write_bson_integer(const string_t &name, const std::int64_t value)
Writes a BSON element with key name and integer value.
Definition: json.h:13790
static std::size_t calc_bson_entry_header_size(const string_t &name)
Definition: json.h:13703
void write_bson_unsigned(const string_t &name, const std::uint64_t value)
Writes a BSON element with key name and unsigned value.
Definition: json.h:13818
static CharType to_char_type(std::uint8_t x) noexcept
Definition: json.h:14359
void write_bson_string(const string_t &name, const string_t &value)
Writes a BSON element with key name and string value value.
Definition: json.h:13758
void write_bson_object_entry(const string_t &name, const typename BasicJsonType::object_t &value)
Writes a BSON element with key name and object value.
Definition: json.h:13840
static constexpr CharType get_ubjson_float_prefix(float)
Definition: json.h:14283
void write_number(const NumberType n)
Definition: json.h:14309
output_adapter_t< CharType > oa
the output
Definition: json.h:14391
void write_bson_element(const string_t &name, const BasicJsonType &j)
Serializes the JSON value j to BSON and associates it with the key name.
Definition: json.h:13955
void write_bson_binary(const string_t &name, const binary_t &value)
Writes a BSON element with key name and binary value value.
Definition: json.h:13892
void write_bson_null(const string_t &name)
Writes a BSON element with key name and null value.
Definition: json.h:13772
static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t &value)
Definition: json.h:13865
void write_bson(const BasicJsonType &j)
Definition: json.h:12847
void write_cbor(const BasicJsonType &j)
Definition: json.h:12867
static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
Definition: json.h:13808
static constexpr CharType to_char_type(std::uint8_t x) noexcept
Definition: json.h:14352
typename BasicJsonType::number_float_t number_float_t
Definition: json.h:12830
static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t &value)
Calculates the size of the BSON serialization of the given JSON-object j.
Definition: json.h:14001
static constexpr CharType get_msgpack_float_prefix(float)
Definition: json.h:14046
void write_bson_boolean(const string_t &name, const bool value)
Writes a BSON element with key name and boolean value value.
Definition: json.h:13730
void write_msgpack(const BasicJsonType &j)
Definition: json.h:13172
void write_compact_float(const number_float_t n, detail::input_format_t format)
Definition: json.h:14325
static std::size_t calc_bson_string_size(const string_t &value)
Definition: json.h:13750
static std::size_t calc_bson_integer_size(const std::int64_t value)
Definition: json.h:13780
static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t &value)
Definition: json.h:13850
static constexpr CharType get_cbor_float_prefix(double)
Definition: json.h:14037
general exception of the basic_json class
Definition: json.h:2420
const int id
the id of the exception
Definition: json.h:2430
JSON_HEDLEY_RETURNS_NON_NULL const char * what() const noexcept override
returns the explanatory string
Definition: json.h:2424
static std::string name(const std::string &ename, int id_)
Definition: json.h:2436
std::runtime_error m
an exception object as storage for error messages
Definition: json.h:2443
Input adapter for stdio file access.
Definition: json.h:4823
file_input_adapter(file_input_adapter &&)=default
std::FILE * m_file
the file pointer to read from
Definition: json.h:4845
std::char_traits< char >::int_type get_character() noexcept
Definition: json.h:4838
file_input_adapter(const file_input_adapter &)=delete
file_input_adapter & operator=(file_input_adapter &&)=delete
file_input_adapter & operator=(const file_input_adapter &)=delete
Input adapter for a (caching) istream.
Definition: json.h:4859
input_stream_adapter & operator=(input_stream_adapter &&rhs)=delete
input_stream_adapter(input_stream_adapter &&rhs) noexcept
Definition: json.h:4882
input_stream_adapter(const input_stream_adapter &)=delete
std::istream * is
the associated input stream
Definition: json.h:4904
std::char_traits< char >::int_type get_character()
Definition: json.h:4891
input_stream_adapter & operator=(input_stream_adapter &)=delete
input_stream_adapter(std::istream &i)
Definition: json.h:4873
exception indicating errors with iterators
Definition: json.h:2578
static invalid_iterator create(int id_, const std::string &what_arg)
Definition: json.h:2580
invalid_iterator(int id_, const char *what_arg)
Definition: json.h:2588
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition: json.h:10879
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.h:11271
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.h:11385
const object_t::key_type & key() const
return the key of an object iterator
Definition: json.h:11448
iter_impl()=default
default constructor
Definition: json.h:10881
iter_impl const operator--(int)
post-decrement (it–)
Definition: json.h:11192
void set_end() noexcept
set the iterator past the last value
Definition: json.h:11047
bool operator==(const iter_impl &other) const
comparison: equal
Definition: json.h:11235
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.h:10904
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.h:11325
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.h:11396
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition: json.h:10913
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.h:11078
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.h:11316
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition: json.h:10908
pointer operator->() const
dereference the iterator
Definition: json.h:11115
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.h:10998
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition: json.h:10966
iter_impl const operator++(int)
post-increment (it++)
Definition: json.h:11149
iter_impl & operator--()
pre-decrement (–it)
Definition: json.h:11203
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.h:10988
iter_impl(pointer object) noexcept
constructor for a given JSON instance
Definition: json.h:10924
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition: json.h:11473
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.h:11363
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.h:11374
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition: json.h:10976
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.h:11307
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.h:10902
reference value() const
return the value of an iterator
Definition: json.h:11464
typename BasicJsonType::object_t object_t
Definition: json.h:10886
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.h:11354
iter_impl & operator++()
pre-increment (++it)
Definition: json.h:11160
reference operator[](difference_type n) const
access to successor
Definition: json.h:11417
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.h:11298
std::bidirectional_iterator_tag iterator_category
The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
Definition: json.h:10899
bool operator!=(const iter_impl &other) const
comparison: not equal
Definition: json.h:11262
typename BasicJsonType::array_t array_t
Definition: json.h:10887
IteratorType anchor
the iterator
Definition: json.h:3920
iteration_proxy_value & operator*()
dereference operator (needed for range-based for)
Definition: json.h:3934
std::input_iterator_tag iterator_category
Definition: json.h:3915
typename std::remove_cv< typename std::remove_reference< decltype(std::declval< IteratorType >().key()) >::type >::type string_type
Definition: json.h:3916
const string_type empty_str
an empty string (to return a reference for primitive values)
Definition: json.h:3928
iteration_proxy_value(IteratorType it) noexcept
Definition: json.h:3931
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition: json.h:3955
std::size_t array_index_last
last stringified array index
Definition: json.h:3924
string_type array_index_str
a string representation of the array index
Definition: json.h:3926
IteratorType::reference value() const
return value of the iterator
Definition: json.h:3989
std::size_t array_index
an index for arrays (used to create key names)
Definition: json.h:3922
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition: json.h:3940
const string_type & key() const
return key of the iterator
Definition: json.h:3961
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition: json.h:3949
proxy class for the items() function
Definition: json.h:3997
iteration_proxy_value< IteratorType > begin() noexcept
return iterator begin (needed for range-based for)
Definition: json.h:4008
IteratorType::reference container
the container to iterate
Definition: json.h:4000
iteration_proxy_value< IteratorType > end() noexcept
return iterator end (needed for range-based for)
Definition: json.h:4014
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.h:4004
std::char_traits< char_type >::int_type get_character()
Definition: json.h:4919
typename std::iterator_traits< IteratorType >::value_type char_type
Definition: json.h:4914
iterator_input_adapter(IteratorType first, IteratorType last)
Definition: json.h:4916
value_type * value_ref
Definition: json.h:12660
json_ref(const json_ref &)=delete
json_ref(json_ref &&)=default
value_type owned_value
Definition: json.h:12659
BasicJsonType value_type
Definition: json.h:12604
json_ref(Args &&... args)
Definition: json.h:12626
json_ref(const value_type &value)
Definition: json.h:12612
json_ref & operator=(const json_ref &)=delete
json_ref & operator=(json_ref &&)=delete
value_type const & operator*() const
Definition: json.h:12648
value_type const * operator->() const
Definition: json.h:12653
json_ref(std::initializer_list< json_ref > init)
Definition: json.h:12617
json_ref(value_type &&value)
Definition: json.h:12606
value_type moved_or_copied() const
Definition: json.h:12639
a template for a reverse iterator class
Definition: json.h:11515
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.h:11524
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.h:11549
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.h:11537
json_reverse_iterator const operator--(int)
post-decrement (it–)
Definition: json.h:11543
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.h:11521
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.h:11555
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.h:11567
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.h:11519
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.h:11528
reference operator[](difference_type n) const
access to successor
Definition: json.h:11579
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.h:11573
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.h:11561
json_reverse_iterator const operator++(int)
post-increment (it++)
Definition: json.h:11531
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.h:11585
reference value() const
return the value of an iterator
Definition: json.h:11592
typename BasicJsonType::string_t string_t
Definition: json.h:5872
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.h:5869
typename BasicJsonType::number_float_t number_float_t
Definition: json.h:5871
typename BasicJsonType::binary_t binary_t
Definition: json.h:5873
bool start_object(std::size_t=std::size_t(-1))
Definition: json.h:5910
bool start_array(std::size_t=std::size_t(-1))
Definition: json.h:5925
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition: json.h:5935
bool number_integer(number_integer_t)
Definition: json.h:5885
bool number_unsigned(number_unsigned_t)
Definition: json.h:5890
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.h:5870
bool number_float(number_float_t, const string_t &)
Definition: json.h:5895
typename BasicJsonType::string_t string_t
Definition: json.h:5576
const bool allow_exceptions
whether to throw exceptions in case of errors
Definition: json.h:5860
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.h:5574
BasicJsonType * object_element
helper to hold the reference for the next object element
Definition: json.h:5854
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.h:5573
const parser_callback_t callback
callback function
Definition: json.h:5858
typename BasicJsonType::parser_callback_t parser_callback_t
Definition: json.h:5578
json_sax_dom_callback_parser(const json_sax_dom_callback_parser &)=delete
typename BasicJsonType::binary_t binary_t
Definition: json.h:5577
json_sax_dom_callback_parser & operator=(const json_sax_dom_callback_parser &)=delete
json_sax_dom_callback_parser & operator=(json_sax_dom_callback_parser &&)=default
bool number_integer(number_integer_t val)
Definition: json.h:5608
BasicJsonType & root
the parsed JSON value
Definition: json.h:5846
std::vector< BasicJsonType * > ref_stack
stack to model hierarchy of values
Definition: json.h:5848
std::pair< bool, BasicJsonType * > handle_value(Value &&v, const bool skip_callback=false)
Definition: json.h:5782
BasicJsonType discarded
a discarded value for the callback
Definition: json.h:5862
std::vector< bool > key_keep_stack
stack to manage which object keys to keep
Definition: json.h:5852
typename BasicJsonType::number_float_t number_float_t
Definition: json.h:5575
typename BasicJsonType::parse_event_t parse_event_t
Definition: json.h:5579
bool errored
whether a syntax error occurred
Definition: json.h:5856
std::vector< bool > keep_stack
stack to manage which values to keep
Definition: json.h:5850
bool number_unsigned(number_unsigned_t val)
Definition: json.h:5614
bool number_float(number_float_t val, const string_t &)
Definition: json.h:5620
json_sax_dom_callback_parser(json_sax_dom_callback_parser &&)=default
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.h:5748
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
Definition: json.h:5581
SAX implementation to create a JSON value from SAX events.
Definition: json.h:5397
bool start_array(std::size_t len)
Definition: json.h:5489
json_sax_dom_parser(const json_sax_dom_parser &)=delete
typename BasicJsonType::binary_t binary_t
Definition: json.h:5403
bool number_unsigned(number_unsigned_t val)
Definition: json.h:5439
bool errored
whether a syntax error occurred
Definition: json.h:5564
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.h:5399
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.h:5509
bool string(string_t &val)
Definition: json.h:5451
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.h:5400
json_sax_dom_parser & operator=(const json_sax_dom_parser &)=delete
bool start_object(std::size_t len)
Definition: json.h:5463
BasicJsonType * object_element
helper to hold the reference for the next object element
Definition: json.h:5562
JSON_HEDLEY_RETURNS_NON_NULL BasicJsonType * handle_value(Value &&v)
Definition: json.h:5535
std::vector< BasicJsonType * > ref_stack
stack to model hierarchy of values
Definition: json.h:5560
bool binary(binary_t &val)
Definition: json.h:5457
const bool allow_exceptions
whether to throw exceptions in case of errors
Definition: json.h:5566
constexpr bool is_errored() const
Definition: json.h:5521
json_sax_dom_parser(json_sax_dom_parser &&)=default
typename BasicJsonType::number_float_t number_float_t
Definition: json.h:5401
BasicJsonType & root
the parsed JSON value
Definition: json.h:5558
bool number_float(number_float_t val, const string_t &)
Definition: json.h:5445
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition: json.h:5410
typename BasicJsonType::string_t string_t
Definition: json.h:5402
bool number_integer(number_integer_t val)
Definition: json.h:5433
json_sax_dom_parser & operator=(json_sax_dom_parser &&)=default
token_type
token types for the parser
Definition: json.h:5978
@ value_float
an floating point number – use get_number_float() for actual value
@ begin_array
the character for array begin [
@ value_string
a string – use get_string() for actual value
@ end_array
the character for array end ]
@ uninitialized
indicating the scanner is uninitialized
@ parse_error
indicating a parse error
@ value_integer
a signed integer – use get_number_integer() for actual value
@ value_separator
the value separator ,
@ end_object
the character for object end }
@ begin_object
the character for object begin {
@ value_unsigned
an unsigned integer – use get_number_unsigned() for actual value
@ end_of_input
indicating the end of the input buffer
@ literal_or_value
a literal or the begin of a value (only for diagnostics)
JSON_HEDLEY_RETURNS_NON_NULL static JSON_HEDLEY_CONST const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
Definition: json.h:6001
lexical analysis
Definition: json.h:6051
number_float_t value_float
Definition: json.h:7564
const bool ignore_comments
whether comments should be ignored (true) or signaled as errors (false)
Definition: json.h:7541
lexer & operator=(lexer &&)=default
void add(char_int_type c)
add a character to token_buffer
Definition: json.h:7340
void reset() noexcept
reset token_buffer; current character is beginning of token
Definition: json.h:7259
token_type scan()
Definition: json.h:7448
bool next_unget
whether the next get() call should just return current
Definition: json.h:7547
char_int_type current
the current character
Definition: json.h:7544
typename BasicJsonType::number_float_t number_float_t
Definition: json.h:6054
void skip_whitespace()
Definition: json.h:7439
typename std::char_traits< char_type >::int_type char_int_type
Definition: json.h:6057
static JSON_HEDLEY_PURE char get_decimal_point() noexcept
return the locale-dependent decimal point
Definition: json.h:6082
number_integer_t value_integer
Definition: json.h:7562
InputAdapterType ia
input adapter
Definition: json.h:7538
lexer(InputAdapterType &&adapter, bool ignore_comments_=false)
Definition: json.h:6062
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.h:6052
static void strtof(float &f, const char *str, char **endptr) noexcept
Definition: json.h:6851
const char_int_type decimal_point_char
the decimal point
Definition: json.h:7567
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.h:7369
bool skip_bom()
skip the UTF-8 byte order mark
Definition: json.h:7425
const char * error_message
a description of occurred lexer errors
Definition: json.h:7559
position_t position
the start position of the current token
Definition: json.h:7550
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.h:7379
std::vector< char_type > token_string
raw input token string (for error messages)
Definition: json.h:7553
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.h:7351
constexpr JSON_HEDLEY_RETURNS_NON_NULL const char * get_error_message() const noexcept
return syntax error message
Definition: json.h:7412
typename lexer_base< BasicJsonType >::token_type token_type
Definition: json.h:6060
typename InputAdapterType::char_type char_type
Definition: json.h:6056
char_int_type get()
Definition: json.h:7276
token_type scan_number()
scan a number literal
Definition: json.h:6908
void unget()
unget current character (read it again on next get)
Definition: json.h:7313
token_type scan_string()
scan a string literal
Definition: json.h:6193
lexer(const lexer &)=delete
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.h:7357
string_t token_buffer
buffer for variable-length tokens (numbers, strings)
Definition: json.h:7556
token_type scan_literal(const char_type *literal_text, const std::size_t length, token_type return_type)
Definition: json.h:7239
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.h:7363
int get_codepoint()
get codepoint from 4 hex characters following \u
Definition: json.h:6108
std::string get_token_string() const
return the last read token (for errors only).
Definition: json.h:7387
number_unsigned_t value_unsigned
Definition: json.h:7563
lexer(lexer &&)=default
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.h:6053
bool next_byte_in_range(std::initializer_list< char_int_type > ranges)
check if the next byte(s) are inside a given range
Definition: json.h:6156
lexer & operator=(lexer &)=delete
typename BasicJsonType::string_t string_t
Definition: json.h:6055
bool scan_comment()
scan a comment
Definition: json.h:6783
exception indicating other library errors
Definition: json.h:2717
static other_error create(int id_, const std::string &what_arg)
Definition: json.h:2719
other_error(int id_, const char *what_arg)
Definition: json.h:2727
exception indicating access out of the defined range
Definition: json.h:2679
static out_of_range create(int id_, const std::string &what_arg)
Definition: json.h:2681
out_of_range(int id_, const char *what_arg)
Definition: json.h:2689
output_adapter(std::vector< CharType > &vec)
Definition: json.h:12793
output_adapter(std::basic_ostream< CharType > &s)
Definition: json.h:12796
output_adapter(StringType &s)
Definition: json.h:12799
output adapter for output streams
Definition: json.h:12744
void write_character(CharType c) override
Definition: json.h:12750
std::basic_ostream< CharType > & stream
Definition: json.h:12762
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition: json.h:12746
output adapter for basic_string
Definition: json.h:12768
void write_character(CharType c) override
Definition: json.h:12774
output_string_adapter(StringType &s) noexcept
Definition: json.h:12770
output adapter for byte vectors
Definition: json.h:12720
std::vector< CharType > & v
Definition: json.h:12738
output_vector_adapter(std::vector< CharType > &vec) noexcept
Definition: json.h:12722
void write_character(CharType c) override
Definition: json.h:12726
exception indicating a parse error
Definition: json.h:2492
parse_error(int id_, std::size_t byte_, const char *what_arg)
Definition: json.h:2530
static parse_error create(int id_, const position_t &pos, const std::string &what_arg)
create a parse error exception
Definition: json.h:2503
const std::size_t byte
byte index of the parse error
Definition: json.h:2527
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg)
Definition: json.h:2510
static std::string position_string(const position_t &pos)
Definition: json.h:2533
syntax analysis
Definition: json.h:10233
lexer_t m_lexer
the lexer
Definition: json.h:10676
bool sax_parse(SAX *sax, const bool strict=true)
Definition: json.h:10334
token_type get_token()
get next token from lexer
Definition: json.h:10636
token_type last_token
the type of the last read token
Definition: json.h:10674
parser(InputAdapterType &&adapter, const parser_callback_t< BasicJsonType > cb=nullptr, const bool allow_exceptions_=true, const bool skip_comments=false)
a parser reading from an input adapter
Definition: json.h:10243
bool accept(const bool strict=true)
public accept interface
Definition: json.h:10326
typename BasicJsonType::string_t string_t
Definition: json.h:10237
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.h:10235
typename lexer_t::token_type token_type
Definition: json.h:10239
lexer< BasicJsonType, InputAdapterType > lexer_t
Definition: json.h:10238
bool sax_parse_internal(SAX *sax)
Definition: json.h:10354
const parser_callback_t< BasicJsonType > callback
callback function
Definition: json.h:10672
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.h:10265
std::string exception_message(const token_type expected, const std::string &context)
Definition: json.h:10641
typename BasicJsonType::number_float_t number_float_t
Definition: json.h:10236
const bool allow_exceptions
whether to throw exceptions in case of errors
Definition: json.h:10678
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.h:10234
primitive_iterator_t operator+(difference_type n) noexcept
Definition: json.h:10756
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition: json.h:10800
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.h:10741
constexpr friend bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.h:10751
constexpr friend difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.h:10763
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.h:10735
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.h:10723
primitive_iterator_t const operator++(int) noexcept
Definition: json.h:10774
static constexpr difference_type end_value
Definition: json.h:10710
primitive_iterator_t & operator--() noexcept
Definition: json.h:10781
primitive_iterator_t & operator++() noexcept
Definition: json.h:10768
void set_end() noexcept
set iterator to a defined past the end
Definition: json.h:10729
constexpr difference_type get_value() const noexcept
Definition: json.h:10717
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition: json.h:10794
primitive_iterator_t const operator--(int) noexcept
Definition: json.h:10787
constexpr friend bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.h:10746
static constexpr difference_type begin_value
Definition: json.h:10709
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition: json.h:16456
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.h:15556
const std::lconv * loc
the locale
Definition: json.h:16441
std::array< char, 64 > number_buffer
a (hopefully) large enough character buffer
Definition: json.h:16438
static constexpr std::uint8_t UTF8_ACCEPT
Definition: json.h:15558
serializer(serializer &&)=delete
const char decimal_point
the locale's decimal point character
Definition: json.h:16445
typename BasicJsonType::number_float_t number_float_t
Definition: json.h:15554
serializer & operator=(const serializer &)=delete
const char thousands_sep
the locale's thousand separator character
Definition: json.h:16443
std::size_t undumped_chars
Definition: json.h:15899
static constexpr std::uint8_t UTF8_REJECT
Definition: json.h:15559
void dump(const BasicJsonType &val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
Definition: json.h:15607
const char indent_char
the indentation character
Definition: json.h:16451
std::size_t bytes_after_last_accept
Definition: json.h:15898
std::array< char, 512 > string_buffer
string buffer
Definition: json.h:16448
typename BasicJsonType::binary_t::value_type binary_char_t
Definition: json.h:15557
JSON_PRIVATE_UNLESS_TESTED const bool ensure_ascii
Definition: json.h:15892
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition: json.h:15567
serializer & operator=(serializer &&)=delete
typename BasicJsonType::string_t string_t
Definition: json.h:15553
serializer(const serializer &)=delete
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.h:15555
string_t indent_string
the indentation string
Definition: json.h:16453
span_input_adapter(CharT b, std::size_t l)
Definition: json.h:5224
contiguous_bytes_input_adapter ia
Definition: json.h:5240
contiguous_bytes_input_adapter && get()
Definition: json.h:5234
span_input_adapter(IteratorType first, IteratorType last)
Definition: json.h:5231
exception indicating executing a member function with a wrong type
Definition: json.h:2632
type_error(int id_, const char *what_arg)
Definition: json.h:2642
static type_error create(int id_, const std::string &what_arg)
Definition: json.h:2634
std::size_t utf8_bytes_index
index to the utf8_codes array for the next valid byte
Definition: json.h:5111
std::char_traits< char >::int_type get_character() noexcept
Definition: json.h:5081
std::size_t utf8_bytes_filled
number of valid bytes in the utf8_codes array
Definition: json.h:5113
wide_string_input_adapter(BaseInputAdapter base)
Definition: json.h:5078
std::array< std::char_traits< char >::int_type, 4 > utf8_bytes
a buffer for UTF-8 bytes
Definition: json.h:5108
JSON Pointer.
Definition: json.h:11625
std::vector< std::string > reference_tokens
the reference tokens
Definition: json.h:12583
const std::string & back() const
return last reference token
Definition: json.h:11876
BasicJsonType & get_checked(BasicJsonType *ptr) const
Definition: json.h:12137
std::string to_string() const
return a string representation of the JSON pointer
Definition: json.h:11670
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for equality
Definition: json.h:12559
result reference_tokens
Definition: json.h:11993
void pop_back()
remove last reference token
Definition: json.h:11852
const BasicJsonType & get_checked(const BasicJsonType *ptr) const
Definition: json.h:12228
BasicJsonType & get_unchecked(BasicJsonType *ptr) const
return a reference to the pointed to value
Definition: json.h:12078
BasicJsonType & get_and_create(BasicJsonType &j) const
create and return a reference to the pointed to value
Definition: json.h:12006
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.h:11923
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for inequality
Definition: json.h:12576
void push_back(const std::string &token)
append an unescaped token at the end of the reference pointer
Definition: json.h:11898
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: json.h:11702
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition: json.h:11748
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.h:11652
friend json_pointer operator/(const json_pointer &lhs, const json_pointer &rhs)
create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
Definition: json.h:11768
bool contains(const BasicJsonType *ptr) const
Definition: json.h:12268
static BasicJsonType unflatten(const BasicJsonType &value)
Definition: json.h:12521
friend json_pointer operator/(const json_pointer &ptr, std::string token)
create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
Definition: json.h:11789
static void replace_substring(std::string &s, const std::string &f, const std::string &t)
replace all occurrences of a substring by another string
Definition: json.h:12423
JSON_PRIVATE_UNLESS_TESTED replace_substring(s, "/", "~1")
static void flatten(const std::string &reference_string, const BasicJsonType &value, BasicJsonType &result)
Definition: json.h:12458
static void unescape(std::string &s)
unescape "~1" to tilde and "~0" to slash (order is important!)
Definition: json.h:12444
json_pointer & operator/=(std::string token)
append an unescaped reference token at the end of this JSON pointer
Definition: json.h:11726
void push_back(std::string &&token)
append an unescaped token at the end of the reference pointer
Definition: json.h:11904
const BasicJsonType & get_unchecked(const BasicJsonType *ptr) const
return a const reference to the pointed to value
Definition: json.h:12186
static std::vector< std::string > split(const std::string &reference_string)
split the string input to reference tokens
Definition: json.h:12348
static BasicJsonType::size_type array_index(const std::string &s)
Definition: json.h:11939
json_pointer result
Definition: json.h:11992
friend json_pointer operator/(const json_pointer &ptr, std::size_t array_idx)
create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
Definition: json.h:11809
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.h:11827
decltype(get< N >(std::declval< ::nlohmann::detail::iteration_proxy_value< IteratorType > >())) type
Definition: json.h:4059
int64x64_t operator-(const int64x64_t &lhs, const int64x64_t &rhs)
Subtraction operator.
Definition: int64x64.h:103
int64x64_t operator+(const int64x64_t &lhs, const int64x64_t &rhs)
Addition operator.
Definition: int64x64.h:89
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition: json.h:2204
#define JSON_HEDLEY_CONST
Definition: json.h:1546
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition: json.h:868
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition: json.h:1188
#define JSON_PRIVATE_UNLESS_TESTED
Definition: json.h:2167
#define NLOHMANN_JSON_VERSION_PATCH
Definition: json.h:35
#define JSON_HEDLEY_LIKELY(expr)
Definition: json.h:1444
#define JSON_HEDLEY_NON_NULL(...)
Definition: json.h:1340
#define JSON_INTERNAL_CATCH(exception)
Definition: json.h:2134
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition: json.h:1765
#define JSON_CATCH(exception)
Definition: json.h:2133
#define JSON_ASSERT(x)
Definition: json.h:2160
#define JSON_THROW(exception)
Definition: json.h:2131
#define NLOHMANN_JSON_VERSION_MAJOR
Definition: json.h:33
#define NLOHMANN_BASIC_JSON_TPL
Definition: json.h:2213
#define JSON_HEDLEY_UNLIKELY(expr)
Definition: json.h:1445
#define JSON_TRY
Definition: json.h:2132
#define NLOHMANN_JSON_VERSION_MINOR
Definition: json.h:34
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition: json.h:869
#define JSON_EXPLICIT
Definition: json.h:2377
#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
Definition: json.h:1138
#define JSON_HEDLEY_PURE
Definition: json.h:1516
def indent(source, debug, level)
Definition: check-style.py:432
Definition: first.py:1
stack
Definition: first.py:41
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
v = buf * 10^decimal_exponent len is the length of the buffer (number of decimal digits) The buffer m...
Definition: json.h:15236
Target reinterpret_bits(const Source source)
Definition: json.h:14454
boundaries compute_boundaries(FloatType value)
Compute the (normalized) diyfp representing the input number 'value' and its boundaries.
Definition: json.h:14595
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
Definition: json.h:14898
constexpr int kGamma
Definition: json.h:14718
void grisu2_round(char *buf, int len, std::uint64_t dist, std::uint64_t delta, std::uint64_t rest, std::uint64_t ten_k)
Definition: json.h:14954
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
Definition: json.h:14995
JSON_HEDLEY_RETURNS_NON_NULL char * format_buffer(char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
prettify v = buf * 10^decimal_exponent
Definition: json.h:15388
constexpr int kAlpha
Definition: json.h:14717
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.h:15336
cached_power get_cached_power_for_binary_exponent(int e)
For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached power-of-ten c = f_c ...
Definition: json.h:14734
typename std::enable_if< B, T >::type enable_if_t
Definition: json.h:2746
typename T::reference reference_t
Definition: json.h:3082
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.h:3471
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition: json.h:3094
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.h:4280
value_t
the JSON type enumeration
Definition: json.h:3445
@ number_integer
number value (signed integer)
@ discarded
discarded by the parser callback function
@ binary
binary array (ordered collection of bytes)
@ object
object (unordered set of name/value pairs)
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition: json.h:3493
decltype(std::declval< T & >().parse_error(std::declval< std::size_t >(), std::declval< const std::string & >(), std::declval< const Exception & >())) parse_error_function_t
Definition: json.h:7638
typename T::pointer pointer_t
Definition: json.h:3079
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
Definition: json.h:7611
void from_json_tuple_impl(const BasicJsonType &j, Tuple &t, index_sequence< Idx... >)
Definition: json.h:3800
@ value
the parser finished reading a JSON value
@ key
the parser read a key of a value in an object
@ array_end
the parser read ] and finished processing a JSON array
@ array_start
the parser read [ and started to process a JSON array
@ object_start
the parser read { and started to process a JSON object
@ object_end
the parser read } and finished processing a JSON object
typename T::difference_type difference_type_t
Definition: json.h:3076
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition: json.h:2921
void int_to_string(string_type &target, std::size_t value)
Definition: json.h:3902
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
Definition: json.h:3641
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
Definition: json.h:7623
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
Definition: json.h:7595
decltype(std::declval< T & >().binary(std::declval< Binary & >())) binary_function_t
Definition: json.h:7615
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
Definition: json.h:7599
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition: json.h:4403
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition: json.h:2934
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.h:2749
cbor_tag_handler_t
how to treat CBOR tags
Definition: json.h:7737
@ error
throw a parse_error exception in case of a tag
error_handler_t
how to treat decoding errors
Definition: json.h:15544
@ strict
throw a type_error exception in case of invalid UTF-8
@ ignore
ignore invalid UTF-8 sequences
@ replace
replace invalid UTF-8 sequences with U+FFFD
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
Definition: json.h:7619
typename T::key_type key_type_t
Definition: json.h:3070
std::size_t combine(std::size_t seed, std::size_t h) noexcept
Definition: json.h:4662
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.h:4680
JSON_HEDLEY_RETURNS_NON_NULL char * to_chars(char *first, const char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
Definition: json.h:15473
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
Definition: json.h:7603
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Definition: json.h:2930
typename detected_or< Default, Op, Args... >::type detected_or_t
Definition: json.h:2927
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
Definition: json.h:7630
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.h:3507
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition: json.h:2918
typename make_void< Ts... >::type void_t
Definition: json.h:2821
std::function< bool(int depth, parse_event_t event, BasicJsonType &parsed)> parser_callback_t
Definition: json.h:10224
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.h:12715
typename T::mapped_type mapped_type_t
Definition: json.h:3067
typename T::iterator iterator_t
Definition: json.h:3088
input_format_t
the supported input formats
Definition: json.h:4812
void to_json(BasicJsonType &j, const T &b)
Definition: json.h:4397
decltype(std::declval< T >().template get< U >()) get_template_function
Definition: json.h:3097
decltype(input_adapter(std::declval< const char * >(), std::declval< const char * >())) contiguous_bytes_input_adapter
Definition: json.h:5189
decltype(std::declval< T & >().null()) null_function_t
Definition: json.h:7591
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.h:4023
iterator_input_adapter_factory< IteratorType >::adapter_type input_adapter(IteratorType first, IteratorType last)
Definition: json.h:5156
typename T::iterator_category iterator_category_t
Definition: json.h:3085
static bool little_endianess(int num=1) noexcept
determine system byte order
Definition: json.h:7749
decltype(std::declval< T & >().number_float(std::declval< Float >(), std::declval< const String & >())) number_float_function_t
Definition: json.h:7607
decltype(std::declval< T & >().end_array()) end_array_function_t
Definition: json.h:7633
void from_json(const BasicJsonType &j, std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > &m)
Definition: json.h:3834
decltype(std::declval< T & >().end_object()) end_object_function_t
Definition: json.h:7626
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition: json.h:3091
typename T::value_type value_type_t
Definition: json.h:3073
namespace for Niels Lohmann
Definition: json.h:82
basic_json<> json
default JSON class
Definition: json.h:3000
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.h:25255
Time & operator+=(Time &lhs, const Time &rhs)
Compound addition assignment for Time.
Definition: nstime.h:1115
void swap(UUID &uuid1, UUID &uuid2) noexcept
Definition: uuid.cc:212
list x
Random number samples.
def start()
Definition: core.py:1853
#define E(name, start, end)
unsigned char byte
Definition: qkd-encryptor.h:64
default JSONSerializer template argument
Definition: json.h:4438
static auto to_json(BasicJsonType &j, ValueType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< ValueType >(val)))) -> decltype(::nlohmann::to_json(j, std::forward< ValueType >(val)), void())
convert any value type to a JSON value
Definition: json.h:4466
static auto from_json(BasicJsonType &&j, ValueType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), val), void())
convert a JSON value to any value type
Definition: json.h:4449
std::false_type value_t
Definition: json.h:2906
static constexpr int kPrecision
Definition: json.h:14465
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.h:14553
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
Definition: json.h:14570
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.h:14488
constexpr diyfp(std::uint64_t f_, int e_) noexcept
Definition: json.h:14470
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.h:14476
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.h:4205
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition: json.h:4229
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: json.h:4215
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition: json.h:4195
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.h:4187
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition: json.h:4129
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition: json.h:4138
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: json.h:4087
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: json.h:4151
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: json.h:4175
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: json.h:4163
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition: json.h:4254
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.h:4246
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.h:4263
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition: json.h:4107
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition: json.h:4117
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: json.h:4099
auto operator()(const BasicJsonType &j, T &val) const noexcept(noexcept(from_json(j, val))) -> decltype(from_json(j, val), void())
Definition: json.h:3854
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.h:3117
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.h:3147
static constexpr std::size_t size() noexcept
Definition: json.h:2758
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.h:10827
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.h:10825
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition: json.h:10823
static constexpr bool value
Definition: json.h:3110
typename std::iterator_traits< T >::value_type value_type
Definition: json.h:5133
typename BasicJsonType::string_t string_t
Definition: json.h:7681
typename BasicJsonType::exception exception_t
Definition: json.h:7683
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.h:7678
typename BasicJsonType::number_float_t number_float_t
Definition: json.h:7680
typename BasicJsonType::binary_t binary_t
Definition: json.h:7682
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.h:7679
typename BasicJsonType::number_float_t number_float_t
Definition: json.h:7649
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.h:7648
typename BasicJsonType::exception exception_t
Definition: json.h:7652
static constexpr bool value
Definition: json.h:7655
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.h:7647
typename BasicJsonType::string_t string_t
Definition: json.h:7650
typename BasicJsonType::binary_t binary_t
Definition: json.h:7651
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.h:5121
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.h:5124
iterator_input_adapter< iterator_type > adapter_type
Definition: json.h:5122
nonesuch(nonesuch const &)=delete
void operator=(nonesuch &&)=delete
nonesuch(nonesuch const &&)=delete
void operator=(nonesuch const &)=delete
abstract output adapter interface
Definition: json.h:12707
virtual void write_characters(const CharType *s, std::size_t length)=0
virtual void write_character(CharType c)=0
struct to capture the start position of the current token
Definition: json.h:87
std::size_t lines_read
the number of lines read
Definition: json.h:93
std::size_t chars_read_current_line
the number of characters read in the current line
Definition: json.h:91
std::size_t chars_read_total
the total number of characters read
Definition: json.h:89
static constexpr T value
Definition: json.h:2790
auto operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
Definition: json.h:4417
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.h:5013
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.h:4955
SAX interface.
Definition: json.h:5271
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
virtual bool string(string_t &val)=0
a string was read
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.h:5272
typename BasicJsonType::binary_t binary_t
Definition: json.h:5276
virtual bool end_array()=0
the end of an array was read
virtual bool key(string_t &val)=0
an object key was read
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.h:5273
virtual bool binary(binary_t &val)=0
a binary string was read
typename BasicJsonType::number_float_t number_float_t
Definition: json.h:5274
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
virtual bool boolean(bool val)=0
a boolean value was read
virtual bool end_object()=0
the end of an object was read
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
typename BasicJsonType::string_t string_t
Definition: json.h:5275
virtual bool number_float(number_float_t val, const string_t &s)=0
an floating-point number was read
virtual ~json_sax()=default
virtual bool number_integer(number_integer_t val)=0
an integer number was read
ordered_map: a minimal map-like container that preserves insertion order for use within nlohmann::bas...
Definition: json.h:16484
std::pair< iterator, bool > insert(const value_type &value)
Definition: json.h:16625
ordered_map(std::initializer_list< T > init, const Allocator &alloc=Allocator())
Definition: json.h:16499
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.h:16487
iterator find(const Key &key)
Definition: json.h:16596
iterator erase(iterator pos)
Definition: json.h:16570
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition: json.h:16502
const_iterator find(const Key &key) const
Definition: json.h:16608
std::pair< iterator, bool > insert(value_type &&value)
Definition: json.h:16620
size_type erase(const Key &key)
Definition: json.h:16551
const T & operator[](const Key &key) const
Definition: json.h:16520
ordered_map(const Allocator &alloc=Allocator())
Definition: json.h:16495
const T & at(const Key &key) const
Definition: json.h:16538
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition: json.h:16497
T & at(const Key &key)
Definition: json.h:16525
T & operator[](const Key &key)
Definition: json.h:16515
size_type count(const Key &key) const
Definition: json.h:16584
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
Definition: json.h:25278
bool operator()(nlohmann::detail::value_t lhs, nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.h:25294